From 9835e2ae736235810b4ea1c162ca5e65c547e770 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 18 May 2024 04:49:50 +0200 Subject: Merging upstream version 1.71.1+dfsg1. Signed-off-by: Daniel Baumann --- .../src/collect/predicates_of.rs | 131 ++++++++++----------- 1 file changed, 64 insertions(+), 67 deletions(-) (limited to 'compiler/rustc_hir_analysis/src/collect/predicates_of.rs') diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index 9358ed612..e5b5dae55 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -1,4 +1,4 @@ -use crate::astconv::AstConv; +use crate::astconv::{AstConv, OnlySelfBounds}; use crate::bounds::Bounds; use crate::collect::ItemCtxt; use crate::constrained_generic_params as cgp; @@ -14,9 +14,6 @@ use rustc_middle::ty::{GenericPredicates, ToPredicate}; use rustc_span::symbol::{sym, Ident}; use rustc_span::{Span, DUMMY_SP}; -#[derive(Debug)] -struct OnlySelfBounds(bool); - /// Returns a list of all type predicates (explicit and implicit) for the definition with /// ID `def_id`. This includes all predicates returned by `predicates_defined_on`, plus /// `Self: Trait` predicates for traits. @@ -99,8 +96,9 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen | ItemKind::Struct(_, generics) | ItemKind::Union(_, generics) => generics, - ItemKind::Trait(_, _, generics, ..) | ItemKind::TraitAlias(generics, _) => { - is_trait = Some(ty::TraitRef::identity(tcx, def_id.to_def_id())); + ItemKind::Trait(_, _, generics, self_bounds, ..) + | ItemKind::TraitAlias(generics, self_bounds) => { + is_trait = Some(self_bounds); generics } ItemKind::OpaqueTy(OpaqueTy { generics, .. }) => generics, @@ -122,10 +120,14 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen // Below we'll consider the bounds on the type parameters (including `Self`) // and the explicit where-clauses, but to get the full set of predicates - // 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.implied_predicates_of(def_id).predicates.iter().cloned()); + // on a trait we must also consider the bounds that follow the trait's name, + // like `trait Foo: A + B + C`. + if let Some(self_bounds) = is_trait { + predicates.extend( + icx.astconv() + .compute_bounds(tcx.types.self_param, self_bounds, OnlySelfBounds(false)) + .predicates(), + ); } // In default impls, we can assume that the self type implements @@ -225,7 +227,13 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen } let mut bounds = Bounds::default(); - icx.astconv().add_bounds(ty, bound_pred.bounds.iter(), &mut bounds, bound_vars); + icx.astconv().add_bounds( + ty, + bound_pred.bounds.iter(), + &mut bounds, + bound_vars, + OnlySelfBounds(false), + ); predicates.extend(bounds.predicates()); } @@ -419,6 +427,8 @@ pub(super) fn explicit_predicates_of<'tcx>( // supertrait). if let ty::Alias(ty::Projection, projection) = ty.kind() { projection.substs == trait_identity_substs + // FIXME(return_type_notation): This check should be more robust + && !tcx.is_impl_trait_in_trait(projection.def_id) && tcx.associated_item(projection.def_id).container_id(tcx) == def_id.to_def_id() } else { @@ -557,7 +567,7 @@ pub(super) fn super_predicates_of( implied_predicates_with_filter(tcx, trait_def_id.to_def_id(), PredicateFilter::SelfOnly) } -pub(super) fn super_predicates_that_define_assoc_type( +pub(super) fn super_predicates_that_define_assoc_item( tcx: TyCtxt<'_>, (trait_def_id, assoc_name): (DefId, Ident), ) -> ty::GenericPredicates<'_> { @@ -608,7 +618,7 @@ pub(super) fn implied_predicates_with_filter( 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), + icx.astconv().compute_bounds(self_param_ty, bounds, OnlySelfBounds(false)), // Also include all where clause bounds icx.type_parameter_bounds_in_generics( generics, @@ -620,7 +630,7 @@ pub(super) fn implied_predicates_with_filter( ), PredicateFilter::SelfOnly => ( // Convert the bounds that follow the colon (or equal in trait aliases) - icx.astconv().compute_bounds(self_param_ty, bounds), + icx.astconv().compute_bounds(self_param_ty, bounds, OnlySelfBounds(true)), // Include where clause bounds for `Self` icx.type_parameter_bounds_in_generics( generics, @@ -632,7 +642,7 @@ pub(super) fn implied_predicates_with_filter( ), 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), + icx.astconv().compute_bounds_that_match_assoc_item(self_param_ty, bounds, assoc_name), // Include where clause bounds for `Self` that reference the associated name icx.type_parameter_bounds_in_generics( generics, @@ -645,19 +655,19 @@ pub(super) fn implied_predicates_with_filter( }; // 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)); + let implied_bounds = + &*tcx.arena.alloc_from_iter(superbounds.predicates().chain(where_bounds_that_match)); debug!(?implied_bounds); - // Now require that immediate supertraits are converted, - // which will, in turn, reach indirect supertraits. + // Now require that immediate supertraits are converted, which will, in + // turn, reach indirect supertraits, so we detect cycles now instead of + // overflowing during elaboration. if matches!(filter, PredicateFilter::SelfOnly) { - // Now require that immediate supertraits are converted, - // which will, in turn, reach indirect supertraits. for &(pred, span) in implied_bounds { debug!("superbound: {:?}", pred); - if let ty::PredicateKind::Clause(ty::Clause::Trait(bound)) = pred.kind().skip_binder() { + if let ty::PredicateKind::Clause(ty::Clause::Trait(bound)) = pred.kind().skip_binder() + && bound.polarity == ty::ImplPolarity::Positive + { tcx.at(span).super_predicates_of(bound.def_id()); } } @@ -713,7 +723,7 @@ pub(super) fn type_param_predicates( | ItemKind::TyAlias(_, generics) | ItemKind::OpaqueTy(OpaqueTy { generics, - origin: hir::OpaqueTyOrigin::TyAlias, + origin: hir::OpaqueTyOrigin::TyAlias { .. }, .. }) | ItemKind::Enum(_, generics) @@ -775,32 +785,35 @@ impl<'tcx> ItemCtxt<'tcx> { only_self_bounds: OnlySelfBounds, assoc_name: Option, ) -> Vec<(ty::Predicate<'tcx>, Span)> { - ast_generics - .predicates - .iter() - .filter_map(|wp| match wp { - hir::WherePredicate::BoundPredicate(bp) => Some(bp), - _ => None, - }) - .flat_map(|bp| { - let bt = if bp.is_param_bound(param_def_id.to_def_id()) { - Some(ty) - } else if !only_self_bounds.0 { - Some(self.to_ty(bp.bounded_ty)) - } else { - None - }; - let bvars = self.tcx.late_bound_vars(bp.hir_id); - - bp.bounds.iter().filter_map(move |b| bt.map(|bt| (bt, b, bvars))).filter( - |(_, b, _)| match assoc_name { - Some(assoc_name) => self.bound_defines_assoc_item(b, assoc_name), - None => true, - }, - ) - }) - .flat_map(|(bt, b, bvars)| predicates_from_bound(self, bt, b, bvars)) - .collect() + let mut bounds = Bounds::default(); + + for predicate in ast_generics.predicates { + let hir::WherePredicate::BoundPredicate(predicate) = predicate else { + continue; + }; + + let bound_ty = if predicate.is_param_bound(param_def_id.to_def_id()) { + ty + } else if !only_self_bounds.0 { + self.to_ty(predicate.bounded_ty) + } else { + continue; + }; + + let bound_vars = self.tcx.late_bound_vars(predicate.hir_id); + self.astconv().add_bounds( + bound_ty, + predicate.bounds.iter().filter(|bound| { + assoc_name + .map_or(true, |assoc_name| self.bound_defines_assoc_item(bound, assoc_name)) + }), + &mut bounds, + bound_vars, + only_self_bounds, + ); + } + + bounds.predicates().collect() } #[instrument(level = "trace", skip(self))] @@ -809,7 +822,7 @@ impl<'tcx> ItemCtxt<'tcx> { hir::GenericBound::Trait(poly_trait_ref, _) => { let trait_ref = &poly_trait_ref.trait_ref; if let Some(trait_did) = trait_ref.trait_def_id() { - self.tcx.trait_may_define_assoc_type(trait_did, assoc_name) + self.tcx.trait_may_define_assoc_item(trait_did, assoc_name) } else { false } @@ -818,19 +831,3 @@ impl<'tcx> ItemCtxt<'tcx> { } } } - -/// Converts a specific `GenericBound` from the AST into a set of -/// predicates that apply to the self type. A vector is returned -/// because this can be anywhere from zero predicates (`T: ?Sized` adds no -/// predicates) to one (`T: Foo`) to many (`T: Bar` adds `T: Bar` -/// and `::X == i32`). -fn predicates_from_bound<'tcx>( - astconv: &dyn AstConv<'tcx>, - param_ty: Ty<'tcx>, - bound: &'tcx hir::GenericBound<'tcx>, - bound_vars: &'tcx ty::List, -) -> Vec<(ty::Predicate<'tcx>, Span)> { - let mut bounds = Bounds::default(); - astconv.add_bounds(param_ty, [bound].into_iter(), &mut bounds, bound_vars); - bounds.predicates().collect() -} -- cgit v1.2.3