@@ -10,7 +10,7 @@ use std::sync::Arc;
10
10
11
11
use hir_def:: {
12
12
builtin_type:: BuiltinType ,
13
- generics:: { WherePredicateTarget , WherePredicate } ,
13
+ generics:: { WherePredicate , WherePredicateTarget } ,
14
14
path:: { GenericArg , Path , PathSegment , PathSegments } ,
15
15
resolver:: { HasResolver , Resolver , TypeNs } ,
16
16
type_ref:: { TypeBound , TypeRef } ,
@@ -27,8 +27,8 @@ use crate::{
27
27
all_super_traits, associated_type_by_name_including_super_traits, generics, make_mut_slice,
28
28
variant_data,
29
29
} ,
30
- FnSig , GenericPredicate , ProjectionPredicate , ProjectionTy , Substs , TraitEnvironment , TraitRef ,
31
- Ty , TypeCtor , PolyFnSig , Binders ,
30
+ Binders , FnSig , GenericPredicate , PolyFnSig , ProjectionPredicate , ProjectionTy , Substs ,
31
+ TraitEnvironment , TraitRef , Ty , TypeCtor ,
32
32
} ;
33
33
34
34
#[ derive( Debug ) ]
@@ -62,7 +62,7 @@ impl<'a, DB: HirDatabase> TyLoweringContext<'a, DB> {
62
62
}
63
63
}
64
64
65
- #[ derive( Copy , Clone , Debug ) ]
65
+ #[ derive( Copy , Clone , Debug , PartialEq , Eq ) ]
66
66
pub enum ImplTraitLoweringMode {
67
67
/// `impl Trait` gets lowered into an opaque type that doesn't unify with
68
68
/// anything except itself. This is used in places where values flow 'out',
@@ -78,7 +78,7 @@ pub enum ImplTraitLoweringMode {
78
78
Disallowed ,
79
79
}
80
80
81
- #[ derive( Copy , Clone , Debug ) ]
81
+ #[ derive( Copy , Clone , Debug , PartialEq , Eq ) ]
82
82
pub enum TypeParamLoweringMode {
83
83
Placeholder ,
84
84
Variable ,
@@ -140,12 +140,13 @@ impl Ty {
140
140
ImplTraitLoweringMode :: Variable => {
141
141
let idx = ctx. impl_trait_counter . get ( ) ;
142
142
ctx. impl_trait_counter . set ( idx + 1 ) ;
143
- let ( self_params, list_params, _impl_trait_params) = if let Some ( def) = ctx. resolver . generic_def ( ) {
144
- let generics = generics ( ctx. db , def) ;
145
- generics. provenance_split ( )
146
- } else {
147
- ( 0 , 0 , 0 )
148
- } ;
143
+ let ( self_params, list_params, _impl_trait_params) =
144
+ if let Some ( def) = ctx. resolver . generic_def ( ) {
145
+ let generics = generics ( ctx. db , def) ;
146
+ generics. provenance_split ( )
147
+ } else {
148
+ ( 0 , 0 , 0 )
149
+ } ;
149
150
// assert!((idx as usize) < impl_trait_params); // TODO return position impl trait
150
151
Ty :: Bound ( idx as u32 + self_params as u32 + list_params as u32 )
151
152
}
@@ -251,7 +252,7 @@ impl Ty {
251
252
// FIXME: maybe return name in resolution?
252
253
let name = generics. param_name ( param_id) ;
253
254
Ty :: Param { idx, name }
254
- } ,
255
+ }
255
256
TypeParamLoweringMode :: Variable => Ty :: Bound ( idx) ,
256
257
}
257
258
}
@@ -262,15 +263,15 @@ impl Ty {
262
263
TypeParamLoweringMode :: Variable => Substs :: bound_vars ( & generics) ,
263
264
} ;
264
265
ctx. db . impl_self_ty ( impl_id) . subst ( & substs)
265
- } ,
266
+ }
266
267
TypeNs :: AdtSelfType ( adt) => {
267
268
let generics = generics ( ctx. db , adt. into ( ) ) ;
268
269
let substs = match ctx. type_param_mode {
269
270
TypeParamLoweringMode :: Placeholder => Substs :: identity ( & generics) ,
270
271
TypeParamLoweringMode :: Variable => Substs :: bound_vars ( & generics) ,
271
272
} ;
272
273
ctx. db . ty ( adt. into ( ) ) . subst ( & substs)
273
- } ,
274
+ }
274
275
275
276
TypeNs :: AdtId ( it) => Ty :: from_hir_path_inner ( ctx, resolved_segment, it. into ( ) ) ,
276
277
TypeNs :: BuiltinType ( it) => Ty :: from_hir_path_inner ( ctx, resolved_segment, it. into ( ) ) ,
@@ -309,7 +310,8 @@ impl Ty {
309
310
segment : PathSegment < ' _ > ,
310
311
) -> Ty {
311
312
let param_idx = match self_ty {
312
- Ty :: Param { idx, .. } => idx,
313
+ Ty :: Param { idx, .. } if ctx. type_param_mode == TypeParamLoweringMode :: Placeholder => idx,
314
+ Ty :: Bound ( idx) if ctx. type_param_mode == TypeParamLoweringMode :: Variable => idx,
313
315
_ => return Ty :: Unknown , // Error: Ambiguous associated type
314
316
} ;
315
317
let def = match ctx. resolver . generic_def ( ) {
@@ -318,7 +320,14 @@ impl Ty {
318
320
} ;
319
321
let predicates = ctx. db . generic_predicates_for_param ( def. into ( ) , param_idx) ;
320
322
let traits_from_env = predicates. iter ( ) . filter_map ( |pred| match pred {
321
- GenericPredicate :: Implemented ( tr) if tr. self_ty ( ) == & self_ty => Some ( tr. trait_ ) ,
323
+ GenericPredicate :: Implemented ( tr) => {
324
+ if let Ty :: Param { idx, .. } = tr. self_ty ( ) {
325
+ if * idx == param_idx {
326
+ return Some ( tr. trait_ ) ;
327
+ }
328
+ }
329
+ None
330
+ }
322
331
_ => None ,
323
332
} ) ;
324
333
let traits = traits_from_env. flat_map ( |t| all_super_traits ( ctx. db , t) ) ;
@@ -516,10 +525,10 @@ impl GenericPredicate {
516
525
TypeParamLoweringMode :: Placeholder => {
517
526
let name = generics. param_name ( param_id) ;
518
527
Ty :: Param { idx, name }
519
- } ,
528
+ }
520
529
TypeParamLoweringMode :: Variable => Ty :: Bound ( idx) ,
521
530
}
522
- } ,
531
+ }
523
532
} ;
524
533
GenericPredicate :: from_type_bound ( ctx, & where_predicate. bound , self_ty)
525
534
}
@@ -615,7 +624,9 @@ pub(crate) fn generic_predicates_for_param_query(
615
624
. where_predicates_in_scope ( )
616
625
// we have to filter out all other predicates *first*, before attempting to lower them
617
626
. filter ( |pred| match & pred. target {
618
- WherePredicateTarget :: TypeRef ( type_ref) => Ty :: from_hir_only_param ( & ctx, type_ref) == Some ( param_idx) ,
627
+ WherePredicateTarget :: TypeRef ( type_ref) => {
628
+ Ty :: from_hir_only_param ( & ctx, type_ref) == Some ( param_idx)
629
+ }
619
630
WherePredicateTarget :: TypeParam ( local_id) => {
620
631
let param_id = hir_def:: TypeParamId { parent : def, local_id : * local_id } ;
621
632
let idx = generics. param_idx ( param_id) ;
@@ -701,8 +712,8 @@ fn type_for_const(db: &impl HirDatabase, def: ConstId) -> Binders<Ty> {
701
712
let data = db. const_data ( def) ;
702
713
let generics = generics ( db, def. into ( ) ) ;
703
714
let resolver = def. resolver ( db) ;
704
- let ctx = TyLoweringContext :: new ( db , & resolver )
705
- . with_type_param_mode ( TypeParamLoweringMode :: Variable ) ;
715
+ let ctx =
716
+ TyLoweringContext :: new ( db , & resolver ) . with_type_param_mode ( TypeParamLoweringMode :: Variable ) ;
706
717
707
718
Binders :: new ( generics. len ( ) , Ty :: from_hir ( & ctx, & data. type_ref ) )
708
719
}
@@ -731,8 +742,8 @@ fn fn_sig_for_struct_constructor(db: &impl HirDatabase, def: StructId) -> PolyFn
731
742
let struct_data = db. struct_data ( def. into ( ) ) ;
732
743
let fields = struct_data. variant_data . fields ( ) ;
733
744
let resolver = def. resolver ( db) ;
734
- let ctx = TyLoweringContext :: new ( db , & resolver )
735
- . with_type_param_mode ( TypeParamLoweringMode :: Variable ) ;
745
+ let ctx =
746
+ TyLoweringContext :: new ( db , & resolver ) . with_type_param_mode ( TypeParamLoweringMode :: Variable ) ;
736
747
let params =
737
748
fields. iter ( ) . map ( |( _, field) | Ty :: from_hir ( & ctx, & field. type_ref ) ) . collect :: < Vec < _ > > ( ) ;
738
749
let ret = type_for_adt ( db, def. into ( ) ) ;
@@ -755,8 +766,8 @@ fn fn_sig_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariantId
755
766
let var_data = & enum_data. variants [ def. local_id ] ;
756
767
let fields = var_data. variant_data . fields ( ) ;
757
768
let resolver = def. parent . resolver ( db) ;
758
- let ctx = TyLoweringContext :: new ( db , & resolver )
759
- . with_type_param_mode ( TypeParamLoweringMode :: Variable ) ;
769
+ let ctx =
770
+ TyLoweringContext :: new ( db , & resolver ) . with_type_param_mode ( TypeParamLoweringMode :: Variable ) ;
760
771
let params =
761
772
fields. iter ( ) . map ( |( _, field) | Ty :: from_hir ( & ctx, & field. type_ref ) ) . collect :: < Vec < _ > > ( ) ;
762
773
let ret = type_for_adt ( db, def. parent . into ( ) ) ;
@@ -784,8 +795,8 @@ fn type_for_adt(db: &impl HirDatabase, adt: AdtId) -> Binders<Ty> {
784
795
fn type_for_type_alias ( db : & impl HirDatabase , t : TypeAliasId ) -> Binders < Ty > {
785
796
let generics = generics ( db, t. into ( ) ) ;
786
797
let resolver = t. resolver ( db) ;
787
- let ctx = TyLoweringContext :: new ( db , & resolver )
788
- . with_type_param_mode ( TypeParamLoweringMode :: Variable ) ;
798
+ let ctx =
799
+ TyLoweringContext :: new ( db , & resolver ) . with_type_param_mode ( TypeParamLoweringMode :: Variable ) ;
789
800
let type_ref = & db. type_alias_data ( t) . type_ref ;
790
801
let substs = Substs :: bound_vars ( & generics) ;
791
802
let inner = Ty :: from_hir ( & ctx, type_ref. as_ref ( ) . unwrap_or ( & TypeRef :: Error ) ) ;
@@ -870,8 +881,8 @@ pub(crate) fn impl_self_ty_query(db: &impl HirDatabase, impl_id: ImplId) -> Bind
870
881
let impl_data = db. impl_data ( impl_id) ;
871
882
let resolver = impl_id. resolver ( db) ;
872
883
let generics = generics ( db, impl_id. into ( ) ) ;
873
- let ctx = TyLoweringContext :: new ( db , & resolver )
874
- . with_type_param_mode ( TypeParamLoweringMode :: Variable ) ;
884
+ let ctx =
885
+ TyLoweringContext :: new ( db , & resolver ) . with_type_param_mode ( TypeParamLoweringMode :: Variable ) ;
875
886
Binders :: new ( generics. len ( ) , Ty :: from_hir ( & ctx, & impl_data. target_type ) )
876
887
}
877
888
0 commit comments