summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_hir_analysis/src/check/check.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_hir_analysis/src/check/check.rs')
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs87
1 files changed, 48 insertions, 39 deletions
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index e61ca232d..8413a1cc0 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -1,5 +1,5 @@
use crate::check::intrinsicck::InlineAsmCtxt;
-use crate::errors::{self, LinkageType};
+use crate::errors::LinkageType;
use super::compare_impl_item::check_type_bounds;
use super::compare_impl_item::{compare_impl_method, compare_impl_ty};
@@ -8,9 +8,8 @@ use rustc_attr as attr;
use rustc_errors::{ErrorGuaranteed, MultiSpan};
use rustc_hir as hir;
use rustc_hir::def::{CtorKind, DefKind};
-use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId};
+use rustc_hir::def_id::LocalModDefId;
use rustc_hir::Node;
-use rustc_infer::infer::outlives::env::OutlivesEnvironment;
use rustc_infer::infer::{RegionVariableOrigin, TyCtxtInferExt};
use rustc_infer::traits::{Obligation, TraitEngineExt as _};
use rustc_lint_defs::builtin::REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS;
@@ -21,18 +20,15 @@ use rustc_middle::ty::layout::{LayoutError, MAX_SIMD_LANES};
use rustc_middle::ty::util::{Discr, IntTypeExt};
use rustc_middle::ty::GenericArgKind;
use rustc_middle::ty::{
- self, AdtDef, ParamEnv, RegionKind, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable,
- TypeVisitableExt,
+ AdtDef, ParamEnv, RegionKind, TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
};
use rustc_session::lint::builtin::{UNINHABITED_STATIC, UNSUPPORTED_CALLING_CONVENTIONS};
use rustc_span::symbol::sym;
-use rustc_span::{self, Span};
use rustc_target::abi::FieldIdx;
-use rustc_target::spec::abi::Abi;
use rustc_trait_selection::traits::error_reporting::on_unimplemented::OnUnimplementedDirective;
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _;
use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt as _;
-use rustc_trait_selection::traits::{self, ObligationCtxt, TraitEngine, TraitEngineExt as _};
+use rustc_trait_selection::traits::{self, TraitEngine, TraitEngineExt as _};
use rustc_type_ir::fold::TypeFoldable;
use std::ops::ControlFlow;
@@ -55,7 +51,7 @@ pub fn check_abi(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: Abi) {
hir_id,
span,
"use of calling convention not supported on this target",
- |lint| lint,
+ |_| {},
);
}
}
@@ -130,7 +126,7 @@ fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: LocalDefId) -> b
for field in &def.non_enum_variant().fields {
let Ok(field_ty) = tcx.try_normalize_erasing_regions(param_env, field.ty(tcx, args))
else {
- tcx.sess.delay_span_bug(span, "could not normalize field type");
+ tcx.sess.span_delayed_bug(span, "could not normalize field type");
continue;
};
@@ -151,7 +147,8 @@ fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: LocalDefId) -> b
return false;
} else if field_ty.needs_drop(tcx, param_env) {
// This should never happen. But we can get here e.g. in case of name resolution errors.
- tcx.sess.delay_span_bug(span, "we should never accept maybe-dropping union fields");
+ tcx.sess
+ .span_delayed_bug(span, "we should never accept maybe-dropping union fields");
}
}
} else {
@@ -181,19 +178,19 @@ fn check_static_inhabited(tcx: TyCtxt<'_>, def_id: LocalDefId) {
}
// Generic statics are rejected, but we still reach this case.
Err(e) => {
- tcx.sess.delay_span_bug(span, format!("{e:?}"));
+ tcx.sess.span_delayed_bug(span, format!("{e:?}"));
return;
}
};
if layout.abi.is_uninhabited() {
tcx.struct_span_lint_hir(
UNINHABITED_STATIC,
- tcx.hir().local_def_id_to_hir_id(def_id),
+ tcx.local_def_id_to_hir_id(def_id),
span,
"static of uninhabited type",
|lint| {
lint
- .note("uninhabited statics cannot be initialized, and any access would be an immediate error")
+ .note("uninhabited statics cannot be initialized, and any access would be an immediate error");
},
);
}
@@ -204,7 +201,7 @@ fn check_static_inhabited(tcx: TyCtxt<'_>, def_id: LocalDefId) {
fn check_opaque(tcx: TyCtxt<'_>, id: hir::ItemId) {
let item = tcx.hir().item(id);
let hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) = item.kind else {
- tcx.sess.delay_span_bug(item.span, "expected opaque item");
+ tcx.sess.span_delayed_bug(item.span, "expected opaque item");
return;
};
@@ -222,11 +219,11 @@ fn check_opaque(tcx: TyCtxt<'_>, id: hir::ItemId) {
if tcx.type_of(item.owner_id.def_id).instantiate_identity().references_error() {
return;
}
- if check_opaque_for_cycles(tcx, item.owner_id.def_id, args, span, &origin).is_err() {
+ if check_opaque_for_cycles(tcx, item.owner_id.def_id, args, span, origin).is_err() {
return;
}
- let _ = check_opaque_meets_bounds(tcx, item.owner_id.def_id, span, &origin);
+ let _ = check_opaque_meets_bounds(tcx, item.owner_id.def_id, span, origin);
}
/// Checks that an opaque type does not contain cycles.
@@ -313,7 +310,7 @@ fn check_opaque_meets_bounds<'tcx>(
Ok(()) => {}
Err(ty_err) => {
let ty_err = ty_err.to_string(tcx);
- return Err(tcx.sess.delay_span_bug(
+ return Err(tcx.sess.span_delayed_bug(
span,
format!("could not unify `{hidden_ty}` with revealed type:\n{ty_err}"),
));
@@ -482,7 +479,7 @@ fn check_item_type(tcx: TyCtxt<'_>, id: hir::ItemId) {
match assoc_item.kind {
ty::AssocKind::Fn => {
let abi = tcx.fn_sig(assoc_item.def_id).skip_binder().abi();
- fn_maybe_err(tcx, assoc_item.ident(tcx).span, abi);
+ forbid_intrinsic_abi(tcx, assoc_item.ident(tcx).span, abi);
}
ty::AssocKind::Type if assoc_item.defaultness(tcx).has_value() => {
let trait_args = GenericArgs::identity_for_item(tcx, id.owner_id);
@@ -507,7 +504,7 @@ fn check_item_type(tcx: TyCtxt<'_>, id: hir::ItemId) {
let origin = tcx.opaque_type_origin(id.owner_id.def_id);
if let hir::OpaqueTyOrigin::FnReturn(fn_def_id)
| hir::OpaqueTyOrigin::AsyncFn(fn_def_id) = origin
- && let hir::Node::TraitItem(trait_item) = tcx.hir().get_by_def_id(fn_def_id)
+ && let hir::Node::TraitItem(trait_item) = tcx.hir_node_by_def_id(fn_def_id)
&& let (_, hir::TraitFn::Required(..)) = trait_item.expect_fn()
{
// Skip opaques from RPIT in traits with no default body.
@@ -518,7 +515,7 @@ fn check_item_type(tcx: TyCtxt<'_>, id: hir::ItemId) {
DefKind::TyAlias => {
let pty_ty = tcx.type_of(id.owner_id).instantiate_identity();
let generics = tcx.generics_of(id.owner_id);
- check_type_params_are_used(tcx, &generics, pty_ty);
+ check_type_params_are_used(tcx, generics, pty_ty);
}
DefKind::ForeignMod => {
let it = tcx.hir().item(id);
@@ -655,7 +652,7 @@ pub(super) fn check_specialization_validity<'tcx>(
if !tcx.is_impl_trait_in_trait(impl_item) {
report_forbidden_specialization(tcx, impl_item, parent_impl);
} else {
- tcx.sess.delay_span_bug(
+ tcx.sess.span_delayed_bug(
DUMMY_SP,
format!("parent item: {parent_impl:?} not marked as default"),
);
@@ -703,7 +700,7 @@ fn check_impl_items_against_trait<'tcx>(
tcx.associated_item(trait_item_id)
} else {
// Checked in `associated_item`.
- tcx.sess.delay_span_bug(tcx.def_span(impl_item), "missing associated item in trait");
+ tcx.sess.span_delayed_bug(tcx.def_span(impl_item), "missing associated item in trait");
continue;
};
match ty_impl_item.kind {
@@ -753,8 +750,7 @@ fn check_impl_items_against_trait<'tcx>(
leaf_def.as_ref().is_some_and(|node_item| !node_item.defining_node.is_from_trait());
if !is_implemented_here {
- let full_impl_span =
- tcx.hir().span_with_body(tcx.hir().local_def_id_to_hir_id(impl_id));
+ let full_impl_span = tcx.hir().span_with_body(tcx.local_def_id_to_hir_id(impl_id));
match tcx.eval_default_body_stability(trait_item_id, full_impl_span) {
EvalResult::Deny { feature, reason, issue, .. } => default_body_is_unstable(
tcx,
@@ -811,8 +807,7 @@ fn check_impl_items_against_trait<'tcx>(
}
if !missing_items.is_empty() {
- let full_impl_span =
- tcx.hir().span_with_body(tcx.hir().local_def_id_to_hir_id(impl_id));
+ let full_impl_span = tcx.hir().span_with_body(tcx.local_def_id_to_hir_id(impl_id));
missing_items_err(tcx, impl_id, &missing_items, full_impl_span);
}
@@ -900,7 +895,7 @@ pub(super) fn check_packed(tcx: TyCtxt<'_>, sp: Span, def: ty::AdtDef<'_>) {
let repr = def.repr();
if repr.packed() {
for attr in tcx.get_attrs(def.did(), sym::repr) {
- for r in attr::parse_repr_attr(&tcx.sess, attr) {
+ for r in attr::parse_repr_attr(tcx.sess, attr) {
if let attr::ReprPacked(pack) = r
&& let Some(repr_pack) = repr.pack
&& pack as u64 != repr_pack.bytes()
@@ -1083,7 +1078,7 @@ pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>)
if non_trivial_count > 0 || prev_non_exhaustive_1zst {
tcx.struct_span_lint_hir(
REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS,
- tcx.hir().local_def_id_to_hir_id(adt.did().expect_local()),
+ tcx.local_def_id_to_hir_id(adt.did().expect_local()),
span,
"zero-sized fields in `repr(transparent)` cannot \
contain external non-exhaustive types",
@@ -1098,7 +1093,7 @@ pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>)
"this {descr} contains `{field_ty}`, which {note}, \
and makes it not a breaking change to become \
non-zero-sized in the future."
- ))
+ ));
},
)
} else {
@@ -1150,8 +1145,8 @@ fn check_enum(tcx: TyCtxt<'_>, def_id: LocalDefId) {
let has_disr = |var: &ty::VariantDef| matches!(var.discr, ty::VariantDiscr::Explicit(_));
let has_non_units = def.variants().iter().any(|var| !is_unit(var));
- let disr_units = def.variants().iter().any(|var| is_unit(&var) && has_disr(&var));
- let disr_non_unit = def.variants().iter().any(|var| !is_unit(&var) && has_disr(&var));
+ let disr_units = def.variants().iter().any(|var| is_unit(var) && has_disr(var));
+ let disr_non_unit = def.variants().iter().any(|var| !is_unit(var) && has_disr(var));
if disr_non_unit || (disr_units && has_non_units) {
let mut err = struct_span_err!(
@@ -1178,7 +1173,7 @@ fn detect_discriminant_duplicate<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>)
ty::VariantDiscr::Explicit(discr_def_id) => {
// In the case the discriminant is both a duplicate and overflowed, let the user know
if let hir::Node::AnonConst(expr) =
- tcx.hir().get_by_def_id(discr_def_id.expect_local())
+ tcx.hir_node_by_def_id(discr_def_id.expect_local())
&& let hir::ExprKind::Lit(lit) = &tcx.hir().body(expr.body).value.kind
&& let rustc_ast::LitKind::Int(lit_value, _int_kind) = &lit.node
&& *lit_value != dis.val
@@ -1451,7 +1446,7 @@ fn opaque_type_cycle_error(
label_match(capture.place.ty(), capture.get_path_span(tcx));
}
// Label any coroutine locals that capture the opaque
- if let DefKind::Coroutine = tcx.def_kind(closure_def_id)
+ if tcx.is_coroutine(closure_def_id)
&& let Some(coroutine_layout) = tcx.mir_coroutine_witnesses(closure_def_id)
{
for interior_ty in &coroutine_layout.field_tys {
@@ -1468,8 +1463,11 @@ fn opaque_type_cycle_error(
err.emit()
}
-pub(super) fn check_coroutine_obligations(tcx: TyCtxt<'_>, def_id: LocalDefId) {
- debug_assert!(matches!(tcx.def_kind(def_id), DefKind::Coroutine));
+pub(super) fn check_coroutine_obligations(
+ tcx: TyCtxt<'_>,
+ def_id: LocalDefId,
+) -> Result<(), ErrorGuaranteed> {
+ debug_assert!(tcx.is_coroutine(def_id.to_def_id()));
let typeck = tcx.typeck(def_id);
let param_env = tcx.param_env(def_id);
@@ -1482,8 +1480,9 @@ pub(super) fn check_coroutine_obligations(tcx: TyCtxt<'_>, def_id: LocalDefId) {
// typeck writeback gives us predicates with their regions erased.
// As borrowck already has checked lifetimes, we do not need to do it again.
.ignoring_regions()
- // Bind opaque types to `def_id` as they should have been checked by borrowck.
- .with_opaque_type_inference(DefiningAnchor::Bind(def_id))
+ // Bind opaque types to type checking root, as they should have been checked by borrowck,
+ // but may show up in some cases, like when (root) obligations are stalled in the new solver.
+ .with_opaque_type_inference(DefiningAnchor::Bind(typeck.hir_owner.def_id))
.build();
let mut fulfillment_cx = <dyn TraitEngine<'_>>::new(&infcx);
@@ -1513,6 +1512,16 @@ pub(super) fn check_coroutine_obligations(tcx: TyCtxt<'_>, def_id: LocalDefId) {
let errors = fulfillment_cx.select_all_or_error(&infcx);
debug!(?errors);
if !errors.is_empty() {
- infcx.err_ctxt().report_fulfillment_errors(errors);
+ return Err(infcx.err_ctxt().report_fulfillment_errors(errors));
}
+
+ // Check that any hidden types found when checking these stalled coroutine obligations
+ // are valid.
+ for (key, ty) in infcx.take_opaque_types() {
+ let hidden_type = infcx.resolve_vars_if_possible(ty.hidden_type);
+ let key = infcx.resolve_vars_if_possible(key);
+ sanity_check_found_hidden_type(tcx, key, hidden_type)?;
+ }
+
+ Ok(())
}