@@ -110,13 +110,6 @@ pub struct LoweringContext<'a> {
110110 /// written at all (e.g., `&T` or `std::cell::Ref<T>`).
111111 anonymous_lifetime_mode : AnonymousLifetimeMode ,
112112
113- // This is a list of in-band type definitions being generated by
114- // Argument-position `impl Trait`.
115- // When traversing a signature such as `fn foo(x: impl Trait)`,
116- // we record `impl Trait` as a new type parameter, then later
117- // add it on to `foo`s generics.
118- in_band_ty_params : Vec < hir:: GenericParam > ,
119-
120113 // Used to create lifetime definitions from in-band lifetime usages.
121114 // e.g. `fn foo(x: &'x u8) -> &'x u8` to `fn foo<'x>(x: &'x u8) -> &'x u8`
122115 // When a named lifetime is encountered in a function or impl header and
@@ -172,12 +165,14 @@ pub trait Resolver {
172165 ) -> hir:: Path ;
173166}
174167
175- #[ derive( Clone , Copy , Debug ) ]
176- enum ImplTraitContext {
168+ #[ derive( Debug ) ]
169+ enum ImplTraitContext < ' a > {
177170 /// Treat `impl Trait` as shorthand for a new universal generic parameter.
178171 /// Example: `fn foo(x: impl Debug)`, where `impl Debug` is conceptually
179172 /// equivalent to a fresh universal parameter like `fn foo<T: Debug>(x: T)`.
180- Universal ,
173+ ///
174+ /// Newly generated parameters should be inserted into the given `Vec`
175+ Universal ( & ' a mut Vec < hir:: GenericParam > ) ,
181176
182177 /// Treat `impl Trait` as shorthand for a new universal existential parameter.
183178 /// Example: `fn foo() -> impl Debug`, where `impl Debug` is conceptually
@@ -190,6 +185,17 @@ enum ImplTraitContext {
190185 Disallowed ,
191186}
192187
188+ impl < ' a > ImplTraitContext < ' a > {
189+ fn reborrow ( & ' b mut self ) -> ImplTraitContext < ' b > {
190+ use self :: ImplTraitContext :: * ;
191+ match self {
192+ Universal ( params) => Universal ( params) ,
193+ Existential ( did) => Existential ( * did) ,
194+ Disallowed => Disallowed ,
195+ }
196+ }
197+ }
198+
193199pub fn lower_crate (
194200 sess : & Session ,
195201 cstore : & CrateStore ,
@@ -224,7 +230,6 @@ pub fn lower_crate(
224230 node_id_to_hir_id : IndexVec :: new ( ) ,
225231 is_generator : false ,
226232 is_in_trait_impl : false ,
227- in_band_ty_params : Vec :: new ( ) ,
228233 lifetimes_to_define : Vec :: new ( ) ,
229234 is_collecting_in_band_lifetimes : false ,
230235 in_scope_lifetimes : Vec :: new ( ) ,
@@ -645,7 +650,7 @@ impl<'a> LoweringContext<'a> {
645650 f : F ,
646651 ) -> ( Vec < hir:: GenericParam > , T )
647652 where
648- F : FnOnce ( & mut LoweringContext ) -> T ,
653+ F : FnOnce ( & mut LoweringContext ) -> ( Vec < hir :: GenericParam > , T ) ,
649654 {
650655 assert ! ( !self . is_collecting_in_band_lifetimes) ;
651656 assert ! ( self . lifetimes_to_define. is_empty( ) ) ;
@@ -656,13 +661,11 @@ impl<'a> LoweringContext<'a> {
656661 self . anonymous_lifetime_mode = anonymous_lifetime_mode;
657662 }
658663
659- assert ! ( self . in_band_ty_params. is_empty( ) ) ;
660- let res = f ( self ) ;
664+ let ( in_band_ty_params, res) = f ( self ) ;
661665
662666 self . is_collecting_in_band_lifetimes = false ;
663667 self . anonymous_lifetime_mode = old_anonymous_lifetime_mode;
664668
665- let in_band_ty_params = self . in_band_ty_params . split_off ( 0 ) ;
666669 let lifetimes_to_define = self . lifetimes_to_define . split_off ( 0 ) ;
667670
668671 let params = lifetimes_to_define
@@ -796,14 +799,19 @@ impl<'a> LoweringContext<'a> {
796799 f : F ,
797800 ) -> ( hir:: Generics , T )
798801 where
799- F : FnOnce ( & mut LoweringContext ) -> T ,
802+ F : FnOnce ( & mut LoweringContext , & mut Vec < hir :: GenericParam > ) -> T ,
800803 {
801804 let ( in_band_defs, ( mut lowered_generics, res) ) = self . with_in_scope_lifetime_defs (
802805 & generics. params ,
803806 |this| {
804- let itctx = ImplTraitContext :: Universal ;
805807 this. collect_in_band_defs ( parent_id, anonymous_lifetime_mode, |this| {
806- ( this. lower_generics ( generics, itctx) , f ( this) )
808+ let mut params = Vec :: new ( ) ;
809+ let generics = this. lower_generics (
810+ generics,
811+ ImplTraitContext :: Universal ( & mut params) ,
812+ ) ;
813+ let res = f ( this, & mut params) ;
814+ ( params, ( generics, res) )
807815 } )
808816 } ,
809817 ) ;
@@ -1069,7 +1077,7 @@ impl<'a> LoweringContext<'a> {
10691077 P ( self . lower_ty_direct ( t, itctx) )
10701078 }
10711079
1072- fn lower_ty_direct ( & mut self , t : & Ty , itctx : ImplTraitContext ) -> hir:: Ty {
1080+ fn lower_ty_direct ( & mut self , t : & Ty , mut itctx : ImplTraitContext ) -> hir:: Ty {
10731081 let kind = match t. node {
10741082 TyKind :: Infer => hir:: TyInfer ,
10751083 TyKind :: Err => hir:: TyErr ,
@@ -1106,7 +1114,9 @@ impl<'a> LoweringContext<'a> {
11061114 ) ,
11071115 TyKind :: Never => hir:: TyNever ,
11081116 TyKind :: Tup ( ref tys) => {
1109- hir:: TyTup ( tys. iter ( ) . map ( |ty| self . lower_ty_direct ( ty, itctx) ) . collect ( ) )
1117+ hir:: TyTup ( tys. iter ( ) . map ( |ty| {
1118+ self . lower_ty_direct ( ty, itctx. reborrow ( ) )
1119+ } ) . collect ( ) )
11101120 }
11111121 TyKind :: Paren ( ref ty) => {
11121122 return self . lower_ty_direct ( ty, itctx) ;
@@ -1140,7 +1150,7 @@ impl<'a> LoweringContext<'a> {
11401150 . iter ( )
11411151 . filter_map ( |bound| match * bound {
11421152 GenericBound :: Trait ( ref ty, TraitBoundModifier :: None ) => {
1143- Some ( self . lower_poly_trait_ref ( ty, itctx) )
1153+ Some ( self . lower_poly_trait_ref ( ty, itctx. reborrow ( ) ) )
11441154 }
11451155 GenericBound :: Trait ( _, TraitBoundModifier :: Maybe ) => None ,
11461156 GenericBound :: Outlives ( ref lifetime) => {
@@ -1167,7 +1177,7 @@ impl<'a> LoweringContext<'a> {
11671177 |this| this. lower_param_bounds ( bounds, itctx) ,
11681178 )
11691179 }
1170- ImplTraitContext :: Universal => {
1180+ ImplTraitContext :: Universal ( in_band_ty_params ) => {
11711181 self . lower_node_id ( def_node_id) ;
11721182 // Add a definition for the in-band TyParam
11731183 let def_index = self
@@ -1176,10 +1186,13 @@ impl<'a> LoweringContext<'a> {
11761186 . opt_def_index ( def_node_id)
11771187 . unwrap ( ) ;
11781188
1179- let hir_bounds = self . lower_param_bounds ( bounds, itctx) ;
1189+ let hir_bounds = self . lower_param_bounds (
1190+ bounds,
1191+ ImplTraitContext :: Universal ( in_band_ty_params) ,
1192+ ) ;
11801193 // Set the name to `impl Bound1 + Bound2`
11811194 let ident = Ident :: from_str ( & pprust:: ty_to_string ( t) ) . with_span_pos ( span) ;
1182- self . in_band_ty_params . push ( hir:: GenericParam {
1195+ in_band_ty_params. push ( hir:: GenericParam {
11831196 id : def_node_id,
11841197 name : ParamName :: Plain ( ident) ,
11851198 pure_wrt_drop : false ,
@@ -1502,10 +1515,10 @@ impl<'a> LoweringContext<'a> {
15021515 qself : & Option < QSelf > ,
15031516 p : & Path ,
15041517 param_mode : ParamMode ,
1505- itctx : ImplTraitContext ,
1518+ mut itctx : ImplTraitContext ,
15061519 ) -> hir:: QPath {
15071520 let qself_position = qself. as_ref ( ) . map ( |q| q. position ) ;
1508- let qself = qself. as_ref ( ) . map ( |q| self . lower_ty ( & q. ty , itctx) ) ;
1521+ let qself = qself. as_ref ( ) . map ( |q| self . lower_ty ( & q. ty , itctx. reborrow ( ) ) ) ;
15091522
15101523 let resolution = self . resolver
15111524 . get_resolution ( id)
@@ -1592,7 +1605,7 @@ impl<'a> LoweringContext<'a> {
15921605 param_mode,
15931606 num_lifetimes,
15941607 parenthesized_generic_args,
1595- itctx,
1608+ itctx. reborrow ( ) ,
15961609 )
15971610 } )
15981611 . collect ( ) ,
@@ -1635,7 +1648,7 @@ impl<'a> LoweringContext<'a> {
16351648 param_mode,
16361649 0 ,
16371650 ParenthesizedGenericArgs :: Warn ,
1638- itctx,
1651+ itctx. reborrow ( ) ,
16391652 ) ) ;
16401653 let qpath = hir:: QPath :: TypeRelative ( ty, segment) ;
16411654
@@ -1752,16 +1765,16 @@ impl<'a> LoweringContext<'a> {
17521765 & mut self ,
17531766 data : & AngleBracketedArgs ,
17541767 param_mode : ParamMode ,
1755- itctx : ImplTraitContext ,
1768+ mut itctx : ImplTraitContext ,
17561769 ) -> ( hir:: GenericArgs , bool ) {
17571770 let & AngleBracketedArgs { ref args, ref bindings, .. } = data;
17581771 let has_types = args. iter ( ) . any ( |arg| match arg {
17591772 ast:: GenericArg :: Type ( _) => true ,
17601773 _ => false ,
17611774 } ) ;
17621775 ( hir:: GenericArgs {
1763- args : args. iter ( ) . map ( |a| self . lower_generic_arg ( a, itctx) ) . collect ( ) ,
1764- bindings : bindings. iter ( ) . map ( |b| self . lower_ty_binding ( b, itctx) ) . collect ( ) ,
1776+ args : args. iter ( ) . map ( |a| self . lower_generic_arg ( a, itctx. reborrow ( ) ) ) . collect ( ) ,
1777+ bindings : bindings. iter ( ) . map ( |b| self . lower_ty_binding ( b, itctx. reborrow ( ) ) ) . collect ( ) ,
17651778 parenthesized : false ,
17661779 } ,
17671780 !has_types && param_mode == ParamMode :: Optional )
@@ -1866,15 +1879,15 @@ impl<'a> LoweringContext<'a> {
18661879 fn lower_fn_decl (
18671880 & mut self ,
18681881 decl : & FnDecl ,
1869- fn_def_id : Option < DefId > ,
1882+ mut in_band_ty_params : Option < ( DefId , & mut Vec < hir :: GenericParam > ) > ,
18701883 impl_trait_return_allow : bool ,
18711884 make_ret_async : Option < NodeId > ,
18721885 ) -> P < hir:: FnDecl > {
18731886 let inputs = decl. inputs
18741887 . iter ( )
18751888 . map ( |arg| {
1876- if fn_def_id . is_some ( ) {
1877- self . lower_ty_direct ( & arg. ty , ImplTraitContext :: Universal )
1889+ if let Some ( ( _ , ref mut ibty ) ) = in_band_ty_params {
1890+ self . lower_ty_direct ( & arg. ty , ImplTraitContext :: Universal ( ibty ) )
18781891 } else {
18791892 self . lower_ty_direct ( & arg. ty , ImplTraitContext :: Disallowed )
18801893 }
@@ -1883,11 +1896,15 @@ impl<'a> LoweringContext<'a> {
18831896
18841897 let output = if let Some ( ret_id) = make_ret_async {
18851898 self . lower_async_fn_ret_ty (
1886- & inputs, & decl. output , fn_def_id. expect ( "make_ret_async but no fn_def_id" ) , ret_id)
1899+ & inputs,
1900+ & decl. output ,
1901+ in_band_ty_params. expect ( "make_ret_async but no fn_def_id" ) . 0 ,
1902+ ret_id,
1903+ )
18871904 } else {
18881905 match decl. output {
1889- FunctionRetTy :: Ty ( ref ty) => match fn_def_id {
1890- Some ( def_id) if impl_trait_return_allow => {
1906+ FunctionRetTy :: Ty ( ref ty) => match in_band_ty_params {
1907+ Some ( ( def_id, _ ) ) if impl_trait_return_allow => {
18911908 hir:: Return ( self . lower_ty ( ty, ImplTraitContext :: Existential ( def_id) ) )
18921909 }
18931910 _ => hir:: Return ( self . lower_ty ( ty, ImplTraitContext :: Disallowed ) ) ,
@@ -2191,17 +2208,19 @@ impl<'a> LoweringContext<'a> {
21912208 & mut self ,
21922209 params : & Vec < GenericParam > ,
21932210 add_bounds : & NodeMap < Vec < GenericBound > > ,
2194- itctx : ImplTraitContext ,
2211+ mut itctx : ImplTraitContext ,
21952212 ) -> hir:: HirVec < hir:: GenericParam > {
2196- params. iter ( ) . map ( |param| self . lower_generic_param ( param, add_bounds, itctx) ) . collect ( )
2213+ params. iter ( ) . map ( |param| {
2214+ self . lower_generic_param ( param, add_bounds, itctx. reborrow ( ) )
2215+ } ) . collect ( )
21972216 }
21982217
21992218 fn lower_generic_param ( & mut self ,
22002219 param : & GenericParam ,
22012220 add_bounds : & NodeMap < Vec < GenericBound > > ,
2202- itctx : ImplTraitContext )
2221+ mut itctx : ImplTraitContext )
22032222 -> hir:: GenericParam {
2204- let mut bounds = self . lower_param_bounds ( & param. bounds , itctx) ;
2223+ let mut bounds = self . lower_param_bounds ( & param. bounds , itctx. reborrow ( ) ) ;
22052224 match param. kind {
22062225 GenericParamKind :: Lifetime => {
22072226 let was_collecting_in_band = self . is_collecting_in_band_lifetimes ;
@@ -2238,8 +2257,9 @@ impl<'a> LoweringContext<'a> {
22382257
22392258 let add_bounds = add_bounds. get ( & param. id ) . map_or ( & [ ] [ ..] , |x| & x) ;
22402259 if !add_bounds. is_empty ( ) {
2260+ let params = self . lower_param_bounds ( add_bounds, itctx. reborrow ( ) ) . into_iter ( ) ;
22412261 bounds = bounds. into_iter ( )
2242- . chain ( self . lower_param_bounds ( add_bounds , itctx ) . into_iter ( ) )
2262+ . chain ( params )
22432263 . collect ( ) ;
22442264 }
22452265
@@ -2434,10 +2454,10 @@ impl<'a> LoweringContext<'a> {
24342454 fn lower_poly_trait_ref (
24352455 & mut self ,
24362456 p : & PolyTraitRef ,
2437- itctx : ImplTraitContext ,
2457+ mut itctx : ImplTraitContext ,
24382458 ) -> hir:: PolyTraitRef {
24392459 let bound_generic_params =
2440- self . lower_generic_params ( & p. bound_generic_params , & NodeMap ( ) , itctx) ;
2460+ self . lower_generic_params ( & p. bound_generic_params , & NodeMap ( ) , itctx. reborrow ( ) ) ;
24412461 let trait_ref = self . with_parent_impl_lifetime_defs (
24422462 & bound_generic_params,
24432463 |this| this. lower_trait_ref ( & p. trait_ref , itctx) ,
@@ -2482,9 +2502,9 @@ impl<'a> LoweringContext<'a> {
24822502 }
24832503 }
24842504
2485- fn lower_param_bounds ( & mut self , bounds : & [ GenericBound ] , itctx : ImplTraitContext )
2505+ fn lower_param_bounds ( & mut self , bounds : & [ GenericBound ] , mut itctx : ImplTraitContext )
24862506 -> hir:: GenericBounds {
2487- bounds. iter ( ) . map ( |bound| self . lower_param_bound ( bound, itctx) ) . collect ( )
2507+ bounds. iter ( ) . map ( |bound| self . lower_param_bound ( bound, itctx. reborrow ( ) ) ) . collect ( )
24882508 }
24892509
24902510 fn lower_block ( & mut self , b : & Block , targeted_by_break : bool ) -> P < hir:: Block > {
@@ -2585,8 +2605,8 @@ impl<'a> LoweringContext<'a> {
25852605 generics,
25862606 fn_def_id,
25872607 AnonymousLifetimeMode :: PassThrough ,
2588- |this| this. lower_fn_decl (
2589- decl, Some ( fn_def_id) , true , header. asyncness . opt_return_id ( ) )
2608+ |this, idty | this. lower_fn_decl (
2609+ decl, Some ( ( fn_def_id, idty ) ) , true , header. asyncness . opt_return_id ( ) ) ,
25902610 ) ;
25912611
25922612 hir:: ItemFn (
@@ -2656,7 +2676,7 @@ impl<'a> LoweringContext<'a> {
26562676 ast_generics,
26572677 def_id,
26582678 AnonymousLifetimeMode :: CreateParameter ,
2659- |this| {
2679+ |this, _ | {
26602680 let trait_ref = trait_ref. as_ref ( ) . map ( |trait_ref| {
26612681 this. lower_trait_ref ( trait_ref, ImplTraitContext :: Disallowed )
26622682 } ) ;
@@ -3191,7 +3211,7 @@ impl<'a> LoweringContext<'a> {
31913211 generics,
31923212 def_id,
31933213 AnonymousLifetimeMode :: PassThrough ,
3194- |this| {
3214+ |this, _ | {
31953215 (
31963216 // Disallow impl Trait in foreign items
31973217 this. lower_fn_decl ( fdec, None , false , None ) ,
@@ -3226,7 +3246,12 @@ impl<'a> LoweringContext<'a> {
32263246 generics,
32273247 fn_def_id,
32283248 AnonymousLifetimeMode :: PassThrough ,
3229- |cx| cx. lower_fn_decl ( & sig. decl , Some ( fn_def_id) , impl_trait_return_allow, is_async) ,
3249+ |this, idty| this. lower_fn_decl (
3250+ & sig. decl ,
3251+ Some ( ( fn_def_id, idty) ) ,
3252+ impl_trait_return_allow,
3253+ is_async,
3254+ ) ,
32303255 ) ;
32313256 ( generics, hir:: MethodSig { header, decl } )
32323257 }
0 commit comments