summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_hir_analysis/src/collect
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:20:29 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:20:29 +0000
commit631cd5845e8de329d0e227aaa707d7ea228b8f8f (patch)
treea1b87c8f8cad01cf18f7c5f57a08f102771ed303 /compiler/rustc_hir_analysis/src/collect
parentAdding debian version 1.69.0+dfsg1-1. (diff)
downloadrustc-631cd5845e8de329d0e227aaa707d7ea228b8f8f.tar.xz
rustc-631cd5845e8de329d0e227aaa707d7ea228b8f8f.zip
Merging upstream version 1.70.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_hir_analysis/src/collect')
-rw-r--r--compiler/rustc_hir_analysis/src/collect/generics_of.rs16
-rw-r--r--compiler/rustc_hir_analysis/src/collect/item_bounds.rs76
-rw-r--r--compiler/rustc_hir_analysis/src/collect/predicates_of.rs200
-rw-r--r--compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs78
-rw-r--r--compiler/rustc_hir_analysis/src/collect/type_of.rs141
5 files changed, 321 insertions, 190 deletions
diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs
index 127d4fa90..119933697 100644
--- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs
@@ -5,16 +5,16 @@ use hir::{
};
use rustc_hir as hir;
use rustc_hir::def::DefKind;
-use rustc_hir::def_id::DefId;
+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::Span;
-pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
+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.expect_local());
+ let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
let node = tcx.hir().get(hir_id);
let parent_def_id = match node {
@@ -121,7 +121,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
Some(parent_def_id.to_def_id())
}
Node::Expr(&Expr { kind: ExprKind::ConstBlock(_), .. }) => {
- Some(tcx.typeck_root_def_id(def_id))
+ Some(tcx.typeck_root_def_id(def_id.to_def_id()))
}
// Exclude `GlobalAsm` here which cannot have generics.
Node::Expr(&Expr { kind: ExprKind::InlineAsm(asm), .. })
@@ -140,7 +140,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
}
}
Node::Expr(&hir::Expr { kind: hir::ExprKind::Closure { .. }, .. }) => {
- Some(tcx.typeck_root_def_id(def_id))
+ Some(tcx.typeck_root_def_id(def_id.to_def_id()))
}
Node::Item(item) => match item.kind {
ItemKind::OpaqueTy(hir::OpaqueTy {
@@ -189,7 +189,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
let opt_self = Some(ty::GenericParamDef {
index: 0,
name: kw::SelfUpper,
- def_id,
+ def_id: def_id.to_def_id(),
pure_wrt_drop: false,
kind: ty::GenericParamDefKind::Type {
has_default: false,
@@ -326,7 +326,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
params.extend(dummy_args.iter().map(|&arg| ty::GenericParamDef {
index: next_index(),
name: Symbol::intern(arg),
- def_id,
+ def_id: def_id.to_def_id(),
pure_wrt_drop: false,
kind: ty::GenericParamDefKind::Type { has_default: false, synthetic: false },
}));
@@ -339,7 +339,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
params.push(ty::GenericParamDef {
index: next_index(),
name: Symbol::intern("<const_ty>"),
- def_id,
+ def_id: def_id.to_def_id(),
pure_wrt_drop: false,
kind: ty::GenericParamDefKind::Type { has_default: false, synthetic: false },
});
diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
index 9cf3ff65a..2e56d2463 100644
--- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
+++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
@@ -3,8 +3,8 @@ use crate::astconv::AstConv;
use rustc_hir as hir;
use rustc_infer::traits::util;
use rustc_middle::ty::subst::InternalSubsts;
-use rustc_middle::ty::{self, DefIdTree, TyCtxt};
-use rustc_span::def_id::DefId;
+use rustc_middle::ty::{self, Ty, TyCtxt};
+use rustc_span::def_id::{DefId, LocalDefId};
use rustc_span::Span;
/// For associated types we include both bounds written on the type
@@ -16,12 +16,12 @@ use rustc_span::Span;
/// `hr-associated-type-bound-1.rs`.
fn associated_type_bounds<'tcx>(
tcx: TyCtxt<'tcx>,
- assoc_item_def_id: DefId,
+ assoc_item_def_id: LocalDefId,
ast_bounds: &'tcx [hir::GenericBound<'tcx>],
span: Span,
) -> &'tcx [(ty::Predicate<'tcx>, Span)] {
let item_ty = tcx.mk_projection(
- assoc_item_def_id,
+ assoc_item_def_id.to_def_id(),
InternalSubsts::identity_for_item(tcx, assoc_item_def_id),
);
@@ -30,8 +30,8 @@ fn associated_type_bounds<'tcx>(
// Associated types are implicitly sized unless a `?Sized` bound is found
icx.astconv().add_implicitly_sized(&mut bounds, item_ty, ast_bounds, None, span);
- let trait_def_id = tcx.parent(assoc_item_def_id);
- let trait_predicates = tcx.trait_explicit_predicates_and_bounds(trait_def_id.expect_local());
+ 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() {
@@ -45,7 +45,11 @@ fn associated_type_bounds<'tcx>(
});
let all_bounds = tcx.arena.alloc_from_iter(bounds.predicates().chain(bounds_from_parent));
- debug!("associated_type_bounds({}) = {:?}", tcx.def_path_str(assoc_item_def_id), all_bounds);
+ debug!(
+ "associated_type_bounds({}) = {:?}",
+ tcx.def_path_str(assoc_item_def_id.to_def_id()),
+ all_bounds
+ );
all_bounds
}
@@ -56,19 +60,12 @@ fn associated_type_bounds<'tcx>(
#[instrument(level = "trace", skip(tcx), ret)]
fn opaque_type_bounds<'tcx>(
tcx: TyCtxt<'tcx>,
- opaque_def_id: DefId,
+ opaque_def_id: LocalDefId,
ast_bounds: &'tcx [hir::GenericBound<'tcx>],
+ item_ty: Ty<'tcx>,
span: Span,
- in_trait: bool,
) -> &'tcx [(ty::Predicate<'tcx>, Span)] {
ty::print::with_no_queries!({
- let substs = InternalSubsts::identity_for_item(tcx, opaque_def_id);
- let item_ty = if in_trait {
- tcx.mk_projection(opaque_def_id, substs)
- } else {
- tcx.mk_opaque(opaque_def_id, substs)
- };
-
let icx = ItemCtxt::new(tcx, opaque_def_id);
let mut bounds = icx.astconv().compute_bounds(item_ty, ast_bounds);
// Opaque types are implicitly sized unless a `?Sized` bound is found
@@ -81,9 +78,31 @@ fn opaque_type_bounds<'tcx>(
pub(super) fn explicit_item_bounds(
tcx: TyCtxt<'_>,
- def_id: DefId,
+ def_id: LocalDefId,
) -> &'_ [(ty::Predicate<'_>, Span)] {
- let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());
+ match tcx.opt_rpitit_info(def_id.to_def_id()) {
+ // 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 opaque_ty = item.expect_opaque_ty();
+ return opaque_type_bounds(
+ tcx,
+ opaque_def_id.expect_local(),
+ opaque_ty.bounds,
+ tcx.mk_projection(
+ def_id.to_def_id(),
+ ty::InternalSubsts::identity_for_item(tcx, def_id),
+ ),
+ item.span,
+ );
+ }
+ // These should have been fed!
+ Some(ty::ImplTraitInTraitData::Impl { .. }) => unreachable!(),
+ None => {}
+ }
+
+ let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
match tcx.hir().get(hir_id) {
hir::Node::TraitItem(hir::TraitItem {
kind: hir::TraitItemKind::Type(bounds, _),
@@ -94,7 +113,15 @@ pub(super) fn explicit_item_bounds(
kind: hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds, in_trait, .. }),
span,
..
- }) => opaque_type_bounds(tcx, def_id, bounds, *span, *in_trait),
+ }) => {
+ let substs = InternalSubsts::identity_for_item(tcx, def_id);
+ let item_ty = if *in_trait && !tcx.lower_impl_trait_in_trait_to_assoc_ty() {
+ tcx.mk_projection(def_id.to_def_id(), substs)
+ } else {
+ tcx.mk_opaque(def_id.to_def_id(), substs)
+ };
+ opaque_type_bounds(tcx, def_id, bounds, item_ty, *span)
+ }
_ => bug!("item_bounds called on {:?}", def_id),
}
}
@@ -103,12 +130,9 @@ pub(super) fn item_bounds(
tcx: TyCtxt<'_>,
def_id: DefId,
) -> ty::EarlyBinder<&'_ ty::List<ty::Predicate<'_>>> {
- let bounds = tcx.mk_predicates_from_iter(
- util::elaborate_predicates(
- tcx,
- tcx.explicit_item_bounds(def_id).iter().map(|&(bound, _span)| bound),
- )
- .map(|obligation| obligation.predicate),
- );
+ let bounds = tcx.mk_predicates_from_iter(util::elaborate(
+ tcx,
+ tcx.explicit_item_bounds(def_id).iter().map(|&(bound, _span)| bound),
+ ));
ty::EarlyBinder(bounds)
}
diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
index 2badd66e3..9358ed612 100644
--- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
@@ -62,15 +62,16 @@ pub(super) fn predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredic
/// Returns a list of user-specified type predicates for the definition with ID `def_id`.
/// N.B., this does not include any implied/inferred constraints.
#[instrument(level = "trace", skip(tcx), ret)]
-fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicates<'_> {
+fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::GenericPredicates<'_> {
use rustc_hir::*;
- let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());
+ let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
let node = tcx.hir().get(hir_id);
let mut is_trait = None;
let mut is_default_impl_trait = None;
+ // FIXME: Should ItemCtxt take a LocalDefId?
let icx = ItemCtxt::new(tcx, def_id);
const NO_GENERICS: &hir::Generics<'_> = hir::Generics::empty();
@@ -99,7 +100,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP
| ItemKind::Union(_, generics) => generics,
ItemKind::Trait(_, _, generics, ..) | ItemKind::TraitAlias(generics, _) => {
- is_trait = Some(ty::TraitRef::identity(tcx, def_id));
+ is_trait = Some(ty::TraitRef::identity(tcx, def_id.to_def_id()));
generics
}
ItemKind::OpaqueTy(OpaqueTy { generics, .. }) => generics,
@@ -124,7 +125,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP
// on a trait we need to add in the supertrait bounds and bounds found on
// associated types.
if let Some(_trait_ref) = is_trait {
- predicates.extend(tcx.super_predicates_of(def_id).predicates.iter().cloned());
+ predicates.extend(tcx.implied_predicates_of(def_id).predicates.iter().cloned());
}
// In default impls, we can assume that the self type implements
@@ -253,7 +254,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP
}
if tcx.features().generic_const_exprs {
- predicates.extend(const_evaluatable_predicates_of(tcx, def_id.expect_local()));
+ predicates.extend(const_evaluatable_predicates_of(tcx, def_id));
}
let mut predicates: Vec<_> = predicates.into_iter().collect();
@@ -392,18 +393,18 @@ pub(super) fn trait_explicit_predicates_and_bounds(
def_id: LocalDefId,
) -> ty::GenericPredicates<'_> {
assert_eq!(tcx.def_kind(def_id), DefKind::Trait);
- gather_explicit_predicates_of(tcx, def_id.to_def_id())
+ gather_explicit_predicates_of(tcx, def_id)
}
pub(super) fn explicit_predicates_of<'tcx>(
tcx: TyCtxt<'tcx>,
- def_id: DefId,
+ def_id: LocalDefId,
) -> ty::GenericPredicates<'tcx> {
let def_kind = tcx.def_kind(def_id);
if let DefKind::Trait = def_kind {
// Remove bounds on associated types from the predicates, they will be
// returned by `explicit_item_bounds`.
- let predicates_and_bounds = tcx.trait_explicit_predicates_and_bounds(def_id.expect_local());
+ let predicates_and_bounds = tcx.trait_explicit_predicates_and_bounds(def_id);
let trait_identity_substs = InternalSubsts::identity_for_item(tcx, def_id);
let is_assoc_item_ty = |ty: Ty<'tcx>| {
@@ -418,7 +419,8 @@ pub(super) fn explicit_predicates_of<'tcx>(
// supertrait).
if let ty::Alias(ty::Projection, projection) = ty.kind() {
projection.substs == trait_identity_substs
- && tcx.associated_item(projection.def_id).container_id(tcx) == def_id
+ && tcx.associated_item(projection.def_id).container_id(tcx)
+ == def_id.to_def_id()
} else {
false
}
@@ -449,7 +451,7 @@ pub(super) fn explicit_predicates_of<'tcx>(
}
} else {
if matches!(def_kind, DefKind::AnonConst) && tcx.lazy_normalization() {
- let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());
+ let hir_id = tcx.hir().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) =
@@ -532,89 +534,136 @@ pub(super) fn explicit_predicates_of<'tcx>(
}
}
+#[derive(Copy, Clone, Debug)]
+pub enum PredicateFilter {
+ /// All predicates may be implied by the trait
+ All,
+
+ /// Only traits that reference `Self: ..` are implied by the trait
+ SelfOnly,
+
+ /// Only traits that reference `Self: ..` and define an associated type
+ /// with the given ident are implied by the trait
+ SelfThatDefines(Ident),
+}
+
/// Ensures that the super-predicates of the trait with a `DefId`
/// of `trait_def_id` are converted and stored. This also ensures that
/// the transitive super-predicates are converted.
pub(super) fn super_predicates_of(
tcx: TyCtxt<'_>,
- trait_def_id: DefId,
+ trait_def_id: LocalDefId,
+) -> ty::GenericPredicates<'_> {
+ implied_predicates_with_filter(tcx, trait_def_id.to_def_id(), PredicateFilter::SelfOnly)
+}
+
+pub(super) fn super_predicates_that_define_assoc_type(
+ tcx: TyCtxt<'_>,
+ (trait_def_id, assoc_name): (DefId, Ident),
+) -> ty::GenericPredicates<'_> {
+ implied_predicates_with_filter(tcx, trait_def_id, PredicateFilter::SelfThatDefines(assoc_name))
+}
+
+pub(super) fn implied_predicates_of(
+ tcx: TyCtxt<'_>,
+ trait_def_id: LocalDefId,
) -> ty::GenericPredicates<'_> {
- tcx.super_predicates_that_define_assoc_type((trait_def_id, None))
+ if tcx.is_trait_alias(trait_def_id.to_def_id()) {
+ implied_predicates_with_filter(tcx, trait_def_id.to_def_id(), PredicateFilter::All)
+ } else {
+ tcx.super_predicates_of(trait_def_id)
+ }
}
/// Ensures that the super-predicates of the trait with a `DefId`
/// of `trait_def_id` are converted and stored. This also ensures that
/// the transitive super-predicates are converted.
-pub(super) fn super_predicates_that_define_assoc_type(
+pub(super) fn implied_predicates_with_filter(
tcx: TyCtxt<'_>,
- (trait_def_id, assoc_name): (DefId, Option<Ident>),
+ trait_def_id: DefId,
+ filter: PredicateFilter,
) -> ty::GenericPredicates<'_> {
- if trait_def_id.is_local() {
- debug!("local trait");
- let trait_hir_id = tcx.hir().local_def_id_to_hir_id(trait_def_id.expect_local());
-
- let Node::Item(item) = tcx.hir().get(trait_hir_id) else {
- bug!("trait_node_id {} is not an item", trait_hir_id);
- };
+ let Some(trait_def_id) = trait_def_id.as_local() else {
+ // if `assoc_name` is None, then the query should've been redirected to an
+ // external provider
+ assert!(matches!(filter, PredicateFilter::SelfThatDefines(_)));
+ return tcx.super_predicates_of(trait_def_id);
+ };
- let (generics, bounds) = match item.kind {
- hir::ItemKind::Trait(.., generics, supertraits, _) => (generics, supertraits),
- hir::ItemKind::TraitAlias(generics, supertraits) => (generics, supertraits),
- _ => span_bug!(item.span, "super_predicates invoked on non-trait"),
- };
+ let trait_hir_id = tcx.hir().local_def_id_to_hir_id(trait_def_id);
- let icx = ItemCtxt::new(tcx, trait_def_id);
+ let Node::Item(item) = tcx.hir().get(trait_hir_id) else {
+ bug!("trait_node_id {} is not an item", trait_hir_id);
+ };
- // Convert the bounds that follow the colon, e.g., `Bar + Zed` in `trait Foo: Bar + Zed`.
- let self_param_ty = tcx.types.self_param;
- let superbounds1 = if let Some(assoc_name) = assoc_name {
- icx.astconv().compute_bounds_that_match_assoc_type(self_param_ty, bounds, assoc_name)
- } else {
- icx.astconv().compute_bounds(self_param_ty, bounds)
- };
+ let (generics, bounds) = match item.kind {
+ hir::ItemKind::Trait(.., generics, supertraits, _) => (generics, supertraits),
+ hir::ItemKind::TraitAlias(generics, supertraits) => (generics, supertraits),
+ _ => span_bug!(item.span, "super_predicates invoked on non-trait"),
+ };
- let superbounds1 = superbounds1.predicates();
-
- // Convert any explicit superbounds in the where-clause,
- // e.g., `trait Foo where Self: Bar`.
- // In the case of trait aliases, however, we include all bounds in the where-clause,
- // so e.g., `trait Foo = where u32: PartialEq<Self>` would include `u32: PartialEq<Self>`
- // as one of its "superpredicates".
- let is_trait_alias = tcx.is_trait_alias(trait_def_id);
- let superbounds2 = icx.type_parameter_bounds_in_generics(
- generics,
- item.owner_id.def_id,
- self_param_ty,
- OnlySelfBounds(!is_trait_alias),
- assoc_name,
- );
+ let icx = ItemCtxt::new(tcx, trait_def_id);
+
+ let self_param_ty = tcx.types.self_param;
+ let (superbounds, where_bounds_that_match) = match filter {
+ PredicateFilter::All => (
+ // Convert the bounds that follow the colon (or equal in trait aliases)
+ icx.astconv().compute_bounds(self_param_ty, bounds),
+ // Also include all where clause bounds
+ icx.type_parameter_bounds_in_generics(
+ generics,
+ item.owner_id.def_id,
+ self_param_ty,
+ OnlySelfBounds(false),
+ None,
+ ),
+ ),
+ PredicateFilter::SelfOnly => (
+ // Convert the bounds that follow the colon (or equal in trait aliases)
+ icx.astconv().compute_bounds(self_param_ty, bounds),
+ // Include where clause bounds for `Self`
+ icx.type_parameter_bounds_in_generics(
+ generics,
+ item.owner_id.def_id,
+ self_param_ty,
+ OnlySelfBounds(true),
+ None,
+ ),
+ ),
+ PredicateFilter::SelfThatDefines(assoc_name) => (
+ // Convert the bounds that follow the colon (or equal) that reference the associated name
+ icx.astconv().compute_bounds_that_match_assoc_type(self_param_ty, bounds, assoc_name),
+ // Include where clause bounds for `Self` that reference the associated name
+ icx.type_parameter_bounds_in_generics(
+ generics,
+ item.owner_id.def_id,
+ self_param_ty,
+ OnlySelfBounds(true),
+ Some(assoc_name),
+ ),
+ ),
+ };
- // Combine the two lists to form the complete set of superbounds:
- let superbounds = &*tcx.arena.alloc_from_iter(superbounds1.into_iter().chain(superbounds2));
- debug!(?superbounds);
+ // Combine the two lists to form the complete set of superbounds:
+ let implied_bounds = &*tcx
+ .arena
+ .alloc_from_iter(superbounds.predicates().into_iter().chain(where_bounds_that_match));
+ debug!(?implied_bounds);
+ // Now require that immediate supertraits are converted,
+ // which will, in turn, reach indirect supertraits.
+ if matches!(filter, PredicateFilter::SelfOnly) {
// Now require that immediate supertraits are converted,
// which will, in turn, reach indirect supertraits.
- if assoc_name.is_none() {
- // Now require that immediate supertraits are converted,
- // which will, in turn, reach indirect supertraits.
- for &(pred, span) in superbounds {
- debug!("superbound: {:?}", pred);
- if let ty::PredicateKind::Clause(ty::Clause::Trait(bound)) =
- pred.kind().skip_binder()
- {
- tcx.at(span).super_predicates_of(bound.def_id());
- }
+ for &(pred, span) in implied_bounds {
+ debug!("superbound: {:?}", pred);
+ if let ty::PredicateKind::Clause(ty::Clause::Trait(bound)) = pred.kind().skip_binder() {
+ tcx.at(span).super_predicates_of(bound.def_id());
}
}
-
- ty::GenericPredicates { parent: None, predicates: superbounds }
- } else {
- // if `assoc_name` is None, then the query should've been redirected to an
- // external provider
- assert!(assoc_name.is_some());
- tcx.super_predicates_of(trait_def_id)
}
+
+ ty::GenericPredicates { parent: None, predicates: implied_bounds }
}
/// Returns the predicates defined on `item_def_id` of the form
@@ -622,7 +671,7 @@ pub(super) fn super_predicates_that_define_assoc_type(
#[instrument(level = "trace", skip(tcx))]
pub(super) fn type_param_predicates(
tcx: TyCtxt<'_>,
- (item_def_id, def_id, assoc_name): (DefId, LocalDefId, Ident),
+ (item_def_id, def_id, assoc_name): (LocalDefId, LocalDefId, Ident),
) -> ty::GenericPredicates<'_> {
use rustc_hir::*;
@@ -637,21 +686,21 @@ pub(super) fn type_param_predicates(
let ty = tcx.mk_ty_param(index, tcx.hir().ty_param_name(def_id));
// Don't look for bounds where the type parameter isn't in scope.
- let parent = if item_def_id == param_owner.to_def_id() {
+ let parent = if item_def_id == param_owner {
None
} else {
- tcx.generics_of(item_def_id).parent
+ tcx.generics_of(item_def_id).parent.map(|def_id| def_id.expect_local())
};
let mut result = parent
.map(|parent| {
let icx = ItemCtxt::new(tcx, parent);
- icx.get_type_parameter_bounds(DUMMY_SP, def_id.to_def_id(), assoc_name)
+ icx.get_type_parameter_bounds(DUMMY_SP, def_id, assoc_name)
})
.unwrap_or_default();
let mut extend = None;
- let item_hir_id = tcx.hir().local_def_id_to_hir_id(item_def_id.expect_local());
+ 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,
@@ -673,7 +722,8 @@ pub(super) fn type_param_predicates(
ItemKind::Trait(_, _, generics, ..) => {
// Implied `Self: Trait` and supertrait bounds.
if param_id == item_hir_id {
- let identity_trait_ref = ty::TraitRef::identity(tcx, item_def_id);
+ let identity_trait_ref =
+ ty::TraitRef::identity(tcx, item_def_id.to_def_id());
extend =
Some((identity_trait_ref.without_const().to_predicate(tcx), item.span));
}
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 65a9052a6..e758fe95d 100644
--- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
+++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
@@ -17,7 +17,7 @@ use rustc_hir::{GenericArg, GenericParam, GenericParamKind, HirIdMap, LifetimeNa
use rustc_middle::bug;
use rustc_middle::hir::nested_filter;
use rustc_middle::middle::resolve_bound_vars::*;
-use rustc_middle::ty::{self, DefIdTree, TyCtxt, TypeSuperVisitable, TypeVisitor};
+use rustc_middle::ty::{self, TyCtxt, TypeSuperVisitable, TypeVisitor};
use rustc_session::lint;
use rustc_span::def_id::DefId;
use rustc_span::symbol::{sym, Ident};
@@ -1051,9 +1051,8 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
}
}
-fn object_lifetime_default(tcx: TyCtxt<'_>, param_def_id: DefId) -> ObjectLifetimeDefault {
+fn object_lifetime_default(tcx: TyCtxt<'_>, param_def_id: LocalDefId) -> ObjectLifetimeDefault {
debug_assert_eq!(tcx.def_kind(param_def_id), DefKind::TyParam);
- let param_def_id = param_def_id.expect_local();
let hir::Node::GenericParam(param) = tcx.hir().get_by_def_id(param_def_id) else {
bug!("expected GenericParam for object_lifetime_default");
};
@@ -1427,25 +1426,25 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
if let ResolvedArg::LateBound(..) = def && crossed_anon_const {
let use_span = self.tcx.hir().span(hir_id);
let def_span = self.tcx.def_span(param_def_id);
- match self.tcx.def_kind(param_def_id) {
+ let guar = match self.tcx.def_kind(param_def_id) {
DefKind::ConstParam => {
self.tcx.sess.emit_err(errors::CannotCaptureLateBoundInAnonConst::Const {
use_span,
def_span,
- });
+ })
}
DefKind::TyParam => {
self.tcx.sess.emit_err(errors::CannotCaptureLateBoundInAnonConst::Type {
use_span,
def_span,
- });
+ })
}
_ => unreachable!(),
- }
- return;
+ };
+ self.map.defs.insert(hir_id, ResolvedArg::Error(guar));
+ } else {
+ self.map.defs.insert(hir_id, def);
}
-
- self.map.defs.insert(hir_id, def);
return;
}
@@ -1462,7 +1461,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
depth: usize,
generic_args: &'tcx hir::GenericArgs<'tcx>,
) {
- if generic_args.parenthesized {
+ if generic_args.parenthesized == hir::GenericArgsParentheses::ParenSugar {
self.visit_fn_like_elision(
generic_args.inputs(),
Some(generic_args.bindings[0].ty()),
@@ -1641,7 +1640,59 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
},
s: self.scope,
};
- if let Some(type_def_id) = type_def_id {
+ // If the binding is parenthesized, then this must be `feature(return_type_notation)`.
+ // In that case, introduce a binder over all of the function's early and late bound vars.
+ //
+ // For example, given
+ // ```
+ // trait Foo {
+ // async fn x<'r, T>();
+ // }
+ // ```
+ // and a bound that looks like:
+ // `for<'a> T::Trait<'a, x(): for<'b> Other<'b>>`
+ // this is going to expand to something like:
+ // `for<'a> for<'r, T> <T as Trait<'a>>::x::<'r, T>::{opaque#0}: for<'b> Other<'b>`.
+ if binding.gen_args.parenthesized == hir::GenericArgsParentheses::ReturnTypeNotation {
+ let bound_vars = if let Some(type_def_id) = type_def_id
+ && self.tcx.def_kind(type_def_id) == DefKind::Trait
+ // FIXME(return_type_notation): We could bound supertrait methods.
+ && let Some(assoc_fn) = self
+ .tcx
+ .associated_items(type_def_id)
+ .find_by_name_and_kind(self.tcx, binding.ident, ty::AssocKind::Fn, type_def_id)
+ {
+ self.tcx
+ .generics_of(assoc_fn.def_id)
+ .params
+ .iter()
+ .map(|param| match param.kind {
+ ty::GenericParamDefKind::Lifetime => ty::BoundVariableKind::Region(
+ ty::BoundRegionKind::BrNamed(param.def_id, param.name),
+ ),
+ ty::GenericParamDefKind::Type { .. } => ty::BoundVariableKind::Ty(
+ ty::BoundTyKind::Param(param.def_id, param.name),
+ ),
+ ty::GenericParamDefKind::Const { .. } => ty::BoundVariableKind::Const,
+ })
+ .chain(self.tcx.fn_sig(assoc_fn.def_id).subst_identity().bound_vars())
+ .collect()
+ } else {
+ self.tcx.sess.delay_span_bug(
+ binding.ident.span,
+ "bad return type notation here",
+ );
+ vec![]
+ };
+ self.with(scope, |this| {
+ let scope = Scope::Supertrait { bound_vars, s: this.scope };
+ this.with(scope, |this| {
+ let (bound_vars, _) = this.poly_trait_ref_binder_info();
+ this.record_late_bound_vars(binding.hir_id, bound_vars);
+ this.visit_assoc_type_binding(binding)
+ });
+ });
+ } else if let Some(type_def_id) = type_def_id {
let bound_vars =
BoundVarContext::supertrait_hrtb_vars(self.tcx, type_def_id, binding.ident);
self.with(scope, |this| {
@@ -1698,8 +1749,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
if trait_defines_associated_type_named(def_id) {
break Some(bound_vars.into_iter().collect());
}
- let predicates =
- tcx.super_predicates_that_define_assoc_type((def_id, Some(assoc_name)));
+ let predicates = tcx.super_predicates_that_define_assoc_type((def_id, assoc_name));
let obligations = predicates.predicates.iter().filter_map(|&(pred, _)| {
let bound_predicate = pred.kind();
match bound_predicate.skip_binder() {
diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs
index 50073d94e..c173bd913 100644
--- a/compiler/rustc_hir_analysis/src/collect/type_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs
@@ -8,9 +8,7 @@ use rustc_middle::hir::nested_filter;
use rustc_middle::ty::print::with_forced_trimmed_paths;
use rustc_middle::ty::subst::InternalSubsts;
use rustc_middle::ty::util::IntTypeExt;
-use rustc_middle::ty::{
- self, DefIdTree, IsSuggestable, Ty, TyCtxt, TypeFolder, TypeSuperFoldable, TypeVisitableExt,
-};
+use rustc_middle::ty::{self, ImplTraitInTraitData, IsSuggestable, Ty, TyCtxt, TypeVisitableExt};
use rustc_span::symbol::Ident;
use rustc_span::{Span, DUMMY_SP};
@@ -62,7 +60,7 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<
.find(|(_, node)| matches!(node, OwnerNode::Item(_)))
.unwrap()
.0
- .to_def_id();
+ .def_id;
let item_ctxt = &ItemCtxt::new(tcx, item_def_id) as &dyn crate::astconv::AstConv<'_>;
let ty = item_ctxt.ast_ty_to_ty(hir_ty);
@@ -243,24 +241,46 @@ fn get_path_containing_arg_in_pat<'hir>(
arg_path
}
-pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::EarlyBinder<Ty<'_>> {
- let def_id = def_id.expect_local();
+pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty<'_>> {
+ // If we are computing `type_of` the synthesized associated type for an RPITIT in the impl
+ // side, use `collect_return_position_impl_trait_in_trait_tys` to infer the value of the
+ // associated type in the impl.
+ if let Some(ImplTraitInTraitData::Impl { fn_def_id, .. }) =
+ tcx.opt_rpitit_info(def_id.to_def_id())
+ {
+ match tcx.collect_return_position_impl_trait_in_trait_tys(fn_def_id) {
+ Ok(map) => {
+ let assoc_item = tcx.associated_item(def_id);
+ return ty::EarlyBinder(map[&assoc_item.trait_item_def_id.unwrap()]);
+ }
+ Err(_) => {
+ return ty::EarlyBinder(tcx.ty_error_with_message(
+ DUMMY_SP,
+ "Could not collect return position impl trait in trait tys",
+ ));
+ }
+ }
+ }
+
use rustc_hir::*;
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
- let icx = ItemCtxt::new(tcx, def_id.to_def_id());
+ let icx = ItemCtxt::new(tcx, def_id);
let output = match tcx.hir().get(hir_id) {
Node::TraitItem(item) => match item.kind {
TraitItemKind::Fn(..) => {
- let substs = InternalSubsts::identity_for_item(tcx, def_id.to_def_id());
+ let substs = InternalSubsts::identity_for_item(tcx, def_id);
tcx.mk_fn_def(def_id.to_def_id(), substs)
}
TraitItemKind::Const(ty, body_id) => body_id
.and_then(|body_id| {
- is_suggestable_infer_ty(ty)
- .then(|| infer_placeholder_type(tcx, def_id, body_id, ty.span, item.ident, "constant",))
+ is_suggestable_infer_ty(ty).then(|| {
+ infer_placeholder_type(
+ tcx, def_id, body_id, ty.span, item.ident, "constant",
+ )
+ })
})
.unwrap_or_else(|| icx.to_ty(ty)),
TraitItemKind::Type(_, Some(ty)) => icx.to_ty(ty),
@@ -271,7 +291,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::EarlyBinder<Ty<'_>>
Node::ImplItem(item) => match item.kind {
ImplItemKind::Fn(..) => {
- let substs = InternalSubsts::identity_for_item(tcx, def_id.to_def_id());
+ let substs = InternalSubsts::identity_for_item(tcx, def_id);
tcx.mk_fn_def(def_id.to_def_id(), substs)
}
ImplItemKind::Const(ty, body_id) => {
@@ -316,22 +336,23 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::EarlyBinder<Ty<'_>>
}
}
ItemKind::TyAlias(self_ty, _) => icx.to_ty(self_ty),
- ItemKind::Impl(hir::Impl { self_ty, .. }) => {
- match self_ty.find_self_aliases() {
- spans if spans.len() > 0 => {
- let guar = tcx.sess.emit_err(crate::errors::SelfInImplSelf { span: spans.into(), note: () });
- tcx.ty_error(guar)
- },
- _ => icx.to_ty(*self_ty),
+ ItemKind::Impl(hir::Impl { self_ty, .. }) => match self_ty.find_self_aliases() {
+ spans if spans.len() > 0 => {
+ let guar = tcx.sess.emit_err(crate::errors::SelfInImplSelf {
+ span: spans.into(),
+ note: (),
+ });
+ tcx.ty_error(guar)
}
+ _ => icx.to_ty(*self_ty),
},
ItemKind::Fn(..) => {
- let substs = InternalSubsts::identity_for_item(tcx, def_id.to_def_id());
+ let substs = InternalSubsts::identity_for_item(tcx, def_id);
tcx.mk_fn_def(def_id.to_def_id(), substs)
}
ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Union(..) => {
let def = tcx.adt_def(def_id);
- let substs = InternalSubsts::identity_for_item(tcx, def_id.to_def_id());
+ let substs = InternalSubsts::identity_for_item(tcx, def_id);
tcx.mk_adt(def, substs)
}
ItemKind::OpaqueTy(OpaqueTy { origin: hir::OpaqueTyOrigin::TyAlias, .. }) => {
@@ -344,8 +365,11 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::EarlyBinder<Ty<'_>>
in_trait,
..
}) => {
- if in_trait {
- assert!(tcx.impl_defaultness(owner).has_value());
+ if in_trait && !tcx.impl_defaultness(owner).has_value() {
+ span_bug!(
+ tcx.def_span(def_id),
+ "tried to get type of this RPITIT with no definition"
+ );
}
find_opaque_ty_constraints_for_rpit(tcx, def_id, owner)
}
@@ -368,7 +392,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::EarlyBinder<Ty<'_>>
Node::ForeignItem(foreign_item) => match foreign_item.kind {
ForeignItemKind::Fn(..) => {
- let substs = InternalSubsts::identity_for_item(tcx, def_id.to_def_id());
+ let substs = InternalSubsts::identity_for_item(tcx, def_id);
tcx.mk_fn_def(def_id.to_def_id(), substs)
}
ForeignItemKind::Static(t, _) => icx.to_ty(t),
@@ -380,7 +404,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::EarlyBinder<Ty<'_>>
tcx.type_of(tcx.hir().get_parent_item(hir_id)).subst_identity()
}
VariantData::Tuple(..) => {
- let substs = InternalSubsts::identity_for_item(tcx, def_id.to_def_id());
+ let substs = InternalSubsts::identity_for_item(tcx, def_id);
tcx.mk_fn_def(def_id.to_def_id(), substs)
}
},
@@ -413,7 +437,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::EarlyBinder<Ty<'_>>
Node::Expr(Expr { kind: ExprKind::ConstBlock(anon_const), .. })
if anon_const.hir_id == hir_id =>
{
- let substs = InternalSubsts::identity_for_item(tcx, def_id.to_def_id());
+ let substs = InternalSubsts::identity_for_item(tcx, def_id);
substs.as_inline_const().ty()
}
@@ -434,15 +458,12 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::EarlyBinder<Ty<'_>>
tcx.adt_def(tcx.hir().get_parent_item(hir_id)).repr().discr_type().to_ty(tcx)
}
- Node::TypeBinding(
- TypeBinding {
- hir_id: binding_id,
- kind: TypeBindingKind::Equality { term: Term::Const(e) },
- ident,
- ..
- },
- ) if let Node::TraitRef(trait_ref) =
- tcx.hir().get_parent(*binding_id)
+ Node::TypeBinding(TypeBinding {
+ hir_id: binding_id,
+ kind: TypeBindingKind::Equality { term: Term::Const(e) },
+ ident,
+ ..
+ }) if let Node::TraitRef(trait_ref) = tcx.hir().get_parent(*binding_id)
&& e.hir_id == hir_id =>
{
let Some(trait_def_id) = trait_ref.trait_def_id() else {
@@ -456,7 +477,9 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::EarlyBinder<Ty<'_>>
def_id.to_def_id(),
);
if let Some(assoc_item) = assoc_item {
- tcx.type_of(assoc_item.def_id).subst_identity()
+ tcx.type_of(assoc_item.def_id)
+ .no_bound_vars()
+ .expect("const parameter types cannot be generic")
} else {
// FIXME(associated_const_equality): add a useful error message here.
tcx.ty_error_with_message(
@@ -466,10 +489,13 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::EarlyBinder<Ty<'_>>
}
}
- Node::TypeBinding(
- TypeBinding { hir_id: binding_id, gen_args, kind, ident, .. },
- ) if let Node::TraitRef(trait_ref) =
- tcx.hir().get_parent(*binding_id)
+ Node::TypeBinding(TypeBinding {
+ hir_id: binding_id,
+ gen_args,
+ kind,
+ ident,
+ ..
+ }) if let Node::TraitRef(trait_ref) = tcx.hir().get_parent(*binding_id)
&& let Some((idx, _)) =
gen_args.args.iter().enumerate().find(|(_, arg)| {
if let GenericArg::Const(ct) = arg {
@@ -498,15 +524,18 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::EarlyBinder<Ty<'_>>
},
def_id.to_def_id(),
);
- if let Some(param)
- = assoc_item.map(|item| &tcx.generics_of(item.def_id).params[idx]).filter(|param| param.kind.is_ty_or_const())
+ if let Some(assoc_item) = assoc_item
+ && let param = &tcx.generics_of(assoc_item.def_id).params[idx]
+ && matches!(param.kind, ty::GenericParamDefKind::Const { .. })
{
- tcx.type_of(param.def_id).subst_identity()
+ tcx.type_of(param.def_id)
+ .no_bound_vars()
+ .expect("const parameter types cannot be generic")
} else {
// FIXME(associated_const_equality): add a useful error message here.
tcx.ty_error_with_message(
DUMMY_SP,
- "Could not find associated const on trait",
+ "Could not find const param on associated item",
)
}
}
@@ -574,7 +603,7 @@ fn find_opaque_ty_constraints_for_tait(tcx: TyCtxt<'_>, def_id: LocalDefId) -> T
found: Option<ty::OpaqueHiddenType<'tcx>>,
/// In the presence of dead code, typeck may figure out a hidden type
- /// while borrowck will now. We collect these cases here and check at
+ /// while borrowck will not. We collect these cases here and check at
/// the end that we actually found a type that matches (modulo regions).
typeck_types: Vec<ty::OpaqueHiddenType<'tcx>>,
}
@@ -746,7 +775,7 @@ fn find_opaque_ty_constraints_for_rpit(
// Use borrowck to get the type with unerased regions.
let concrete_opaque_types = &self.tcx.mir_borrowck(def_id).concrete_opaque_types;
debug!(?concrete_opaque_types);
- for &(def_id, concrete_type) in concrete_opaque_types {
+ for (&def_id, &concrete_type) in concrete_opaque_types {
if def_id != self.def_id {
// Ignore constraints for other opaque types.
continue;
@@ -842,28 +871,6 @@ fn infer_placeholder_type<'a>(
item_ident: Ident,
kind: &'static str,
) -> Ty<'a> {
- // Attempts to make the type nameable by turning FnDefs into FnPtrs.
- struct MakeNameable<'tcx> {
- tcx: TyCtxt<'tcx>,
- }
-
- impl<'tcx> TypeFolder<TyCtxt<'tcx>> for MakeNameable<'tcx> {
- fn interner(&self) -> TyCtxt<'tcx> {
- self.tcx
- }
-
- fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
- let ty = match *ty.kind() {
- ty::FnDef(def_id, substs) => {
- self.tcx.mk_fn_ptr(self.tcx.fn_sig(def_id).subst(self.tcx, substs))
- }
- _ => ty,
- };
-
- ty.super_fold_with(self)
- }
- }
-
let ty = tcx.diagnostic_only_typeck(def_id).node_type(body_id.hir_id);
// If this came from a free `const` or `static mut?` item,