Unnamed repository; edit this file 'description' to name the repository.
| -rw-r--r-- | crates/hir-ty/src/builtin_derive.rs | 15 | ||||
| -rw-r--r-- | crates/hir-ty/src/display.rs | 4 | ||||
| -rw-r--r-- | crates/hir-ty/src/dyn_compatibility.rs | 10 | ||||
| -rw-r--r-- | crates/hir-ty/src/infer/expr.rs | 2 | ||||
| -rw-r--r-- | crates/hir-ty/src/infer/path.rs | 2 | ||||
| -rw-r--r-- | crates/hir-ty/src/lower.rs | 103 | ||||
| -rw-r--r-- | crates/hir-ty/src/method_resolution.rs | 2 | ||||
| -rw-r--r-- | crates/hir-ty/src/method_resolution/confirm.rs | 4 | ||||
| -rw-r--r-- | crates/hir-ty/src/method_resolution/probe.rs | 2 | ||||
| -rw-r--r-- | crates/hir-ty/src/next_solver/interner.rs | 92 | ||||
| -rw-r--r-- | crates/hir-ty/src/next_solver/ty.rs | 2 | ||||
| -rw-r--r-- | crates/hir-ty/src/specialization.rs | 2 | ||||
| -rw-r--r-- | crates/hir-ty/src/tests/regression.rs | 15 | ||||
| -rw-r--r-- | crates/hir/src/display.rs | 4 | ||||
| -rw-r--r-- | crates/hir/src/lib.rs | 2 |
15 files changed, 134 insertions, 127 deletions
diff --git a/crates/hir-ty/src/builtin_derive.rs b/crates/hir-ty/src/builtin_derive.rs index 92629b7a05..eb3922f4b6 100644 --- a/crates/hir-ty/src/builtin_derive.rs +++ b/crates/hir-ty/src/builtin_derive.rs @@ -174,8 +174,11 @@ pub fn predicates<'db>(db: &'db dyn HirDatabase, impl_: BuiltinDeriveImplId) -> if matches!(loc.adt, AdtId::EnumId(_)) { // Enums don't have extra bounds. GenericPredicates::from_explicit_own_predicates(StoredEarlyBinder::bind( - Clauses::new_from_slice(adt_predicates.explicit_predicates().skip_binder()) - .store(), + Clauses::new_from_iter( + interner, + adt_predicates.own_explicit_predicates().skip_binder(), + ) + .store(), )) } else { simple_trait_predicates(interner, loc, generic_params, adt_predicates, trait_id) @@ -191,7 +194,7 @@ pub fn predicates<'db>(db: &'db dyn HirDatabase, impl_: BuiltinDeriveImplId) -> )); }; let duplicated_bounds = - adt_predicates.explicit_predicates().iter_identity_copied().filter_map(|pred| { + adt_predicates.explicit_predicates().iter_identity().filter_map(|pred| { let mentions_pointee = pred.visit_with(&mut MentionsPointee { pointee_param_idx }).is_break(); if !mentions_pointee { @@ -212,7 +215,7 @@ pub fn predicates<'db>(db: &'db dyn HirDatabase, impl_: BuiltinDeriveImplId) -> interner, adt_predicates .explicit_predicates() - .iter_identity_copied() + .iter_identity() .chain(duplicated_bounds) .chain(unsize_bound), ) @@ -313,7 +316,7 @@ fn simple_trait_predicates<'db>( interner, adt_predicates .explicit_predicates() - .iter_identity_copied() + .iter_identity() .chain(extra_predicates) .chain(assoc_type_bounds), ) @@ -440,7 +443,7 @@ mod tests { format_to!( predicates, "{}\n\n", - preds.iter().format_with("\n", |pred, formatter| formatter(&format_args!( + preds.format_with("\n", |pred, formatter| formatter(&format_args!( "{pred:?}" ))), ); diff --git a/crates/hir-ty/src/display.rs b/crates/hir-ty/src/display.rs index d680588645..0c4e34db7d 100644 --- a/crates/hir-ty/src/display.rs +++ b/crates/hir-ty/src/display.rs @@ -640,7 +640,7 @@ fn write_projection<'db>( // FIXME: We shouldn't use `param.id`, it should be removed. We should know the // `GenericDefId` from the formatted type (store it inside the `HirFormatter`). let bounds = GenericPredicates::query_all(f.db, param.id.parent()) - .iter_identity_copied() + .iter_identity() .filter(|wc| { let ty = match wc.kind().skip_binder() { ClauseKind::Trait(tr) => tr.self_ty(), @@ -1466,7 +1466,7 @@ impl<'db> HirDisplay<'db> for Ty<'db> { } TypeParamProvenance::ArgumentImplTrait => { let bounds = GenericPredicates::query_all(f.db, param.id.parent()) - .iter_identity_copied() + .iter_identity() .filter(|wc| match wc.kind().skip_binder() { ClauseKind::Trait(tr) => tr.self_ty() == *self, ClauseKind::Projection(proj) => proj.self_ty() == *self, diff --git a/crates/hir-ty/src/dyn_compatibility.rs b/crates/hir-ty/src/dyn_compatibility.rs index 4c300affd8..e70918f8e1 100644 --- a/crates/hir-ty/src/dyn_compatibility.rs +++ b/crates/hir-ty/src/dyn_compatibility.rs @@ -141,7 +141,7 @@ pub fn generics_require_sized_self(db: &dyn HirDatabase, def: GenericDefId) -> b // FIXME: We should use `explicit_predicates_of` here, which hasn't been implemented to // rust-analyzer yet // https://github.com/rust-lang/rust/blob/ddaf12390d3ffb7d5ba74491a48f3cd528e5d777/compiler/rustc_hir_analysis/src/collect/predicates_of.rs#L490 - elaborate::elaborate(interner, predicates.iter_identity_copied()).any(|pred| { + elaborate::elaborate(interner, predicates.iter_identity()).any(|pred| { match pred.kind().skip_binder() { ClauseKind::Trait(trait_pred) => { if sized == trait_pred.def_id().0 @@ -164,7 +164,7 @@ pub fn generics_require_sized_self(db: &dyn HirDatabase, def: GenericDefId) -> b // So, just return single boolean value for existence of such `Self` reference fn predicates_reference_self(db: &dyn HirDatabase, trait_: TraitId) -> bool { GenericPredicates::query_explicit(db, trait_.into()) - .iter_identity_copied() + .iter_identity() .any(|pred| predicate_references_self(db, trait_, pred, AllowSelfProjection::No)) } @@ -360,8 +360,8 @@ where cb(MethodViolationCode::UndispatchableReceiver)?; } - let predicates = GenericPredicates::query_own(db, func.into()); - for pred in predicates.iter_identity_copied() { + let predicates = GenericPredicates::query_own_explicit(db, func.into()); + for pred in predicates.iter_identity() { let pred = pred.kind().skip_binder(); if matches!(pred, ClauseKind::TypeOutlives(_)) { @@ -459,7 +459,7 @@ fn receiver_is_dispatchable<'db>( clauses: Clauses::new_from_iter( interner, generic_predicates - .iter_identity_copied() + .iter_identity() .chain([unsize_predicate.upcast(interner), trait_predicate.upcast(interner)]) .chain(meta_sized_predicate), ), diff --git a/crates/hir-ty/src/infer/expr.rs b/crates/hir-ty/src/infer/expr.rs index dc57b1d1c2..ee34a30eba 100644 --- a/crates/hir-ty/src/infer/expr.rs +++ b/crates/hir-ty/src/infer/expr.rs @@ -2158,7 +2158,7 @@ impl<'db> InferenceContext<'_, 'db> { ); let param_env = self.table.param_env; self.table.register_predicates(clauses_as_obligations( - generic_predicates.iter_instantiated_copied(self.interner(), parameters.as_slice()), + generic_predicates.iter_instantiated(self.interner(), parameters.as_slice()), ObligationCause::new(), param_env, )); diff --git a/crates/hir-ty/src/infer/path.rs b/crates/hir-ty/src/infer/path.rs index 71d68ccd47..3cadc8e933 100644 --- a/crates/hir-ty/src/infer/path.rs +++ b/crates/hir-ty/src/infer/path.rs @@ -228,7 +228,7 @@ impl<'db> InferenceContext<'_, 'db> { let predicates = GenericPredicates::query_all(self.db, def); let param_env = self.table.param_env; self.table.register_predicates(clauses_as_obligations( - predicates.iter_instantiated_copied(interner, subst.as_slice()), + predicates.iter_instantiated(interner, subst.as_slice()), ObligationCause::new(), param_env, )); diff --git a/crates/hir-ty/src/lower.rs b/crates/hir-ty/src/lower.rs index 7259099107..71a7db6559 100644 --- a/crates/hir-ty/src/lower.rs +++ b/crates/hir-ty/src/lower.rs @@ -2016,17 +2016,21 @@ fn type_alias_bounds_with_diagnostics<'db>( #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct GenericPredicates { - // The order is the following: first, if `parent_is_trait == true`, comes the implicit trait - // predicate for the parent. Then come the bounds of the associated types of the parents, - // then the explicit, self-only predicates for the parent, then the explicit, self-only trait - // predicate for the child, then the bounds of the associated types of the child, - // then the implicit trait predicate for the child, if `is_trait` is `true`. + // The order is the following: + // + // 1. If `has_trait_implied_predicate == true`, the implicit trait predicate. + // 2. The bounds of the associated types of the parents, coming from `Trait<Assoc: Trait>`. + // Note: associated type bounds from `Self::Assoc: Trait` on traits *won't* be included + // here, they are in 3. + // 3. The explicit, self-only predicates for the parent. + // 4. The explicit, self-only trait predicate for the child, + // 5. The bounds of the associated types of the child. predicates: StoredEarlyBinder<StoredClauses>, + // Keep this ordered according to the above. + has_trait_implied_predicate: bool, parent_explicit_self_predicates_start: u32, own_predicates_start: u32, own_assoc_ty_bounds_start: u32, - is_trait: bool, - parent_is_trait: bool, } #[salsa::tracked] @@ -2065,11 +2069,10 @@ impl GenericPredicates { let len = predicates.get().skip_binder().len() as u32; Self { predicates, + has_trait_implied_predicate: false, parent_explicit_self_predicates_start: 0, own_predicates_start: 0, own_assoc_ty_bounds_start: len, - is_trait: false, - parent_is_trait: false, } } @@ -2082,58 +2085,68 @@ impl GenericPredicates { pub fn query_all<'db>( db: &'db dyn HirDatabase, def: GenericDefId, - ) -> EarlyBinder<'db, &'db [Clause<'db>]> { + ) -> EarlyBinder<'db, impl Iterator<Item = Clause<'db>>> { Self::query(db, def).all_predicates() } #[inline] - pub fn query_own<'db>( + pub fn query_own_explicit<'db>( db: &'db dyn HirDatabase, def: GenericDefId, - ) -> EarlyBinder<'db, &'db [Clause<'db>]> { - Self::query(db, def).own_predicates() + ) -> EarlyBinder<'db, impl Iterator<Item = Clause<'db>>> { + Self::query(db, def).own_explicit_predicates() } #[inline] pub fn query_explicit<'db>( db: &'db dyn HirDatabase, def: GenericDefId, - ) -> EarlyBinder<'db, &'db [Clause<'db>]> { + ) -> EarlyBinder<'db, impl Iterator<Item = Clause<'db>>> { Self::query(db, def).explicit_predicates() } #[inline] - pub fn query_explicit_implied<'db>( - db: &'db dyn HirDatabase, - def: GenericDefId, - ) -> EarlyBinder<'db, &'db [Clause<'db>]> { - Self::query(db, def).explicit_implied_predicates() + pub fn all_predicates(&self) -> EarlyBinder<'_, impl Iterator<Item = Clause<'_>>> { + self.predicates.get().map_bound(|it| it.as_slice().iter().copied()) } #[inline] - pub fn all_predicates(&self) -> EarlyBinder<'_, &[Clause<'_>]> { - self.predicates.get().map_bound(|it| it.as_slice()) + pub fn own_explicit_predicates(&self) -> EarlyBinder<'_, impl Iterator<Item = Clause<'_>>> { + self.predicates + .get() + .map_bound(|it| it.as_slice()[self.own_predicates_start as usize..].iter().copied()) } #[inline] - pub fn own_predicates(&self) -> EarlyBinder<'_, &[Clause<'_>]> { - self.predicates.get().map_bound(|it| &it.as_slice()[self.own_predicates_start as usize..]) + pub fn explicit_predicates(&self) -> EarlyBinder<'_, impl Iterator<Item = Clause<'_>>> { + self.predicates.get().map_bound(|it| { + it.as_slice()[usize::from(self.has_trait_implied_predicate)..].iter().copied() + }) } - /// Returns the predicates, minus the implicit `Self: Trait` predicate and bounds of the - /// associated types for a trait. #[inline] - pub fn explicit_predicates(&self) -> EarlyBinder<'_, &[Clause<'_>]> { + pub fn explicit_non_assoc_types_predicates( + &self, + ) -> EarlyBinder<'_, impl Iterator<Item = Clause<'_>>> { self.predicates.get().map_bound(|it| { - &it.as_slice()[self.parent_explicit_self_predicates_start as usize + it.as_slice()[self.parent_explicit_self_predicates_start as usize ..self.own_assoc_ty_bounds_start as usize] + .iter() + .copied() }) } #[inline] - pub fn explicit_implied_predicates(&self) -> EarlyBinder<'_, &[Clause<'_>]> { - self.predicates.get().map_bound(|it| { - &it.as_slice()[usize::from(self.parent_is_trait)..it.len() - usize::from(self.is_trait)] + pub fn explicit_assoc_types_predicates( + &self, + ) -> EarlyBinder<'_, impl Iterator<Item = Clause<'_>>> { + self.predicates.get().map_bound(|predicates| { + let predicates = predicates.as_slice(); + predicates[usize::from(self.has_trait_implied_predicate) + ..self.parent_explicit_self_predicates_start as usize] + .iter() + .copied() + .chain(predicates[self.own_assoc_ty_bounds_start as usize..].iter().copied()) }) } } @@ -2142,10 +2155,8 @@ pub(crate) fn param_env_from_predicates<'db>( interner: DbInterner<'db>, predicates: &'db GenericPredicates, ) -> ParamEnv<'db> { - let clauses = rustc_type_ir::elaborate::elaborate( - interner, - predicates.all_predicates().iter_identity_copied(), - ); + let clauses = + rustc_type_ir::elaborate::elaborate(interner, predicates.all_predicates().iter_identity()); let clauses = Clauses::new_from_iter(interner, clauses); // FIXME: We should normalize projections here, like rustc does. @@ -2290,42 +2301,28 @@ fn generic_predicates(db: &dyn HirDatabase, def: GenericDefId) -> (GenericPredic let diagnostics = create_diagnostics(ctx.diagnostics); - // The order is: - // - // 1. parent implicit trait pred - // 2. parent assoc bounds - // 3. parent self only preds - // 4. own self only preds - // 5. own assoc ty bounds - // 6. own implicit trait pred - // - // The purpose of this is to index the slice of the followings, without making extra `Vec`s or - // iterators: - // - explicit self only predicates, of own or own + self - // - explicit predicates, of own or own + self let predicates = parent_implicit_trait_predicate .iter() + .chain(own_implicit_trait_predicate.iter()) .chain(parent_assoc_ty_bounds.iter()) .chain(parent_predicates.iter()) .chain(own_predicates.iter()) .chain(own_assoc_ty_bounds.iter()) - .chain(own_implicit_trait_predicate.iter()) .copied() .collect::<Vec<_>>(); - let parent_is_trait = parent_implicit_trait_predicate.is_some(); - let is_trait = own_implicit_trait_predicate.is_some(); + let has_trait_implied_predicate = + parent_implicit_trait_predicate.is_some() || own_implicit_trait_predicate.is_some(); let parent_explicit_self_predicates_start = - parent_is_trait as u32 + parent_assoc_ty_bounds.len() as u32; + has_trait_implied_predicate as u32 + parent_assoc_ty_bounds.len() as u32; let own_predicates_start = parent_explicit_self_predicates_start + parent_predicates.len() as u32; let own_assoc_ty_bounds_start = own_predicates_start + own_predicates.len() as u32; let predicates = GenericPredicates { + has_trait_implied_predicate, parent_explicit_self_predicates_start, own_predicates_start, own_assoc_ty_bounds_start, - is_trait, - parent_is_trait, predicates: StoredEarlyBinder::bind(Clauses::new_from_slice(&predicates).store()), }; return (predicates, diagnostics); diff --git a/crates/hir-ty/src/method_resolution.rs b/crates/hir-ty/src/method_resolution.rs index 05b9ea5d74..b18e48c1fe 100644 --- a/crates/hir-ty/src/method_resolution.rs +++ b/crates/hir-ty/src/method_resolution.rs @@ -324,7 +324,7 @@ impl<'db> InferenceTable<'db> { // any late-bound regions appearing in its bounds. let bounds = GenericPredicates::query_all(self.db, method_item.into()); let bounds = clauses_as_obligations( - bounds.iter_instantiated_copied(interner, args.as_slice()), + bounds.iter_instantiated(interner, args.as_slice()), ObligationCause::new(), self.param_env, ); diff --git a/crates/hir-ty/src/method_resolution/confirm.rs b/crates/hir-ty/src/method_resolution/confirm.rs index ec589085a8..94c70c29f7 100644 --- a/crates/hir-ty/src/method_resolution/confirm.rs +++ b/crates/hir-ty/src/method_resolution/confirm.rs @@ -136,7 +136,7 @@ impl<'a, 'b, 'db> ConfirmContext<'a, 'b, 'db> { ); let illegal_sized_bound = self.predicates_require_illegal_sized_bound( GenericPredicates::query_all(self.db(), self.candidate.into()) - .iter_instantiated_copied(self.interner(), filler_args.as_slice()), + .iter_instantiated(self.interner(), filler_args.as_slice()), ); // Unify the (adjusted) self type with what the method expects. @@ -509,7 +509,7 @@ impl<'a, 'b, 'db> ConfirmContext<'a, 'b, 'db> { let def_id = self.candidate; let method_predicates = clauses_as_obligations( GenericPredicates::query_all(self.db(), def_id.into()) - .iter_instantiated_copied(self.interner(), all_args), + .iter_instantiated(self.interner(), all_args), ObligationCause::new(), self.ctx.table.param_env, ); diff --git a/crates/hir-ty/src/method_resolution/probe.rs b/crates/hir-ty/src/method_resolution/probe.rs index 8c76bfbc07..3604076ccd 100644 --- a/crates/hir-ty/src/method_resolution/probe.rs +++ b/crates/hir-ty/src/method_resolution/probe.rs @@ -1595,7 +1595,7 @@ impl<'a, 'db, Choice: ProbeChoice<'db>> ProbeContext<'a, 'db, Choice> { // Check whether the impl imposes obligations we have to worry about. let impl_bounds = GenericPredicates::query_all(self.db(), impl_def_id.into()); let impl_bounds = clauses_as_obligations( - impl_bounds.iter_instantiated_copied(self.interner(), impl_args.as_slice()), + impl_bounds.iter_instantiated(self.interner(), impl_args.as_slice()), ObligationCause::new(), self.param_env(), ); diff --git a/crates/hir-ty/src/next_solver/interner.rs b/crates/hir-ty/src/next_solver/interner.rs index 5b81c7675d..622648bc8d 100644 --- a/crates/hir-ty/src/next_solver/interner.rs +++ b/crates/hir-ty/src/next_solver/interner.rs @@ -1439,81 +1439,55 @@ impl<'db> Interner for DbInterner<'db> { } } - #[tracing::instrument(level = "debug", skip(self), ret)] fn predicates_of( self, def_id: Self::DefId, ) -> EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>> { - predicates_of(self.db, def_id).all_predicates().map_bound(|it| it.iter().copied()) + predicates_of(self.db, def_id).all_predicates() } - #[tracing::instrument(level = "debug", skip(self), ret)] fn own_predicates_of( self, def_id: Self::DefId, ) -> EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>> { - predicates_of(self.db, def_id).own_predicates().map_bound(|it| it.iter().copied()) + predicates_of(self.db, def_id).own_explicit_predicates() } - #[tracing::instrument(skip(self), ret)] fn explicit_super_predicates_of( self, def_id: Self::TraitId, ) -> EarlyBinder<Self, impl IntoIterator<Item = (Self::Clause, Self::Span)>> { - let is_self = |ty: Ty<'db>| match ty.kind() { - rustc_type_ir::TyKind::Param(param) => param.index == 0, - _ => false, - }; - - GenericPredicates::query_explicit(self.db, def_id.0.into()).map_bound(move |predicates| { - predicates - .iter() - .copied() - .filter(move |p| match p.kind().skip_binder() { - // rustc has the following assertion: - // https://github.com/rust-lang/rust/blob/52618eb338609df44978b0ca4451ab7941fd1c7a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs#L525-L608 - ClauseKind::Trait(it) => is_self(it.self_ty()), - ClauseKind::TypeOutlives(it) => is_self(it.0), - ClauseKind::Projection(it) => is_self(it.self_ty()), - ClauseKind::HostEffect(it) => is_self(it.self_ty()), - _ => false, - }) - .map(|p| (p, Span::dummy())) - }) + GenericPredicates::query(self.db, def_id.0.into()) + .explicit_non_assoc_types_predicates() + .map_bound(move |predicates| { + predicates.filter(|p| is_clause_at_ty(p, is_ty_self)).map(|p| (p, Span::dummy())) + }) } - #[tracing::instrument(skip(self), ret)] fn explicit_implied_predicates_of( self, def_id: Self::DefId, ) -> EarlyBinder<Self, impl IntoIterator<Item = (Self::Clause, Self::Span)>> { - fn is_self_or_assoc(ty: Ty<'_>) -> bool { - match ty.kind() { - rustc_type_ir::TyKind::Param(param) => param.index == 0, - rustc_type_ir::TyKind::Alias(rustc_type_ir::AliasTyKind::Projection, alias) => { - is_self_or_assoc(alias.self_ty()) - } - _ => false, + fn is_ty_assoc_of_self(ty: Ty<'_>) -> bool { + // FIXME: Is this correct wrt. combined kind of assoc type bounds, i.e. `where Self::Assoc: Trait<Assoc2: Trait>` + // wrt. `Assoc2`, which we should exclude? + if let TyKind::Alias(AliasTyKind::Projection, alias) = ty.kind() { + is_ty_assoc_of_self(alias.self_ty()) + } else { + is_ty_self(ty) } } - predicates_of(self.db, def_id).explicit_implied_predicates().map_bound(|predicates| { - predicates - .iter() - .copied() - .filter(|p| match p.kind().skip_binder() { - ClauseKind::Trait(it) => is_self_or_assoc(it.self_ty()), - ClauseKind::TypeOutlives(it) => is_self_or_assoc(it.0), - ClauseKind::Projection(it) => is_self_or_assoc(it.self_ty()), - ClauseKind::HostEffect(it) => is_self_or_assoc(it.self_ty()), - // FIXME: Not sure is this correct to allow other clauses but we might replace - // `generic_predicates_ns` query here with something closer to rustc's - // `implied_bounds_with_filter`, which is more granular lowering than this - // "lower at once and then filter" implementation. - _ => true, - }) - .map(|p| (p, Span::dummy())) - }) + let predicates = predicates_of(self.db, def_id); + let non_assoc_types = predicates + .explicit_non_assoc_types_predicates() + .skip_binder() + .filter(|p| is_clause_at_ty(p, is_ty_self)); + let assoc_types = predicates + .explicit_assoc_types_predicates() + .skip_binder() + .filter(|p| is_clause_at_ty(p, is_ty_assoc_of_self)); + EarlyBinder::bind(non_assoc_types.chain(assoc_types).map(|it| (it, Span::dummy()))) } fn impl_super_outlives( @@ -2294,6 +2268,24 @@ impl<'db> Interner for DbInterner<'db> { } } +fn is_ty_self(ty: Ty<'_>) -> bool { + match ty.kind() { + TyKind::Param(param) => param.index == 0, + _ => false, + } +} +fn is_clause_at_ty(p: &Clause<'_>, filter: impl FnOnce(Ty<'_>) -> bool) -> bool { + match p.kind().skip_binder() { + // rustc has the following assertion: + // https://github.com/rust-lang/rust/blob/52618eb338609df44978b0ca4451ab7941fd1c7a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs#L525-L608 + ClauseKind::Trait(it) => filter(it.self_ty()), + ClauseKind::TypeOutlives(it) => filter(it.0), + ClauseKind::Projection(it) => filter(it.self_ty()), + ClauseKind::HostEffect(it) => filter(it.self_ty()), + _ => false, + } +} + impl<'db> DbInterner<'db> { pub fn shift_bound_var_indices<T>(self, bound_vars: usize, value: T) -> T where diff --git a/crates/hir-ty/src/next_solver/ty.rs b/crates/hir-ty/src/next_solver/ty.rs index 192cdb70ae..8e892b65ea 100644 --- a/crates/hir-ty/src/next_solver/ty.rs +++ b/crates/hir-ty/src/next_solver/ty.rs @@ -696,7 +696,7 @@ impl<'db> Ty<'db> { TypeOrConstParamData::TypeParamData(p) => match p.provenance { TypeParamProvenance::ArgumentImplTrait => { let predicates = GenericPredicates::query_all(db, param.id.parent()) - .iter_identity_copied() + .iter_identity() .filter(|wc| match wc.kind().skip_binder() { ClauseKind::Trait(tr) => tr.self_ty() == self, ClauseKind::Projection(pred) => pred.self_ty() == self, diff --git a/crates/hir-ty/src/specialization.rs b/crates/hir-ty/src/specialization.rs index 90cbcfea6a..8bc6c51fae 100644 --- a/crates/hir-ty/src/specialization.rs +++ b/crates/hir-ty/src/specialization.rs @@ -109,7 +109,7 @@ fn specializes_query( // only be referenced via projection predicates. ocx.register_obligations(clauses_as_obligations( GenericPredicates::query_all(db, parent_impl_def_id.into()) - .iter_instantiated_copied(interner, parent_args.as_slice()), + .iter_instantiated(interner, parent_args.as_slice()), cause.clone(), param_env, )); diff --git a/crates/hir-ty/src/tests/regression.rs b/crates/hir-ty/src/tests/regression.rs index e4fc7e56c6..d3dfc44c22 100644 --- a/crates/hir-ty/src/tests/regression.rs +++ b/crates/hir-ty/src/tests/regression.rs @@ -2841,3 +2841,18 @@ fn wrapped_abs<T: SelfAbs<Output = T>>(v: T) -> T { "#, ); } + +#[test] +fn regression_21899() { + check_no_mismatches( + r#" +trait B where + Self::T: B, +{ + type T; +} + +fn foo<T: B>(v: T::T) {} + "#, + ); +} diff --git a/crates/hir/src/display.rs b/crates/hir/src/display.rs index 4bfdd239f9..53f24713cd 100644 --- a/crates/hir/src/display.rs +++ b/crates/hir/src/display.rs @@ -76,7 +76,7 @@ fn write_builtin_derive_impl_method<'db>( let predicates = hir_ty::builtin_derive::predicates(db, impl_).explicit_predicates().skip_binder(); - write_params_bounds(f, predicates)?; + write_params_bounds(f, &Vec::from_iter(predicates))?; } Ok(()) @@ -578,7 +578,7 @@ impl<'db> HirDisplay<'db> for TypeParam { let ty = self.ty(f.db).ty; let predicates = GenericPredicates::query_all(f.db, self.id.parent()); let predicates = predicates - .iter_identity_copied() + .iter_identity() .filter(|wc| match wc.kind().skip_binder() { ClauseKind::Trait(tr) => tr.self_ty() == ty, ClauseKind::Projection(proj) => proj.self_ty() == ty, diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index bc5e164830..eb5b3b37a6 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -4680,7 +4680,7 @@ impl TypeParam { pub fn trait_bounds(self, db: &dyn HirDatabase) -> Vec<Trait> { let self_ty = self.ty(db).ty; GenericPredicates::query_explicit(db, self.id.parent()) - .iter_identity_copied() + .iter_identity() .filter_map(|pred| match &pred.kind().skip_binder() { ClauseKind::Trait(trait_ref) if trait_ref.self_ty() == self_ty => { Some(Trait::from(trait_ref.def_id().0)) |