diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs index da779a165690..0b81f4693712 100644 --- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs +++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs @@ -43,7 +43,7 @@ fn associated_type_bounds<'tcx>( match filter { PredicateFilter::All | PredicateFilter::SelfOnly - | PredicateFilter::SelfThatDefines(_) + | PredicateFilter::SelfTraitThatDefines(_) | PredicateFilter::SelfAndAssociatedTypeBounds => { icx.lowerer().add_sized_bound(&mut bounds, item_ty, hir_bounds, None, span); } @@ -122,7 +122,7 @@ fn remap_gat_vars_and_recurse_into_nested_projections<'tcx>( PredicateFilter::SelfOnly => { return None; } - PredicateFilter::SelfThatDefines(_) + PredicateFilter::SelfTraitThatDefines(_) | PredicateFilter::SelfConstIfConst | PredicateFilter::SelfAndAssociatedTypeBounds | PredicateFilter::ConstIfConst => { @@ -329,7 +329,7 @@ fn opaque_type_bounds<'tcx>( match filter { PredicateFilter::All | PredicateFilter::SelfOnly - | PredicateFilter::SelfThatDefines(_) + | PredicateFilter::SelfTraitThatDefines(_) | PredicateFilter::SelfAndAssociatedTypeBounds => { // Associated types are implicitly sized unless a `?Sized` bound is found icx.lowerer().add_sized_bound(&mut bounds, item_ty, hir_bounds, None, span); diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index 3d6f5ab24599..93915007cc35 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -557,7 +557,11 @@ pub(super) fn explicit_supertraits_containing_assoc_item<'tcx>( tcx: TyCtxt<'tcx>, (trait_def_id, assoc_name): (DefId, Ident), ) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> { - implied_predicates_with_filter(tcx, trait_def_id, PredicateFilter::SelfThatDefines(assoc_name)) + implied_predicates_with_filter( + tcx, + trait_def_id, + PredicateFilter::SelfTraitThatDefines(assoc_name), + ) } pub(super) fn explicit_implied_predicates_of<'tcx>( @@ -586,7 +590,7 @@ pub(super) fn implied_predicates_with_filter<'tcx>( 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(_)); + assert_matches!(filter, PredicateFilter::SelfTraitThatDefines(_)); return tcx.explicit_super_predicates_of(trait_def_id); }; @@ -660,7 +664,7 @@ pub(super) fn assert_only_contains_predicates_from<'tcx>( } match filter { - PredicateFilter::SelfOnly | PredicateFilter::SelfThatDefines(_) => { + PredicateFilter::SelfOnly => { for (clause, _) in bounds { match clause.kind().skip_binder() { ty::ClauseKind::Trait(trait_predicate) => { @@ -700,6 +704,33 @@ pub(super) fn assert_only_contains_predicates_from<'tcx>( } } } + PredicateFilter::SelfTraitThatDefines(_) => { + for (clause, _) in bounds { + match clause.kind().skip_binder() { + ty::ClauseKind::Trait(trait_predicate) => { + assert_eq!( + trait_predicate.self_ty(), + ty, + "expected `Self` predicate when computing \ + `{filter:?}` implied bounds: {clause:?}" + ); + } + + ty::ClauseKind::Projection(_) + | ty::ClauseKind::TypeOutlives(_) + | ty::ClauseKind::RegionOutlives(_) + | ty::ClauseKind::ConstArgHasType(_, _) + | ty::ClauseKind::WellFormed(_) + | ty::ClauseKind::ConstEvaluatable(_) + | ty::ClauseKind::HostEffect(..) => { + bug!( + "unexpected non-`Self` predicate when computing \ + `{filter:?}` implied bounds: {clause:?}" + ); + } + } + } + } PredicateFilter::ConstIfConst => { for (clause, _) in bounds { match clause.kind().skip_binder() { @@ -771,11 +802,10 @@ pub(super) fn type_param_predicates<'tcx>( 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()]; // Don't look for bounds where the type parameter isn't in scope. let parent = if item_def_id == param_owner { + // FIXME: Shouldn't this be unreachable? None } else { tcx.generics_of(item_def_id).parent.map(|def_id| def_id.expect_local()) @@ -795,6 +825,7 @@ pub(super) fn type_param_predicates<'tcx>( let Some(hir_generics) = hir_node.generics() else { return result; }; + if let Node::Item(item) = hir_node && let ItemKind::Trait(..) = item.kind // Implied `Self: Trait` and supertrait bounds. @@ -805,18 +836,11 @@ pub(super) fn type_param_predicates<'tcx>( } let icx = ItemCtxt::new(tcx, item_def_id); - let extra_predicates = extend.into_iter().chain( - icx.probe_ty_param_bounds_in_generics( - hir_generics, - def_id, - PredicateFilter::SelfThatDefines(assoc_name), - ) - .into_iter() - .filter(|(predicate, _)| match predicate.kind().skip_binder() { - ty::ClauseKind::Trait(data) => data.self_ty().is_param(index), - _ => false, - }), - ); + let extra_predicates = extend.into_iter().chain(icx.probe_ty_param_bounds_in_generics( + hir_generics, + def_id, + PredicateFilter::SelfTraitThatDefines(assoc_name), + )); ty::EarlyBinder::bind( tcx.arena.alloc_from_iter(result.skip_binder().iter().copied().chain(extra_predicates)), @@ -851,7 +875,7 @@ impl<'tcx> ItemCtxt<'tcx> { // Ok } PredicateFilter::SelfOnly - | PredicateFilter::SelfThatDefines(_) + | PredicateFilter::SelfTraitThatDefines(_) | PredicateFilter::SelfConstIfConst | PredicateFilter::SelfAndAssociatedTypeBounds => continue, PredicateFilter::ConstIfConst => unreachable!(), diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs index a5709089db68..425d72603ad5 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs @@ -152,9 +152,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { 'tcx: 'hir, { for hir_bound in hir_bounds { - // In order to avoid cycles, when we're lowering `SelfThatDefines`, + // In order to avoid cycles, when we're lowering `SelfTraitThatDefines`, // we skip over any traits that don't define the given associated type. - if let PredicateFilter::SelfThatDefines(assoc_name) = predicate_filter { + if let PredicateFilter::SelfTraitThatDefines(assoc_name) = predicate_filter { if let Some(trait_ref) = hir_bound.trait_ref() && let Some(trait_did) = trait_ref.trait_def_id() && self.tcx().trait_may_define_assoc_item(trait_did, assoc_name) @@ -395,7 +395,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { match predicate_filter { PredicateFilter::All | PredicateFilter::SelfOnly - | PredicateFilter::SelfThatDefines(_) | PredicateFilter::SelfAndAssociatedTypeBounds => { bounds.push_projection_bound( tcx, @@ -406,6 +405,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { constraint.span, ); } + // SelfTraitThatDefines is only interested in trait predicates. + PredicateFilter::SelfTraitThatDefines(_) => {} // `ConstIfConst` is only interested in `~const` bounds. PredicateFilter::ConstIfConst | PredicateFilter::SelfConstIfConst => {} } @@ -432,7 +433,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { ); } PredicateFilter::SelfOnly - | PredicateFilter::SelfThatDefines(_) + | PredicateFilter::SelfTraitThatDefines(_) | PredicateFilter::SelfConstIfConst => {} } } diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index 2bd8a5223aa3..7ce078b0b99e 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -75,7 +75,7 @@ pub enum PredicateFilter { /// Only traits that reference `Self: ..` and define an associated type /// with the given ident are implied by the trait. This mode exists to /// side-step query cycles when lowering associated types. - SelfThatDefines(Ident), + SelfTraitThatDefines(Ident), /// Only traits that reference `Self: ..` and their associated type bounds. /// For example, given `Self: Tr`, this would expand to `Self: Tr` @@ -708,9 +708,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { ); match predicate_filter { + // This is only concerned with trait predicates. + PredicateFilter::SelfTraitThatDefines(..) => { + bounds.push_trait_bound(tcx, poly_trait_ref, span, polarity); + } PredicateFilter::All | PredicateFilter::SelfOnly - | PredicateFilter::SelfThatDefines(..) | PredicateFilter::SelfAndAssociatedTypeBounds => { debug!(?poly_trait_ref); bounds.push_trait_bound(tcx, poly_trait_ref, span, polarity);