@@ -1088,7 +1088,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
10881088
10891089 // TODO: rtn comment goes here
10901090 let associated_return_type_bound =
1091- binding. gen_args . parenthesized && self . tcx ( ) . features ( ) . associated_return_type_bounds ;
1091+ binding. gen_args . parenthesized && tcx. features ( ) . associated_return_type_bounds ;
10921092
10931093 let candidate = if return_type_notation {
10941094 if self . trait_defines_associated_item_named (
@@ -1156,7 +1156,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
11561156 dup_bindings
11571157 . entry ( assoc_item. def_id )
11581158 . and_modify ( |prev_span| {
1159- self . tcx ( ) . sess . emit_err ( ValueOfAssociatedStructAlreadySpecified {
1159+ tcx. sess . emit_err ( ValueOfAssociatedStructAlreadySpecified {
11601160 span : binding. span ,
11611161 prev_span : * prev_span,
11621162 item_name : binding. item_name ,
@@ -1166,14 +1166,53 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
11661166 . or_insert ( binding. span ) ;
11671167 }
11681168
1169- let projection_ty = if associated_return_type_bound {
1170- let generics = self . tcx ( ) . generics_of ( assoc_item. def_id ) ;
1171- if !generics. params . is_empty ( ) {
1172- todo ! ( ) ;
1173- }
1174- let output = self . tcx ( ) . fn_sig ( assoc_item. def_id ) . skip_binder ( ) . output ( ) ;
1175- let fn_bound_vars = output. bound_vars ( ) ;
1169+ let projection_ty = if return_type_notation {
1170+ // If we have an method return type bound, then we need to substitute
1171+ // the method's early bound params with suitable late-bound params.
1172+ let mut num_bound_vars = candidate. bound_vars ( ) . len ( ) ;
1173+ let substs =
1174+ candidate. skip_binder ( ) . substs . extend_to ( tcx, assoc_item. def_id , |param, _| {
1175+ let subst = match param. kind {
1176+ GenericParamDefKind :: Lifetime => tcx
1177+ . mk_re_late_bound (
1178+ ty:: INNERMOST ,
1179+ ty:: BoundRegion {
1180+ var : ty:: BoundVar :: from_usize ( num_bound_vars) ,
1181+ kind : ty:: BoundRegionKind :: BrNamed ( param. def_id , param. name ) ,
1182+ } ,
1183+ )
1184+ . into ( ) ,
1185+ GenericParamDefKind :: Type { .. } => tcx
1186+ . mk_bound (
1187+ ty:: INNERMOST ,
1188+ ty:: BoundTy {
1189+ var : ty:: BoundVar :: from_usize ( num_bound_vars) ,
1190+ kind : ty:: BoundTyKind :: Param ( param. def_id , param. name ) ,
1191+ } ,
1192+ )
1193+ . into ( ) ,
1194+ GenericParamDefKind :: Const { .. } => {
1195+ let ty = tcx
1196+ . type_of ( param. def_id )
1197+ . no_bound_vars ( )
1198+ . expect ( "ct params cannot have early bound vars" ) ;
1199+ tcx. mk_const (
1200+ ty:: ConstKind :: Bound (
1201+ ty:: INNERMOST ,
1202+ ty:: BoundVar :: from_usize ( num_bound_vars) ,
1203+ ) ,
1204+ ty,
1205+ )
1206+ . into ( )
1207+ }
1208+ } ;
1209+ num_bound_vars += 1 ;
1210+ subst
1211+ } ) ;
11761212
1213+ // Next, we need to check that the return-type notation is being used on
1214+ // an RPITIT (return-position impl trait in trait) or AFIT (async fn in trait).
1215+ let output = tcx. fn_sig ( assoc_item. def_id ) . skip_binder ( ) . output ( ) ;
11771216 let output = if let ty:: Alias ( ty:: Projection , alias_ty) = * output. skip_binder ( ) . kind ( )
11781217 && tcx. def_kind ( alias_ty. def_id ) == DefKind :: ImplTraitPlaceholder
11791218 {
@@ -1182,13 +1221,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
11821221 todo ! ( "found return type of {output:?}" ) ;
11831222 } ;
11841223
1185- let trait_bound_vars = candidate. bound_vars ( ) ;
1186- let shifted_output = tcx. shift_bound_var_indices ( trait_bound_vars. len ( ) , output) ;
1187- let subst_output =
1188- ty:: EarlyBinder ( shifted_output) . subst ( tcx, candidate. skip_binder ( ) . substs ) ;
1189- let bound_vars =
1190- tcx. mk_bound_variable_kinds_from_iter ( trait_bound_vars. iter ( ) . chain ( fn_bound_vars) ) ;
1224+ // Finally, move the fn return type's bound vars over to account for the early bound
1225+ // params (and trait ref's late bound params). This logic is very similar to
1226+ // `Predicate::subst_supertrait`, and it's no coincidence why.
1227+ let shifted_output = tcx. shift_bound_var_indices ( num_bound_vars, output) ;
1228+ let subst_output = ty:: EarlyBinder ( shifted_output) . subst ( tcx, substs) ;
11911229
1230+ let bound_vars = tcx. late_bound_vars ( binding. hir_id ) ;
11921231 ty:: Binder :: bind_with_vars ( subst_output, bound_vars)
11931232 } else {
11941233 // Include substitutions for generic parameters of associated types
@@ -1211,7 +1250,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
12111250
12121251 debug ! ( ?substs_trait_ref_and_assoc_item) ;
12131252
1214- self . tcx ( ) . mk_alias_ty ( assoc_item. def_id , substs_trait_ref_and_assoc_item)
1253+ tcx. mk_alias_ty ( assoc_item. def_id , substs_trait_ref_and_assoc_item)
12151254 } )
12161255 } ;
12171256
0 commit comments