summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_hir_analysis/src
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_hir_analysis/src')
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/bounds.rs151
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/errors.rs313
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/generics.rs27
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/lint.rs7
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/mod.rs618
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/object_safety.rs11
-rw-r--r--compiler/rustc_hir_analysis/src/autoderef.rs2
-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
-rw-r--r--compiler/rustc_hir_analysis/src/check_unused.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/builtin.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/orphan.rs14
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/unsafety.rs10
-rw-r--r--compiler/rustc_hir_analysis/src/collect.rs41
-rw-r--r--compiler/rustc_hir_analysis/src/collect/generics_of.rs28
-rw-r--r--compiler/rustc_hir_analysis/src/collect/item_bounds.rs24
-rw-r--r--compiler/rustc_hir_analysis/src/collect/predicates_of.rs43
-rw-r--r--compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs84
-rw-r--r--compiler/rustc_hir_analysis/src/collect/type_of.rs25
-rw-r--r--compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs16
-rw-r--r--compiler/rustc_hir_analysis/src/constrained_generic_params.rs6
-rw-r--r--compiler/rustc_hir_analysis/src/errors.rs150
-rw-r--r--compiler/rustc_hir_analysis/src/hir_wf_check.rs37
-rw-r--r--compiler/rustc_hir_analysis/src/impl_wf_check.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/lib.rs14
-rw-r--r--compiler/rustc_hir_analysis/src/outlives/mod.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/outlives/utils.rs14
-rw-r--r--compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs9
-rw-r--r--compiler/rustc_hir_analysis/src/variance/constraints.rs12
-rw-r--r--compiler/rustc_hir_analysis/src/variance/mod.rs2
39 files changed, 1186 insertions, 1348 deletions
diff --git a/compiler/rustc_hir_analysis/src/astconv/bounds.rs b/compiler/rustc_hir_analysis/src/astconv/bounds.rs
index 3e700f2da..0748644cc 100644
--- a/compiler/rustc_hir_analysis/src/astconv/bounds.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/bounds.rs
@@ -3,8 +3,7 @@ use rustc_errors::struct_span_err;
use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::{DefId, LocalDefId};
-use rustc_lint_defs::Applicability;
-use rustc_middle::ty::{self as ty, Ty, TypeVisitableExt};
+use rustc_middle::ty::{self as ty, Ty};
use rustc_span::symbol::Ident;
use rustc_span::{ErrorGuaranteed, Span};
use rustc_trait_selection::traits;
@@ -135,17 +134,6 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
only_self_bounds,
);
}
- &hir::GenericBound::LangItemTrait(lang_item, span, hir_id, args) => {
- self.instantiate_lang_item_trait_ref(
- lang_item,
- span,
- hir_id,
- args,
- param_ty,
- bounds,
- only_self_bounds,
- );
- }
hir::GenericBound::Outlives(lifetime) => {
let region = self.ast_region_to_region(lifetime, None);
bounds.push_region_bound(
@@ -194,8 +182,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
self.add_bounds(
param_ty,
- ast_bounds.iter().filter(|bound| {
- match filter {
+ ast_bounds.iter().filter(|bound| match filter {
PredicateFilter::All
| PredicateFilter::SelfOnly
| PredicateFilter::SelfAndAssociatedTypeBounds => true,
@@ -209,7 +196,6 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
false
}
}
- }
}),
&mut bounds,
ty::List::empty(),
@@ -258,64 +244,49 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
let tcx = self.tcx();
- let return_type_notation =
- binding.gen_args.parenthesized == hir::GenericArgsParentheses::ReturnTypeNotation;
-
- let candidate = if return_type_notation {
- if self.trait_defines_associated_item_named(
- trait_ref.def_id(),
- ty::AssocKind::Fn,
- binding.item_name,
- ) {
- trait_ref
+ let assoc_kind =
+ if binding.gen_args.parenthesized == hir::GenericArgsParentheses::ReturnTypeNotation {
+ ty::AssocKind::Fn
+ } else if let ConvertedBindingKind::Equality(term) = binding.kind
+ && let ty::TermKind::Const(_) = term.node.unpack()
+ {
+ ty::AssocKind::Const
} else {
- self.one_bound_for_assoc_method(
- traits::supertraits(tcx, trait_ref),
- trait_ref.print_only_trait_path(),
- binding.item_name,
- path_span,
- )?
- }
- } else if self.trait_defines_associated_item_named(
+ ty::AssocKind::Type
+ };
+
+ let candidate = if self.trait_defines_associated_item_named(
trait_ref.def_id(),
- ty::AssocKind::Type,
+ assoc_kind,
binding.item_name,
) {
- // Simple case: X is defined in the current trait.
+ // Simple case: The assoc item is defined in the current trait.
trait_ref
} else {
// Otherwise, we have to walk through the supertraits to find
- // those that do.
- self.one_bound_for_assoc_type(
+ // one that does define it.
+ self.one_bound_for_assoc_item(
|| traits::supertraits(tcx, trait_ref),
trait_ref.skip_binder().print_only_trait_name(),
None,
+ assoc_kind,
binding.item_name,
path_span,
- match binding.kind {
- ConvertedBindingKind::Equality(term) => Some(term),
- _ => None,
- },
+ Some(&binding),
)?
};
let (assoc_ident, def_scope) =
tcx.adjust_ident_and_get_scope(binding.item_name, candidate.def_id(), hir_ref_id);
- // We have already adjusted the item name above, so compare with `ident.normalize_to_macros_2_0()` instead
- // of calling `filter_by_name_and_kind`.
- let find_item_of_kind = |kind| {
- tcx.associated_items(candidate.def_id())
- .filter_by_name_unhygienic(assoc_ident.name)
- .find(|i| i.kind == kind && i.ident(tcx).normalize_to_macros_2_0() == assoc_ident)
- };
- let assoc_item = if return_type_notation {
- find_item_of_kind(ty::AssocKind::Fn)
- } else {
- find_item_of_kind(ty::AssocKind::Type)
- .or_else(|| find_item_of_kind(ty::AssocKind::Const))
- }
- .expect("missing associated type");
+ // We have already adjusted the item name above, so compare with `.normalize_to_macros_2_0()`
+ // instead of calling `filter_by_name_and_kind` which would needlessly normalize the
+ // `assoc_ident` again and again.
+ let assoc_item = tcx
+ .associated_items(candidate.def_id())
+ .filter_by_name_unhygienic(assoc_ident.name)
+ .find(|i| i.kind == assoc_kind && i.ident(tcx).normalize_to_macros_2_0() == assoc_ident)
+ .expect("missing associated item");
if !assoc_item.visibility(tcx).is_accessible_from(def_scope, tcx) {
tcx.sess
@@ -342,7 +313,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
.or_insert(binding.span);
}
- let projection_ty = if return_type_notation {
+ let projection_ty = if let ty::AssocKind::Fn = assoc_kind {
let mut emitted_bad_param_err = false;
// If we have an method return type bound, then we need to substitute
// the method's early bound params with suitable late-bound params.
@@ -350,7 +321,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
let args =
candidate.skip_binder().args.extend_to(tcx, assoc_item.def_id, |param, _| {
let subst = match param.kind {
- ty::GenericParamDefKind::Lifetime => ty::Region::new_late_bound(
+ ty::GenericParamDefKind::Lifetime => ty::Region::new_bound(
tcx,
ty::INNERMOST,
ty::BoundRegion {
@@ -469,7 +440,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
let late_bound_in_trait_ref =
tcx.collect_constrained_late_bound_regions(&projection_ty);
let late_bound_in_ty =
- tcx.collect_referenced_late_bound_regions(&trait_ref.rebind(ty));
+ tcx.collect_referenced_late_bound_regions(&trait_ref.rebind(ty.node));
debug!(?late_bound_in_trait_ref);
debug!(?late_bound_in_ty);
@@ -494,77 +465,27 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
}
}
- let assoc_item_def_id = projection_ty.skip_binder().def_id;
- let def_kind = tcx.def_kind(assoc_item_def_id);
match binding.kind {
- ConvertedBindingKind::Equality(..) if return_type_notation => {
+ ConvertedBindingKind::Equality(..) if let ty::AssocKind::Fn = assoc_kind => {
return Err(self.tcx().sess.emit_err(
crate::errors::ReturnTypeNotationEqualityBound { span: binding.span },
));
}
- ConvertedBindingKind::Equality(mut term) => {
+ ConvertedBindingKind::Equality(term) => {
// "Desugar" a constraint like `T: Iterator<Item = u32>` this to
// the "projection predicate" for:
//
// `<T as Iterator>::Item = u32`
- match (def_kind, term.unpack()) {
- (DefKind::AssocTy, ty::TermKind::Ty(_))
- | (DefKind::AssocConst, ty::TermKind::Const(_)) => (),
- (_, _) => {
- let got = if let Some(_) = term.ty() { "type" } else { "constant" };
- let expected = tcx.def_descr(assoc_item_def_id);
- let mut err = tcx.sess.struct_span_err(
- binding.span,
- format!("expected {expected} bound, found {got}"),
- );
- err.span_note(
- tcx.def_span(assoc_item_def_id),
- format!("{expected} defined here"),
- );
-
- if let DefKind::AssocConst = def_kind
- && let Some(t) = term.ty()
- && (t.is_enum() || t.references_error())
- && tcx.features().associated_const_equality
- {
- err.span_suggestion(
- binding.span,
- "if equating a const, try wrapping with braces",
- format!("{} = {{ const }}", binding.item_name),
- Applicability::HasPlaceholders,
- );
- }
- let reported = err.emit();
- term = match def_kind {
- DefKind::AssocTy => Ty::new_error(tcx, reported).into(),
- DefKind::AssocConst => ty::Const::new_error(
- tcx,
- reported,
- tcx.type_of(assoc_item_def_id)
- .instantiate(tcx, projection_ty.skip_binder().args),
- )
- .into(),
- _ => unreachable!(),
- };
- }
- }
bounds.push_projection_bound(
tcx,
- projection_ty
- .map_bound(|projection_ty| ty::ProjectionPredicate { projection_ty, term }),
+ projection_ty.map_bound(|projection_ty| ty::ProjectionPredicate {
+ projection_ty,
+ term: term.node,
+ }),
binding.span,
);
}
ConvertedBindingKind::Constraint(ast_bounds) => {
- match def_kind {
- DefKind::AssocTy => {}
- _ => {
- return Err(tcx.sess.emit_err(errors::AssocBoundOnConst {
- span: assoc_ident.span,
- descr: tcx.def_descr(assoc_item_def_id),
- }));
- }
- }
// "Desugar" a constraint like `T: Iterator<Item: Debug>` to
//
// `<T as Iterator>::Item: Debug`
diff --git a/compiler/rustc_hir_analysis/src/astconv/errors.rs b/compiler/rustc_hir_analysis/src/astconv/errors.rs
index 32be7e083..13ad9a453 100644
--- a/compiler/rustc_hir_analysis/src/astconv/errors.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/errors.rs
@@ -1,23 +1,22 @@
-use crate::astconv::AstConv;
+use crate::astconv::{AstConv, ConvertedBindingKind};
use crate::errors::{
- AssocTypeBindingNotAllowed, ManualImplementation, MissingTypeParams,
+ self, AssocTypeBindingNotAllowed, ManualImplementation, MissingTypeParams,
ParenthesizedFnTraitExpansion,
};
+use crate::fluent_generated as fluent;
use crate::traits::error_reporting::report_object_safety_error;
-use rustc_data_structures::fx::FxHashMap;
+use rustc_data_structures::fx::{FxHashMap, FxIndexMap, FxIndexSet};
use rustc_errors::{pluralize, struct_span_err, Applicability, Diagnostic, ErrorGuaranteed};
use rustc_hir as hir;
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_infer::traits::FulfillmentError;
-use rustc_middle::ty::{self, suggest_constraining_type_param, Ty, TyCtxt};
+use rustc_middle::ty::{self, suggest_constraining_type_param, Ty, TyCtxt, TypeVisitableExt};
use rustc_session::parse::feature_err;
use rustc_span::edit_distance::find_best_match_for_name;
use rustc_span::symbol::{sym, Ident};
use rustc_span::{Span, Symbol, DUMMY_SP};
use rustc_trait_selection::traits::object_safety_violations_for_assoc_item;
-use std::collections::BTreeSet;
-
impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
/// On missing type parameters, emit an E0393 error and provide a structured suggestion using
/// the type parameter's name as a placeholder.
@@ -99,83 +98,88 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
}
}
- pub(crate) fn complain_about_assoc_type_not_found<I>(
+ pub(super) fn complain_about_assoc_item_not_found<I>(
&self,
all_candidates: impl Fn() -> I,
ty_param_name: &str,
ty_param_def_id: Option<LocalDefId>,
+ assoc_kind: ty::AssocKind,
assoc_name: Ident,
span: Span,
+ binding: Option<&super::ConvertedBinding<'_, 'tcx>>,
) -> ErrorGuaranteed
where
I: Iterator<Item = ty::PolyTraitRef<'tcx>>,
{
+ let tcx = self.tcx();
+
+ // First and foremost, provide a more user-friendly & “intuitive” error on kind mismatches.
+ if let Some(assoc_item) = all_candidates().find_map(|r| {
+ tcx.associated_items(r.def_id())
+ .filter_by_name_unhygienic(assoc_name.name)
+ .find(|item| tcx.hygienic_eq(assoc_name, item.ident(tcx), r.def_id()))
+ }) {
+ return self.complain_about_assoc_kind_mismatch(
+ assoc_item, assoc_kind, assoc_name, span, binding,
+ );
+ }
+
+ let assoc_kind_str = super::assoc_kind_str(assoc_kind);
+
// The fallback span is needed because `assoc_name` might be an `Fn()`'s `Output` without a
// valid span, so we point at the whole path segment instead.
let is_dummy = assoc_name.span == DUMMY_SP;
- let mut err = struct_span_err!(
- self.tcx().sess,
- if is_dummy { span } else { assoc_name.span },
- E0220,
- "associated type `{}` not found for `{}`",
+ let mut err = errors::AssocItemNotFound {
+ span: if is_dummy { span } else { assoc_name.span },
assoc_name,
- ty_param_name
- );
+ assoc_kind: assoc_kind_str,
+ ty_param_name,
+ label: None,
+ sugg: None,
+ };
if is_dummy {
- err.span_label(span, format!("associated type `{assoc_name}` not found"));
- return err.emit();
+ err.label = Some(errors::AssocItemNotFoundLabel::NotFound { span });
+ return tcx.sess.emit_err(err);
}
let all_candidate_names: Vec<_> = all_candidates()
- .flat_map(|r| self.tcx().associated_items(r.def_id()).in_definition_order())
+ .flat_map(|r| tcx.associated_items(r.def_id()).in_definition_order())
.filter_map(|item| {
- if !item.is_impl_trait_in_trait() && item.kind == ty::AssocKind::Type {
- Some(item.name)
- } else {
- None
- }
+ (!item.is_impl_trait_in_trait() && item.kind == assoc_kind).then_some(item.name)
})
.collect();
if let Some(suggested_name) =
find_best_match_for_name(&all_candidate_names, assoc_name.name, None)
{
- err.span_suggestion(
- assoc_name.span,
- "there is an associated type with a similar name",
+ err.sugg = Some(errors::AssocItemNotFoundSugg::Similar {
+ span: assoc_name.span,
+ assoc_kind: assoc_kind_str,
suggested_name,
- Applicability::MaybeIncorrect,
- );
- return err.emit();
+ });
+ return tcx.sess.emit_err(err);
}
// If we didn't find a good item in the supertraits (or couldn't get
// the supertraits), like in ItemCtxt, then look more generally from
// all visible traits. If there's one clear winner, just suggest that.
- let visible_traits: Vec<_> = self
- .tcx()
+ let visible_traits: Vec<_> = tcx
.all_traits()
.filter(|trait_def_id| {
- let viz = self.tcx().visibility(*trait_def_id);
+ let viz = tcx.visibility(*trait_def_id);
let def_id = self.item_def_id();
- viz.is_accessible_from(def_id, self.tcx())
+ viz.is_accessible_from(def_id, tcx)
})
.collect();
let wider_candidate_names: Vec<_> = visible_traits
.iter()
- .flat_map(|trait_def_id| {
- self.tcx().associated_items(*trait_def_id).in_definition_order()
- })
+ .flat_map(|trait_def_id| tcx.associated_items(*trait_def_id).in_definition_order())
.filter_map(|item| {
- if !item.is_impl_trait_in_trait() && item.kind == ty::AssocKind::Type {
- Some(item.name)
- } else {
- None
- }
+ (!item.is_impl_trait_in_trait() && item.kind == assoc_kind).then_some(item.name)
})
.collect();
@@ -184,96 +188,155 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
{
if let [best_trait] = visible_traits
.iter()
+ .copied()
.filter(|trait_def_id| {
- self.tcx()
- .associated_items(*trait_def_id)
+ tcx.associated_items(trait_def_id)
.filter_by_name_unhygienic(suggested_name)
- .any(|item| item.kind == ty::AssocKind::Type)
+ .any(|item| item.kind == assoc_kind)
})
.collect::<Vec<_>>()[..]
{
- let trait_name = self.tcx().def_path_str(*best_trait);
- let an = if suggested_name != assoc_name.name { "a similarly named" } else { "an" };
- err.span_label(
- assoc_name.span,
- format!(
- "there is {an} associated type `{suggested_name}` in the \
- trait `{trait_name}`",
- ),
- );
- let hir = self.tcx().hir();
+ let trait_name = tcx.def_path_str(best_trait);
+ err.label = Some(errors::AssocItemNotFoundLabel::FoundInOtherTrait {
+ span: assoc_name.span,
+ assoc_kind: assoc_kind_str,
+ trait_name: &trait_name,
+ suggested_name,
+ identically_named: suggested_name == assoc_name.name,
+ });
+ let hir = tcx.hir();
if let Some(def_id) = ty_param_def_id
- && let parent = hir.get_parent_item(hir.local_def_id_to_hir_id(def_id))
+ && let parent = hir.get_parent_item(tcx.local_def_id_to_hir_id(def_id))
&& let Some(generics) = hir.get_generics(parent.def_id)
{
- if generics.bounds_for_param(def_id)
- .flat_map(|pred| pred.bounds.iter())
- .any(|b| match b {
+ if generics.bounds_for_param(def_id).flat_map(|pred| pred.bounds.iter()).any(
+ |b| match b {
hir::GenericBound::Trait(t, ..) => {
- t.trait_ref.trait_def_id().as_ref() == Some(best_trait)
+ t.trait_ref.trait_def_id() == Some(best_trait)
}
_ => false,
- })
- {
+ },
+ ) {
// The type param already has a bound for `trait_name`, we just need to
- // change the associated type.
- err.span_suggestion_verbose(
- assoc_name.span,
- format!(
- "change the associated type name to use `{suggested_name}` from \
- `{trait_name}`",
- ),
- suggested_name.to_string(),
- Applicability::MaybeIncorrect,
- );
- } else if suggest_constraining_type_param(
- self.tcx(),
- generics,
- &mut err,
- &ty_param_name,
- &trait_name,
- None,
- None,
- )
- && suggested_name != assoc_name.name
+ // change the associated item.
+ err.sugg = Some(errors::AssocItemNotFoundSugg::SimilarInOtherTrait {
+ span: assoc_name.span,
+ assoc_kind: assoc_kind_str,
+ suggested_name,
+ });
+ return tcx.sess.emit_err(err);
+ }
+
+ let mut err = tcx.sess.create_err(err);
+ if suggest_constraining_type_param(
+ tcx,
+ generics,
+ &mut err,
+ &ty_param_name,
+ &trait_name,
+ None,
+ None,
+ ) && suggested_name != assoc_name.name
{
// We suggested constraining a type parameter, but the associated type on it
// was also not an exact match, so we also suggest changing it.
err.span_suggestion_verbose(
assoc_name.span,
- "and also change the associated type name",
+ fluent::hir_analysis_assoc_item_not_found_similar_in_other_trait_with_bound_sugg,
suggested_name.to_string(),
Applicability::MaybeIncorrect,
);
}
+ return err.emit();
}
- return err.emit();
+ return tcx.sess.emit_err(err);
}
}
// If we still couldn't find any associated type, and only one associated type exists,
// suggests using it.
-
- if all_candidate_names.len() == 1 {
+ if let [candidate_name] = all_candidate_names.as_slice() {
// this should still compile, except on `#![feature(associated_type_defaults)]`
// where it could suggests `type A = Self::A`, thus recursing infinitely
- let applicability = if self.tcx().features().associated_type_defaults {
+ let applicability = if tcx.features().associated_type_defaults {
Applicability::Unspecified
} else {
Applicability::MaybeIncorrect
};
- err.span_suggestion(
- assoc_name.span,
- format!("`{ty_param_name}` has the following associated type"),
- all_candidate_names.first().unwrap().to_string(),
+ err.sugg = Some(errors::AssocItemNotFoundSugg::Other {
+ span: assoc_name.span,
applicability,
- );
+ ty_param_name,
+ assoc_kind: assoc_kind_str,
+ suggested_name: *candidate_name,
+ });
} else {
- err.span_label(assoc_name.span, format!("associated type `{assoc_name}` not found"));
+ err.label = Some(errors::AssocItemNotFoundLabel::NotFound { span: assoc_name.span });
}
- err.emit()
+ tcx.sess.emit_err(err)
+ }
+
+ fn complain_about_assoc_kind_mismatch(
+ &self,
+ assoc_item: &ty::AssocItem,
+ assoc_kind: ty::AssocKind,
+ ident: Ident,
+ span: Span,
+ binding: Option<&super::ConvertedBinding<'_, 'tcx>>,
+ ) -> ErrorGuaranteed {
+ let tcx = self.tcx();
+
+ let bound_on_assoc_const_label = if let ty::AssocKind::Const = assoc_item.kind
+ && let Some(binding) = binding
+ && let ConvertedBindingKind::Constraint(_) = binding.kind
+ {
+ let lo = if binding.gen_args.span_ext.is_dummy() {
+ ident.span
+ } else {
+ binding.gen_args.span_ext
+ };
+ Some(lo.between(span.shrink_to_hi()))
+ } else {
+ None
+ };
+
+ // FIXME(associated_const_equality): This has quite a few false positives and negatives.
+ let wrap_in_braces_sugg = if let Some(binding) = binding
+ && let ConvertedBindingKind::Equality(term) = binding.kind
+ && let ty::TermKind::Ty(ty) = term.node.unpack()
+ && (ty.is_enum() || ty.references_error())
+ && tcx.features().associated_const_equality
+ {
+ Some(errors::AssocKindMismatchWrapInBracesSugg {
+ lo: term.span.shrink_to_lo(),
+ hi: term.span.shrink_to_hi(),
+ })
+ } else {
+ None
+ };
+
+ // For equality bounds, we want to blame the term (RHS) instead of the item (LHS) since
+ // one can argue that that's more “untuitive” to the user.
+ let (span, expected_because_label, expected, got) = if let Some(binding) = binding
+ && let ConvertedBindingKind::Equality(term) = binding.kind
+ {
+ (term.span, Some(ident.span), assoc_item.kind, assoc_kind)
+ } else {
+ (ident.span, None, assoc_kind, assoc_item.kind)
+ };
+
+ tcx.sess.emit_err(errors::AssocKindMismatch {
+ span,
+ expected: super::assoc_kind_str(expected),
+ got: super::assoc_kind_str(got),
+ expected_because_label,
+ assoc_kind: super::assoc_kind_str(assoc_item.kind),
+ def_span: tcx.def_span(assoc_item.def_id),
+ bound_on_assoc_const_label,
+ wrap_in_braces_sugg,
+ })
}
pub(crate) fn complain_about_ambiguous_inherent_assoc_type(
@@ -506,23 +569,24 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
/// emit a generic note suggesting using a `where` clause to constraint instead.
pub(crate) fn complain_about_missing_associated_types(
&self,
- associated_types: FxHashMap<Span, BTreeSet<DefId>>,
+ associated_types: FxIndexMap<Span, FxIndexSet<DefId>>,
potential_assoc_types: Vec<Span>,
trait_bounds: &[hir::PolyTraitRef<'_>],
) {
if associated_types.values().all(|v| v.is_empty()) {
return;
}
+
let tcx = self.tcx();
// FIXME: Marked `mut` so that we can replace the spans further below with a more
// appropriate one, but this should be handled earlier in the span assignment.
- let mut associated_types: FxHashMap<Span, Vec<_>> = associated_types
+ let mut associated_types: FxIndexMap<Span, Vec<_>> = associated_types
.into_iter()
.map(|(span, def_ids)| {
(span, def_ids.into_iter().map(|did| tcx.associated_item(did)).collect())
})
.collect();
- let mut names: FxHashMap<String, Vec<Symbol>> = Default::default();
+ let mut names: FxIndexMap<String, Vec<Symbol>> = Default::default();
let mut names_len = 0;
// Account for things like `dyn Foo + 'a`, like in tests `issue-22434.rs` and
@@ -585,6 +649,32 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
}
}
+ // We get all the associated items that _are_ set,
+ // so that we can check if any of their names match one of the ones we are missing.
+ // This would mean that they are shadowing the associated type we are missing,
+ // and we can then use their span to indicate this to the user.
+ let bound_names = trait_bounds
+ .iter()
+ .filter_map(|poly_trait_ref| {
+ let path = poly_trait_ref.trait_ref.path.segments.last()?;
+ let args = path.args?;
+
+ Some(args.bindings.iter().filter_map(|binding| {
+ let ident = binding.ident;
+ let trait_def = path.res.def_id();
+ let assoc_item = tcx.associated_items(trait_def).find_by_name_and_kind(
+ tcx,
+ ident,
+ ty::AssocKind::Type,
+ trait_def,
+ );
+
+ Some((ident.name, assoc_item?))
+ }))
+ })
+ .flatten()
+ .collect::<FxHashMap<Symbol, &ty::AssocItem>>();
+
let mut names = names
.into_iter()
.map(|(trait_, mut assocs)| {
@@ -625,16 +715,42 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
*names.entry(item.name).or_insert(0) += 1;
}
let mut dupes = false;
+ let mut shadows = false;
for item in assoc_items {
let prefix = if names[&item.name] > 1 {
let trait_def_id = item.container_id(tcx);
dupes = true;
format!("{}::", tcx.def_path_str(trait_def_id))
+ } else if bound_names.get(&item.name).is_some_and(|x| x != &item) {
+ let trait_def_id = item.container_id(tcx);
+ shadows = true;
+ format!("{}::", tcx.def_path_str(trait_def_id))
} else {
String::new()
};
+
+ let mut is_shadowed = false;
+
+ if let Some(assoc_item) = bound_names.get(&item.name)
+ && assoc_item != &item
+ {
+ is_shadowed = true;
+
+ let rename_message =
+ if assoc_item.def_id.is_local() { ", consider renaming it" } else { "" };
+ err.span_label(
+ tcx.def_span(assoc_item.def_id),
+ format!("`{}{}` shadowed here{}", prefix, item.name, rename_message),
+ );
+ }
+
+ let rename_message = if is_shadowed { ", consider renaming it" } else { "" };
+
if let Some(sp) = tcx.hir().span_if_local(item.def_id) {
- err.span_label(sp, format!("`{}{}` defined here", prefix, item.name));
+ err.span_label(
+ sp,
+ format!("`{}{}` defined here{}", prefix, item.name, rename_message),
+ );
}
}
if potential_assoc_types.len() == assoc_items.len() {
@@ -642,8 +758,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
// extra type arguments present. A suggesting to replace the generic args with
// associated types is already emitted.
already_has_generics_args_suggestion = true;
- } else if let (Ok(snippet), false) =
- (tcx.sess.source_map().span_to_snippet(*span), dupes)
+ } else if let (Ok(snippet), false, false) =
+ (tcx.sess.source_map().span_to_snippet(*span), dupes, shadows)
{
let types: Vec<_> =
assoc_items.iter().map(|item| format!("{} = Type", item.name)).collect();
@@ -725,6 +841,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
err.span_help(where_constraints, where_msg);
}
}
+
err.emit();
}
}
diff --git a/compiler/rustc_hir_analysis/src/astconv/generics.rs b/compiler/rustc_hir_analysis/src/astconv/generics.rs
index d29a27ece..b495b00ec 100644
--- a/compiler/rustc_hir_analysis/src/astconv/generics.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/generics.rs
@@ -243,6 +243,31 @@ pub fn create_args_for_parent_generic_args<'tcx, 'a>(
match (args_iter.peek(), params.peek()) {
(Some(&arg), Some(&param)) => {
match (arg, &param.kind, arg_count.explicit_late_bound) {
+ (
+ GenericArg::Const(hir::ConstArg {
+ is_desugared_from_effects: true,
+ ..
+ }),
+ GenericParamDefKind::Const { is_host_effect: false, .. }
+ | GenericParamDefKind::Type { .. }
+ | GenericParamDefKind::Lifetime,
+ _,
+ ) => {
+ // SPECIAL CASE FOR DESUGARED EFFECT PARAMS
+ // This comes from the following example:
+ //
+ // ```
+ // #[const_trait]
+ // pub trait PartialEq<Rhs: ?Sized = Self> {}
+ // impl const PartialEq for () {}
+ // ```
+ //
+ // Since this is a const impl, we need to insert a host arg at the end of
+ // `PartialEq`'s generics, but this errors since `Rhs` isn't specified.
+ // To work around this, we infer all arguments until we reach the host param.
+ args.push(ctx.inferred_kind(Some(&args), param, infer_args));
+ params.next();
+ }
(GenericArg::Lifetime(_), GenericParamDefKind::Lifetime, _)
| (
GenericArg::Type(_) | GenericArg::Infer(_),
@@ -636,7 +661,7 @@ pub(crate) fn prohibit_explicit_late_bound_lifetimes(
args.args[0].hir_id(),
multispan,
msg,
- |lint| lint,
+ |_| {},
);
}
diff --git a/compiler/rustc_hir_analysis/src/astconv/lint.rs b/compiler/rustc_hir_analysis/src/astconv/lint.rs
index bc57bbcca..9afb04b74 100644
--- a/compiler/rustc_hir_analysis/src/astconv/lint.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/lint.rs
@@ -24,7 +24,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
..
}),
..
- }) = tcx.hir().get_by_def_id(parent_id)
+ }) = tcx.hir_node_by_def_id(parent_id)
&& self_ty.hir_id == impl_self_ty.hir_id
{
if !of_trait_ref.trait_def_id().is_some_and(|def_id| def_id.is_local()) {
@@ -106,7 +106,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
);
}
// check if the impl trait that we are considering is a impl of a local trait
- self.maybe_lint_blanket_trait_impl(&self_ty, &mut diag);
+ self.maybe_lint_blanket_trait_impl(self_ty, &mut diag);
diag.stash(self_ty.span, StashKey::TraitMissingMethod);
} else {
let msg = "trait objects without an explicit `dyn` are deprecated";
@@ -121,8 +121,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
sugg,
Applicability::MachineApplicable,
);
- self.maybe_lint_blanket_trait_impl(&self_ty, lint);
- lint
+ self.maybe_lint_blanket_trait_impl(self_ty, lint);
},
);
}
diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs
index 2fcb45ef8..6f8e80172 100644
--- a/compiler/rustc_hir_analysis/src/astconv/mod.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs
@@ -18,29 +18,30 @@ use crate::require_c_abi_if_c_variadic;
use rustc_ast::TraitObjectSyntax;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_errors::{
- struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, FatalError,
- MultiSpan,
+ error_code, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed,
+ FatalError, MultiSpan,
};
use rustc_hir as hir;
use rustc_hir::def::{CtorOf, DefKind, Namespace, Res};
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::intravisit::{walk_generics, Visitor as _};
use rustc_hir::{GenericArg, GenericArgs, OpaqueTyOrigin};
-use rustc_infer::infer::{InferCtxt, InferOk, TyCtxtInferExt};
+use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
use rustc_infer::traits::ObligationCause;
use rustc_middle::middle::stability::AllowUnstable;
use rustc_middle::ty::GenericParamDefKind;
use rustc_middle::ty::{
- self, Const, GenericArgKind, GenericArgsRef, IsSuggestable, Ty, TyCtxt, TypeVisitableExt,
+ self, Const, GenericArgKind, GenericArgsRef, IsSuggestable, ParamEnv, Ty, TyCtxt,
+ TypeVisitableExt,
};
use rustc_session::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS;
use rustc_span::edit_distance::find_best_match_for_name;
+use rustc_span::source_map::{respan, Spanned};
use rustc_span::symbol::{kw, Ident, Symbol};
use rustc_span::{sym, BytePos, Span, DUMMY_SP};
use rustc_target::spec::abi;
use rustc_trait_selection::traits::wf::object_region_bounds;
-use rustc_trait_selection::traits::{self, NormalizeExt, ObligationCtxt};
-use rustc_type_ir::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
+use rustc_trait_selection::traits::{self, ObligationCtxt};
use std::fmt::Display;
use std::slice;
@@ -162,7 +163,7 @@ struct ConvertedBinding<'a, 'tcx> {
#[derive(Debug)]
enum ConvertedBindingKind<'a, 'tcx> {
- Equality(ty::Term<'tcx>),
+ Equality(Spanned<ty::Term<'tcx>>),
Constraint(&'a [hir::GenericBound<'a>]),
}
@@ -239,7 +240,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
def: Option<&ty::GenericParamDef>,
) -> ty::Region<'tcx> {
let tcx = self.tcx();
- let lifetime_name = |def_id| tcx.hir().name(tcx.hir().local_def_id_to_hir_id(def_id));
+ let lifetime_name = |def_id| tcx.hir().name(tcx.local_def_id_to_hir_id(def_id));
match tcx.named_bound_var(lifetime.hir_id) {
Some(rbv::ResolvedArg::StaticLifetime) => tcx.lifetimes.re_static,
@@ -250,7 +251,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
var: ty::BoundVar::from_u32(index),
kind: ty::BrNamed(def_id, name),
};
- ty::Region::new_late_bound(tcx, debruijn, br)
+ ty::Region::new_bound(tcx, debruijn, br)
}
Some(rbv::ResolvedArg::EarlyBound(def_id)) => {
@@ -258,12 +259,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
let item_def_id = tcx.hir().ty_param_owner(def_id.expect_local());
let generics = tcx.generics_of(item_def_id);
let index = generics.param_def_id_to_index[&def_id];
- ty::Region::new_early_bound(tcx, ty::EarlyBoundRegion { def_id, index, name })
+ ty::Region::new_early_param(tcx, ty::EarlyParamRegion { def_id, index, name })
}
Some(rbv::ResolvedArg::Free(scope, id)) => {
let name = lifetime_name(id.expect_local());
- ty::Region::new_free(tcx, scope, ty::BrNamed(id, name))
+ ty::Region::new_late_param(tcx, scope, ty::BrNamed(id, name))
// (*) -- not late-bound, won't change
}
@@ -476,7 +477,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
ty::Const::new_misc_error(tcx, ty).into()
}
}
- _ => unreachable!(),
+ (kind, arg) => span_bug!(
+ self.span,
+ "mismatched path argument for kind {kind:?}: found arg {arg:?}"
+ ),
}
}
@@ -595,12 +599,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
.map(|binding| {
let kind = match &binding.kind {
hir::TypeBindingKind::Equality { term } => match term {
- hir::Term::Ty(ty) => {
- ConvertedBindingKind::Equality(self.ast_ty_to_ty(ty).into())
- }
+ hir::Term::Ty(ty) => ConvertedBindingKind::Equality(respan(
+ ty.span,
+ self.ast_ty_to_ty(ty).into(),
+ )),
hir::Term::Const(c) => {
+ let span = self.tcx().def_span(c.def_id);
let c = Const::from_anon_const(self.tcx(), c.def_id);
- ConvertedBindingKind::Equality(c.into())
+ ConvertedBindingKind::Equality(respan(span, c.into()))
}
},
hir::TypeBindingKind::Constraint { bounds } => {
@@ -672,36 +678,57 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
)
}
- fn instantiate_poly_trait_ref_inner(
+ /// Given a trait bound like `Debug`, applies that trait bound the given self-type to construct
+ /// a full trait reference. The resulting trait reference is returned. This may also generate
+ /// auxiliary bounds, which are added to `bounds`.
+ ///
+ /// Example:
+ ///
+ /// ```ignore (illustrative)
+ /// poly_trait_ref = Iterator<Item = u32>
+ /// self_ty = Foo
+ /// ```
+ ///
+ /// this would return `Foo: Iterator` and add `<Foo as Iterator>::Item = u32` into `bounds`.
+ ///
+ /// **A note on binders:** against our usual convention, there is an implied binder around
+ /// the `self_ty` and `poly_trait_ref` parameters here. So they may reference bound regions.
+ /// If for example you had `for<'a> Foo<'a>: Bar<'a>`, then the `self_ty` would be `Foo<'a>`
+ /// where `'a` is a bound region at depth 0. Similarly, the `poly_trait_ref` would be
+ /// `Bar<'a>`. The returned poly-trait-ref will have this binder instantiated explicitly,
+ /// however.
+ #[instrument(level = "debug", skip(self, span, constness, bounds, speculative))]
+ pub(crate) fn instantiate_poly_trait_ref(
&self,
- hir_id: hir::HirId,
+ trait_ref: &hir::TraitRef<'_>,
span: Span,
- binding_span: Option<Span>,
constness: ty::BoundConstness,
polarity: ty::ImplPolarity,
+ self_ty: Ty<'tcx>,
bounds: &mut Bounds<'tcx>,
speculative: bool,
- trait_ref_span: Span,
- trait_def_id: DefId,
- trait_segment: &hir::PathSegment<'_>,
- args: &GenericArgs<'_>,
- infer_args: bool,
- self_ty: Ty<'tcx>,
only_self_bounds: OnlySelfBounds,
) -> GenericArgCountResult {
+ let trait_def_id = trait_ref.trait_def_id().unwrap_or_else(|| FatalError.raise());
+ let trait_segment = trait_ref.path.segments.last().unwrap();
+ let args = trait_segment.args();
+
+ self.prohibit_generics(trait_ref.path.segments.split_last().unwrap().1.iter(), |_| {});
+ self.complain_about_internal_fn_trait(span, trait_def_id, trait_segment, false);
+
let (generic_args, arg_count) = self.create_args_for_ast_path(
- trait_ref_span,
+ trait_ref.path.span,
trait_def_id,
&[],
trait_segment,
args,
- infer_args,
+ trait_segment.infer_args,
Some(self_ty),
constness,
);
let tcx = self.tcx();
- let bound_vars = tcx.late_bound_vars(hir_id);
+ let bound_vars = tcx.late_bound_vars(trait_ref.hir_ref_id);
debug!(?bound_vars);
let assoc_bindings = self.create_assoc_bindings_for_generic_args(args);
@@ -720,21 +747,22 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
// since we should have emitten an error for them earlier, and they will
// not be well-formed!
if polarity == ty::ImplPolarity::Negative {
- self.tcx()
- .sess
- .delay_span_bug(binding.span, "negative trait bounds should not have bindings");
+ self.tcx().sess.span_delayed_bug(
+ binding.span,
+ "negative trait bounds should not have bindings",
+ );
continue;
}
// Specify type to assert that error was already reported in `Err` case.
let _: Result<_, ErrorGuaranteed> = self.add_predicates_for_ast_type_binding(
- hir_id,
+ trait_ref.hir_ref_id,
poly_trait_ref,
binding,
bounds,
speculative,
&mut dup_bindings,
- binding_span.unwrap_or(binding.span),
+ binding.span,
constness,
only_self_bounds,
polarity,
@@ -745,102 +773,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
arg_count
}
- /// Given a trait bound like `Debug`, applies that trait bound the given self-type to construct
- /// a full trait reference. The resulting trait reference is returned. This may also generate
- /// auxiliary bounds, which are added to `bounds`.
- ///
- /// Example:
- ///
- /// ```ignore (illustrative)
- /// poly_trait_ref = Iterator<Item = u32>
- /// self_ty = Foo
- /// ```
- ///
- /// this would return `Foo: Iterator` and add `<Foo as Iterator>::Item = u32` into `bounds`.
- ///
- /// **A note on binders:** against our usual convention, there is an implied bounder around
- /// the `self_ty` and `poly_trait_ref` parameters here. So they may reference bound regions.
- /// If for example you had `for<'a> Foo<'a>: Bar<'a>`, then the `self_ty` would be `Foo<'a>`
- /// where `'a` is a bound region at depth 0. Similarly, the `poly_trait_ref` would be
- /// `Bar<'a>`. The returned poly-trait-ref will have this binder instantiated explicitly,
- /// however.
- #[instrument(level = "debug", skip(self, span, constness, bounds, speculative))]
- pub(crate) fn instantiate_poly_trait_ref(
- &self,
- trait_ref: &hir::TraitRef<'_>,
- span: Span,
- constness: ty::BoundConstness,
- polarity: ty::ImplPolarity,
- self_ty: Ty<'tcx>,
- bounds: &mut Bounds<'tcx>,
- speculative: bool,
- only_self_bounds: OnlySelfBounds,
- ) -> GenericArgCountResult {
- let hir_id = trait_ref.hir_ref_id;
- let binding_span = None;
- let trait_ref_span = trait_ref.path.span;
- let trait_def_id = trait_ref.trait_def_id().unwrap_or_else(|| FatalError.raise());
- let trait_segment = trait_ref.path.segments.last().unwrap();
- let args = trait_segment.args();
- let infer_args = trait_segment.infer_args;
-
- self.prohibit_generics(trait_ref.path.segments.split_last().unwrap().1.iter(), |_| {});
- self.complain_about_internal_fn_trait(span, trait_def_id, trait_segment, false);
-
- self.instantiate_poly_trait_ref_inner(
- hir_id,
- span,
- binding_span,
- constness,
- polarity,
- bounds,
- speculative,
- trait_ref_span,
- trait_def_id,
- trait_segment,
- args,
- infer_args,
- self_ty,
- only_self_bounds,
- )
- }
-
- pub(crate) fn instantiate_lang_item_trait_ref(
- &self,
- lang_item: hir::LangItem,
- span: Span,
- hir_id: hir::HirId,
- args: &GenericArgs<'_>,
- self_ty: Ty<'tcx>,
- bounds: &mut Bounds<'tcx>,
- only_self_bounds: OnlySelfBounds,
- ) {
- let binding_span = Some(span);
- let constness = ty::BoundConstness::NotConst;
- let speculative = false;
- let trait_ref_span = span;
- let trait_def_id = self.tcx().require_lang_item(lang_item, Some(span));
- let trait_segment = &hir::PathSegment::invalid();
- let infer_args = false;
-
- self.instantiate_poly_trait_ref_inner(
- hir_id,
- span,
- binding_span,
- constness,
- ty::ImplPolarity::Positive,
- bounds,
- speculative,
- trait_ref_span,
- trait_def_id,
- trait_segment,
- args,
- infer_args,
- self_ty,
- only_self_bounds,
- );
- }
-
fn ast_path_to_mono_trait_ref(
&self,
span: Span,
@@ -945,7 +877,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
Applicability::MachineApplicable,
);
} else {
- match (types, traits) {
+ let mut types = types.to_vec();
+ types.sort();
+ let mut traits = traits.to_vec();
+ traits.sort();
+ match (&types[..], &traits[..]) {
([], []) => {
err.span_suggestion_verbose(
span,
@@ -1051,7 +987,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
debug!("find_bound_for_assoc_item: predicates={:#?}", predicates);
let param_name = tcx.hir().ty_param_name(ty_param_def_id);
- self.one_bound_for_assoc_type(
+ self.one_bound_for_assoc_item(
|| {
traits::transitive_bounds_that_define_assoc_item(
tcx,
@@ -1063,6 +999,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
},
param_name,
Some(ty_param_def_id),
+ ty::AssocKind::Type,
assoc_name,
span,
None,
@@ -1071,48 +1008,45 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
// Checks that `bounds` contains exactly one element and reports appropriate
// errors otherwise.
- #[instrument(level = "debug", skip(self, all_candidates, ty_param_name, is_equality), ret)]
- fn one_bound_for_assoc_type<I>(
+ #[instrument(level = "debug", skip(self, all_candidates, ty_param_name, binding), ret)]
+ fn one_bound_for_assoc_item<I>(
&self,
all_candidates: impl Fn() -> I,
ty_param_name: impl Display,
ty_param_def_id: Option<LocalDefId>,
+ assoc_kind: ty::AssocKind,
assoc_name: Ident,
span: Span,
- is_equality: Option<ty::Term<'tcx>>,
+ binding: Option<&ConvertedBinding<'_, 'tcx>>,
) -> Result<ty::PolyTraitRef<'tcx>, ErrorGuaranteed>
where
I: Iterator<Item = ty::PolyTraitRef<'tcx>>,
{
+ let tcx = self.tcx();
+
let mut matching_candidates = all_candidates().filter(|r| {
- self.trait_defines_associated_item_named(r.def_id(), ty::AssocKind::Type, assoc_name)
- });
- let mut const_candidates = all_candidates().filter(|r| {
- self.trait_defines_associated_item_named(r.def_id(), ty::AssocKind::Const, assoc_name)
+ self.trait_defines_associated_item_named(r.def_id(), assoc_kind, assoc_name)
});
- let (mut bound, mut next_cand) = match (matching_candidates.next(), const_candidates.next())
- {
- (Some(bound), _) => (bound, matching_candidates.next()),
- (None, Some(bound)) => (bound, const_candidates.next()),
- (None, None) => {
- let reported = self.complain_about_assoc_type_not_found(
- all_candidates,
- &ty_param_name.to_string(),
- ty_param_def_id,
- assoc_name,
- span,
- );
- return Err(reported);
- }
+ let Some(mut bound) = matching_candidates.next() else {
+ let reported = self.complain_about_assoc_item_not_found(
+ all_candidates,
+ &ty_param_name.to_string(),
+ ty_param_def_id,
+ assoc_kind,
+ assoc_name,
+ span,
+ binding,
+ );
+ return Err(reported);
};
debug!(?bound);
// look for a candidate that is not the same as our first bound, disregarding
// whether the bound is const.
+ let mut next_cand = matching_candidates.next();
while let Some(mut bound2) = next_cand {
debug!(?bound2);
- let tcx = self.tcx();
if bound2.bound_vars() != bound.bound_vars() {
break;
}
@@ -1133,7 +1067,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
.map(|(n, arg)| if host_index == n { tcx.consts.true_.into() } else { arg });
if unconsted_args.eq(bound2.skip_binder().args.iter()) {
- next_cand = matching_candidates.next().or_else(|| const_candidates.next());
+ next_cand = matching_candidates.next();
} else {
break;
}
@@ -1142,51 +1076,53 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
if let Some(bound2) = next_cand {
debug!(?bound2);
- let bounds = IntoIterator::into_iter([bound, bound2]).chain(matching_candidates);
- let mut err = if is_equality.is_some() {
- // More specific Error Index entry.
- struct_span_err!(
- self.tcx().sess,
- span,
- E0222,
- "ambiguous associated type `{}` in bounds of `{}`",
- assoc_name,
- ty_param_name
- )
- } else {
- struct_span_err!(
- self.tcx().sess,
- span,
- E0221,
- "ambiguous associated type `{}` in bounds of `{}`",
- assoc_name,
- ty_param_name
- )
- };
- err.span_label(span, format!("ambiguous associated type `{assoc_name}`"));
+ let assoc_kind_str = assoc_kind_str(assoc_kind);
+ let ty_param_name = &ty_param_name.to_string();
+ let mut err = tcx.sess.create_err(crate::errors::AmbiguousAssocItem {
+ span,
+ assoc_kind: assoc_kind_str,
+ assoc_name,
+ ty_param_name,
+ });
+ // Provide a more specific error code index entry for equality bindings.
+ err.code(
+ if let Some(binding) = binding
+ && let ConvertedBindingKind::Equality(_) = binding.kind
+ {
+ error_code!(E0222)
+ } else {
+ error_code!(E0221)
+ },
+ );
+ // FIXME(#97583): Resugar equality bounds to type/const bindings.
+ // FIXME: Turn this into a structured, translateable & more actionable suggestion.
let mut where_bounds = vec![];
- for bound in bounds {
+ for bound in [bound, bound2].into_iter().chain(matching_candidates) {
let bound_id = bound.def_id();
- let bound_span = self
- .tcx()
+ let bound_span = tcx
.associated_items(bound_id)
- .find_by_name_and_kind(self.tcx(), assoc_name, ty::AssocKind::Type, bound_id)
- .and_then(|item| self.tcx().hir().span_if_local(item.def_id));
+ .find_by_name_and_kind(tcx, assoc_name, assoc_kind, bound_id)
+ .and_then(|item| tcx.hir().span_if_local(item.def_id));
if let Some(bound_span) = bound_span {
err.span_label(
bound_span,
- format!(
- "ambiguous `{assoc_name}` from `{}`",
- bound.print_only_trait_path(),
- ),
+ format!("ambiguous `{assoc_name}` from `{}`", bound.print_trait_sugared(),),
);
- if let Some(constraint) = &is_equality {
- where_bounds.push(format!(
- " T: {trait}::{assoc_name} = {constraint}",
- trait=bound.print_only_trait_path(),
- ));
+ if let Some(binding) = binding {
+ match binding.kind {
+ ConvertedBindingKind::Equality(term) => {
+ // FIXME(#97583): This isn't syntactically well-formed!
+ where_bounds.push(format!(
+ " T: {trait}::{assoc_name} = {term}",
+ trait = bound.print_only_trait_path(),
+ term = term.node,
+ ));
+ }
+ // FIXME: Provide a suggestion.
+ ConvertedBindingKind::Constraint(_bounds) => {}
+ }
} else {
err.span_suggestion_verbose(
span.with_hi(assoc_name.span.lo()),
@@ -1197,7 +1133,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
}
} else {
err.note(format!(
- "associated type `{ty_param_name}` could derive from `{}`",
+ "associated {assoc_kind_str} `{assoc_name}` could derive from `{}`",
bound.print_only_trait_path(),
));
}
@@ -1218,46 +1154,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
Ok(bound)
}
- #[instrument(level = "debug", skip(self, all_candidates, ty_name), ret)]
- fn one_bound_for_assoc_method(
- &self,
- all_candidates: impl Iterator<Item = ty::PolyTraitRef<'tcx>>,
- ty_name: impl Display,
- assoc_name: Ident,
- span: Span,
- ) -> Result<ty::PolyTraitRef<'tcx>, ErrorGuaranteed> {
- let mut matching_candidates = all_candidates.filter(|r| {
- self.trait_defines_associated_item_named(r.def_id(), ty::AssocKind::Fn, assoc_name)
- });
-
- let candidate = match matching_candidates.next() {
- Some(candidate) => candidate,
- None => {
- return Err(self.tcx().sess.emit_err(
- crate::errors::ReturnTypeNotationMissingMethod {
- span,
- ty_name: ty_name.to_string(),
- assoc_name: assoc_name.name,
- },
- ));
- }
- };
-
- if let Some(conflicting_candidate) = matching_candidates.next() {
- return Err(self.tcx().sess.emit_err(
- crate::errors::ReturnTypeNotationConflictingBound {
- span,
- ty_name: ty_name.to_string(),
- assoc_name: assoc_name.name,
- first_bound: candidate.print_only_trait_path(),
- second_bound: conflicting_candidate.print_only_trait_path(),
- },
- ));
- }
-
- Ok(candidate)
- }
-
// Create a type from a path to an associated type or to an enum variant.
// For a path `A::B::C::D`, `qself_ty` and `qself_def` are the type and def for `A::B::C`
// and item_segment is the path segment for `D`. We return a type and a def for
@@ -1415,11 +1311,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
// trait reference.
let Some(trait_ref) = tcx.impl_trait_ref(impl_def_id) else {
// A cycle error occurred, most likely.
- let guar = tcx.sess.delay_span_bug(span, "expected cycle error");
+ let guar = tcx.sess.span_delayed_bug(span, "expected cycle error");
return Err(guar);
};
- self.one_bound_for_assoc_type(
+ self.one_bound_for_assoc_item(
|| {
traits::supertraits(
tcx,
@@ -1428,6 +1324,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
},
kw::SelfUpper,
None,
+ ty::AssocKind::Type,
assoc_ident,
span,
None,
@@ -1508,15 +1405,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
};
let trait_did = bound.def_id();
- let Some(assoc_ty_did) = self.lookup_assoc_ty(assoc_ident, hir_ref_id, span, trait_did)
- else {
- // Assume that if it's not matched, there must be a const defined with the same name
- // but it was used in a type position.
- let msg = format!("found associated const `{assoc_ident}` when type was expected");
- let guar = tcx.sess.struct_span_err(span, msg).emit();
- return Err(guar);
- };
-
+ let assoc_ty_did = self.lookup_assoc_ty(assoc_ident, hir_ref_id, span, trait_did).unwrap();
let ty = self.projected_ty_from_poly_trait_ref(span, assoc_ty_did, assoc_segment, bound);
if let Some(variant_def_id) = variant_resolution {
@@ -1545,8 +1434,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
format!("<{} as {}>::{}", qself_ty, tcx.item_name(trait_did), assoc_ident),
Applicability::MachineApplicable,
);
-
- lint
},
);
}
@@ -1602,134 +1489,110 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
// FIXME(inherent_associated_types): Acquiring the ParamEnv this early leads to cycle errors
// when inside of an ADT (#108491) or where clause.
let param_env = tcx.param_env(block.owner);
- let cause = ObligationCause::misc(span, block.owner.def_id);
-
- let mut fulfillment_errors = Vec::new();
- let mut applicable_candidates: Vec<_> = infcx.probe(|_| {
- // Regions are not considered during selection.
- let self_ty = self_ty
- .fold_with(&mut BoundVarEraser { tcx, universe: infcx.create_next_universe() });
-
- struct BoundVarEraser<'tcx> {
- tcx: TyCtxt<'tcx>,
- universe: ty::UniverseIndex,
- }
- // FIXME(non_lifetime_binders): Don't assign the same universe to each placeholder.
- impl<'tcx> TypeFolder<TyCtxt<'tcx>> for BoundVarEraser<'tcx> {
- fn interner(&self) -> TyCtxt<'tcx> {
- self.tcx
- }
+ let mut universes = if self_ty.has_escaping_bound_vars() {
+ vec![None; self_ty.outer_exclusive_binder().as_usize()]
+ } else {
+ vec![]
+ };
- fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
- if r.is_late_bound() { self.tcx.lifetimes.re_erased } else { r }
- }
+ let (impl_, (assoc_item, def_scope)) =
+ crate::traits::project::with_replaced_escaping_bound_vars(
+ infcx,
+ &mut universes,
+ self_ty,
+ |self_ty| {
+ self.select_inherent_assoc_type_candidates(
+ infcx, name, span, self_ty, param_env, candidates,
+ )
+ },
+ )?;
+
+ self.check_assoc_ty(assoc_item, name, def_scope, block, span);
+
+ // FIXME(fmease): Currently creating throwaway `parent_args` to please
+ // `create_args_for_associated_item`. Modify the latter instead (or sth. similar) to
+ // not require the parent args logic.
+ let parent_args = ty::GenericArgs::identity_for_item(tcx, impl_);
+ let args = self.create_args_for_associated_item(span, assoc_item, segment, parent_args);
+ let args = tcx.mk_args_from_iter(
+ std::iter::once(ty::GenericArg::from(self_ty))
+ .chain(args.into_iter().skip(parent_args.len())),
+ );
- fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
- match *ty.kind() {
- ty::Bound(_, bv) => Ty::new_placeholder(
- self.tcx,
- ty::PlaceholderType { universe: self.universe, bound: bv },
- ),
- _ => ty.super_fold_with(self),
- }
- }
+ let ty = Ty::new_alias(tcx, ty::Inherent, ty::AliasTy::new(tcx, assoc_item, args));
- fn fold_const(
- &mut self,
- ct: ty::Const<'tcx>,
- ) -> <TyCtxt<'tcx> as rustc_type_ir::Interner>::Const {
- assert!(!ct.ty().has_escaping_bound_vars());
-
- match ct.kind() {
- ty::ConstKind::Bound(_, bv) => ty::Const::new_placeholder(
- self.tcx,
- ty::PlaceholderConst { universe: self.universe, bound: bv },
- ct.ty(),
- ),
- _ => ct.super_fold_with(self),
- }
- }
- }
+ Ok(Some((ty, assoc_item)))
+ }
- let InferOk { value: self_ty, obligations } =
- infcx.at(&cause, param_env).normalize(self_ty);
+ fn select_inherent_assoc_type_candidates(
+ &self,
+ infcx: &InferCtxt<'tcx>,
+ name: Ident,
+ span: Span,
+ self_ty: Ty<'tcx>,
+ param_env: ParamEnv<'tcx>,
+ candidates: Vec<(DefId, (DefId, DefId))>,
+ ) -> Result<(DefId, (DefId, DefId)), ErrorGuaranteed> {
+ let tcx = self.tcx();
+ let mut fulfillment_errors = Vec::new();
- candidates
- .iter()
- .copied()
- .filter(|&(impl_, _)| {
- infcx.probe(|_| {
- let ocx = ObligationCtxt::new(&infcx);
- ocx.register_obligations(obligations.clone());
-
- let impl_args = infcx.fresh_args_for_item(span, impl_);
- let impl_ty = tcx.type_of(impl_).instantiate(tcx, impl_args);
- let impl_ty = ocx.normalize(&cause, param_env, impl_ty);
-
- // Check that the self types can be related.
- // FIXME(inherent_associated_types): Should we use `eq` here? Method probing uses
- // `sup` for this situtation, too. What for? To constrain inference variables?
- if ocx.sup(&ObligationCause::dummy(), param_env, impl_ty, self_ty).is_err()
- {
- return false;
- }
+ let applicable_candidates: Vec<_> = candidates
+ .iter()
+ .copied()
+ .filter(|&(impl_, _)| {
+ infcx.probe(|_| {
+ let ocx = ObligationCtxt::new(infcx);
+ let self_ty = ocx.normalize(&ObligationCause::dummy(), param_env, self_ty);
+
+ let impl_args = infcx.fresh_args_for_item(span, impl_);
+ let impl_ty = tcx.type_of(impl_).instantiate(tcx, impl_args);
+ let impl_ty = ocx.normalize(&ObligationCause::dummy(), param_env, impl_ty);
+
+ // Check that the self types can be related.
+ if ocx.eq(&ObligationCause::dummy(), param_env, impl_ty, self_ty).is_err() {
+ return false;
+ }
- // Check whether the impl imposes obligations we have to worry about.
- let impl_bounds = tcx.predicates_of(impl_).instantiate(tcx, impl_args);
- let impl_bounds = ocx.normalize(&cause, param_env, impl_bounds);
- let impl_obligations = traits::predicates_for_generics(
- |_, _| cause.clone(),
- param_env,
- impl_bounds,
- );
- ocx.register_obligations(impl_obligations);
+ // Check whether the impl imposes obligations we have to worry about.
+ let impl_bounds = tcx.predicates_of(impl_).instantiate(tcx, impl_args);
+ let impl_bounds =
+ ocx.normalize(&ObligationCause::dummy(), param_env, impl_bounds);
+ let impl_obligations = traits::predicates_for_generics(
+ |_, _| ObligationCause::dummy(),
+ param_env,
+ impl_bounds,
+ );
+ ocx.register_obligations(impl_obligations);
- let mut errors = ocx.select_where_possible();
- if !errors.is_empty() {
- fulfillment_errors.append(&mut errors);
- return false;
- }
+ let mut errors = ocx.select_where_possible();
+ if !errors.is_empty() {
+ fulfillment_errors.append(&mut errors);
+ return false;
+ }
- true
- })
+ true
})
- .collect()
- });
+ })
+ .collect();
- if applicable_candidates.len() > 1 {
- return Err(self.complain_about_ambiguous_inherent_assoc_type(
+ match &applicable_candidates[..] {
+ &[] => Err(self.complain_about_inherent_assoc_type_not_found(
name,
- applicable_candidates.into_iter().map(|(_, (candidate, _))| candidate).collect(),
+ self_ty,
+ candidates,
+ fulfillment_errors,
span,
- ));
- }
+ )),
- if let Some((impl_, (assoc_item, def_scope))) = applicable_candidates.pop() {
- self.check_assoc_ty(assoc_item, name, def_scope, block, span);
-
- // FIXME(fmease): Currently creating throwaway `parent_args` to please
- // `create_args_for_associated_item`. Modify the latter instead (or sth. similar) to
- // not require the parent args logic.
- let parent_args = ty::GenericArgs::identity_for_item(tcx, impl_);
- let args = self.create_args_for_associated_item(span, assoc_item, segment, parent_args);
- let args = tcx.mk_args_from_iter(
- std::iter::once(ty::GenericArg::from(self_ty))
- .chain(args.into_iter().skip(parent_args.len())),
- );
+ &[applicable_candidate] => Ok(applicable_candidate),
- let ty = Ty::new_alias(tcx, ty::Inherent, ty::AliasTy::new(tcx, assoc_item, args));
-
- return Ok(Some((ty, assoc_item)));
+ &[_, ..] => Err(self.complain_about_ambiguous_inherent_assoc_type(
+ name,
+ applicable_candidates.into_iter().map(|(_, (candidate, _))| candidate).collect(),
+ span,
+ )),
}
-
- Err(self.complain_about_inherent_assoc_type_not_found(
- name,
- self_ty,
- candidates,
- fulfillment_errors,
- span,
- ))
}
fn lookup_assoc_ty(
@@ -1753,8 +1616,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
let tcx = self.tcx();
let (ident, def_scope) = tcx.adjust_ident_and_get_scope(name, scope, block);
- // We have already adjusted the item name above, so compare with `ident.normalize_to_macros_2_0()` instead
- // of calling `find_by_name_and_kind`.
+ // We have already adjusted the item name above, so compare with `.normalize_to_macros_2_0()`
+ // instead of calling `filter_by_name_and_kind` which would needlessly normalize the
+ // `ident` again and again.
let item = tcx.associated_items(scope).in_definition_order().find(|i| {
i.kind.namespace() == Namespace::TypeNS
&& i.ident(tcx).normalize_to_macros_2_0() == ident
@@ -1869,7 +1733,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
let parent_def_id = def_id
.as_local()
- .map(|def_id| tcx.hir().local_def_id_to_hir_id(def_id))
+ .map(|def_id| tcx.local_def_id_to_hir_id(def_id))
.map(|hir_id| tcx.hir().get_parent_item(hir_id).to_def_id());
debug!("qpath_to_ty: parent_def_id={:?}", parent_def_id);
@@ -1973,7 +1837,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
types_and_spans[..types_and_spans.len() - 1]
.iter()
.map(|(x, _)| x.as_str())
- .intersperse(&", ")
+ .intersperse(", ")
.collect::<String>()
),
[(only, _)] => only.to_string(),
@@ -2008,7 +1872,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
"s",
),
[only] => (only.to_string(), ""),
- [] => unreachable!(),
+ [] => unreachable!("expected at least one generic to prohibit"),
};
let last_span = *arg_spans.last().unwrap();
let span: MultiSpan = arg_spans.into();
@@ -2396,7 +2260,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
let e = self
.tcx()
.sess
- .delay_span_bug(path.span, "path with `Res::Err` but no error emitted");
+ .span_delayed_bug(path.span, "path with `Res::Err` but no error emitted");
self.set_tainted_by_errors(e);
Ty::new_error(self.tcx(), e)
}
@@ -2543,7 +2407,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
.map(|(ty, _, _)| ty)
.unwrap_or_else(|guar| Ty::new_error(tcx, guar))
}
- &hir::TyKind::Path(hir::QPath::LangItem(lang_item, span, _)) => {
+ &hir::TyKind::Path(hir::QPath::LangItem(lang_item, span)) => {
let def_id = tcx.require_lang_item(lang_item, Some(span));
let (args, _) = self.create_args_for_ast_path(
span,
@@ -2617,8 +2481,19 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
if let Some(i) = (param.index as usize).checked_sub(generics.count() - lifetimes.len())
{
// Resolve our own lifetime parameters.
- let GenericParamDefKind::Lifetime { .. } = param.kind else { bug!() };
- let hir::GenericArg::Lifetime(lifetime) = &lifetimes[i] else { bug!() };
+ let GenericParamDefKind::Lifetime { .. } = param.kind else {
+ span_bug!(
+ tcx.def_span(param.def_id),
+ "only expected lifetime for opaque's own generics, got {:?}",
+ param.kind
+ );
+ };
+ let hir::GenericArg::Lifetime(lifetime) = &lifetimes[i] else {
+ bug!(
+ "expected lifetime argument for param {param:?}, found {:?}",
+ &lifetimes[i]
+ )
+ };
self.ast_region_to_region(lifetime, None).into()
} else {
tcx.mk_param_from_def(param)
@@ -2777,7 +2652,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
let hir = tcx.hir();
let hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Fn(..), ident, .. }) =
- hir.get(fn_hir_id)
+ tcx.hir_node(fn_hir_id)
else {
return None;
};
@@ -2845,6 +2720,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
/// provided, if they provided one, and otherwise search the supertypes of trait bounds
/// for region bounds. It may be that we can derive no bound at all, in which case
/// we return `None`.
+ #[instrument(level = "debug", skip(self, span), ret)]
fn compute_object_lifetime_bound(
&self,
span: Span,
@@ -2853,8 +2729,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
{
let tcx = self.tcx();
- debug!("compute_opt_region_bound(existential_predicates={:?})", existential_predicates);
-
// No explicit region bound specified. Therefore, examine trait
// bounds and see if we can derive region bounds from those.
let derived_region_bounds = object_region_bounds(tcx, existential_predicates);
@@ -2881,3 +2755,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
Some(r)
}
}
+
+fn assoc_kind_str(kind: ty::AssocKind) -> &'static str {
+ match kind {
+ ty::AssocKind::Fn => "function",
+ ty::AssocKind::Const => "constant",
+ ty::AssocKind::Type => "type",
+ }
+}
diff --git a/compiler/rustc_hir_analysis/src/astconv/object_safety.rs b/compiler/rustc_hir_analysis/src/astconv/object_safety.rs
index 00ff3f836..dd5deb6f2 100644
--- a/compiler/rustc_hir_analysis/src/astconv/object_safety.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/object_safety.rs
@@ -1,7 +1,7 @@
use crate::astconv::{GenericArgCountMismatch, GenericArgCountResult, OnlySelfBounds};
use crate::bounds::Bounds;
use crate::errors::TraitObjectDeclaredWithNoTraits;
-use rustc_data_structures::fx::{FxHashMap, FxHashSet};
+use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
use rustc_errors::struct_span_err;
use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res};
@@ -14,7 +14,6 @@ use rustc_trait_selection::traits::error_reporting::report_object_safety_error;
use rustc_trait_selection::traits::{self, astconv_object_safety_violations};
use smallvec::{smallvec, SmallVec};
-use std::collections::BTreeSet;
use super::AstConv;
@@ -74,7 +73,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
| ty::ClauseKind::ConstArgHasType(..)
| ty::ClauseKind::WellFormed(_)
| ty::ClauseKind::ConstEvaluatable(_) => {
- bug!()
+ span_bug!(span, "did not expect {pred} clause in object bounds");
}
}
}
@@ -107,6 +106,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
trait here instead: `trait NewTrait: {} {{}}`",
regular_traits
.iter()
+ // FIXME: This should `print_sugared`, but also needs to integrate projection bounds...
.map(|t| t.trait_ref().print_only_trait_path().to_string())
.collect::<Vec<_>>()
.join(" + "),
@@ -148,8 +148,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
}
}
- // Use a `BTreeSet` to keep output in a more consistent order.
- let mut associated_types: FxHashMap<Span, BTreeSet<DefId>> = FxHashMap::default();
+ let mut associated_types: FxIndexMap<Span, FxIndexSet<DefId>> = FxIndexMap::default();
let regular_traits_refs_spans = trait_bounds
.into_iter()
@@ -327,7 +326,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
false
});
if references_self {
- let guar = tcx.sess.delay_span_bug(
+ let guar = tcx.sess.span_delayed_bug(
span,
"trait object projection bounds reference `Self`",
);
diff --git a/compiler/rustc_hir_analysis/src/autoderef.rs b/compiler/rustc_hir_analysis/src/autoderef.rs
index 39db29504..5fc500f48 100644
--- a/compiler/rustc_hir_analysis/src/autoderef.rs
+++ b/compiler/rustc_hir_analysis/src/autoderef.rs
@@ -182,7 +182,7 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> {
}
};
- let errors = fulfill_cx.select_where_possible(&self.infcx);
+ let errors = fulfill_cx.select_where_possible(self.infcx);
if !errors.is_empty() {
// This shouldn't happen, except for evaluate/fulfill mismatches,
// but that's not a reason for an ICE (`predicate_may_hold` is conservative
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)
diff --git a/compiler/rustc_hir_analysis/src/check_unused.rs b/compiler/rustc_hir_analysis/src/check_unused.rs
index 9ad73eeff..36cb8f7a2 100644
--- a/compiler/rustc_hir_analysis/src/check_unused.rs
+++ b/compiler/rustc_hir_analysis/src/check_unused.rs
@@ -45,7 +45,7 @@ fn check_unused_traits(tcx: TyCtxt<'_>, (): ()) {
item.hir_id(),
path.span,
msg,
- |lint| lint,
+ |_| {},
);
}
}
diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs
index e5e192e00..f277badf2 100644
--- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs
@@ -550,7 +550,7 @@ fn infringing_fields_error(
.entry((ty.clone(), predicate.clone()))
.or_default()
.push(origin.span());
- if let ty::RegionKind::ReEarlyBound(ebr) = *b
+ if let ty::RegionKind::ReEarlyParam(ebr) = *b
&& ebr.has_name()
{
bounds.push((b.to_string(), a.to_string(), None));
diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs
index 7205b7a21..3f8c0db87 100644
--- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs
@@ -198,7 +198,7 @@ impl<'tcx> InherentOverlapChecker<'tcx> {
// entire graph when there are many connected regions.
rustc_index::newtype_index! {
- #[custom_encodable]
+ #[orderable]
pub struct RegionId {}
}
diff --git a/compiler/rustc_hir_analysis/src/coherence/orphan.rs b/compiler/rustc_hir_analysis/src/coherence/orphan.rs
index 7eeb78374..d33cfe4ad 100644
--- a/compiler/rustc_hir_analysis/src/coherence/orphan.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/orphan.rs
@@ -58,7 +58,7 @@ fn do_orphan_check_impl<'tcx>(
tr.path.span,
trait_ref,
impl_.self_ty.span,
- &impl_.generics,
+ impl_.generics,
err,
)?
}
@@ -452,7 +452,13 @@ fn lint_auto_trait_impl<'tcx>(
trait_ref: ty::TraitRef<'tcx>,
impl_def_id: LocalDefId,
) {
- assert_eq!(trait_ref.args.len(), 1);
+ if trait_ref.args.len() != 1 {
+ tcx.sess.dcx().span_delayed_bug(
+ tcx.def_span(impl_def_id),
+ "auto traits cannot have generic parameters",
+ );
+ return;
+ }
let self_ty = trait_ref.self_ty();
let (self_type_did, args) = match self_ty.kind() {
ty::Adt(def, args) => (def.did(), args),
@@ -491,7 +497,7 @@ fn lint_auto_trait_impl<'tcx>(
tcx.struct_span_lint_hir(
lint::builtin::SUSPICIOUS_AUTO_TRAIT_IMPLS,
- tcx.hir().local_def_id_to_hir_id(impl_def_id),
+ tcx.local_def_id_to_hir_id(impl_def_id),
tcx.def_span(impl_def_id),
DelayDm(|| {
format!(
@@ -516,7 +522,7 @@ fn lint_auto_trait_impl<'tcx>(
format!(
"try using the same sequence of generic parameters as the {self_descr} definition",
),
- )
+ );
},
);
}
diff --git a/compiler/rustc_hir_analysis/src/coherence/unsafety.rs b/compiler/rustc_hir_analysis/src/coherence/unsafety.rs
index 6b18b0ebe..8a02bab92 100644
--- a/compiler/rustc_hir_analysis/src/coherence/unsafety.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/unsafety.rs
@@ -23,7 +23,7 @@ pub(super) fn check_item(tcx: TyCtxt<'_>, def_id: LocalDefId) {
tcx.def_span(def_id),
E0199,
"implementing the trait `{}` is not unsafe",
- trait_ref.print_only_trait_path()
+ trait_ref.print_trait_sugared()
)
.span_suggestion_verbose(
item.span.with_hi(item.span.lo() + rustc_span::BytePos(7)),
@@ -40,13 +40,13 @@ pub(super) fn check_item(tcx: TyCtxt<'_>, def_id: LocalDefId) {
tcx.def_span(def_id),
E0200,
"the trait `{}` requires an `unsafe impl` declaration",
- trait_ref.print_only_trait_path()
+ trait_ref.print_trait_sugared()
)
.note(format!(
"the trait `{}` enforces invariants that the compiler can't check. \
Review the trait documentation and make sure this implementation \
upholds those invariants before adding the `unsafe` keyword",
- trait_ref.print_only_trait_path()
+ trait_ref.print_trait_sugared()
))
.span_suggestion_verbose(
item.span.shrink_to_lo(),
@@ -69,7 +69,7 @@ pub(super) fn check_item(tcx: TyCtxt<'_>, def_id: LocalDefId) {
"the trait `{}` enforces invariants that the compiler can't check. \
Review the trait documentation and make sure this implementation \
upholds those invariants before adding the `unsafe` keyword",
- trait_ref.print_only_trait_path()
+ trait_ref.print_trait_sugared()
))
.span_suggestion_verbose(
item.span.shrink_to_lo(),
@@ -82,7 +82,7 @@ pub(super) fn check_item(tcx: TyCtxt<'_>, def_id: LocalDefId) {
(_, _, Unsafety::Unsafe, hir::ImplPolarity::Negative(_)) => {
// Reported in AST validation
- tcx.sess.delay_span_bug(item.span, "unsafe negative impl");
+ tcx.sess.span_delayed_bug(item.span, "unsafe negative impl");
}
(_, _, Unsafety::Normal, hir::ImplPolarity::Negative(_))
| (Unsafety::Unsafe, _, Unsafety::Unsafe, hir::ImplPolarity::Positive)
diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs
index 9636c6144..d48535c82 100644
--- a/compiler/rustc_hir_analysis/src/collect.rs
+++ b/compiler/rustc_hir_analysis/src/collect.rs
@@ -221,7 +221,7 @@ pub(crate) fn placeholder_type_error_diag<'tcx>(
// Check if parent is const or static
let parent_id = tcx.hir().parent_id(hir_ty.hir_id);
- let parent_node = tcx.hir().get(parent_id);
+ let parent_node = tcx.hir_node(parent_id);
is_const_or_static = matches!(
parent_node,
@@ -350,11 +350,11 @@ impl<'tcx> ItemCtxt<'tcx> {
}
pub fn hir_id(&self) -> hir::HirId {
- self.tcx.hir().local_def_id_to_hir_id(self.item_def_id)
+ self.tcx.local_def_id_to_hir_id(self.item_def_id)
}
pub fn node(&self) -> hir::Node<'tcx> {
- self.tcx.hir().get(self.hir_id())
+ self.tcx.hir_node(self.hir_id())
}
}
@@ -440,10 +440,10 @@ impl<'tcx> AstConv<'tcx> for ItemCtxt<'tcx> {
second: format!(
"{}::",
// Replace the existing lifetimes with a new named lifetime.
- self.tcx.replace_late_bound_regions_uncached(
+ self.tcx.instantiate_bound_regions_uncached(
poly_trait_ref,
|_| {
- ty::Region::new_early_bound(self.tcx, ty::EarlyBoundRegion {
+ ty::Region::new_early_param(self.tcx, ty::EarlyParamRegion {
def_id: item_def_id,
index: 0,
name: Symbol::intern(&lt_name),
@@ -672,7 +672,7 @@ fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) {
hir::TraitItemKind::Const(ty, body_id) => {
tcx.ensure().type_of(def_id);
- if !tcx.sess.diagnostic().has_stashed_diagnostic(ty.span, StashKey::ItemNoType)
+ if !tcx.sess.dcx().has_stashed_diagnostic(ty.span, StashKey::ItemNoType)
&& !(is_suggestable_infer_ty(ty) && body_id.is_some())
{
// Account for `const C: _;`.
@@ -814,7 +814,7 @@ fn convert_variant(
})
.collect();
let recovered = match def {
- hir::VariantData::Struct(_, r) => *r,
+ hir::VariantData::Struct { recovered, .. } => *recovered,
_ => false,
};
ty::VariantDef::new(
@@ -835,9 +835,8 @@ fn convert_variant(
fn adt_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::AdtDef<'_> {
use rustc_hir::*;
- let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
- let Node::Item(item) = tcx.hir().get(hir_id) else {
- bug!();
+ let Node::Item(item) = tcx.hir_node_by_def_id(def_id) else {
+ bug!("expected ADT to be an item");
};
let repr = tcx.repr_options_of_def(def_id.to_def_id());
@@ -888,7 +887,7 @@ fn adt_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::AdtDef<'_> {
(adt_kind, variants)
}
- _ => bug!(),
+ _ => bug!("{:?} is not an ADT", item.owner_id.def_id),
};
tcx.mk_adt_def(def_id.to_def_id(), kind, variants, repr)
}
@@ -1090,7 +1089,7 @@ fn is_suggestable_infer_ty(ty: &hir::Ty<'_>) -> bool {
pub fn get_infer_ret_ty<'hir>(output: &'hir hir::FnRetTy<'hir>) -> Option<&'hir hir::Ty<'hir>> {
if let hir::FnRetTy::Return(ty) = output {
if is_suggestable_infer_ty(ty) {
- return Some(&*ty);
+ return Some(*ty);
}
}
None
@@ -1101,11 +1100,11 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<ty::PolyFnSig<
use rustc_hir::Node::*;
use rustc_hir::*;
- 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 icx = ItemCtxt::new(tcx, def_id);
- let output = match tcx.hir().get(hir_id) {
+ let output = match tcx.hir_node(hir_id) {
TraitItem(hir::TraitItem {
kind: TraitItemKind::Fn(sig, TraitFn::Provided(_)),
generics,
@@ -1186,7 +1185,7 @@ fn infer_return_ty_for_fn_sig<'tcx>(
def_id: LocalDefId,
icx: &ItemCtxt<'tcx>,
) -> ty::PolyFnSig<'tcx> {
- 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);
match get_infer_ret_ty(&sig.decl.output) {
Some(ty) => {
@@ -1373,7 +1372,7 @@ fn impl_trait_ref(
if let Some(ErrorGuaranteed { .. }) = check_impl_constness(
tcx,
tcx.is_const_trait_impl_raw(def_id.to_def_id()),
- &ast_trait_ref,
+ ast_trait_ref,
) {
// we have a const impl, but for a trait without `#[const_trait]`, so
// without the host param. If we continue with the HIR trait ref, we get
@@ -1383,7 +1382,7 @@ fn impl_trait_ref(
let last_segment = path_segments.len() - 1;
let mut args = *path_segments[last_segment].args();
let last_arg = args.args.len() - 1;
- assert!(matches!(args.args[last_arg], hir::GenericArg::Const(anon_const) if tcx.has_attr(anon_const.value.def_id, sym::rustc_host)));
+ assert!(matches!(args.args[last_arg], hir::GenericArg::Const(anon_const) if anon_const.is_desugared_from_effects));
args.args = &args.args[..args.args.len() - 1];
path_segments[last_segment].args = Some(&args);
let path = hir::Path {
@@ -1394,7 +1393,7 @@ fn impl_trait_ref(
let trait_ref = hir::TraitRef { path: &path, hir_ref_id: ast_trait_ref.hir_ref_id };
icx.astconv().instantiate_mono_trait_ref(&trait_ref, selfty)
} else {
- icx.astconv().instantiate_mono_trait_ref(&ast_trait_ref, selfty)
+ icx.astconv().instantiate_mono_trait_ref(ast_trait_ref, selfty)
}
})
.map(ty::EarlyBinder::bind)
@@ -1519,7 +1518,7 @@ fn compute_sig_of_foreign_fn_decl<'tcx>(
} else {
hir::Unsafety::Unsafe
};
- 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 fty =
ItemCtxt::new(tcx, def_id).astconv().ty_of_fn(hir_id, unsafety, abi, decl, None, None);
@@ -1551,7 +1550,7 @@ fn compute_sig_of_foreign_fn_decl<'tcx>(
}
fn coroutine_kind(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<hir::CoroutineKind> {
- match tcx.hir().get_by_def_id(def_id) {
+ match tcx.hir_node_by_def_id(def_id) {
Node::Expr(&rustc_hir::Expr {
kind: rustc_hir::ExprKind::Closure(&rustc_hir::Closure { body, .. }),
..
@@ -1561,7 +1560,7 @@ fn coroutine_kind(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<hir::CoroutineK
}
fn is_type_alias_impl_trait<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> bool {
- match tcx.hir().get_by_def_id(def_id) {
+ match tcx.hir_node_by_def_id(def_id) {
Node::Item(hir::Item { kind: hir::ItemKind::OpaqueTy(opaque), .. }) => {
matches!(opaque.origin, hir::OpaqueTyOrigin::TyAlias { .. })
}
diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs
index 3d60c57b9..3ee2822ed 100644
--- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs
@@ -9,14 +9,14 @@ use rustc_hir::def_id::LocalDefId;
use rustc_middle::ty::{self, TyCtxt};
use rustc_session::lint;
use rustc_span::symbol::{kw, Symbol};
-use rustc_span::{sym, Span};
+use rustc_span::Span;
pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
use rustc_hir::*;
- 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 node = tcx.hir().get(hir_id);
+ let node = tcx.hir_node(hir_id);
let parent_def_id = match node {
Node::ImplItem(_)
| Node::TraitItem(_)
@@ -182,7 +182,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
}
let no_generics = hir::Generics::empty();
- let ast_generics = node.generics().unwrap_or(&no_generics);
+ let ast_generics = node.generics().unwrap_or(no_generics);
let (opt_self, allow_defaults) = match node {
Node::Item(item) => {
match item.kind {
@@ -279,7 +279,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
param.hir_id,
param.span,
TYPE_DEFAULT_NOT_ALLOWED,
- |lint| lint,
+ |_| {},
);
}
Defaults::Deny => {
@@ -298,13 +298,11 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
kind,
})
}
- GenericParamKind::Const { default, .. } => {
- let is_host_param = tcx.has_attr(param.def_id, sym::rustc_host);
-
+ GenericParamKind::Const { ty: _, default, is_host_effect } => {
if !matches!(allow_defaults, Defaults::Allowed)
&& default.is_some()
- // `rustc_host` effect params are allowed to have defaults.
- && !is_host_param
+ // `host` effect params are allowed to have defaults.
+ && !is_host_effect
{
tcx.sess.span_err(
param.span,
@@ -315,7 +313,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
let index = next_index();
- if is_host_param {
+ if is_host_effect {
if let Some(idx) = host_effect_index {
bug!("parent also has host effect param? index: {idx}, def: {def_id:?}");
}
@@ -330,7 +328,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
pure_wrt_drop: param.pure_wrt_drop,
kind: ty::GenericParamDefKind::Const {
has_default: default.is_some(),
- is_host_effect: is_host_param,
+ is_host_effect,
},
})
}
@@ -458,11 +456,11 @@ fn has_late_bound_regions<'tcx>(tcx: TyCtxt<'tcx>, node: Node<'tcx>) -> Option<S
match node {
Node::TraitItem(item) => match &item.kind {
- hir::TraitItemKind::Fn(sig, _) => has_late_bound_regions(tcx, &item.generics, sig.decl),
+ hir::TraitItemKind::Fn(sig, _) => has_late_bound_regions(tcx, item.generics, sig.decl),
_ => None,
},
Node::ImplItem(item) => match &item.kind {
- hir::ImplItemKind::Fn(sig, _) => has_late_bound_regions(tcx, &item.generics, sig.decl),
+ hir::ImplItemKind::Fn(sig, _) => has_late_bound_regions(tcx, item.generics, sig.decl),
_ => None,
},
Node::ForeignItem(item) => match item.kind {
@@ -489,7 +487,7 @@ struct AnonConstInParamTyDetector {
impl<'v> Visitor<'v> for AnonConstInParamTyDetector {
fn visit_generic_param(&mut self, p: &'v hir::GenericParam<'v>) {
- if let GenericParamKind::Const { ty, default: _ } = p.kind {
+ if let GenericParamKind::Const { ty, default: _, is_host_effect: _ } = p.kind {
let prev = self.in_param_ty;
self.in_param_ty = true;
self.visit_ty(ty);
diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
index d746e6dea..39ca1bba0 100644
--- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
+++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
@@ -34,17 +34,14 @@ fn associated_type_bounds<'tcx>(
let trait_def_id = tcx.local_parent(assoc_item_def_id);
let trait_predicates = tcx.trait_explicit_predicates_and_bounds(trait_def_id);
- let bounds_from_parent = trait_predicates
- .predicates
- .iter()
- .copied()
- .filter(|(pred, _)| match pred.kind().skip_binder() {
+ let bounds_from_parent = trait_predicates.predicates.iter().copied().filter(|(pred, _)| {
+ match pred.kind().skip_binder() {
ty::ClauseKind::Trait(tr) => tr.self_ty() == item_ty,
ty::ClauseKind::Projection(proj) => proj.projection_ty.self_ty() == item_ty,
ty::ClauseKind::TypeOutlives(outlives) => outlives.0 == item_ty,
_ => false,
- })
- .map(|(clause, span)| (clause, span));
+ }
+ });
let all_bounds = tcx.arena.alloc_from_iter(bounds.clauses().chain(bounds_from_parent));
debug!(
@@ -86,7 +83,7 @@ pub(super) fn explicit_item_bounds(
// RPITIT's bounds are the same as opaque type bounds, but with
// a projection self type.
Some(ty::ImplTraitInTraitData::Trait { opaque_def_id, .. }) => {
- let item = tcx.hir().get_by_def_id(opaque_def_id.expect_local()).expect_item();
+ let item = tcx.hir_node_by_def_id(opaque_def_id.expect_local()).expect_item();
let opaque_ty = item.expect_opaque_ty();
return ty::EarlyBinder::bind(opaque_type_bounds(
tcx,
@@ -100,13 +97,14 @@ pub(super) fn explicit_item_bounds(
item.span,
));
}
- // These should have been fed!
- Some(ty::ImplTraitInTraitData::Impl { .. }) => unreachable!(),
+ Some(ty::ImplTraitInTraitData::Impl { .. }) => span_bug!(
+ tcx.def_span(def_id),
+ "item bounds for RPITIT in impl to be fed on def-id creation"
+ ),
None => {}
}
- let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
- let bounds = match tcx.hir().get(hir_id) {
+ let bounds = match tcx.hir_node_by_def_id(def_id) {
hir::Node::TraitItem(hir::TraitItem {
kind: hir::TraitItemKind::Type(bounds, _),
span,
@@ -132,7 +130,7 @@ pub(super) fn explicit_item_bounds(
let (hir::OpaqueTyOrigin::FnReturn(fn_def_id)
| hir::OpaqueTyOrigin::AsyncFn(fn_def_id)) = *origin
else {
- bug!()
+ span_bug!(*span, "RPITIT cannot be a TAIT, but got origin {origin:?}");
};
let args = GenericArgs::identity_for_item(tcx, def_id);
let item_ty = Ty::new_opaque(tcx, def_id.to_def_id(), args);
diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
index 104da581e..41520718a 100644
--- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
@@ -134,8 +134,8 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
None => {}
}
- let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
- let node = tcx.hir().get(hir_id);
+ let hir_id = tcx.local_def_id_to_hir_id(def_id);
+ let node = tcx.hir_node(hir_id);
let mut is_trait = None;
let mut is_default_impl_trait = None;
@@ -290,13 +290,18 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
}
hir::WherePredicate::RegionPredicate(region_pred) => {
- let r1 = icx.astconv().ast_region_to_region(&region_pred.lifetime, None);
+ let r1 = icx.astconv().ast_region_to_region(region_pred.lifetime, None);
predicates.extend(region_pred.bounds.iter().map(|bound| {
let (r2, span) = match bound {
hir::GenericBound::Outlives(lt) => {
(icx.astconv().ast_region_to_region(lt, None), lt.ident.span)
}
- _ => bug!(),
+ bound => {
+ span_bug!(
+ bound.span(),
+ "lifetime param bounds must be outlives, but found {bound:?}"
+ )
+ }
};
let pred = ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(r1, r2))
.to_predicate(tcx);
@@ -337,7 +342,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
// and the duplicated parameter, to ensure that they do not get out of sync.
if let Node::Item(&Item { kind: ItemKind::OpaqueTy(..), .. }) = node {
let opaque_ty_id = tcx.hir().parent_id(hir_id);
- let opaque_ty_node = tcx.hir().get(opaque_ty_id);
+ let opaque_ty_node = tcx.hir_node(opaque_ty_id);
let Node::Ty(&Ty { kind: TyKind::OpaqueDef(_, lifetimes, _), .. }) = opaque_ty_node else {
bug!("unexpected {opaque_ty_node:?}")
};
@@ -362,10 +367,10 @@ fn compute_bidirectional_outlives_predicates<'tcx>(
) {
for param in opaque_own_params {
let orig_lifetime = tcx.map_rpit_lifetime_to_fn_lifetime(param.def_id.expect_local());
- if let ty::ReEarlyBound(..) = *orig_lifetime {
- let dup_lifetime = ty::Region::new_early_bound(
+ if let ty::ReEarlyParam(..) = *orig_lifetime {
+ let dup_lifetime = ty::Region::new_early_param(
tcx,
- ty::EarlyBoundRegion { def_id: param.def_id, index: param.index, name: param.name },
+ ty::EarlyParamRegion { def_id: param.def_id, index: param.index, name: param.name },
);
let span = tcx.def_span(param.def_id);
predicates.push((
@@ -412,8 +417,8 @@ fn const_evaluatable_predicates_of(
}
}
- let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
- let node = tcx.hir().get(hir_id);
+ let hir_id = tcx.local_def_id_to_hir_id(def_id);
+ let node = tcx.hir_node(hir_id);
let mut collector = ConstCollector { tcx, preds: FxIndexSet::default() };
if let hir::Node::Item(item) = node
@@ -503,7 +508,7 @@ pub(super) fn explicit_predicates_of<'tcx>(
}
} else {
if matches!(def_kind, DefKind::AnonConst) && tcx.features().generic_const_exprs {
- 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_def_id = tcx.hir().get_parent_item(hir_id);
if let Some(defaulted_param_def_id) =
@@ -571,7 +576,7 @@ pub(super) fn explicit_predicates_of<'tcx>(
// To fix this, we call `explicit_predicates_of` directly on `foo`, the parent's parent.
// In the above example this is `foo::{opaque#0}` or `impl Iterator`
- let parent_hir_id = tcx.hir().local_def_id_to_hir_id(parent_def_id.def_id);
+ let parent_hir_id = tcx.local_def_id_to_hir_id(parent_def_id.def_id);
// In the above example this is the function `foo`
let item_def_id = tcx.hir().get_parent_item(parent_hir_id);
@@ -631,9 +636,9 @@ pub(super) fn implied_predicates_with_filter(
return tcx.super_predicates_of(trait_def_id);
};
- let trait_hir_id = tcx.hir().local_def_id_to_hir_id(trait_def_id);
+ let trait_hir_id = tcx.local_def_id_to_hir_id(trait_def_id);
- let Node::Item(item) = tcx.hir().get(trait_hir_id) else {
+ let Node::Item(item) = tcx.hir_node(trait_hir_id) else {
bug!("trait_node_id {} is not an item", trait_hir_id);
};
@@ -691,7 +696,7 @@ pub(super) fn type_param_predicates(
// written inline like `<T: Foo>` or in a where-clause like
// `where T: Foo`.
- let param_id = tcx.hir().local_def_id_to_hir_id(def_id);
+ let param_id = tcx.local_def_id_to_hir_id(def_id);
let param_owner = tcx.hir().ty_param_owner(def_id);
let generics = tcx.generics_of(param_owner);
let index = generics.param_def_id_to_index[&def_id.to_def_id()];
@@ -712,11 +717,11 @@ pub(super) fn type_param_predicates(
.unwrap_or_default();
let mut extend = None;
- let item_hir_id = tcx.hir().local_def_id_to_hir_id(item_def_id);
- let ast_generics = match tcx.hir().get(item_hir_id) {
- Node::TraitItem(item) => &item.generics,
+ let item_hir_id = tcx.local_def_id_to_hir_id(item_def_id);
+ let ast_generics = match tcx.hir_node(item_hir_id) {
+ Node::TraitItem(item) => item.generics,
- Node::ImplItem(item) => &item.generics,
+ Node::ImplItem(item) => item.generics,
Node::Item(item) => {
match item.kind {
diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
index 6424d1c79..9f0742dad 100644
--- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
+++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
@@ -295,7 +295,7 @@ fn late_arg_as_bound_arg<'tcx>(
) -> ty::BoundVariableKind {
match arg {
ResolvedArg::LateBound(_, _, def_id) => {
- let name = tcx.hir().name(tcx.hir().local_def_id_to_hir_id(def_id.expect_local()));
+ let name = tcx.hir().name(tcx.local_def_id_to_hir_id(def_id.expect_local()));
match param.kind {
GenericParamKind::Lifetime { .. } => {
ty::BoundVariableKind::Region(ty::BrNamed(*def_id, name))
@@ -335,7 +335,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
// though this may happen when we call `poly_trait_ref_binder_info` with
// an (erroneous, #113423) associated return type bound in an impl header.
if !supertrait_bound_vars.is_empty() {
- self.tcx.sess.delay_span_bug(
+ self.tcx.sess.span_delayed_bug(
DUMMY_SP,
format!(
"found supertrait lifetimes without a binder to append \
@@ -350,7 +350,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
// Nested poly trait refs have the binders concatenated
let mut full_binders =
self.map.late_bound_vars.entry(*hir_id).or_default().clone();
- full_binders.extend(supertrait_bound_vars.into_iter());
+ full_binders.extend(supertrait_bound_vars);
break (full_binders, BinderScopeType::Concatenating);
}
}
@@ -565,7 +565,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
let mut bound_vars = FxIndexMap::default();
debug!(?generics.params);
for param in generics.params {
- let (def_id, reg) = ResolvedArg::early(&param);
+ let (def_id, reg) = ResolvedArg::early(param);
bound_vars.insert(def_id, reg);
}
@@ -684,7 +684,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
lifetime: self.map.defs.get(&lifetime_ref.hir_id).cloned(),
s: self.scope,
};
- self.with(scope, |this| this.visit_ty(&mt.ty));
+ self.with(scope, |this| this.visit_ty(mt.ty));
}
hir::TyKind::OpaqueDef(item_id, lifetimes, _in_trait) => {
// Resolve the lifetimes in the bounds to the lifetime defs in the generics.
@@ -733,7 +733,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
let def = self.map.defs.get(&lifetime.hir_id).cloned();
let Some(ResolvedArg::LateBound(_, _, def_id)) = def else { continue };
let Some(def_id) = def_id.as_local() else { continue };
- let hir_id = self.tcx.hir().local_def_id_to_hir_id(def_id);
+ let hir_id = self.tcx.local_def_id_to_hir_id(def_id);
// Ensure that the parent of the def is an item, not HRTB
let parent_id = self.tcx.hir().parent_id(hir_id);
if !parent_id.is_owner() {
@@ -748,7 +748,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
}
if let hir::Node::Item(hir::Item {
kind: hir::ItemKind::OpaqueTy { .. }, ..
- }) = self.tcx.hir().get(parent_id)
+ }) = self.tcx.hir_node(parent_id)
{
let mut err = self.tcx.sess.struct_span_err(
lifetime.ident.span,
@@ -775,7 +775,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
}
Type(bounds, ty) => {
self.visit_early(trait_item.hir_id(), trait_item.generics, |this| {
- this.visit_generics(&trait_item.generics);
+ this.visit_generics(trait_item.generics);
for bound in bounds {
this.visit_param_bound(bound);
}
@@ -847,7 +847,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
hir::FnRetTy::DefaultReturn(_) => None,
hir::FnRetTy::Return(ty) => Some(ty),
};
- self.visit_fn_like_elision(&fd.inputs, output, matches!(fk, intravisit::FnKind::Closure));
+ self.visit_fn_like_elision(fd.inputs, output, matches!(fk, intravisit::FnKind::Closure));
intravisit::walk_fn_kind(self, fk);
self.visit_nested_body(body_id)
}
@@ -894,7 +894,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
};
self.with(scope, |this| {
walk_list!(this, visit_generic_param, bound_generic_params);
- this.visit_ty(&bounded_ty);
+ this.visit_ty(bounded_ty);
walk_list!(this, visit_param_bound, bounds);
})
}
@@ -925,7 +925,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
"you can use the `'static` lifetime directly, in place of `{}`",
lifetime.ident,
);
- lint.help(help)
+ lint.help(help);
},
);
}
@@ -938,32 +938,6 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
}
}
- fn visit_param_bound(&mut self, bound: &'tcx hir::GenericBound<'tcx>) {
- match bound {
- hir::GenericBound::LangItemTrait(_, _, hir_id, _) => {
- // FIXME(jackh726): This is pretty weird. `LangItemTrait` doesn't go
- // through the regular poly trait ref code, so we don't get another
- // chance to introduce a binder. For now, I'm keeping the existing logic
- // of "if there isn't a Binder scope above us, add one", but I
- // imagine there's a better way to go about this.
- let (binders, scope_type) = self.poly_trait_ref_binder_info();
-
- self.record_late_bound_vars(*hir_id, binders);
- let scope = Scope::Binder {
- hir_id: *hir_id,
- bound_vars: FxIndexMap::default(),
- s: self.scope,
- scope_type,
- where_bound_origin: None,
- };
- self.with(scope, |this| {
- intravisit::walk_param_bound(this, bound);
- });
- }
- _ => intravisit::walk_param_bound(self, bound),
- }
- }
-
fn visit_poly_trait_ref(&mut self, trait_ref: &'tcx hir::PolyTraitRef<'tcx>) {
self.visit_poly_trait_ref_inner(trait_ref, NonLifetimeBinderAllowed::Allow);
}
@@ -992,7 +966,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
self.visit_ty(ty);
}
}
- GenericParamKind::Const { ty, default } => {
+ GenericParamKind::Const { ty, default, is_host_effect: _ } => {
self.visit_ty(ty);
if let Some(default) = default {
self.visit_body(self.tcx.hir().body(default.body));
@@ -1004,7 +978,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
fn object_lifetime_default(tcx: TyCtxt<'_>, param_def_id: LocalDefId) -> ObjectLifetimeDefault {
debug_assert_eq!(tcx.def_kind(param_def_id), DefKind::TyParam);
- let hir::Node::GenericParam(param) = tcx.hir().get_by_def_id(param_def_id) else {
+ let hir::Node::GenericParam(param) = tcx.hir_node_by_def_id(param_def_id) else {
bug!("expected GenericParam for object_lifetime_default");
};
match param.source {
@@ -1061,7 +1035,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
{
let BoundVarContext { tcx, map, .. } = self;
let mut this = BoundVarContext { tcx: *tcx, map, scope: &wrap_scope };
- let span = debug_span!("scope", scope = ?TruncatedScopeDebug(&this.scope));
+ let span = debug_span!("scope", scope = ?TruncatedScopeDebug(this.scope));
{
let _enter = span.enter();
f(&mut this);
@@ -1300,12 +1274,16 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
what,
})
}
- _ => unreachable!(),
+ kind => span_bug!(
+ use_span,
+ "did not expect to resolve lifetime to {}",
+ kind.descr(param_def_id)
+ ),
};
def = ResolvedArg::Error(guar);
} else if let Some(body_id) = outermost_body {
let fn_id = self.tcx.hir().body_owner(body_id);
- match self.tcx.hir().get(fn_id) {
+ match self.tcx.hir_node(fn_id) {
Node::Item(hir::Item { owner_id, kind: hir::ItemKind::Fn(..), .. })
| Node::TraitItem(hir::TraitItem {
owner_id,
@@ -1363,7 +1341,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
}
}
- self.tcx.sess.delay_span_bug(
+ self.tcx.sess.span_delayed_bug(
lifetime_ref.ident.span,
format!("Could not resolve {:?} in scope {:#?}", lifetime_ref, self.scope,),
);
@@ -1441,7 +1419,11 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
what,
})
}
- _ => unreachable!(),
+ kind => span_bug!(
+ use_span,
+ "did not expect to resolve non-lifetime param to {}",
+ kind.descr(param_def_id.to_def_id())
+ ),
};
self.map.defs.insert(hir_id, ResolvedArg::Error(guar));
} else {
@@ -1493,7 +1475,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
}
}
- self.tcx.sess.delay_span_bug(
+ self.tcx.sess.span_delayed_bug(
self.tcx.hir().span(hir_id),
format!("could not resolve {param_def_id:?}"),
);
@@ -1724,7 +1706,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
} else {
self.tcx
.sess
- .delay_span_bug(binding.ident.span, "bad return type notation here");
+ .span_delayed_bug(binding.ident.span, "bad return type notation here");
vec![]
};
self.with(scope, |this| {
@@ -1848,8 +1830,8 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
}
}
+ #[instrument(level = "debug", skip(self))]
fn resolve_object_lifetime_default(&mut self, lifetime_ref: &'tcx hir::Lifetime) {
- debug!("resolve_object_lifetime_default(lifetime_ref={:?})", lifetime_ref);
let mut late_depth = 0;
let mut scope = self.scope;
let lifetime = loop {
@@ -2012,7 +1994,7 @@ fn is_late_bound_map(
fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<!> {
debug!("r={:?}", r.kind());
- if let ty::RegionKind::ReEarlyBound(region) = r.kind() {
+ if let ty::RegionKind::ReEarlyParam(region) = r.kind() {
self.arg_is_constrained[region.index as usize] = true;
}
@@ -2057,7 +2039,7 @@ fn is_late_bound_map(
Some(true) => Some(arg),
Some(false) => None,
None => {
- tcx.sess.delay_span_bug(
+ tcx.sess.span_delayed_bug(
*span,
format!(
"Incorrect generic arg count for alias {alias_def:?}"
@@ -2122,8 +2104,8 @@ pub fn deny_non_region_late_bound(
let mut first = true;
for (var, arg) in bound_vars {
- let Node::GenericParam(param) = tcx.hir().get_by_def_id(*var) else {
- bug!();
+ let Node::GenericParam(param) = tcx.hir_node_by_def_id(*var) else {
+ span_bug!(tcx.def_span(*var), "expected bound-var def-id to resolve to param");
};
let what = match param.kind {
diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs
index d7bd2a7b1..19e7fe388 100644
--- a/compiler/rustc_hir_analysis/src/collect/type_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs
@@ -18,12 +18,18 @@ mod opaque;
fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
use hir::*;
use rustc_middle::ty::Ty;
- 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 Node::AnonConst(_) = tcx.hir().get(hir_id) else { panic!() };
+ let node = tcx.hir_node(hir_id);
+ let Node::AnonConst(_) = node else {
+ span_bug!(
+ tcx.def_span(def_id),
+ "expected anon const in `anon_const_type_of`, got {node:?}"
+ );
+ };
let parent_node_id = tcx.hir().parent_id(hir_id);
- let parent_node = tcx.hir().get(parent_node_id);
+ let parent_node = tcx.hir_node(parent_node_id);
let (generics, arg_idx) = match parent_node {
// Easy case: arrays repeat expressions.
@@ -61,7 +67,7 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
}
Node::TypeBinding(binding @ &TypeBinding { hir_id: binding_id, .. })
- if let Node::TraitRef(trait_ref) = tcx.hir().get(tcx.hir().parent_id(binding_id)) =>
+ if let Node::TraitRef(trait_ref) = tcx.hir_node(tcx.hir().parent_id(binding_id)) =>
{
let Some(trait_def_id) = trait_ref.trait_def_id() else {
return Ty::new_error_with_message(
@@ -350,11 +356,11 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
}
}
- 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 icx = ItemCtxt::new(tcx, def_id);
- let output = match tcx.hir().get(hir_id) {
+ let output = match tcx.hir_node(hir_id) {
Node::TraitItem(item) => match item.kind {
TraitItemKind::Fn(..) => {
let args = ty::GenericArgs::identity_for_item(tcx, def_id);
@@ -475,7 +481,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
},
Node::Ctor(def) | Node::Variant(Variant { data: def, .. }) => match def {
- VariantData::Unit(..) | VariantData::Struct(..) => {
+ VariantData::Unit(..) | VariantData::Struct { .. } => {
tcx.type_of(tcx.hir().get_parent_item(hir_id)).instantiate_identity()
}
VariantData::Tuple(..) => {
@@ -517,8 +523,7 @@ pub(super) fn type_of_opaque(
if let Some(def_id) = def_id.as_local() {
use rustc_hir::*;
- let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
- Ok(ty::EarlyBinder::bind(match tcx.hir().get(hir_id) {
+ Ok(ty::EarlyBinder::bind(match tcx.hir_node_by_def_id(def_id) {
Node::Item(item) => match item.kind {
ItemKind::OpaqueTy(OpaqueTy {
origin: hir::OpaqueTyOrigin::TyAlias { .. },
@@ -569,7 +574,7 @@ fn infer_placeholder_type<'a>(
// then the user may have written e.g. `const A = 42;`.
// In this case, the parser has stashed a diagnostic for
// us to improve in typeck so we do that now.
- match tcx.sess.diagnostic().steal_diagnostic(span, StashKey::ItemNoType) {
+ match tcx.sess.dcx().steal_diagnostic(span, StashKey::ItemNoType) {
Some(mut err) => {
if !ty.references_error() {
// Only suggest adding `:` if it was missing (and suggested by parsing diagnostic)
diff --git a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs
index e8ab2651d..3785b61f2 100644
--- a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs
+++ b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs
@@ -41,7 +41,7 @@ pub fn test_opaque_hidden_types(tcx: TyCtxt<'_>) {
/// ```
#[instrument(skip(tcx), level = "debug")]
pub(super) fn find_opaque_ty_constraints_for_tait(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Ty<'_> {
- 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 scope = tcx.hir().get_defining_scope(hir_id);
let mut locator = TaitConstraintLocator { def_id, tcx, found: None, typeck_types: vec![] };
@@ -50,8 +50,8 @@ pub(super) fn find_opaque_ty_constraints_for_tait(tcx: TyCtxt<'_>, def_id: Local
if scope == hir::CRATE_HIR_ID {
tcx.hir().walk_toplevel_module(&mut locator);
} else {
- trace!("scope={:#?}", tcx.hir().get(scope));
- match tcx.hir().get(scope) {
+ trace!("scope={:#?}", tcx.hir_node(scope));
+ match tcx.hir_node(scope) {
// We explicitly call `visit_*` methods, instead of using `intravisit::walk_*` methods
// This allows our visitor to process the defining item itself, causing
// it to pick up any 'sibling' defining uses.
@@ -95,7 +95,7 @@ pub(super) fn find_opaque_ty_constraints_for_tait(tcx: TyCtxt<'_>, def_id: Local
let reported = tcx.sess.emit_err(UnconstrainedOpaqueType {
span: tcx.def_span(def_id),
name: tcx.item_name(parent_def_id.to_def_id()),
- what: match tcx.hir().get(scope) {
+ what: match tcx.hir_node(scope) {
_ if scope == hir::CRATE_HIR_ID => "module",
Node::Item(hir::Item { kind: hir::ItemKind::Mod(_), .. }) => "module",
Node::Item(hir::Item { kind: hir::ItemKind::Impl(_), .. }) => "impl",
@@ -278,11 +278,15 @@ pub(super) fn find_opaque_ty_constraints_for_rpit<'tcx>(
let mir_opaque_ty = tcx.mir_borrowck(owner_def_id).concrete_opaque_types.get(&def_id).copied();
if let Some(mir_opaque_ty) = mir_opaque_ty {
- let scope = tcx.hir().local_def_id_to_hir_id(owner_def_id);
+ if mir_opaque_ty.references_error() {
+ return mir_opaque_ty.ty;
+ }
+
+ let scope = tcx.local_def_id_to_hir_id(owner_def_id);
debug!(?scope);
let mut locator = RpitConstraintChecker { def_id, tcx, found: mir_opaque_ty };
- match tcx.hir().get(scope) {
+ match tcx.hir_node(scope) {
Node::Item(it) => intravisit::walk_item(&mut locator, it),
Node::ImplItem(it) => intravisit::walk_impl_item(&mut locator, it),
Node::TraitItem(it) => intravisit::walk_trait_item(&mut locator, it),
diff --git a/compiler/rustc_hir_analysis/src/constrained_generic_params.rs b/compiler/rustc_hir_analysis/src/constrained_generic_params.rs
index ed5e9dd2b..65d1ffa40 100644
--- a/compiler/rustc_hir_analysis/src/constrained_generic_params.rs
+++ b/compiler/rustc_hir_analysis/src/constrained_generic_params.rs
@@ -13,8 +13,8 @@ impl From<ty::ParamTy> for Parameter {
}
}
-impl From<ty::EarlyBoundRegion> for Parameter {
- fn from(param: ty::EarlyBoundRegion) -> Self {
+impl From<ty::EarlyParamRegion> for Parameter {
+ fn from(param: ty::EarlyParamRegion) -> Self {
Parameter(param.index)
}
}
@@ -73,7 +73,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ParameterCollector {
}
fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> {
- if let ty::ReEarlyBound(data) = *r {
+ if let ty::ReEarlyParam(data) = *r {
self.parameters.push(Parameter::from(data));
}
ControlFlow::Continue(())
diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs
index dd83b5b6f..f461b6a94 100644
--- a/compiler/rustc_hir_analysis/src/errors.rs
+++ b/compiler/rustc_hir_analysis/src/errors.rs
@@ -2,14 +2,126 @@
use crate::fluent_generated as fluent;
use rustc_errors::{
- error_code, Applicability, DiagnosticBuilder, ErrorGuaranteed, Handler, IntoDiagnostic,
+ error_code, Applicability, DiagCtxt, DiagnosticBuilder, ErrorGuaranteed, IntoDiagnostic,
MultiSpan,
};
use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
-use rustc_middle::ty::{self, print::TraitRefPrintOnlyTraitPath, Ty};
+use rustc_middle::ty::Ty;
use rustc_span::{symbol::Ident, Span, Symbol};
#[derive(Diagnostic)]
+#[diag(hir_analysis_ambiguous_assoc_item)]
+pub struct AmbiguousAssocItem<'a> {
+ #[primary_span]
+ #[label]
+ pub span: Span,
+ pub assoc_kind: &'static str,
+ pub assoc_name: Ident,
+ pub ty_param_name: &'a str,
+}
+
+#[derive(Diagnostic)]
+#[diag(hir_analysis_assoc_kind_mismatch)]
+pub struct AssocKindMismatch {
+ #[primary_span]
+ #[label]
+ pub span: Span,
+ pub expected: &'static str,
+ pub got: &'static str,
+ #[label(hir_analysis_expected_because_label)]
+ pub expected_because_label: Option<Span>,
+ pub assoc_kind: &'static str,
+ #[note]
+ pub def_span: Span,
+ #[label(hir_analysis_bound_on_assoc_const_label)]
+ pub bound_on_assoc_const_label: Option<Span>,
+ #[subdiagnostic]
+ pub wrap_in_braces_sugg: Option<AssocKindMismatchWrapInBracesSugg>,
+}
+
+#[derive(Subdiagnostic)]
+#[multipart_suggestion(
+ hir_analysis_assoc_kind_mismatch_wrap_in_braces_sugg,
+ applicability = "maybe-incorrect"
+)]
+pub struct AssocKindMismatchWrapInBracesSugg {
+ #[suggestion_part(code = "{{ ")]
+ pub lo: Span,
+ #[suggestion_part(code = " }}")]
+ pub hi: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(hir_analysis_assoc_item_not_found, code = "E0220")]
+pub struct AssocItemNotFound<'a> {
+ #[primary_span]
+ pub span: Span,
+ pub assoc_name: Ident,
+ pub assoc_kind: &'static str,
+ pub ty_param_name: &'a str,
+ #[subdiagnostic]
+ pub label: Option<AssocItemNotFoundLabel<'a>>,
+ #[subdiagnostic]
+ pub sugg: Option<AssocItemNotFoundSugg<'a>>,
+}
+
+#[derive(Subdiagnostic)]
+pub enum AssocItemNotFoundLabel<'a> {
+ #[label(hir_analysis_assoc_item_not_found_label)]
+ NotFound {
+ #[primary_span]
+ span: Span,
+ },
+ #[label(hir_analysis_assoc_item_not_found_found_in_other_trait_label)]
+ FoundInOtherTrait {
+ #[primary_span]
+ span: Span,
+ assoc_kind: &'static str,
+ trait_name: &'a str,
+ suggested_name: Symbol,
+ identically_named: bool,
+ },
+}
+
+#[derive(Subdiagnostic)]
+
+pub enum AssocItemNotFoundSugg<'a> {
+ #[suggestion(
+ hir_analysis_assoc_item_not_found_similar_sugg,
+ code = "{suggested_name}",
+ applicability = "maybe-incorrect"
+ )]
+ Similar {
+ #[primary_span]
+ span: Span,
+ assoc_kind: &'static str,
+ suggested_name: Symbol,
+ },
+ #[suggestion(
+ hir_analysis_assoc_item_not_found_similar_in_other_trait_sugg,
+ code = "{suggested_name}",
+ style = "verbose",
+ applicability = "maybe-incorrect"
+ )]
+ SimilarInOtherTrait {
+ #[primary_span]
+ span: Span,
+ assoc_kind: &'static str,
+ suggested_name: Symbol,
+ },
+ #[suggestion(hir_analysis_assoc_item_not_found_other_sugg, code = "{suggested_name}")]
+ Other {
+ #[primary_span]
+ span: Span,
+ #[applicability]
+ applicability: Applicability,
+ ty_param_name: &'a str,
+ assoc_kind: &'static str,
+ suggested_name: Symbol,
+ },
+}
+
+#[derive(Diagnostic)]
#[diag(hir_analysis_unrecognized_atomic_operation, code = "E0092")]
pub struct UnrecognizedAtomicOperation<'a> {
#[primary_span]
@@ -205,8 +317,8 @@ pub struct MissingTypeParams {
// Manual implementation of `IntoDiagnostic` to be able to call `span_to_snippet`.
impl<'a> IntoDiagnostic<'a> for MissingTypeParams {
#[track_caller]
- fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
- let mut err = handler.struct_span_err_with_code(
+ fn into_diagnostic(self, dcx: &'a DiagCtxt) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
+ let mut err = dcx.struct_span_err_with_code(
self.span,
fluent::hir_analysis_missing_type_params,
error_code!(E0393),
@@ -538,27 +650,6 @@ pub(crate) struct ReturnTypeNotationEqualityBound {
}
#[derive(Diagnostic)]
-#[diag(hir_analysis_return_type_notation_missing_method)]
-pub(crate) struct ReturnTypeNotationMissingMethod {
- #[primary_span]
- pub span: Span,
- pub ty_name: String,
- pub assoc_name: Symbol,
-}
-
-#[derive(Diagnostic)]
-#[diag(hir_analysis_return_type_notation_conflicting_bound)]
-#[note]
-pub(crate) struct ReturnTypeNotationConflictingBound<'tcx> {
- #[primary_span]
- pub span: Span,
- pub ty_name: String,
- pub assoc_name: Symbol,
- pub first_bound: ty::Binder<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
- pub second_bound: ty::Binder<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
-}
-
-#[derive(Diagnostic)]
#[diag(hir_analysis_placeholder_not_allowed_item_signatures, code = "E0121")]
pub(crate) struct PlaceholderNotAllowedItemSignatures {
#[primary_span]
@@ -955,15 +1046,6 @@ pub(crate) struct ReturnPositionImplTraitInTraitRefined<'tcx> {
}
#[derive(Diagnostic)]
-#[diag(hir_analysis_assoc_bound_on_const)]
-#[note]
-pub struct AssocBoundOnConst {
- #[primary_span]
- pub span: Span,
- pub descr: &'static str,
-}
-
-#[derive(Diagnostic)]
#[diag(hir_analysis_inherent_ty_outside, code = "E0390")]
#[help]
pub struct InherentTyOutside {
diff --git a/compiler/rustc_hir_analysis/src/hir_wf_check.rs b/compiler/rustc_hir_analysis/src/hir_wf_check.rs
index ca7679cfb..78745fe47 100644
--- a/compiler/rustc_hir_analysis/src/hir_wf_check.rs
+++ b/compiler/rustc_hir_analysis/src/hir_wf_check.rs
@@ -5,7 +5,7 @@ use rustc_hir::{ForeignItem, ForeignItemKind};
use rustc_infer::infer::TyCtxtInferExt;
use rustc_infer::traits::{ObligationCause, WellFormedLoc};
use rustc_middle::query::Providers;
-use rustc_middle::ty::{self, Region, TyCtxt, TypeFoldable, TypeFolder};
+use rustc_middle::ty::{self, TyCtxt};
use rustc_span::def_id::LocalDefId;
use rustc_trait_selection::traits::{self, ObligationCtxt};
@@ -25,11 +25,11 @@ fn diagnostic_hir_wf_check<'tcx>(
WellFormedLoc::Ty(def_id) => def_id,
WellFormedLoc::Param { function, param_idx: _ } => function,
};
- let hir_id = hir.local_def_id_to_hir_id(def_id);
+ let hir_id = tcx.local_def_id_to_hir_id(def_id);
// HIR wfcheck should only ever happen as part of improving an existing error
tcx.sess
- .delay_span_bug(tcx.def_span(def_id), "Performed HIR wfcheck without an existing error!");
+ .span_delayed_bug(tcx.def_span(def_id), "Performed HIR wfcheck without an existing error!");
let icx = ItemCtxt::new(tcx, def_id);
@@ -68,7 +68,13 @@ fn diagnostic_hir_wf_check<'tcx>(
let infcx = self.tcx.infer_ctxt().build();
let ocx = ObligationCtxt::new(&infcx);
- let tcx_ty = self.icx.to_ty(ty).fold_with(&mut EraseAllBoundRegions { tcx: self.tcx });
+ let tcx_ty = self.icx.to_ty(ty);
+ // This visitor can walk into binders, resulting in the `tcx_ty` to
+ // potentially reference escaping bound variables. We simply erase
+ // those here.
+ let tcx_ty = self.tcx.fold_regions(tcx_ty, |r, _| {
+ if r.is_bound() { self.tcx.lifetimes.re_erased } else { r }
+ });
let cause = traits::ObligationCause::new(
ty.span,
self.def_id,
@@ -116,7 +122,7 @@ fn diagnostic_hir_wf_check<'tcx>(
// We will walk 'into' this type to try to find
// a more precise span for our predicate.
let tys = match loc {
- WellFormedLoc::Ty(_) => match hir.get(hir_id) {
+ WellFormedLoc::Ty(_) => match tcx.hir_node(hir_id) {
hir::Node::ImplItem(item) => match item.kind {
hir::ImplItemKind::Type(ty) => vec![ty],
hir::ImplItemKind::Const(ty, _) => vec![ty],
@@ -178,24 +184,3 @@ fn diagnostic_hir_wf_check<'tcx>(
}
visitor.cause
}
-
-struct EraseAllBoundRegions<'tcx> {
- tcx: TyCtxt<'tcx>,
-}
-
-// Higher ranked regions are complicated.
-// To make matters worse, the HIR WF check can instantiate them
-// outside of a `Binder`, due to the way we (ab)use
-// `ItemCtxt::to_ty`. To make things simpler, we just erase all
-// of them, regardless of depth. At worse, this will give
-// us an inaccurate span for an error message, but cannot
-// lead to unsoundness (we call `delay_span_bug` at the start
-// of `diagnostic_hir_wf_check`).
-impl<'tcx> TypeFolder<TyCtxt<'tcx>> for EraseAllBoundRegions<'tcx> {
- fn interner(&self) -> TyCtxt<'tcx> {
- self.tcx
- }
- fn fold_region(&mut self, r: Region<'tcx>) -> Region<'tcx> {
- if r.is_late_bound() { self.tcx.lifetimes.re_erased } else { r }
- }
-}
diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check.rs b/compiler/rustc_hir_analysis/src/impl_wf_check.rs
index 788121f7a..fff4a919e 100644
--- a/compiler/rustc_hir_analysis/src/impl_wf_check.rs
+++ b/compiler/rustc_hir_analysis/src/impl_wf_check.rs
@@ -74,7 +74,7 @@ fn enforce_impl_params_are_constrained(tcx: TyCtxt<'_>, impl_def_id: LocalDefId)
if impl_self_ty.references_error() {
// Don't complain about unconstrained type params when self ty isn't known due to errors.
// (#36836)
- tcx.sess.delay_span_bug(
+ tcx.sess.span_delayed_bug(
tcx.def_span(impl_def_id),
format!(
"potentially unconstrained type parameters weren't evaluated: {impl_self_ty:?}",
diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs
index 2b8219c01..91cdffbbe 100644
--- a/compiler/rustc_hir_analysis/src/lib.rs
+++ b/compiler/rustc_hir_analysis/src/lib.rs
@@ -57,9 +57,9 @@ This API is completely unstable and subject to change.
#![allow(rustc::potential_query_instability)]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
-#![cfg_attr(not(bootstrap), doc(rust_logo))]
-#![cfg_attr(not(bootstrap), feature(rustdoc_internals))]
-#![cfg_attr(not(bootstrap), allow(internal_features))]
+#![doc(rust_logo)]
+#![feature(rustdoc_internals)]
+#![allow(internal_features)]
#![feature(box_patterns)]
#![feature(control_flow_enum)]
#![feature(if_let_guard)]
@@ -99,8 +99,6 @@ pub mod structured_errors;
mod variance;
use rustc_errors::ErrorGuaranteed;
-use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
-use rustc_fluent_macro::fluent_messages;
use rustc_hir as hir;
use rustc_middle::middle;
use rustc_middle::query::Providers;
@@ -115,7 +113,7 @@ use astconv::{AstConv, OnlySelfBounds};
use bounds::Bounds;
use rustc_hir::def::DefKind;
-fluent_messages! { "../messages.ftl" }
+rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
fn require_c_abi_if_c_variadic(tcx: TyCtxt<'_>, decl: &hir::FnDecl<'_>, abi: Abi, span: Span) {
const CONVENTIONS_UNSTABLE: &str = "`C`, `cdecl`, `aapcs`, `win64`, `sysv64` or `efiapi`";
@@ -211,8 +209,8 @@ pub fn check_crate(tcx: TyCtxt<'_>) -> Result<(), ErrorGuaranteed> {
tcx.hir().for_each_module(|module| tcx.ensure().check_mod_item_types(module))
});
- // HACK: `check_mod_type_wf` may spuriously emit errors due to `delay_span_bug`, even if those errors
- // only actually get emitted in `check_mod_item_types`.
+ // HACK: `check_mod_type_wf` may spuriously emit errors due to `span_delayed_bug`, even if
+ // those errors only actually get emitted in `check_mod_item_types`.
errs?;
if tcx.features().rustc_attrs {
diff --git a/compiler/rustc_hir_analysis/src/outlives/mod.rs b/compiler/rustc_hir_analysis/src/outlives/mod.rs
index be9d076bd..9541e5107 100644
--- a/compiler/rustc_hir_analysis/src/outlives/mod.rs
+++ b/compiler/rustc_hir_analysis/src/outlives/mod.rs
@@ -18,7 +18,7 @@ pub fn provide(providers: &mut Providers) {
}
fn inferred_outlives_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[(ty::Clause<'_>, Span)] {
- let id = tcx.hir().local_def_id_to_hir_id(item_def_id);
+ let id = tcx.local_def_id_to_hir_id(item_def_id);
if matches!(tcx.def_kind(item_def_id), hir::def::DefKind::AnonConst)
&& tcx.features().generic_const_exprs
@@ -41,7 +41,7 @@ fn inferred_outlives_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[(ty::Clau
}
}
- match tcx.hir().get(id) {
+ match tcx.hir_node(id) {
Node::Item(item) => match item.kind {
hir::ItemKind::Struct(..) | hir::ItemKind::Enum(..) | hir::ItemKind::Union(..) => {
let crate_map = tcx.inferred_outlives_crate(());
diff --git a/compiler/rustc_hir_analysis/src/outlives/utils.rs b/compiler/rustc_hir_analysis/src/outlives/utils.rs
index a6410c944..8077acea5 100644
--- a/compiler/rustc_hir_analysis/src/outlives/utils.rs
+++ b/compiler/rustc_hir_analysis/src/outlives/utils.rs
@@ -80,6 +80,10 @@ pub(crate) fn insert_outlives_predicate<'tcx>(
.or_insert(span);
}
+ Component::Placeholder(_) => {
+ span_bug!(span, "Should not deduce placeholder outlives component");
+ }
+
Component::Alias(alias_ty) => {
// This would either arise from something like:
//
@@ -146,11 +150,11 @@ fn is_free_region(region: Region<'_>) -> bool {
// These correspond to `T: 'a` relationships:
//
// struct Foo<'a, T> {
- // field: &'a T, // this would generate a ReEarlyBound referencing `'a`
+ // field: &'a T, // this would generate a ReEarlyParam referencing `'a`
// }
//
// We care about these, so fall through.
- ty::ReEarlyBound(_) => true,
+ ty::ReEarlyParam(_) => true,
// These correspond to `T: 'static` relationships which can be
// rather surprising.
@@ -167,13 +171,13 @@ fn is_free_region(region: Region<'_>) -> bool {
// }
//
// The type above might generate a `T: 'b` bound, but we can
- // ignore it. We can't put it on the struct header anyway.
- ty::ReLateBound(..) => false,
+ // ignore it. We can't name this lifetime pn the struct header anyway.
+ ty::ReBound(..) => false,
ty::ReError(_) => false,
// These regions don't appear in types from type declarations:
- ty::ReErased | ty::ReVar(..) | ty::RePlaceholder(..) | ty::ReFree(..) => {
+ ty::ReErased | ty::ReVar(..) | ty::RePlaceholder(..) | ty::ReLateParam(..) => {
bug!("unexpected region in outlives inference: {:?}", region);
}
}
diff --git a/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs b/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs
index 76bd370a6..fab841e36 100644
--- a/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs
+++ b/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs
@@ -137,10 +137,9 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
// is from the 'of_trait' field of the enclosing impl
let parent = self.tcx.hir().get_parent(self.path_segment.hir_id);
- let parent_item = self
- .tcx
- .hir()
- .get_by_def_id(self.tcx.hir().get_parent_item(self.path_segment.hir_id).def_id);
+ let parent_item = self.tcx.hir_node_by_def_id(
+ self.tcx.hir().get_parent_item(self.path_segment.hir_id).def_id,
+ );
// Get the HIR id of the trait ref
let hir::Node::TraitRef(hir::TraitRef { hir_ref_id: trait_ref_id, .. }) = parent else {
@@ -774,7 +773,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
);
if let Some(parent_node) = self.tcx.hir().opt_parent_id(self.path_segment.hir_id)
- && let Some(parent_node) = self.tcx.hir().find(parent_node)
+ && let Some(parent_node) = self.tcx.opt_hir_node(parent_node)
&& let hir::Node::Expr(expr) = parent_node
{
match &expr.kind {
diff --git a/compiler/rustc_hir_analysis/src/variance/constraints.rs b/compiler/rustc_hir_analysis/src/variance/constraints.rs
index 5f8b1ace6..f09594cbb 100644
--- a/compiler/rustc_hir_analysis/src/variance/constraints.rs
+++ b/compiler/rustc_hir_analysis/src/variance/constraints.rs
@@ -413,20 +413,22 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
variance: VarianceTermPtr<'a>,
) {
match *region {
- ty::ReEarlyBound(ref data) => {
+ ty::ReEarlyParam(ref data) => {
self.add_constraint(current, data.index, variance);
}
ty::ReStatic => {}
- ty::ReLateBound(..) => {
- // Late-bound regions do not get substituted the same
- // way early-bound regions do, so we skip them here.
+ ty::ReBound(..) => {
+ // Either a higher-ranked region inside of a type or a
+ // late-bound function parameter.
+ //
+ // We do not compute constraints for either of these.
}
ty::ReError(_) => {}
- ty::ReFree(..) | ty::ReVar(..) | ty::RePlaceholder(..) | ty::ReErased => {
+ ty::ReLateParam(..) | ty::ReVar(..) | ty::RePlaceholder(..) | ty::ReErased => {
// We don't expect to see anything but 'static or bound
// regions when visiting member types or method types.
bug!(
diff --git a/compiler/rustc_hir_analysis/src/variance/mod.rs b/compiler/rustc_hir_analysis/src/variance/mod.rs
index 9fb39a0e9..410706110 100644
--- a/compiler/rustc_hir_analysis/src/variance/mod.rs
+++ b/compiler/rustc_hir_analysis/src/variance/mod.rs
@@ -106,7 +106,7 @@ fn variance_of_opaque(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Varianc
impl<'tcx> ty::TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeLifetimeCollector<'tcx> {
#[instrument(level = "trace", skip(self), ret)]
fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> {
- if let ty::RegionKind::ReEarlyBound(ebr) = r.kind() {
+ if let ty::RegionKind::ReEarlyParam(ebr) = r.kind() {
self.variances[ebr.index as usize] = ty::Invariant;
}
ControlFlow::Continue(())