summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_hir_analysis/src/check
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_hir_analysis/src/check')
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs87
-rw-r--r--compiler/rustc_hir_analysis/src/check/compare_impl_item.rs417
-rw-r--r--compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs17
-rw-r--r--compiler/rustc_hir_analysis/src/check/dropck.rs5
-rw-r--r--compiler/rustc_hir_analysis/src/check/entry.rs65
-rw-r--r--compiler/rustc_hir_analysis/src/check/intrinsic.rs36
-rw-r--r--compiler/rustc_hir_analysis/src/check/intrinsicck.rs32
-rw-r--r--compiler/rustc_hir_analysis/src/check/mod.rs57
-rw-r--r--compiler/rustc_hir_analysis/src/check/region.rs37
-rw-r--r--compiler/rustc_hir_analysis/src/check/wfcheck.rs111
10 files changed, 346 insertions, 518 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(())
}
diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
index 857515f97..264868fdf 100644
--- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
+++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
@@ -2,9 +2,7 @@ use super::potentially_plural_count;
use crate::errors::LifetimesOrBoundsMismatchOnTrait;
use hir::def_id::{DefId, LocalDefId};
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
-use rustc_errors::{
- pluralize, struct_span_err, Applicability, DiagnosticId, ErrorGuaranteed, MultiSpan,
-};
+use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticId, ErrorGuaranteed};
use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::intravisit;
@@ -50,13 +48,7 @@ pub(super) fn compare_impl_method<'tcx>(
let _: Result<_, ErrorGuaranteed> = try {
check_method_is_structurally_compatible(tcx, impl_m, trait_m, impl_trait_ref, false)?;
- compare_method_predicate_entailment(
- tcx,
- impl_m,
- trait_m,
- impl_trait_ref,
- CheckImpliedWfMode::Check,
- )?;
+ compare_method_predicate_entailment(tcx, impl_m, trait_m, impl_trait_ref)?;
refine::check_refining_return_position_impl_trait_in_trait(
tcx,
impl_m,
@@ -170,7 +162,6 @@ fn compare_method_predicate_entailment<'tcx>(
impl_m: ty::AssocItem,
trait_m: ty::AssocItem,
impl_trait_ref: ty::TraitRef<'tcx>,
- check_implied_wf: CheckImpliedWfMode,
) -> Result<(), ErrorGuaranteed> {
let trait_to_impl_args = impl_trait_ref.args;
@@ -307,7 +298,7 @@ fn compare_method_predicate_entailment<'tcx>(
debug!(?impl_sig, ?trait_sig, ?terr, "sub_types failed");
let emitted = report_trait_method_mismatch(
- &infcx,
+ infcx,
cause,
terr,
(trait_m, trait_sig),
@@ -317,10 +308,10 @@ fn compare_method_predicate_entailment<'tcx>(
return Err(emitted);
}
- if check_implied_wf == CheckImpliedWfMode::Check && !(impl_sig, trait_sig).references_error() {
+ if !(impl_sig, trait_sig).references_error() {
// Select obligations to make progress on inference before processing
// the wf obligation below.
- // FIXME(-Ztrait-solver=next): Not needed when the hack below is removed.
+ // FIXME(-Znext-solver): Not needed when the hack below is removed.
let errors = ocx.select_where_possible();
if !errors.is_empty() {
let reported = infcx.err_ctxt().report_fulfillment_errors(errors);
@@ -333,8 +324,9 @@ fn compare_method_predicate_entailment<'tcx>(
// trigger the lint. Instead, let's only consider type outlives and
// region outlives obligations.
//
- // FIXME(-Ztrait-solver=next): Try removing this hack again once
- // the new solver is stable.
+ // FIXME(-Znext-solver): Try removing this hack again once the new
+ // solver is stable. We should just be able to register a WF pred for
+ // the fn sig.
let mut wf_args: smallvec::SmallVec<[_; 4]> =
unnormalized_impl_sig.inputs_and_output.iter().map(|ty| ty.into()).collect();
// Annoyingly, asking for the WF predicates of an array (with an unevaluated const (only?))
@@ -357,7 +349,7 @@ fn compare_method_predicate_entailment<'tcx>(
// We need to register Projection oblgiations too, because we may end up with
// an implied `X::Item: 'a`, which gets desugared into `X::Item = ?0`, `?0: 'a`.
// If we only register the region outlives obligation, this leads to an unconstrained var.
- // See `implied_bounds_entailment_alias_var` test.
+ // See `implied_bounds_entailment_alias_var.rs` test.
ty::PredicateKind::Clause(
ty::ClauseKind::RegionOutlives(..)
| ty::ClauseKind::TypeOutlives(..)
@@ -378,26 +370,8 @@ fn compare_method_predicate_entailment<'tcx>(
// version.
let errors = ocx.select_all_or_error();
if !errors.is_empty() {
- match check_implied_wf {
- CheckImpliedWfMode::Check => {
- let impl_m_hir_id = tcx.hir().local_def_id_to_hir_id(impl_m_def_id);
- return compare_method_predicate_entailment(
- tcx,
- impl_m,
- trait_m,
- impl_trait_ref,
- CheckImpliedWfMode::Skip,
- )
- .map(|()| {
- // If the skip-mode was successful, emit a lint.
- emit_implied_wf_lint(infcx.tcx, impl_m, impl_m_hir_id, vec![]);
- });
- }
- CheckImpliedWfMode::Skip => {
- let reported = infcx.err_ctxt().report_fulfillment_errors(errors);
- return Err(reported);
- }
- }
+ let reported = infcx.err_ctxt().report_fulfillment_errors(errors);
+ return Err(reported);
}
// Finally, resolve all regions. This catches wily misuses of
@@ -408,119 +382,14 @@ fn compare_method_predicate_entailment<'tcx>(
);
let errors = infcx.resolve_regions(&outlives_env);
if !errors.is_empty() {
- // FIXME(compiler-errors): This can be simplified when IMPLIED_BOUNDS_ENTAILMENT
- // becomes a hard error (i.e. ideally we'd just call `resolve_regions_and_report_errors`
- let impl_m_hir_id = tcx.hir().local_def_id_to_hir_id(impl_m_def_id);
- match check_implied_wf {
- CheckImpliedWfMode::Check => {
- return compare_method_predicate_entailment(
- tcx,
- impl_m,
- trait_m,
- impl_trait_ref,
- CheckImpliedWfMode::Skip,
- )
- .map(|()| {
- let bad_args = extract_bad_args_for_implies_lint(
- tcx,
- &errors,
- (trait_m, trait_sig),
- // Unnormalized impl sig corresponds to the HIR types written
- (impl_m, unnormalized_impl_sig),
- impl_m_hir_id,
- );
- // If the skip-mode was successful, emit a lint.
- emit_implied_wf_lint(tcx, impl_m, impl_m_hir_id, bad_args);
- });
- }
- CheckImpliedWfMode::Skip => {
- if infcx.tainted_by_errors().is_none() {
- infcx.err_ctxt().report_region_errors(impl_m_def_id, &errors);
- }
- return Err(tcx
- .sess
- .delay_span_bug(rustc_span::DUMMY_SP, "error should have been emitted"));
- }
- }
+ return Err(infcx
+ .tainted_by_errors()
+ .unwrap_or_else(|| infcx.err_ctxt().report_region_errors(impl_m_def_id, &errors)));
}
Ok(())
}
-fn extract_bad_args_for_implies_lint<'tcx>(
- tcx: TyCtxt<'tcx>,
- errors: &[infer::RegionResolutionError<'tcx>],
- (trait_m, trait_sig): (ty::AssocItem, ty::FnSig<'tcx>),
- (impl_m, impl_sig): (ty::AssocItem, ty::FnSig<'tcx>),
- hir_id: hir::HirId,
-) -> Vec<(Span, Option<String>)> {
- let mut blame_generics = vec![];
- for error in errors {
- // Look for the subregion origin that contains an input/output type
- let origin = match error {
- infer::RegionResolutionError::ConcreteFailure(o, ..) => o,
- infer::RegionResolutionError::GenericBoundFailure(o, ..) => o,
- infer::RegionResolutionError::SubSupConflict(_, _, o, ..) => o,
- infer::RegionResolutionError::UpperBoundUniverseConflict(.., o, _) => o,
- };
- // Extract (possible) input/output types from origin
- match origin {
- infer::SubregionOrigin::Subtype(trace) => {
- if let Some((a, b)) = trace.values.ty() {
- blame_generics.extend([a, b]);
- }
- }
- infer::SubregionOrigin::RelateParamBound(_, ty, _) => blame_generics.push(*ty),
- infer::SubregionOrigin::ReferenceOutlivesReferent(ty, _) => blame_generics.push(*ty),
- _ => {}
- }
- }
-
- let fn_decl = tcx.hir().fn_decl_by_hir_id(hir_id).unwrap();
- let opt_ret_ty = match fn_decl.output {
- hir::FnRetTy::DefaultReturn(_) => None,
- hir::FnRetTy::Return(ty) => Some(ty),
- };
-
- // Map late-bound regions from trait to impl, so the names are right.
- let mapping = std::iter::zip(
- tcx.fn_sig(trait_m.def_id).skip_binder().bound_vars(),
- tcx.fn_sig(impl_m.def_id).skip_binder().bound_vars(),
- )
- .filter_map(|(impl_bv, trait_bv)| {
- if let ty::BoundVariableKind::Region(impl_bv) = impl_bv
- && let ty::BoundVariableKind::Region(trait_bv) = trait_bv
- {
- Some((impl_bv, trait_bv))
- } else {
- None
- }
- })
- .collect();
-
- // For each arg, see if it was in the "blame" of any of the region errors.
- // If so, then try to produce a suggestion to replace the argument type with
- // one from the trait.
- let mut bad_args = vec![];
- for (idx, (ty, hir_ty)) in
- std::iter::zip(impl_sig.inputs_and_output, fn_decl.inputs.iter().chain(opt_ret_ty))
- .enumerate()
- {
- let expected_ty = trait_sig.inputs_and_output[idx]
- .fold_with(&mut RemapLateBound { tcx, mapping: &mapping });
- if blame_generics.iter().any(|blame| ty.contains(*blame)) {
- let expected_ty_sugg = expected_ty.to_string();
- bad_args.push((
- hir_ty.span,
- // Only suggest something if it actually changed.
- (expected_ty_sugg != ty.to_string()).then_some(expected_ty_sugg),
- ));
- }
- }
-
- bad_args
-}
-
struct RemapLateBound<'a, 'tcx> {
tcx: TyCtxt<'tcx>,
mapping: &'a FxHashMap<ty::BoundRegionKind, ty::BoundRegionKind>,
@@ -532,8 +401,8 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for RemapLateBound<'_, 'tcx> {
}
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
- if let ty::ReFree(fr) = *r {
- ty::Region::new_free(
+ if let ty::ReLateParam(fr) = *r {
+ ty::Region::new_late_param(
self.tcx,
fr.scope,
self.mapping.get(&fr.bound_region).copied().unwrap_or(fr.bound_region),
@@ -544,53 +413,6 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for RemapLateBound<'_, 'tcx> {
}
}
-fn emit_implied_wf_lint<'tcx>(
- tcx: TyCtxt<'tcx>,
- impl_m: ty::AssocItem,
- hir_id: hir::HirId,
- bad_args: Vec<(Span, Option<String>)>,
-) {
- let span: MultiSpan = if bad_args.is_empty() {
- tcx.def_span(impl_m.def_id).into()
- } else {
- bad_args.iter().map(|(span, _)| *span).collect::<Vec<_>>().into()
- };
- tcx.struct_span_lint_hir(
- rustc_session::lint::builtin::IMPLIED_BOUNDS_ENTAILMENT,
- hir_id,
- span,
- "impl method assumes more implied bounds than the corresponding trait method",
- |lint| {
- let bad_args: Vec<_> =
- bad_args.into_iter().filter_map(|(span, sugg)| Some((span, sugg?))).collect();
- if !bad_args.is_empty() {
- lint.multipart_suggestion(
- format!(
- "replace {} type{} to make the impl signature compatible",
- pluralize!("this", bad_args.len()),
- pluralize!(bad_args.len())
- ),
- bad_args,
- Applicability::MaybeIncorrect,
- );
- }
- lint
- },
- );
-}
-
-#[derive(Debug, PartialEq, Eq)]
-enum CheckImpliedWfMode {
- /// Checks implied well-formedness of the impl method. If it fails, we will
- /// re-check with `Skip`, and emit a lint if it succeeds.
- Check,
- /// Skips checking implied well-formedness of the impl method, but will emit
- /// a lint if the `compare_method_predicate_entailment` succeeded. This means that
- /// the reason that we had failed earlier during `Check` was due to the impl
- /// having stronger requirements than the trait.
- Skip,
-}
-
fn compare_asyncness<'tcx>(
tcx: TyCtxt<'tcx>,
impl_m: ty::AssocItem,
@@ -667,7 +489,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
let trait_to_impl_args = impl_trait_ref.args;
- let impl_m_hir_id = tcx.hir().local_def_id_to_hir_id(impl_m_def_id);
+ let impl_m_hir_id = tcx.local_def_id_to_hir_id(impl_m_def_id);
let return_span = tcx.hir().fn_decl_by_hir_id(impl_m_hir_id).unwrap().output.span();
let cause = ObligationCause::new(
return_span,
@@ -937,7 +759,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
remapped_types.insert(def_id, ty::EarlyBinder::bind(ty));
}
Err(err) => {
- let reported = tcx.sess.delay_span_bug(
+ let reported = tcx.sess.span_delayed_bug(
return_span,
format!("could not fully resolve: {ty} => {err:?}"),
);
@@ -1078,20 +900,26 @@ impl<'tcx> ty::FallibleTypeFolder<TyCtxt<'tcx>> for RemapHiddenTyRegions<'tcx> {
region: ty::Region<'tcx>,
) -> Result<ty::Region<'tcx>, Self::Error> {
match region.kind() {
- // Remap all free regions, which correspond to late-bound regions in the function.
- ty::ReFree(_) => {}
+ // Remap late-bound regions from the function.
+ ty::ReLateParam(_) => {}
// Remap early-bound regions as long as they don't come from the `impl` itself,
// in which case we don't really need to renumber them.
- ty::ReEarlyBound(ebr) if self.tcx.parent(ebr.def_id) != self.impl_def_id => {}
+ ty::ReEarlyParam(ebr) if self.tcx.parent(ebr.def_id) != self.impl_def_id => {}
_ => return Ok(region),
}
- let e = if let Some(region) = self.map.get(&region) {
- if let ty::ReEarlyBound(e) = region.kind() { e } else { bug!() }
+ let e = if let Some(id_region) = self.map.get(&region) {
+ if let ty::ReEarlyParam(e) = id_region.kind() {
+ e
+ } else {
+ bug!(
+ "expected to map region {region} to early-bound identity region, but got {id_region}"
+ );
+ }
} else {
let guar = match region.kind() {
- ty::ReEarlyBound(ty::EarlyBoundRegion { def_id, .. })
- | ty::ReFree(ty::FreeRegion {
+ ty::ReEarlyParam(ty::EarlyParamRegion { def_id, .. })
+ | ty::ReLateParam(ty::LateParamRegion {
bound_region: ty::BoundRegionKind::BrNamed(def_id, _),
..
}) => {
@@ -1114,14 +942,16 @@ impl<'tcx> ty::FallibleTypeFolder<TyCtxt<'tcx>> for RemapHiddenTyRegions<'tcx> {
.note(format!("hidden type inferred to be `{}`", self.ty))
.emit()
}
- _ => self.tcx.sess.delay_span_bug(DUMMY_SP, "should've been able to remap region"),
+ _ => {
+ self.tcx.sess.span_delayed_bug(DUMMY_SP, "should've been able to remap region")
+ }
};
return Err(guar);
};
- Ok(ty::Region::new_early_bound(
+ Ok(ty::Region::new_early_param(
self.tcx,
- ty::EarlyBoundRegion {
+ ty::EarlyParamRegion {
def_id: e.def_id,
name: e.name,
index: (e.index as usize - self.num_trait_args + self.num_impl_args) as u32,
@@ -1140,7 +970,7 @@ fn report_trait_method_mismatch<'tcx>(
) -> ErrorGuaranteed {
let tcx = infcx.tcx;
let (impl_err_span, trait_err_span) =
- extract_spans_for_error_reporting(&infcx, terr, &cause, impl_m, trait_m);
+ extract_spans_for_error_reporting(infcx, terr, &cause, impl_m, trait_m);
let mut diag = struct_span_err!(
tcx.sess,
@@ -1473,7 +1303,7 @@ fn compare_number_of_generics<'tcx>(
// inheriting the generics from will also have mismatched arguments, and
// we'll report an error for that instead. Delay a bug for safety, though.
if trait_.is_impl_trait_in_trait() {
- return Err(tcx.sess.delay_span_bug(
+ return Err(tcx.sess.span_delayed_bug(
rustc_span::DUMMY_SP,
"errors comparing numbers of generics of trait/impl functions were not emitted",
));
@@ -1708,92 +1538,87 @@ fn compare_synthetic_generics<'tcx>(
trait_m.name
);
err.span_label(trait_span, "declaration in trait here");
- match (impl_synthetic, trait_synthetic) {
+ if impl_synthetic {
// The case where the impl method uses `impl Trait` but the trait method uses
// explicit generics
- (true, false) => {
- err.span_label(impl_span, "expected generic parameter, found `impl Trait`");
- let _: Option<_> = try {
- // try taking the name from the trait impl
- // FIXME: this is obviously suboptimal since the name can already be used
- // as another generic argument
- let new_name = tcx.opt_item_name(trait_def_id)?;
- let trait_m = trait_m.def_id.as_local()?;
- let trait_m = tcx.hir().expect_trait_item(trait_m);
-
- let impl_m = impl_m.def_id.as_local()?;
- let impl_m = tcx.hir().expect_impl_item(impl_m);
-
- // in case there are no generics, take the spot between the function name
- // and the opening paren of the argument list
- let new_generics_span = tcx.def_ident_span(impl_def_id)?.shrink_to_hi();
- // in case there are generics, just replace them
- let generics_span =
- impl_m.generics.span.substitute_dummy(new_generics_span);
- // replace with the generics from the trait
- let new_generics =
- tcx.sess.source_map().span_to_snippet(trait_m.generics.span).ok()?;
-
- err.multipart_suggestion(
- "try changing the `impl Trait` argument to a generic parameter",
- vec![
- // replace `impl Trait` with `T`
- (impl_span, new_name.to_string()),
- // replace impl method generics with trait method generics
- // This isn't quite right, as users might have changed the names
- // of the generics, but it works for the common case
- (generics_span, new_generics),
- ],
- Applicability::MaybeIncorrect,
- );
- };
- }
+ err.span_label(impl_span, "expected generic parameter, found `impl Trait`");
+ let _: Option<_> = try {
+ // try taking the name from the trait impl
+ // FIXME: this is obviously suboptimal since the name can already be used
+ // as another generic argument
+ let new_name = tcx.opt_item_name(trait_def_id)?;
+ let trait_m = trait_m.def_id.as_local()?;
+ let trait_m = tcx.hir().expect_trait_item(trait_m);
+
+ let impl_m = impl_m.def_id.as_local()?;
+ let impl_m = tcx.hir().expect_impl_item(impl_m);
+
+ // in case there are no generics, take the spot between the function name
+ // and the opening paren of the argument list
+ let new_generics_span = tcx.def_ident_span(impl_def_id)?.shrink_to_hi();
+ // in case there are generics, just replace them
+ let generics_span = impl_m.generics.span.substitute_dummy(new_generics_span);
+ // replace with the generics from the trait
+ let new_generics =
+ tcx.sess.source_map().span_to_snippet(trait_m.generics.span).ok()?;
+
+ err.multipart_suggestion(
+ "try changing the `impl Trait` argument to a generic parameter",
+ vec![
+ // replace `impl Trait` with `T`
+ (impl_span, new_name.to_string()),
+ // replace impl method generics with trait method generics
+ // This isn't quite right, as users might have changed the names
+ // of the generics, but it works for the common case
+ (generics_span, new_generics),
+ ],
+ Applicability::MaybeIncorrect,
+ );
+ };
+ } else {
// The case where the trait method uses `impl Trait`, but the impl method uses
// explicit generics.
- (false, true) => {
- err.span_label(impl_span, "expected `impl Trait`, found generic parameter");
- let _: Option<_> = try {
- let impl_m = impl_m.def_id.as_local()?;
- let impl_m = tcx.hir().expect_impl_item(impl_m);
- let (sig, _) = impl_m.expect_fn();
- let input_tys = sig.decl.inputs;
-
- struct Visitor(Option<Span>, hir::def_id::LocalDefId);
- impl<'v> intravisit::Visitor<'v> for Visitor {
- fn visit_ty(&mut self, ty: &'v hir::Ty<'v>) {
- intravisit::walk_ty(self, ty);
- if let hir::TyKind::Path(hir::QPath::Resolved(None, path)) = ty.kind
- && let Res::Def(DefKind::TyParam, def_id) = path.res
- && def_id == self.1.to_def_id()
- {
- self.0 = Some(ty.span);
- }
+ err.span_label(impl_span, "expected `impl Trait`, found generic parameter");
+ let _: Option<_> = try {
+ let impl_m = impl_m.def_id.as_local()?;
+ let impl_m = tcx.hir().expect_impl_item(impl_m);
+ let (sig, _) = impl_m.expect_fn();
+ let input_tys = sig.decl.inputs;
+
+ struct Visitor(Option<Span>, hir::def_id::LocalDefId);
+ impl<'v> intravisit::Visitor<'v> for Visitor {
+ fn visit_ty(&mut self, ty: &'v hir::Ty<'v>) {
+ intravisit::walk_ty(self, ty);
+ if let hir::TyKind::Path(hir::QPath::Resolved(None, path)) = ty.kind
+ && let Res::Def(DefKind::TyParam, def_id) = path.res
+ && def_id == self.1.to_def_id()
+ {
+ self.0 = Some(ty.span);
}
}
+ }
- let mut visitor = Visitor(None, impl_def_id);
- for ty in input_tys {
- intravisit::Visitor::visit_ty(&mut visitor, ty);
- }
- let span = visitor.0?;
-
- let bounds = impl_m.generics.bounds_for_param(impl_def_id).next()?.bounds;
- let bounds = bounds.first()?.span().to(bounds.last()?.span());
- let bounds = tcx.sess.source_map().span_to_snippet(bounds).ok()?;
-
- err.multipart_suggestion(
- "try removing the generic parameter and using `impl Trait` instead",
- vec![
- // delete generic parameters
- (impl_m.generics.span, String::new()),
- // replace param usage with `impl Trait`
- (span, format!("impl {bounds}")),
- ],
- Applicability::MaybeIncorrect,
- );
- };
- }
- _ => unreachable!(),
+ let mut visitor = Visitor(None, impl_def_id);
+ for ty in input_tys {
+ intravisit::Visitor::visit_ty(&mut visitor, ty);
+ }
+ let span = visitor.0?;
+
+ let bounds = impl_m.generics.bounds_for_param(impl_def_id).next()?.bounds;
+ let bounds = bounds.first()?.span().to(bounds.last()?.span());
+ let bounds = tcx.sess.source_map().span_to_snippet(bounds).ok()?;
+
+ err.multipart_suggestion(
+ "try removing the generic parameter and using `impl Trait` instead",
+ vec![
+ // delete generic parameters
+ (impl_m.generics.span, String::new()),
+ // replace param usage with `impl Trait`
+ (span, format!("impl {bounds}")),
+ ],
+ Applicability::MaybeIncorrect,
+ );
+ };
}
error_found = Some(err.emit_unless(delay));
}
@@ -1857,7 +1682,9 @@ fn compare_generic_param_kinds<'tcx>(
// this is exhaustive so that anyone adding new generic param kinds knows
// to make sure this error is reported for them.
(Const { .. }, Const { .. }) | (Type { .. }, Type { .. }) => false,
- (Lifetime { .. }, _) | (_, Lifetime { .. }) => unreachable!(),
+ (Lifetime { .. }, _) | (_, Lifetime { .. }) => {
+ bug!("lifetime params are expected to be filtered by `ty_const_params_of`")
+ }
} {
let param_impl_span = tcx.def_span(param_impl.def_id);
let param_trait_span = tcx.def_span(param_trait.def_id);
@@ -1881,7 +1708,10 @@ fn compare_generic_param_kinds<'tcx>(
)
}
Type { .. } => format!("{prefix} type parameter"),
- Lifetime { .. } => unreachable!(),
+ Lifetime { .. } => span_bug!(
+ tcx.def_span(param.def_id),
+ "lifetime params are expected to be filtered by `ty_const_params_of`"
+ ),
};
let trait_header_span = tcx.def_ident_span(tcx.parent(trait_item.def_id)).unwrap();
@@ -2179,13 +2009,16 @@ pub(super) fn check_type_bounds<'tcx>(
let impl_ty_span = if impl_ty.is_impl_trait_in_trait() {
tcx.def_span(impl_ty_def_id)
} else {
- match tcx.hir().get_by_def_id(impl_ty_def_id) {
+ match tcx.hir_node_by_def_id(impl_ty_def_id) {
hir::Node::TraitItem(hir::TraitItem {
kind: hir::TraitItemKind::Type(_, Some(ty)),
..
}) => ty.span,
hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Type(ty), .. }) => ty.span,
- _ => bug!(),
+ item => span_bug!(
+ tcx.def_span(impl_ty_def_id),
+ "cannot call `check_type_bounds` on item: {item:?}",
+ ),
}
};
let assumed_wf_types = ocx.assumed_wf_types_and_report_errors(param_env, impl_ty_def_id)?;
@@ -2345,7 +2178,7 @@ fn param_env_with_gat_bounds<'tcx>(
let kind = ty::BoundRegionKind::BrNamed(param.def_id, param.name);
let bound_var = ty::BoundVariableKind::Region(kind);
bound_vars.push(bound_var);
- ty::Region::new_late_bound(
+ ty::Region::new_bound(
tcx,
ty::INNERMOST,
ty::BoundRegion {
diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs
index bc5029a1d..67796855e 100644
--- a/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs
+++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs
@@ -91,7 +91,7 @@ pub(super) fn check_refining_return_position_impl_trait_in_trait<'tcx>(
// This opaque also needs to be from the impl method -- otherwise,
// it's a refinement to a TAIT.
- if !tcx.hir().get_if_local(impl_opaque.def_id).map_or(false, |node| {
+ if !tcx.hir().get_if_local(impl_opaque.def_id).is_some_and(|node| {
matches!(
node.expect_item().expect_opaque_ty().origin,
hir::OpaqueTyOrigin::AsyncFn(def_id) | hir::OpaqueTyOrigin::FnReturn(def_id)
@@ -153,7 +153,7 @@ pub(super) fn check_refining_return_position_impl_trait_in_trait<'tcx>(
trait_m_sig.inputs_and_output,
));
if !ocx.select_all_or_error().is_empty() {
- tcx.sess.delay_span_bug(
+ tcx.sess.span_delayed_bug(
DUMMY_SP,
"encountered errors when checking RPITIT refinement (selection)",
);
@@ -165,7 +165,7 @@ pub(super) fn check_refining_return_position_impl_trait_in_trait<'tcx>(
);
let errors = infcx.resolve_regions(&outlives_env);
if !errors.is_empty() {
- tcx.sess.delay_span_bug(
+ tcx.sess.span_delayed_bug(
DUMMY_SP,
"encountered errors when checking RPITIT refinement (regions)",
);
@@ -173,7 +173,7 @@ pub(super) fn check_refining_return_position_impl_trait_in_trait<'tcx>(
}
// Resolve any lifetime variables that may have been introduced during normalization.
let Ok((trait_bounds, impl_bounds)) = infcx.fully_resolve((trait_bounds, impl_bounds)) else {
- tcx.sess.delay_span_bug(
+ tcx.sess.span_delayed_bug(
DUMMY_SP,
"encountered errors when checking RPITIT refinement (resolution)",
);
@@ -262,7 +262,10 @@ fn report_mismatched_rpitit_signature<'tcx>(
if tcx.asyncness(impl_m_def_id).is_async() && tcx.asyncness(trait_m_def_id).is_async() {
let ty::Alias(ty::Projection, future_ty) = return_ty.kind() else {
- bug!();
+ span_bug!(
+ tcx.def_span(trait_m_def_id),
+ "expected return type of async fn in trait to be a AFIT projection"
+ );
};
let Some(future_output_ty) = tcx
.explicit_item_bounds(future_ty.def_id)
@@ -272,13 +275,13 @@ fn report_mismatched_rpitit_signature<'tcx>(
_ => None,
})
else {
- bug!()
+ span_bug!(tcx.def_span(trait_m_def_id), "expected `Future` projection bound in AFIT");
};
return_ty = future_output_ty;
}
let (span, impl_return_span, pre, post) =
- match tcx.hir().get_by_def_id(impl_m_def_id.expect_local()).fn_decl().unwrap().output {
+ match tcx.hir_node_by_def_id(impl_m_def_id.expect_local()).fn_decl().unwrap().output {
hir::FnRetTy::DefaultReturn(span) => (tcx.def_span(impl_m_def_id), span, "-> ", " "),
hir::FnRetTy::Return(ty) => (ty.span, ty.span, "", ""),
};
diff --git a/compiler/rustc_hir_analysis/src/check/dropck.rs b/compiler/rustc_hir_analysis/src/check/dropck.rs
index dda3f7425..58c77bb45 100644
--- a/compiler/rustc_hir_analysis/src/check/dropck.rs
+++ b/compiler/rustc_hir_analysis/src/check/dropck.rs
@@ -66,7 +66,7 @@ pub fn check_drop_impl(tcx: TyCtxt<'_>, drop_impl_did: DefId) -> Result<(), Erro
// already checked by coherence, but compilation may
// not have been terminated.
let span = tcx.def_span(drop_impl_did);
- let reported = tcx.sess.delay_span_bug(
+ let reported = tcx.sess.span_delayed_bug(
span,
format!("should have been rejected by coherence check: {dtor_self_type}"),
);
@@ -81,8 +81,7 @@ fn ensure_drop_params_and_item_params_correspond<'tcx>(
self_type_did: DefId,
adt_to_impl_args: GenericArgsRef<'tcx>,
) -> Result<(), ErrorGuaranteed> {
- let Err(arg) = tcx.uses_unique_generic_params(adt_to_impl_args, CheckRegions::OnlyEarlyBound)
- else {
+ let Err(arg) = tcx.uses_unique_generic_params(adt_to_impl_args, CheckRegions::OnlyParam) else {
return Ok(());
};
diff --git a/compiler/rustc_hir_analysis/src/check/entry.rs b/compiler/rustc_hir_analysis/src/check/entry.rs
index 6681292c9..1d737e17e 100644
--- a/compiler/rustc_hir_analysis/src/check/entry.rs
+++ b/compiler/rustc_hir_analysis/src/check/entry.rs
@@ -42,8 +42,8 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
if !def_id.is_local() {
return None;
}
- let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());
- match tcx.hir().find(hir_id) {
+ let hir_id = tcx.local_def_id_to_hir_id(def_id.expect_local());
+ match tcx.opt_hir_node(hir_id) {
Some(Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, generics, _), .. })) => {
generics.params.is_empty().not().then_some(generics.span)
}
@@ -57,8 +57,8 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
if !def_id.is_local() {
return None;
}
- let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());
- match tcx.hir().find(hir_id) {
+ let hir_id = tcx.local_def_id_to_hir_id(def_id.expect_local());
+ match tcx.opt_hir_node(hir_id) {
Some(Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, generics, _), .. })) => {
Some(generics.where_clause_span)
}
@@ -79,8 +79,8 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
if !def_id.is_local() {
return None;
}
- let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());
- match tcx.hir().find(hir_id) {
+ let hir_id = tcx.local_def_id_to_hir_id(def_id.expect_local());
+ match tcx.opt_hir_node(hir_id) {
Some(Node::Item(hir::Item { kind: hir::ItemKind::Fn(fn_sig, _, _), .. })) => {
Some(fn_sig.decl.output.span())
}
@@ -92,24 +92,6 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
let mut error = false;
let main_diagnostics_def_id = main_fn_diagnostics_def_id(tcx, main_def_id, main_span);
- let main_fn_generics = tcx.generics_of(main_def_id);
- let main_fn_predicates = tcx.predicates_of(main_def_id);
- if main_fn_generics.count() != 0 || !main_fnsig.bound_vars().is_empty() {
- let generics_param_span = main_fn_generics_params_span(tcx, main_def_id);
- tcx.sess.emit_err(errors::MainFunctionGenericParameters {
- span: generics_param_span.unwrap_or(main_span),
- label_span: generics_param_span,
- });
- error = true;
- } else if !main_fn_predicates.predicates.is_empty() {
- // generics may bring in implicit predicates, so we skip this check if generics is present.
- let generics_where_clauses_span = main_fn_where_clauses_span(tcx, main_def_id);
- tcx.sess.emit_err(errors::WhereClauseOnMain {
- span: generics_where_clauses_span.unwrap_or(main_span),
- generics_span: generics_where_clauses_span,
- });
- error = true;
- }
let main_asyncness = tcx.asyncness(main_def_id);
if main_asyncness.is_async() {
@@ -142,10 +124,6 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
if let Some(term_did) = tcx.lang_items().termination() {
let return_ty = main_fnsig.output();
let return_ty_span = main_fn_return_type_span(tcx, main_def_id).unwrap_or(main_span);
- if !return_ty.bound_vars().is_empty() {
- tcx.sess.emit_err(errors::MainFunctionReturnTypeGeneric { span: return_ty_span });
- error = true;
- }
let return_ty = return_ty.skip_binder();
let infcx = tcx.infer_ctxt().build();
let cause = traits::ObligationCause::new(
@@ -180,7 +158,7 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
Abi::Rust,
));
- check_function_signature(
+ if check_function_signature(
tcx,
ObligationCause::new(
main_span,
@@ -189,17 +167,38 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
),
main_def_id,
expected_sig,
- );
+ )
+ .is_err()
+ {
+ return;
+ }
+
+ let main_fn_generics = tcx.generics_of(main_def_id);
+ let main_fn_predicates = tcx.predicates_of(main_def_id);
+ if main_fn_generics.count() != 0 || !main_fnsig.bound_vars().is_empty() {
+ let generics_param_span = main_fn_generics_params_span(tcx, main_def_id);
+ tcx.sess.emit_err(errors::MainFunctionGenericParameters {
+ span: generics_param_span.unwrap_or(main_span),
+ label_span: generics_param_span,
+ });
+ } else if !main_fn_predicates.predicates.is_empty() {
+ // generics may bring in implicit predicates, so we skip this check if generics is present.
+ let generics_where_clauses_span = main_fn_where_clauses_span(tcx, main_def_id);
+ tcx.sess.emit_err(errors::WhereClauseOnMain {
+ span: generics_where_clauses_span.unwrap_or(main_span),
+ generics_span: generics_where_clauses_span,
+ });
+ }
}
fn check_start_fn_ty(tcx: TyCtxt<'_>, start_def_id: DefId) {
let start_def_id = start_def_id.expect_local();
- let start_id = tcx.hir().local_def_id_to_hir_id(start_def_id);
+ let start_id = tcx.local_def_id_to_hir_id(start_def_id);
let start_span = tcx.def_span(start_def_id);
let start_t = tcx.type_of(start_def_id).instantiate_identity();
match start_t.kind() {
ty::FnDef(..) => {
- if let Some(Node::Item(it)) = tcx.hir().find(start_id) {
+ if let Some(Node::Item(it)) = tcx.opt_hir_node(start_id) {
if let hir::ItemKind::Fn(sig, generics, _) = &it.kind {
let mut error = false;
if !generics.params.is_empty() {
@@ -255,7 +254,7 @@ fn check_start_fn_ty(tcx: TyCtxt<'_>, start_def_id: DefId) {
Abi::Rust,
));
- check_function_signature(
+ let _ = check_function_signature(
tcx,
ObligationCause::new(
start_span,
diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
index c61719c1f..126bab68a 100644
--- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs
+++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
@@ -55,7 +55,7 @@ fn equate_intrinsic_type<'tcx>(
&& gen_count_ok(own_counts.consts, n_cts, "const")
{
let it_def_id = it.owner_id.def_id;
- check_function_signature(
+ let _ = check_function_signature(
tcx,
ObligationCause::new(it.span, it_def_id, ObligationCauseCode::IntrinsicType),
it_def_id.into(),
@@ -143,12 +143,12 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
]);
let mk_va_list_ty = |mutbl| {
tcx.lang_items().va_list().map(|did| {
- let region = ty::Region::new_late_bound(
+ let region = ty::Region::new_bound(
tcx,
ty::INNERMOST,
ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind: ty::BrAnon },
);
- let env_region = ty::Region::new_late_bound(
+ let env_region = ty::Region::new_bound(
tcx,
ty::INNERMOST,
ty::BoundRegion { var: ty::BoundVar::from_u32(1), kind: ty::BrEnv },
@@ -225,25 +225,6 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
],
Ty::new_ptr(tcx, ty::TypeAndMut { ty: param(0), mutbl: hir::Mutability::Not }),
),
- sym::option_payload_ptr => {
- let option_def_id = tcx.require_lang_item(hir::LangItem::Option, None);
- let p0 = param(0);
- (
- 1,
- vec![Ty::new_ptr(
- tcx,
- ty::TypeAndMut {
- ty: Ty::new_adt(
- tcx,
- tcx.adt_def(option_def_id),
- tcx.mk_args_from_iter([ty::GenericArg::from(p0)].into_iter()),
- ),
- mutbl: hir::Mutability::Not,
- },
- )],
- Ty::new_ptr(tcx, ty::TypeAndMut { ty: p0, mutbl: hir::Mutability::Not }),
- )
- }
sym::ptr_mask => (
1,
vec![
@@ -411,7 +392,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
1,
vec![Ty::new_imm_ref(
tcx,
- ty::Region::new_late_bound(tcx, ty::INNERMOST, br),
+ ty::Region::new_bound(tcx, ty::INNERMOST, br),
param(0),
)],
Ty::new_projection(tcx, discriminant_def_id, tcx.mk_args(&[param(0).into()])),
@@ -465,11 +446,8 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
sym::raw_eq => {
let br = ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind: ty::BrAnon };
- let param_ty = Ty::new_imm_ref(
- tcx,
- ty::Region::new_late_bound(tcx, ty::INNERMOST, br),
- param(0),
- );
+ let param_ty =
+ Ty::new_imm_ref(tcx, ty::Region::new_bound(tcx, ty::INNERMOST, br), param(0));
(1, vec![param_ty; 2], tcx.types.bool)
}
@@ -543,6 +521,8 @@ pub fn check_platform_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>)
sym::simd_fpowi => (1, 0, vec![param(0), tcx.types.i32], param(0)),
sym::simd_fma => (1, 0, vec![param(0), param(0), param(0)], param(0)),
sym::simd_gather => (3, 0, vec![param(0), param(1), param(2)], param(0)),
+ sym::simd_masked_load => (3, 0, vec![param(0), param(1), param(2)], param(2)),
+ sym::simd_masked_store => (3, 0, vec![param(0), param(1), param(2)], Ty::new_unit(tcx)),
sym::simd_scatter => (3, 0, vec![param(0), param(1), param(2)], Ty::new_unit(tcx)),
sym::simd_insert => (2, 0, vec![param(0), tcx.types.u32, param(1)], param(0)),
sym::simd_extract => (2, 0, vec![param(0), tcx.types.u32], param(1)),
diff --git a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs
index cd7e99172..d86ebc2c9 100644
--- a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs
+++ b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs
@@ -49,7 +49,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
16 => InlineAsmType::I16,
32 => InlineAsmType::I32,
64 => InlineAsmType::I64,
- _ => unreachable!(),
+ width => bug!("unsupported pointer width: {width}"),
};
match *ty.kind() {
@@ -101,7 +101,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
16 => InlineAsmType::VecI16(size),
32 => InlineAsmType::VecI32(size),
64 => InlineAsmType::VecI64(size),
- _ => unreachable!(),
+ width => bug!("unsupported pointer width: {width}"),
})
}
ty::Float(FloatTy::F32) => Some(InlineAsmType::VecF32(size)),
@@ -109,7 +109,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
_ => None,
}
}
- ty::Infer(_) => unreachable!(),
+ ty::Infer(_) => bug!("unexpected infer ty in asm operand"),
_ => None,
}
}
@@ -136,8 +136,15 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
ty::Adt(adt, args) if Some(adt.did()) == self.tcx.lang_items().maybe_uninit() => {
let fields = &adt.non_enum_variant().fields;
let ty = fields[FieldIdx::from_u32(1)].ty(self.tcx, args);
- let ty::Adt(ty, args) = ty.kind() else { unreachable!() };
- assert!(ty.is_manually_drop());
+ // FIXME: Are we just trying to map to the `T` in `MaybeUninit<T>`?
+ // If so, just get it from the args.
+ let ty::Adt(ty, args) = ty.kind() else {
+ unreachable!("expected first field of `MaybeUninit` to be an ADT")
+ };
+ assert!(
+ ty.is_manually_drop(),
+ "expected first field of `MaybeUnit` to be `ManuallyDrop`"
+ );
let fields = &ty.non_enum_variant().fields;
let ty = fields[FieldIdx::from_u32(0)].ty(self.tcx, args);
self.get_asm_ty(ty)
@@ -269,7 +276,6 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
lint.help(format!(
"or use `{{{idx}:{default_modifier}}}` to keep the default formatting of `{default_result}`",
));
- lint
},
);
}
@@ -281,7 +287,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
pub fn check_asm(&self, asm: &hir::InlineAsm<'tcx>, enclosing_id: LocalDefId) {
let target_features = self.tcx.asm_target_features(enclosing_id.to_def_id());
let Some(asm_arch) = self.tcx.sess.asm_arch else {
- self.tcx.sess.delay_span_bug(DUMMY_SP, "target architecture does not support asm");
+ self.tcx.sess.span_delayed_bug(DUMMY_SP, "target architecture does not support asm");
return;
};
for (idx, (op, op_sp)) in asm.operands.iter().enumerate() {
@@ -307,7 +313,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
if let Err(msg) = reg.validate(
asm_arch,
self.tcx.sess.relocation_model(),
- &target_features,
+ target_features,
&self.tcx.sess.target,
op.is_clobber(),
) {
@@ -382,7 +388,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
asm.template,
true,
None,
- &target_features,
+ target_features,
);
}
hir::InlineAsmOperand::Out { reg, late: _, expr } => {
@@ -394,7 +400,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
asm.template,
false,
None,
- &target_features,
+ target_features,
);
}
}
@@ -406,7 +412,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
asm.template,
false,
None,
- &target_features,
+ target_features,
);
}
hir::InlineAsmOperand::SplitInOut { reg, late: _, in_expr, out_expr } => {
@@ -417,7 +423,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
asm.template,
true,
None,
- &target_features,
+ target_features,
);
if let Some(out_expr) = out_expr {
self.check_asm_operand_type(
@@ -427,7 +433,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
asm.template,
false,
Some((in_expr, in_ty)),
- &target_features,
+ target_features,
);
}
}
diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs
index 15c5558fc..e4904a043 100644
--- a/compiler/rustc_hir_analysis/src/check/mod.rs
+++ b/compiler/rustc_hir_analysis/src/check/mod.rs
@@ -77,6 +77,7 @@ use std::num::NonZeroU32;
use check::check_mod_item_types;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
+use rustc_errors::ErrorGuaranteed;
use rustc_errors::{pluralize, struct_span_err, Diagnostic, DiagnosticBuilder};
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::intravisit::Visitor;
@@ -128,9 +129,9 @@ fn get_owner_return_paths(
tcx: TyCtxt<'_>,
def_id: LocalDefId,
) -> Option<(LocalDefId, ReturnsVisitor<'_>)> {
- let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
+ let hir_id = tcx.local_def_id_to_hir_id(def_id);
let parent_id = tcx.hir().get_parent_item(hir_id).def_id;
- tcx.hir().find_by_def_id(parent_id).and_then(|node| node.body_id()).map(|body_id| {
+ tcx.opt_hir_node_by_def_id(parent_id).and_then(|node| node.body_id()).map(|body_id| {
let body = tcx.hir().body(body_id);
let mut visitor = ReturnsVisitor::default();
visitor.visit_body(body);
@@ -141,7 +142,7 @@ fn get_owner_return_paths(
/// Forbid defining intrinsics in Rust code,
/// as they must always be defined by the compiler.
// FIXME: Move this to a more appropriate place.
-pub fn fn_maybe_err(tcx: TyCtxt<'_>, sp: Span, abi: Abi) {
+pub fn forbid_intrinsic_abi(tcx: TyCtxt<'_>, sp: Span, abi: Abi) {
if let Abi::RustIntrinsic | Abi::PlatformIntrinsic = abi {
tcx.sess.span_err(sp, "intrinsic must be in `extern \"rust-intrinsic\" { ... }` block");
}
@@ -570,7 +571,26 @@ pub fn check_function_signature<'tcx>(
mut cause: ObligationCause<'tcx>,
fn_id: DefId,
expected_sig: ty::PolyFnSig<'tcx>,
-) {
+) -> Result<(), ErrorGuaranteed> {
+ fn extract_span_for_error_reporting<'tcx>(
+ tcx: TyCtxt<'tcx>,
+ err: TypeError<'_>,
+ cause: &ObligationCause<'tcx>,
+ fn_id: LocalDefId,
+ ) -> rustc_span::Span {
+ let mut args = {
+ let node = tcx.hir().expect_owner(fn_id);
+ let decl = node.fn_decl().unwrap_or_else(|| bug!("expected fn decl, found {:?}", node));
+ decl.inputs.iter().map(|t| t.span).chain(std::iter::once(decl.output.span()))
+ };
+
+ match err {
+ TypeError::ArgumentMutability(i)
+ | TypeError::ArgumentSorts(ExpectedFound { .. }, i) => args.nth(i).unwrap(),
+ _ => cause.span(),
+ }
+ }
+
let local_id = fn_id.as_local().unwrap_or(CRATE_DEF_ID);
let param_env = ty::ParamEnv::empty();
@@ -587,8 +607,7 @@ pub fn check_function_signature<'tcx>(
Ok(()) => {
let errors = ocx.select_all_or_error();
if !errors.is_empty() {
- infcx.err_ctxt().report_fulfillment_errors(errors);
- return;
+ return Err(infcx.err_ctxt().report_fulfillment_errors(errors));
}
}
Err(err) => {
@@ -610,30 +629,14 @@ pub fn check_function_signature<'tcx>(
false,
false,
);
- diag.emit();
- return;
+ return Err(diag.emit());
}
}
let outlives_env = OutlivesEnvironment::new(param_env);
- let _ = ocx.resolve_regions_and_report_errors(local_id, &outlives_env);
-
- fn extract_span_for_error_reporting<'tcx>(
- tcx: TyCtxt<'tcx>,
- err: TypeError<'_>,
- cause: &ObligationCause<'tcx>,
- fn_id: LocalDefId,
- ) -> rustc_span::Span {
- let mut args = {
- let node = tcx.hir().expect_owner(fn_id);
- let decl = node.fn_decl().unwrap_or_else(|| bug!("expected fn decl, found {:?}", node));
- decl.inputs.iter().map(|t| t.span).chain(std::iter::once(decl.output.span()))
- };
-
- match err {
- TypeError::ArgumentMutability(i)
- | TypeError::ArgumentSorts(ExpectedFound { .. }, i) => args.nth(i).unwrap(),
- _ => cause.span(),
- }
+ if let Err(e) = ocx.resolve_regions_and_report_errors(local_id, &outlives_env) {
+ return Err(e);
}
+
+ Ok(())
}
diff --git a/compiler/rustc_hir_analysis/src/check/region.rs b/compiler/rustc_hir_analysis/src/check/region.rs
index 40b33117f..37b308f9f 100644
--- a/compiler/rustc_hir_analysis/src/check/region.rs
+++ b/compiler/rustc_hir_analysis/src/check/region.rs
@@ -414,11 +414,11 @@ fn resolve_expr<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, expr: &'tcx h
// then we'll assign too low a count to any `yield` expressions
// we encounter in 'right_expression' - they should really occur after all of the
// expressions in 'left_expression'.
- visitor.visit_expr(&right_expr);
+ visitor.visit_expr(right_expr);
visitor.pessimistic_yield = prev_pessimistic;
debug!("resolve_expr - restoring pessimistic_yield to {}", prev_pessimistic);
- visitor.visit_expr(&left_expr);
+ visitor.visit_expr(left_expr);
debug!("resolve_expr - fixing up counts to {}", visitor.expr_and_pat_count);
// Remove and process any scopes pushed by the visitor
@@ -582,7 +582,7 @@ fn resolve_local<'tcx>(
// due to rule C.
if let Some(expr) = init {
- record_rvalue_scope_if_borrow_expr(visitor, &expr, blk_scope);
+ record_rvalue_scope_if_borrow_expr(visitor, expr, blk_scope);
if let Some(pat) = pat {
if is_binding_pat(pat) {
@@ -645,25 +645,24 @@ fn resolve_local<'tcx>(
match pat.kind {
PatKind::Binding(hir::BindingAnnotation(hir::ByRef::Yes, _), ..) => true,
- PatKind::Struct(_, field_pats, _) => {
- field_pats.iter().any(|fp| is_binding_pat(&fp.pat))
- }
+ PatKind::Struct(_, field_pats, _) => field_pats.iter().any(|fp| is_binding_pat(fp.pat)),
PatKind::Slice(pats1, pats2, pats3) => {
- pats1.iter().any(|p| is_binding_pat(&p))
- || pats2.iter().any(|p| is_binding_pat(&p))
- || pats3.iter().any(|p| is_binding_pat(&p))
+ pats1.iter().any(|p| is_binding_pat(p))
+ || pats2.iter().any(|p| is_binding_pat(p))
+ || pats3.iter().any(|p| is_binding_pat(p))
}
PatKind::Or(subpats)
| PatKind::TupleStruct(_, subpats, _)
- | PatKind::Tuple(subpats, _) => subpats.iter().any(|p| is_binding_pat(&p)),
+ | PatKind::Tuple(subpats, _) => subpats.iter().any(|p| is_binding_pat(p)),
- PatKind::Box(subpat) => is_binding_pat(&subpat),
+ PatKind::Box(subpat) => is_binding_pat(subpat),
PatKind::Ref(_, _)
| PatKind::Binding(hir::BindingAnnotation(hir::ByRef::No, _), ..)
| PatKind::Wild
+ | PatKind::Never
| PatKind::Path(_)
| PatKind::Lit(_)
| PatKind::Range(_, _, _) => false,
@@ -700,20 +699,20 @@ fn resolve_local<'tcx>(
}
hir::ExprKind::Struct(_, fields, _) => {
for field in fields {
- record_rvalue_scope_if_borrow_expr(visitor, &field.expr, blk_id);
+ record_rvalue_scope_if_borrow_expr(visitor, field.expr, blk_id);
}
}
hir::ExprKind::Array(subexprs) | hir::ExprKind::Tup(subexprs) => {
for subexpr in subexprs {
- record_rvalue_scope_if_borrow_expr(visitor, &subexpr, blk_id);
+ record_rvalue_scope_if_borrow_expr(visitor, subexpr, blk_id);
}
}
hir::ExprKind::Cast(subexpr, _) => {
- record_rvalue_scope_if_borrow_expr(visitor, &subexpr, blk_id)
+ record_rvalue_scope_if_borrow_expr(visitor, subexpr, blk_id)
}
hir::ExprKind::Block(block, _) => {
if let Some(subexpr) = block.expr {
- record_rvalue_scope_if_borrow_expr(visitor, &subexpr, blk_id);
+ record_rvalue_scope_if_borrow_expr(visitor, subexpr, blk_id);
}
}
hir::ExprKind::Call(..) | hir::ExprKind::MethodCall(..) => {
@@ -795,13 +794,13 @@ impl<'tcx> Visitor<'tcx> for RegionResolutionVisitor<'tcx> {
// The arguments and `self` are parented to the fn.
self.cx.var_parent = self.cx.parent.take();
for param in body.params {
- self.visit_pat(&param.pat);
+ self.visit_pat(param.pat);
}
// The body of the every fn is a root scope.
self.cx.parent = self.cx.var_parent;
if self.tcx.hir().body_owner_kind(owner_id).is_fn_or_closure() {
- self.visit_expr(&body.value)
+ self.visit_expr(body.value)
} else {
// Only functions have an outer terminating (drop) scope, while
// temporaries in constant initializers may be 'static, but only
@@ -822,7 +821,7 @@ impl<'tcx> Visitor<'tcx> for RegionResolutionVisitor<'tcx> {
// (i.e., `'static`), which means that after `g` returns, it drops,
// and all the associated destruction scope rules apply.
self.cx.var_parent = None;
- resolve_local(self, None, Some(&body.value));
+ resolve_local(self, None, Some(body.value));
}
if body.coroutine_kind.is_some() {
@@ -849,7 +848,7 @@ impl<'tcx> Visitor<'tcx> for RegionResolutionVisitor<'tcx> {
resolve_expr(self, ex);
}
fn visit_local(&mut self, l: &'tcx Local<'tcx>) {
- resolve_local(self, Some(&l.pat), l.init)
+ resolve_local(self, Some(l.pat), l.init)
}
}
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index eb4491b89..b2ff79591 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -118,10 +118,10 @@ where
if tcx.sess.err_count() > 0 {
return Err(err);
} else {
- // HACK(oli-obk): tests/ui/specialization/min_specialization/specialize_on_type_error.rs causes an
- // error (delay_span_bug) during normalization, without reporting an error, so we need to act as if
- // no error happened, in order to let our callers continue and report an error later in
- // check_impl_items_against_trait.
+ // HACK(oli-obk): tests/ui/specialization/min_specialization/specialize_on_type_error.rs
+ // causes an error (span_delayed_bug) during normalization, without reporting an error,
+ // so we need to act as if no error happened, in order to let our callers continue and
+ // report an error later in check_impl_items_against_trait.
return Ok(());
}
}
@@ -204,11 +204,14 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<()
res = Err(err.emit());
}
// We match on both `ty::ImplPolarity` and `ast::ImplPolarity` just to get the `!` span.
- match (tcx.impl_polarity(def_id), impl_.polarity) {
- (ty::ImplPolarity::Positive, _) => {
+ match tcx.impl_polarity(def_id) {
+ ty::ImplPolarity::Positive => {
res = res.and(check_impl(tcx, item, impl_.self_ty, &impl_.of_trait));
}
- (ty::ImplPolarity::Negative, ast::ImplPolarity::Negative(span)) => {
+ ty::ImplPolarity::Negative => {
+ let ast::ImplPolarity::Negative(span) = impl_.polarity else {
+ bug!("impl_polarity query disagrees with impl's polarity in AST");
+ };
// FIXME(#27579): what amount of WF checking do we need for neg impls?
if let hir::Defaultness::Default { .. } = impl_.defaultness {
let mut spans = vec![span];
@@ -222,10 +225,9 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<()
.emit());
}
}
- (ty::ImplPolarity::Reservation, _) => {
+ ty::ImplPolarity::Reservation => {
// FIXME: what amount of WF checking do we need for reservation impls?
}
- _ => unreachable!(),
}
res
}
@@ -584,7 +586,7 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable<TyCtxt<'tcx>>>(
// reflected in a where clause on the GAT itself.
for (ty, ty_idx) in &types {
// In our example, requires that `Self: 'a`
- if ty_known_to_outlive(tcx, item_def_id, param_env, &wf_tys, *ty, *region_a) {
+ if ty_known_to_outlive(tcx, item_def_id, param_env, wf_tys, *ty, *region_a) {
debug!(?ty_idx, ?region_a_idx);
debug!("required clause: {ty} must outlive {region_a}");
// Translate into the generic parameters of the GAT. In
@@ -595,9 +597,9 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable<TyCtxt<'tcx>>>(
// Same for the region. In our example, 'a corresponds
// to the 'me parameter.
let region_param = gat_generics.param_at(*region_a_idx, tcx);
- let region_param = ty::Region::new_early_bound(
+ let region_param = ty::Region::new_early_param(
tcx,
- ty::EarlyBoundRegion {
+ ty::EarlyParamRegion {
def_id: region_param.def_id,
index: region_param.index,
name: region_param.name,
@@ -623,14 +625,14 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable<TyCtxt<'tcx>>>(
if matches!(**region_b, ty::ReStatic | ty::ReError(_)) || region_a == region_b {
continue;
}
- if region_known_to_outlive(tcx, item_def_id, param_env, &wf_tys, *region_a, *region_b) {
+ if region_known_to_outlive(tcx, item_def_id, param_env, wf_tys, *region_a, *region_b) {
debug!(?region_a_idx, ?region_b_idx);
debug!("required clause: {region_a} must outlive {region_b}");
// Translate into the generic parameters of the GAT.
let region_a_param = gat_generics.param_at(*region_a_idx, tcx);
- let region_a_param = ty::Region::new_early_bound(
+ let region_a_param = ty::Region::new_early_param(
tcx,
- ty::EarlyBoundRegion {
+ ty::EarlyParamRegion {
def_id: region_a_param.def_id,
index: region_a_param.index,
name: region_a_param.name,
@@ -638,9 +640,9 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable<TyCtxt<'tcx>>>(
);
// Same for the region.
let region_b_param = gat_generics.param_at(*region_b_idx, tcx);
- let region_b_param = ty::Region::new_early_bound(
+ let region_b_param = ty::Region::new_early_param(
tcx,
- ty::EarlyBoundRegion {
+ ty::EarlyParamRegion {
def_id: region_b_param.def_id,
index: region_b_param.index,
name: region_b_param.name,
@@ -671,7 +673,7 @@ fn ty_known_to_outlive<'tcx>(
ty: Ty<'tcx>,
region: ty::Region<'tcx>,
) -> bool {
- resolve_regions_with_wf_tys(tcx, id, param_env, &wf_tys, |infcx, region_bound_pairs| {
+ resolve_regions_with_wf_tys(tcx, id, param_env, wf_tys, |infcx, region_bound_pairs| {
let origin = infer::RelateParamBound(DUMMY_SP, ty, None);
let outlives = &mut TypeOutlives::new(infcx, tcx, region_bound_pairs, None, param_env);
outlives.type_must_outlive(origin, ty, region, ConstraintCategory::BoringNoLocation);
@@ -688,7 +690,7 @@ fn region_known_to_outlive<'tcx>(
region_a: ty::Region<'tcx>,
region_b: ty::Region<'tcx>,
) -> bool {
- resolve_regions_with_wf_tys(tcx, id, param_env, &wf_tys, |mut infcx, _| {
+ resolve_regions_with_wf_tys(tcx, id, param_env, wf_tys, |mut infcx, _| {
use rustc_infer::infer::outlives::obligations::TypeOutlivesDelegate;
let origin = infer::RelateRegionParamBound(DUMMY_SP);
// `region_a: region_b` -> `region_b <= region_a`
@@ -763,7 +765,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for GATSubstCollector<'tcx> {
ty::Alias(ty::Projection, p) if p.def_id == self.gat => {
for (idx, subst) in p.args.iter().enumerate() {
match subst.unpack() {
- GenericArgKind::Lifetime(lt) if !lt.is_late_bound() => {
+ GenericArgKind::Lifetime(lt) if !lt.is_bound() => {
self.regions.insert((lt, idx));
}
GenericArgKind::Type(t) => {
@@ -793,7 +795,7 @@ fn could_be_self(trait_def_id: LocalDefId, ty: &hir::Ty<'_>) -> bool {
/// When this is done, suggest using `Self` instead.
fn check_object_unsafe_self_trait_by_name(tcx: TyCtxt<'_>, item: &hir::TraitItem<'_>) {
let (trait_name, trait_def_id) =
- match tcx.hir().get_by_def_id(tcx.hir().get_parent_item(item.hir_id()).def_id) {
+ match tcx.hir_node_by_def_id(tcx.hir().get_parent_item(item.hir_id()).def_id) {
hir::Node::Item(item) => match item.kind {
hir::ItemKind::Trait(..) => (item.ident, item.owner_id),
_ => return,
@@ -859,7 +861,7 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) -> Result<(),
hir::GenericParamKind::Lifetime { .. } | hir::GenericParamKind::Type { .. } => Ok(()),
// Const parameters are well formed if their type is structural match.
- hir::GenericParamKind::Const { ty: hir_ty, default: _ } => {
+ hir::GenericParamKind::Const { ty: hir_ty, default: _, is_host_effect: _ } => {
let ty = tcx.type_of(param.def_id).instantiate_identity();
if tcx.features().adt_const_params {
@@ -992,15 +994,6 @@ fn check_associated_item(
})
}
-fn item_adt_kind(kind: &ItemKind<'_>) -> Option<AdtKind> {
- match kind {
- ItemKind::Struct(..) => Some(AdtKind::Struct),
- ItemKind::Union(..) => Some(AdtKind::Union),
- ItemKind::Enum(..) => Some(AdtKind::Enum),
- _ => None,
- }
-}
-
/// In a type definition, we check that to ensure that the types of the fields are well-formed.
fn check_type_defn<'tcx>(
tcx: TyCtxt<'tcx>,
@@ -1019,7 +1012,7 @@ fn check_type_defn<'tcx>(
for field in &variant.fields {
let field_id = field.did.expect_local();
let hir::FieldDef { ty: hir_ty, .. } =
- tcx.hir().get_by_def_id(field_id).expect_field();
+ tcx.hir_node_by_def_id(field_id).expect_field();
let ty = wfcx.normalize(
hir_ty.span,
None,
@@ -1040,7 +1033,7 @@ fn check_type_defn<'tcx>(
let ty = tcx.erase_regions(ty);
if ty.has_infer() {
tcx.sess
- .delay_span_bug(item.span, format!("inference variables in {ty:?}"));
+ .span_delayed_bug(item.span, format!("inference variables in {ty:?}"));
// Just treat unresolved type expression as if it needs drop.
true
} else {
@@ -1057,7 +1050,7 @@ fn check_type_defn<'tcx>(
let last = idx == variant.fields.len() - 1;
let field_id = field.did.expect_local();
let hir::FieldDef { ty: hir_ty, .. } =
- tcx.hir().get_by_def_id(field_id).expect_field();
+ tcx.hir_node_by_def_id(field_id).expect_field();
let ty = wfcx.normalize(
hir_ty.span,
None,
@@ -1068,9 +1061,14 @@ fn check_type_defn<'tcx>(
hir_ty.span,
wfcx.body_def_id,
traits::FieldSized {
- adt_kind: match item_adt_kind(&item.kind) {
- Some(i) => i,
- None => bug!(),
+ adt_kind: match &item.kind {
+ ItemKind::Struct(..) => AdtKind::Struct,
+ ItemKind::Union(..) => AdtKind::Union,
+ ItemKind::Enum(..) => AdtKind::Enum,
+ kind => span_bug!(
+ item.span,
+ "should be wfchecking an ADT, got {kind:?}"
+ ),
},
span: hir_ty.span,
last,
@@ -1302,7 +1300,9 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id
| GenericParamDefKind::Const { has_default, .. } => {
has_default && def.index >= generics.parent_count as u32
}
- GenericParamDefKind::Lifetime => unreachable!(),
+ GenericParamDefKind::Lifetime => {
+ span_bug!(tcx.def_span(def.def_id), "lifetime params can have no default")
+ }
};
// Check that concrete defaults are well-formed. See test `type-check-defaults.rs`.
@@ -1607,15 +1607,10 @@ fn check_method_receiver<'tcx>(
}
fn e0307(tcx: TyCtxt<'_>, span: Span, receiver_ty: Ty<'_>) -> ErrorGuaranteed {
- struct_span_err!(
- tcx.sess.diagnostic(),
- span,
- E0307,
- "invalid `self` parameter type: {receiver_ty}"
- )
- .note("type of `self` must be `Self` or a type that dereferences to it")
- .help(HELP_FOR_SELF_TYPE)
- .emit()
+ struct_span_err!(tcx.sess.dcx(), span, E0307, "invalid `self` parameter type: {receiver_ty}")
+ .note("type of `self` must be `Self` or a type that dereferences to it")
+ .help(HELP_FOR_SELF_TYPE)
+ .emit()
}
/// Returns whether `receiver_ty` would be considered a valid receiver type for `self_ty`. If
@@ -1750,15 +1745,15 @@ fn check_variances_for_type_defn<'tcx>(
}
}
ItemKind::TyAlias(..) => {
- if tcx.type_alias_is_lazy(item.owner_id) {
- if tcx.type_of(item.owner_id).skip_binder().references_error() {
- return;
- }
- } else {
- bug!();
+ assert!(
+ tcx.type_alias_is_lazy(item.owner_id),
+ "should not be computing variance of non-weak type alias"
+ );
+ if tcx.type_of(item.owner_id).skip_binder().references_error() {
+ return;
}
}
- _ => bug!(),
+ kind => span_bug!(item.span, "cannot compute the variances of {kind:?}"),
}
let ty_predicates = tcx.predicates_of(item.owner_id);
@@ -1812,8 +1807,10 @@ fn check_variances_for_type_defn<'tcx>(
//
// if they aren't in the same order, then the user has written invalid code, and already
// got an error about it (or I'm wrong about this)
- tcx.sess
- .delay_span_bug(hir_param.span, "hir generics and ty generics in different order");
+ tcx.sess.span_delayed_bug(
+ hir_param.span,
+ "hir generics and ty generics in different order",
+ );
continue;
}
@@ -1880,7 +1877,7 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> {
// Match the existing behavior.
if pred.is_global() && !pred.has_type_flags(TypeFlags::HAS_BINDER_VARS) {
let pred = self.normalize(span, None, pred);
- let hir_node = tcx.hir().find_by_def_id(self.body_def_id);
+ let hir_node = tcx.opt_hir_node_by_def_id(self.body_def_id);
// only use the span of the predicate clause (#90869)