22
33use std:: ops:: ControlFlow ;
44
5- use chalk_ir:: {
6- DebruijnIndex ,
7- visit:: { TypeSuperVisitable , TypeVisitable , TypeVisitor } ,
8- } ;
9- use chalk_solve:: rust_ir:: InlineBound ;
5+ use chalk_ir:: DebruijnIndex ;
106use hir_def:: {
117 AssocItemId , ConstId , CrateRootModuleId , FunctionId , GenericDefId , HasModule , TraitId ,
128 TypeAliasId , lang_item:: LangItem , signatures:: TraitFlags ,
@@ -21,14 +17,14 @@ use rustc_type_ir::{
2117use smallvec:: SmallVec ;
2218
2319use crate :: {
24- AliasEq , AliasTy , Binders , BoundVar , ImplTraitId , Interner , ProjectionTyExt , Ty , TyKind ,
25- WhereClause , all_super_traits,
20+ ImplTraitId , Interner , TyKind , WhereClause , all_super_traits,
2621 db:: { HirDatabase , InternedOpaqueTyId } ,
27- from_assoc_type_id , from_chalk_trait_id,
22+ from_chalk_trait_id,
2823 generics:: trait_self_param_idx,
24+ lower_nextsolver:: associated_ty_item_bounds,
2925 next_solver:: {
30- Clauses , DbInterner , GenericArgs , ParamEnv , SolverDefId , TraitPredicate , TypingMode ,
31- infer:: DbInternerInferExt , mk_param,
26+ Clause , Clauses , DbInterner , GenericArgs , ParamEnv , SolverDefId , TraitPredicate ,
27+ TypingMode , infer:: DbInternerInferExt , mk_param,
3228 } ,
3329 traits:: next_trait_solve_in_ctxt,
3430 utils:: elaborate_clause_supertraits,
@@ -165,7 +161,7 @@ pub fn generics_require_sized_self(db: &dyn HirDatabase, def: GenericDefId) -> b
165161// but we don't have good way to render such locations.
166162// So, just return single boolean value for existence of such `Self` reference
167163fn predicates_reference_self ( db : & dyn HirDatabase , trait_ : TraitId ) -> bool {
168- db. generic_predicates ( trait_. into ( ) )
164+ db. generic_predicates_ns ( trait_. into ( ) )
169165 . iter ( )
170166 . any ( |pred| predicate_references_self ( db, trait_, pred, AllowSelfProjection :: No ) )
171167}
@@ -177,37 +173,18 @@ fn bounds_reference_self(db: &dyn HirDatabase, trait_: TraitId) -> bool {
177173 . items
178174 . iter ( )
179175 . filter_map ( |( _, it) | match * it {
180- AssocItemId :: TypeAliasId ( id) => {
181- let assoc_ty_data = db. associated_ty_data ( id) ;
182- Some ( assoc_ty_data)
183- }
176+ AssocItemId :: TypeAliasId ( id) => Some ( associated_ty_item_bounds ( db, id) ) ,
184177 _ => None ,
185178 } )
186- . any ( |assoc_ty_data| {
187- assoc_ty_data. binders . skip_binders ( ) . bounds . iter ( ) . any ( |bound| {
188- let def = from_assoc_type_id ( assoc_ty_data. id ) . into ( ) ;
189- match bound. skip_binders ( ) {
190- InlineBound :: TraitBound ( it) => it. args_no_self . iter ( ) . any ( |arg| {
191- contains_illegal_self_type_reference (
192- db,
193- def,
194- trait_,
195- arg,
196- DebruijnIndex :: ONE ,
197- AllowSelfProjection :: Yes ,
198- )
199- } ) ,
200- InlineBound :: AliasEqBound ( it) => it. parameters . iter ( ) . any ( |arg| {
201- contains_illegal_self_type_reference (
202- db,
203- def,
204- trait_,
205- arg,
206- DebruijnIndex :: ONE ,
207- AllowSelfProjection :: Yes ,
208- )
209- } ) ,
210- }
179+ . any ( |bounds| {
180+ bounds. skip_binder ( ) . iter ( ) . any ( |pred| match pred. skip_binder ( ) {
181+ rustc_type_ir:: ExistentialPredicate :: Trait ( it) => it. args . iter ( ) . any ( |arg| {
182+ contains_illegal_self_type_reference ( db, trait_, & arg, AllowSelfProjection :: Yes )
183+ } ) ,
184+ rustc_type_ir:: ExistentialPredicate :: Projection ( it) => it. args . iter ( ) . any ( |arg| {
185+ contains_illegal_self_type_reference ( db, trait_, & arg, AllowSelfProjection :: Yes )
186+ } ) ,
187+ rustc_type_ir:: ExistentialPredicate :: AutoTrait ( _) => false ,
211188 } )
212189 } )
213190}
@@ -218,120 +195,26 @@ enum AllowSelfProjection {
218195 No ,
219196}
220197
221- fn predicate_references_self (
222- db : & dyn HirDatabase ,
198+ fn predicate_references_self < ' db > (
199+ db : & ' db dyn HirDatabase ,
223200 trait_ : TraitId ,
224- predicate : & Binders < Binders < WhereClause > > ,
201+ predicate : & Clause < ' db > ,
225202 allow_self_projection : AllowSelfProjection ,
226203) -> bool {
227- match predicate. skip_binders ( ) . skip_binders ( ) {
228- WhereClause :: Implemented ( trait_ref) => {
229- trait_ref. substitution . iter ( Interner ) . skip ( 1 ) . any ( |arg| {
230- contains_illegal_self_type_reference (
231- db,
232- trait_. into ( ) ,
233- trait_,
234- arg,
235- DebruijnIndex :: ONE ,
236- allow_self_projection,
237- )
238- } )
239- }
240- WhereClause :: AliasEq ( AliasEq { alias : AliasTy :: Projection ( proj) , .. } ) => {
241- proj. substitution . iter ( Interner ) . skip ( 1 ) . any ( |arg| {
242- contains_illegal_self_type_reference (
243- db,
244- trait_. into ( ) ,
245- trait_,
246- arg,
247- DebruijnIndex :: ONE ,
248- allow_self_projection,
249- )
204+ match predicate. kind ( ) . skip_binder ( ) {
205+ ClauseKind :: Trait ( trait_pred) => trait_pred. trait_ref . args . iter ( ) . skip ( 1 ) . any ( |arg| {
206+ contains_illegal_self_type_reference ( db, trait_, & arg, allow_self_projection)
207+ } ) ,
208+ ClauseKind :: Projection ( proj_pred) => {
209+ proj_pred. projection_term . args . iter ( ) . skip ( 1 ) . any ( |arg| {
210+ contains_illegal_self_type_reference ( db, trait_, & arg, allow_self_projection)
250211 } )
251212 }
252213 _ => false ,
253214 }
254215}
255216
256- fn contains_illegal_self_type_reference < T : TypeVisitable < Interner > > (
257- db : & dyn HirDatabase ,
258- def : GenericDefId ,
259- trait_ : TraitId ,
260- t : & T ,
261- outer_binder : DebruijnIndex ,
262- allow_self_projection : AllowSelfProjection ,
263- ) -> bool {
264- let Some ( trait_self_param_idx) = trait_self_param_idx ( db, def) else {
265- return false ;
266- } ;
267- struct IllegalSelfTypeVisitor < ' a > {
268- db : & ' a dyn HirDatabase ,
269- trait_ : TraitId ,
270- super_traits : Option < SmallVec < [ TraitId ; 4 ] > > ,
271- trait_self_param_idx : usize ,
272- allow_self_projection : AllowSelfProjection ,
273- }
274- impl TypeVisitor < Interner > for IllegalSelfTypeVisitor < ' _ > {
275- type BreakTy = ( ) ;
276-
277- fn as_dyn ( & mut self ) -> & mut dyn TypeVisitor < Interner , BreakTy = Self :: BreakTy > {
278- self
279- }
280-
281- fn interner ( & self ) -> Interner {
282- Interner
283- }
284-
285- fn visit_ty ( & mut self , ty : & Ty , outer_binder : DebruijnIndex ) -> ControlFlow < Self :: BreakTy > {
286- match ty. kind ( Interner ) {
287- TyKind :: BoundVar ( BoundVar { debruijn, index } ) => {
288- if * debruijn == outer_binder && * index == self . trait_self_param_idx {
289- ControlFlow :: Break ( ( ) )
290- } else {
291- ty. super_visit_with ( self . as_dyn ( ) , outer_binder)
292- }
293- }
294- TyKind :: Alias ( AliasTy :: Projection ( proj) ) => match self . allow_self_projection {
295- AllowSelfProjection :: Yes => {
296- let trait_ = proj. trait_ ( self . db ) ;
297- if self . super_traits . is_none ( ) {
298- self . super_traits = Some ( all_super_traits ( self . db , self . trait_ ) ) ;
299- }
300- if self . super_traits . as_ref ( ) . is_some_and ( |s| s. contains ( & trait_) ) {
301- ControlFlow :: Continue ( ( ) )
302- } else {
303- ty. super_visit_with ( self . as_dyn ( ) , outer_binder)
304- }
305- }
306- AllowSelfProjection :: No => ty. super_visit_with ( self . as_dyn ( ) , outer_binder) ,
307- } ,
308- _ => ty. super_visit_with ( self . as_dyn ( ) , outer_binder) ,
309- }
310- }
311-
312- fn visit_const (
313- & mut self ,
314- constant : & chalk_ir:: Const < Interner > ,
315- outer_binder : DebruijnIndex ,
316- ) -> std:: ops:: ControlFlow < Self :: BreakTy > {
317- constant. data ( Interner ) . ty . super_visit_with ( self . as_dyn ( ) , outer_binder)
318- }
319- }
320-
321- let mut visitor = IllegalSelfTypeVisitor {
322- db,
323- trait_,
324- super_traits : None ,
325- trait_self_param_idx,
326- allow_self_projection,
327- } ;
328- t. visit_with ( visitor. as_dyn ( ) , outer_binder) . is_break ( )
329- }
330-
331- fn contains_illegal_self_type_reference_ns <
332- ' db ,
333- T : rustc_type_ir:: TypeVisitable < DbInterner < ' db > > ,
334- > (
217+ fn contains_illegal_self_type_reference < ' db , T : rustc_type_ir:: TypeVisitable < DbInterner < ' db > > > (
335218 db : & ' db dyn HirDatabase ,
336219 trait_ : TraitId ,
337220 t : & T ,
@@ -440,13 +323,17 @@ where
440323 }
441324
442325 let sig = db. callable_item_signature_ns ( func. into ( ) ) ;
443- if sig. skip_binder ( ) . inputs ( ) . iter ( ) . skip ( 1 ) . any ( |ty| {
444- contains_illegal_self_type_reference_ns ( db, trait_, & ty, AllowSelfProjection :: Yes )
445- } ) {
326+ if sig
327+ . skip_binder ( )
328+ . inputs ( )
329+ . iter ( )
330+ . skip ( 1 )
331+ . any ( |ty| contains_illegal_self_type_reference ( db, trait_, & ty, AllowSelfProjection :: Yes ) )
332+ {
446333 cb ( MethodViolationCode :: ReferencesSelfInput ) ?;
447334 }
448335
449- if contains_illegal_self_type_reference_ns (
336+ if contains_illegal_self_type_reference (
450337 db,
451338 trait_,
452339 & sig. skip_binder ( ) . output ( ) ,
@@ -496,7 +383,7 @@ where
496383 continue ;
497384 }
498385
499- if contains_illegal_self_type_reference_ns ( db, trait_, & pred, AllowSelfProjection :: Yes ) {
386+ if contains_illegal_self_type_reference ( db, trait_, & pred, AllowSelfProjection :: Yes ) {
500387 cb ( MethodViolationCode :: WhereClauseReferencesSelf ) ?;
501388 break ;
502389 }
0 commit comments