@@ -112,12 +112,15 @@ pub enum SizedByDefault {
112
112
No ,
113
113
}
114
114
115
+ #[ derive( Debug ) ]
115
116
struct ConvertedBinding < ' a , ' tcx > {
116
117
item_name : Ident ,
117
118
kind : ConvertedBindingKind < ' a , ' tcx > ,
119
+ gen_args : & ' a GenericArgs < ' a > ,
118
120
span : Span ,
119
121
}
120
122
123
+ #[ derive( Debug ) ]
121
124
enum ConvertedBindingKind < ' a , ' tcx > {
122
125
Equality ( Ty < ' tcx > ) ,
123
126
Constraint ( & ' a [ hir:: GenericBound < ' a > ] ) ,
@@ -323,6 +326,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
323
326
324
327
let tcx = self . tcx ( ) ;
325
328
let generics = tcx. generics_of ( def_id) ;
329
+ debug ! ( "generics: {:?}" , generics) ;
326
330
327
331
if generics. has_self {
328
332
if generics. parent . is_some ( ) {
@@ -557,7 +561,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
557
561
ConvertedBindingKind :: Constraint ( bounds)
558
562
}
559
563
} ;
560
- ConvertedBinding { item_name : binding. ident , kind, span : binding. span }
564
+ ConvertedBinding {
565
+ item_name : binding. ident ,
566
+ kind,
567
+ gen_args : binding. gen_args ,
568
+ span : binding. span ,
569
+ }
561
570
} )
562
571
. collect ( ) ;
563
572
@@ -918,60 +927,27 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
918
927
dup_bindings : & mut FxHashMap < DefId , Span > ,
919
928
path_span : Span ,
920
929
) -> Result < ( ) , ErrorReported > {
921
- let tcx = self . tcx ( ) ;
922
-
923
- if !speculative {
924
- // Given something like `U: SomeTrait<T = X>`, we want to produce a
925
- // predicate like `<U as SomeTrait>::T = X`. This is somewhat
926
- // subtle in the event that `T` is defined in a supertrait of
927
- // `SomeTrait`, because in that case we need to upcast.
928
- //
929
- // That is, consider this case:
930
- //
931
- // ```
932
- // trait SubTrait: SuperTrait<i32> { }
933
- // trait SuperTrait<A> { type T; }
934
- //
935
- // ... B: SubTrait<T = foo> ...
936
- // ```
937
- //
938
- // We want to produce `<B as SuperTrait<i32>>::T == foo`.
939
-
940
- // Find any late-bound regions declared in `ty` that are not
941
- // declared in the trait-ref. These are not well-formed.
942
- //
943
- // Example:
944
- //
945
- // for<'a> <T as Iterator>::Item = &'a str // <-- 'a is bad
946
- // for<'a> <T as FnMut<(&'a u32,)>>::Output = &'a str // <-- 'a is ok
947
- if let ConvertedBindingKind :: Equality ( ty) = binding. kind {
948
- let late_bound_in_trait_ref =
949
- tcx. collect_constrained_late_bound_regions ( & trait_ref) ;
950
- let late_bound_in_ty =
951
- tcx. collect_referenced_late_bound_regions ( & ty:: Binder :: bind ( ty) ) ;
952
- debug ! ( "late_bound_in_trait_ref = {:?}" , late_bound_in_trait_ref) ;
953
- debug ! ( "late_bound_in_ty = {:?}" , late_bound_in_ty) ;
930
+ // Given something like `U: SomeTrait<T = X>`, we want to produce a
931
+ // predicate like `<U as SomeTrait>::T = X`. This is somewhat
932
+ // subtle in the event that `T` is defined in a supertrait of
933
+ // `SomeTrait`, because in that case we need to upcast.
934
+ //
935
+ // That is, consider this case:
936
+ //
937
+ // ```
938
+ // trait SubTrait: SuperTrait<i32> { }
939
+ // trait SuperTrait<A> { type T; }
940
+ //
941
+ // ... B: SubTrait<T = foo> ...
942
+ // ```
943
+ //
944
+ // We want to produce `<B as SuperTrait<i32>>::T == foo`.
954
945
955
- // FIXME: point at the type params that don't have appropriate lifetimes:
956
- // struct S1<F: for<'a> Fn(&i32, &i32) -> &'a i32>(F);
957
- // ---- ---- ^^^^^^^
958
- self . validate_late_bound_regions (
959
- late_bound_in_trait_ref,
960
- late_bound_in_ty,
961
- |br_name| {
962
- struct_span_err ! (
963
- tcx. sess,
964
- binding. span,
965
- E0582 ,
966
- "binding for associated type `{}` references {}, \
967
- which does not appear in the trait input types",
968
- binding. item_name,
969
- br_name
970
- )
971
- } ,
972
- ) ;
973
- }
974
- }
946
+ debug ! (
947
+ "add_predicates_for_ast_type_binding(hir_ref_id {:?}, trait_ref {:?}, binding {:?}, bounds {:?}" ,
948
+ hir_ref_id, trait_ref, binding, bounds
949
+ ) ;
950
+ let tcx = self . tcx ( ) ;
975
951
976
952
let candidate =
977
953
if self . trait_defines_associated_type_named ( trait_ref. def_id ( ) , binding. item_name ) {
@@ -1030,20 +1006,85 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
1030
1006
. or_insert ( binding. span ) ;
1031
1007
}
1032
1008
1009
+ // Include substitutions for generic parameters of associated types
1010
+ let projection_ty = candidate. map_bound ( |trait_ref| {
1011
+ let item_segment = hir:: PathSegment {
1012
+ ident : assoc_ty. ident ,
1013
+ hir_id : None ,
1014
+ res : None ,
1015
+ args : Some ( binding. gen_args ) ,
1016
+ infer_args : false ,
1017
+ } ;
1018
+
1019
+ let substs_trait_ref_and_assoc_item = self . create_substs_for_associated_item (
1020
+ tcx,
1021
+ path_span,
1022
+ assoc_ty. def_id ,
1023
+ & item_segment,
1024
+ trait_ref. substs ,
1025
+ ) ;
1026
+
1027
+ debug ! (
1028
+ "add_predicates_for_ast_type_binding: substs for trait-ref and assoc_item: {:?}" ,
1029
+ substs_trait_ref_and_assoc_item
1030
+ ) ;
1031
+
1032
+ ty:: ProjectionTy {
1033
+ item_def_id : assoc_ty. def_id ,
1034
+ substs : substs_trait_ref_and_assoc_item,
1035
+ }
1036
+ } ) ;
1037
+
1038
+ if !speculative {
1039
+ // Find any late-bound regions declared in `ty` that are not
1040
+ // declared in the trait-ref or assoc_ty. These are not well-formed.
1041
+ //
1042
+ // Example:
1043
+ //
1044
+ // for<'a> <T as Iterator>::Item = &'a str // <-- 'a is bad
1045
+ // for<'a> <T as FnMut<(&'a u32,)>>::Output = &'a str // <-- 'a is ok
1046
+ if let ConvertedBindingKind :: Equality ( ty) = binding. kind {
1047
+ let late_bound_in_trait_ref =
1048
+ tcx. collect_constrained_late_bound_regions ( & projection_ty) ;
1049
+ let late_bound_in_ty =
1050
+ tcx. collect_referenced_late_bound_regions ( & ty:: Binder :: bind ( ty) ) ;
1051
+ debug ! ( "late_bound_in_trait_ref = {:?}" , late_bound_in_trait_ref) ;
1052
+ debug ! ( "late_bound_in_ty = {:?}" , late_bound_in_ty) ;
1053
+
1054
+ // FIXME: point at the type params that don't have appropriate lifetimes:
1055
+ // struct S1<F: for<'a> Fn(&i32, &i32) -> &'a i32>(F);
1056
+ // ---- ---- ^^^^^^^
1057
+ self . validate_late_bound_regions (
1058
+ late_bound_in_trait_ref,
1059
+ late_bound_in_ty,
1060
+ |br_name| {
1061
+ struct_span_err ! (
1062
+ tcx. sess,
1063
+ binding. span,
1064
+ E0582 ,
1065
+ "binding for associated type `{}` references {}, \
1066
+ which does not appear in the trait input types",
1067
+ binding. item_name,
1068
+ br_name
1069
+ )
1070
+ } ,
1071
+ ) ;
1072
+ }
1073
+ }
1074
+
1033
1075
match binding. kind {
1034
1076
ConvertedBindingKind :: Equality ( ref ty) => {
1035
1077
// "Desugar" a constraint like `T: Iterator<Item = u32>` this to
1036
1078
// the "projection predicate" for:
1037
1079
//
1038
1080
// `<T as Iterator>::Item = u32`
1039
1081
bounds. projection_bounds . push ( (
1040
- candidate. map_bound ( |trait_ref| ty:: ProjectionPredicate {
1041
- projection_ty : ty:: ProjectionTy :: from_ref_and_name (
1042
- tcx,
1043
- trait_ref,
1044
- binding. item_name ,
1045
- ) ,
1046
- ty,
1082
+ projection_ty. map_bound ( |projection_ty| {
1083
+ debug ! (
1084
+ "add_predicates_for_ast_type_binding: projection_ty {:?}, substs: {:?}" ,
1085
+ projection_ty, projection_ty. substs
1086
+ ) ;
1087
+ ty:: ProjectionPredicate { projection_ty, ty }
1047
1088
} ) ,
1048
1089
binding. span ,
1049
1090
) ) ;
@@ -1055,7 +1096,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
1055
1096
//
1056
1097
// Calling `skip_binder` is okay, because `add_bounds` expects the `param_ty`
1057
1098
// parameter to have a skipped binder.
1058
- let param_ty = tcx. mk_projection ( assoc_ty. def_id , candidate. skip_binder ( ) . substs ) ;
1099
+ let param_ty =
1100
+ tcx. mk_projection ( assoc_ty. def_id , projection_ty. skip_binder ( ) . substs ) ;
1059
1101
self . add_bounds ( param_ty, ast_bounds, bounds) ;
1060
1102
}
1061
1103
}
0 commit comments