@@ -110,13 +110,6 @@ pub struct LoweringContext<'a> {
110
110
/// written at all (e.g., `&T` or `std::cell::Ref<T>`).
111
111
anonymous_lifetime_mode : AnonymousLifetimeMode ,
112
112
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
-
120
113
// Used to create lifetime definitions from in-band lifetime usages.
121
114
// e.g. `fn foo(x: &'x u8) -> &'x u8` to `fn foo<'x>(x: &'x u8) -> &'x u8`
122
115
// When a named lifetime is encountered in a function or impl header and
@@ -172,12 +165,14 @@ pub trait Resolver {
172
165
) -> hir:: Path ;
173
166
}
174
167
175
- #[ derive( Clone , Copy , Debug ) ]
176
- enum ImplTraitContext {
168
+ #[ derive( Debug ) ]
169
+ enum ImplTraitContext < ' a > {
177
170
/// Treat `impl Trait` as shorthand for a new universal generic parameter.
178
171
/// Example: `fn foo(x: impl Debug)`, where `impl Debug` is conceptually
179
172
/// 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 > ) ,
181
176
182
177
/// Treat `impl Trait` as shorthand for a new universal existential parameter.
183
178
/// Example: `fn foo() -> impl Debug`, where `impl Debug` is conceptually
@@ -190,6 +185,17 @@ enum ImplTraitContext {
190
185
Disallowed ,
191
186
}
192
187
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
+
193
199
pub fn lower_crate (
194
200
sess : & Session ,
195
201
cstore : & CrateStore ,
@@ -224,7 +230,6 @@ pub fn lower_crate(
224
230
node_id_to_hir_id : IndexVec :: new ( ) ,
225
231
is_generator : false ,
226
232
is_in_trait_impl : false ,
227
- in_band_ty_params : Vec :: new ( ) ,
228
233
lifetimes_to_define : Vec :: new ( ) ,
229
234
is_collecting_in_band_lifetimes : false ,
230
235
in_scope_lifetimes : Vec :: new ( ) ,
@@ -645,7 +650,7 @@ impl<'a> LoweringContext<'a> {
645
650
f : F ,
646
651
) -> ( Vec < hir:: GenericParam > , T )
647
652
where
648
- F : FnOnce ( & mut LoweringContext ) -> T ,
653
+ F : FnOnce ( & mut LoweringContext ) -> ( Vec < hir :: GenericParam > , T ) ,
649
654
{
650
655
assert ! ( !self . is_collecting_in_band_lifetimes) ;
651
656
assert ! ( self . lifetimes_to_define. is_empty( ) ) ;
@@ -656,13 +661,11 @@ impl<'a> LoweringContext<'a> {
656
661
self . anonymous_lifetime_mode = anonymous_lifetime_mode;
657
662
}
658
663
659
- assert ! ( self . in_band_ty_params. is_empty( ) ) ;
660
- let res = f ( self ) ;
664
+ let ( in_band_ty_params, res) = f ( self ) ;
661
665
662
666
self . is_collecting_in_band_lifetimes = false ;
663
667
self . anonymous_lifetime_mode = old_anonymous_lifetime_mode;
664
668
665
- let in_band_ty_params = self . in_band_ty_params . split_off ( 0 ) ;
666
669
let lifetimes_to_define = self . lifetimes_to_define . split_off ( 0 ) ;
667
670
668
671
let params = lifetimes_to_define
@@ -796,14 +799,19 @@ impl<'a> LoweringContext<'a> {
796
799
f : F ,
797
800
) -> ( hir:: Generics , T )
798
801
where
799
- F : FnOnce ( & mut LoweringContext ) -> T ,
802
+ F : FnOnce ( & mut LoweringContext , & mut Vec < hir :: GenericParam > ) -> T ,
800
803
{
801
804
let ( in_band_defs, ( mut lowered_generics, res) ) = self . with_in_scope_lifetime_defs (
802
805
& generics. params ,
803
806
|this| {
804
- let itctx = ImplTraitContext :: Universal ;
805
807
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) )
807
815
} )
808
816
} ,
809
817
) ;
@@ -1069,7 +1077,7 @@ impl<'a> LoweringContext<'a> {
1069
1077
P ( self . lower_ty_direct ( t, itctx) )
1070
1078
}
1071
1079
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 {
1073
1081
let kind = match t. node {
1074
1082
TyKind :: Infer => hir:: TyInfer ,
1075
1083
TyKind :: Err => hir:: TyErr ,
@@ -1106,7 +1114,9 @@ impl<'a> LoweringContext<'a> {
1106
1114
) ,
1107
1115
TyKind :: Never => hir:: TyNever ,
1108
1116
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 ( ) )
1110
1120
}
1111
1121
TyKind :: Paren ( ref ty) => {
1112
1122
return self . lower_ty_direct ( ty, itctx) ;
@@ -1140,7 +1150,7 @@ impl<'a> LoweringContext<'a> {
1140
1150
. iter ( )
1141
1151
. filter_map ( |bound| match * bound {
1142
1152
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 ( ) ) )
1144
1154
}
1145
1155
GenericBound :: Trait ( _, TraitBoundModifier :: Maybe ) => None ,
1146
1156
GenericBound :: Outlives ( ref lifetime) => {
@@ -1167,7 +1177,7 @@ impl<'a> LoweringContext<'a> {
1167
1177
|this| this. lower_param_bounds ( bounds, itctx) ,
1168
1178
)
1169
1179
}
1170
- ImplTraitContext :: Universal => {
1180
+ ImplTraitContext :: Universal ( in_band_ty_params ) => {
1171
1181
self . lower_node_id ( def_node_id) ;
1172
1182
// Add a definition for the in-band TyParam
1173
1183
let def_index = self
@@ -1176,10 +1186,13 @@ impl<'a> LoweringContext<'a> {
1176
1186
. opt_def_index ( def_node_id)
1177
1187
. unwrap ( ) ;
1178
1188
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
+ ) ;
1180
1193
// Set the name to `impl Bound1 + Bound2`
1181
1194
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 {
1183
1196
id : def_node_id,
1184
1197
name : ParamName :: Plain ( ident) ,
1185
1198
pure_wrt_drop : false ,
@@ -1502,10 +1515,10 @@ impl<'a> LoweringContext<'a> {
1502
1515
qself : & Option < QSelf > ,
1503
1516
p : & Path ,
1504
1517
param_mode : ParamMode ,
1505
- itctx : ImplTraitContext ,
1518
+ mut itctx : ImplTraitContext ,
1506
1519
) -> hir:: QPath {
1507
1520
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 ( ) ) ) ;
1509
1522
1510
1523
let resolution = self . resolver
1511
1524
. get_resolution ( id)
@@ -1592,7 +1605,7 @@ impl<'a> LoweringContext<'a> {
1592
1605
param_mode,
1593
1606
num_lifetimes,
1594
1607
parenthesized_generic_args,
1595
- itctx,
1608
+ itctx. reborrow ( ) ,
1596
1609
)
1597
1610
} )
1598
1611
. collect ( ) ,
@@ -1635,7 +1648,7 @@ impl<'a> LoweringContext<'a> {
1635
1648
param_mode,
1636
1649
0 ,
1637
1650
ParenthesizedGenericArgs :: Warn ,
1638
- itctx,
1651
+ itctx. reborrow ( ) ,
1639
1652
) ) ;
1640
1653
let qpath = hir:: QPath :: TypeRelative ( ty, segment) ;
1641
1654
@@ -1752,16 +1765,16 @@ impl<'a> LoweringContext<'a> {
1752
1765
& mut self ,
1753
1766
data : & AngleBracketedArgs ,
1754
1767
param_mode : ParamMode ,
1755
- itctx : ImplTraitContext ,
1768
+ mut itctx : ImplTraitContext ,
1756
1769
) -> ( hir:: GenericArgs , bool ) {
1757
1770
let & AngleBracketedArgs { ref args, ref bindings, .. } = data;
1758
1771
let has_types = args. iter ( ) . any ( |arg| match arg {
1759
1772
ast:: GenericArg :: Type ( _) => true ,
1760
1773
_ => false ,
1761
1774
} ) ;
1762
1775
( 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 ( ) ,
1765
1778
parenthesized : false ,
1766
1779
} ,
1767
1780
!has_types && param_mode == ParamMode :: Optional )
@@ -1866,15 +1879,15 @@ impl<'a> LoweringContext<'a> {
1866
1879
fn lower_fn_decl (
1867
1880
& mut self ,
1868
1881
decl : & FnDecl ,
1869
- fn_def_id : Option < DefId > ,
1882
+ mut in_band_ty_params : Option < ( DefId , & mut Vec < hir :: GenericParam > ) > ,
1870
1883
impl_trait_return_allow : bool ,
1871
1884
make_ret_async : Option < NodeId > ,
1872
1885
) -> P < hir:: FnDecl > {
1873
1886
let inputs = decl. inputs
1874
1887
. iter ( )
1875
1888
. 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 ) )
1878
1891
} else {
1879
1892
self . lower_ty_direct ( & arg. ty , ImplTraitContext :: Disallowed )
1880
1893
}
@@ -1883,11 +1896,15 @@ impl<'a> LoweringContext<'a> {
1883
1896
1884
1897
let output = if let Some ( ret_id) = make_ret_async {
1885
1898
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
+ )
1887
1904
} else {
1888
1905
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 => {
1891
1908
hir:: Return ( self . lower_ty ( ty, ImplTraitContext :: Existential ( def_id) ) )
1892
1909
}
1893
1910
_ => hir:: Return ( self . lower_ty ( ty, ImplTraitContext :: Disallowed ) ) ,
@@ -2191,17 +2208,19 @@ impl<'a> LoweringContext<'a> {
2191
2208
& mut self ,
2192
2209
params : & Vec < GenericParam > ,
2193
2210
add_bounds : & NodeMap < Vec < GenericBound > > ,
2194
- itctx : ImplTraitContext ,
2211
+ mut itctx : ImplTraitContext ,
2195
2212
) -> 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 ( )
2197
2216
}
2198
2217
2199
2218
fn lower_generic_param ( & mut self ,
2200
2219
param : & GenericParam ,
2201
2220
add_bounds : & NodeMap < Vec < GenericBound > > ,
2202
- itctx : ImplTraitContext )
2221
+ mut itctx : ImplTraitContext )
2203
2222
-> 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 ( ) ) ;
2205
2224
match param. kind {
2206
2225
GenericParamKind :: Lifetime => {
2207
2226
let was_collecting_in_band = self . is_collecting_in_band_lifetimes ;
@@ -2238,8 +2257,9 @@ impl<'a> LoweringContext<'a> {
2238
2257
2239
2258
let add_bounds = add_bounds. get ( & param. id ) . map_or ( & [ ] [ ..] , |x| & x) ;
2240
2259
if !add_bounds. is_empty ( ) {
2260
+ let params = self . lower_param_bounds ( add_bounds, itctx. reborrow ( ) ) . into_iter ( ) ;
2241
2261
bounds = bounds. into_iter ( )
2242
- . chain ( self . lower_param_bounds ( add_bounds , itctx ) . into_iter ( ) )
2262
+ . chain ( params )
2243
2263
. collect ( ) ;
2244
2264
}
2245
2265
@@ -2434,10 +2454,10 @@ impl<'a> LoweringContext<'a> {
2434
2454
fn lower_poly_trait_ref (
2435
2455
& mut self ,
2436
2456
p : & PolyTraitRef ,
2437
- itctx : ImplTraitContext ,
2457
+ mut itctx : ImplTraitContext ,
2438
2458
) -> hir:: PolyTraitRef {
2439
2459
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 ( ) ) ;
2441
2461
let trait_ref = self . with_parent_impl_lifetime_defs (
2442
2462
& bound_generic_params,
2443
2463
|this| this. lower_trait_ref ( & p. trait_ref , itctx) ,
@@ -2482,9 +2502,9 @@ impl<'a> LoweringContext<'a> {
2482
2502
}
2483
2503
}
2484
2504
2485
- fn lower_param_bounds ( & mut self , bounds : & [ GenericBound ] , itctx : ImplTraitContext )
2505
+ fn lower_param_bounds ( & mut self , bounds : & [ GenericBound ] , mut itctx : ImplTraitContext )
2486
2506
-> 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 ( )
2488
2508
}
2489
2509
2490
2510
fn lower_block ( & mut self , b : & Block , targeted_by_break : bool ) -> P < hir:: Block > {
@@ -2585,8 +2605,8 @@ impl<'a> LoweringContext<'a> {
2585
2605
generics,
2586
2606
fn_def_id,
2587
2607
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 ( ) ) ,
2590
2610
) ;
2591
2611
2592
2612
hir:: ItemFn (
@@ -2656,7 +2676,7 @@ impl<'a> LoweringContext<'a> {
2656
2676
ast_generics,
2657
2677
def_id,
2658
2678
AnonymousLifetimeMode :: CreateParameter ,
2659
- |this| {
2679
+ |this, _ | {
2660
2680
let trait_ref = trait_ref. as_ref ( ) . map ( |trait_ref| {
2661
2681
this. lower_trait_ref ( trait_ref, ImplTraitContext :: Disallowed )
2662
2682
} ) ;
@@ -3191,7 +3211,7 @@ impl<'a> LoweringContext<'a> {
3191
3211
generics,
3192
3212
def_id,
3193
3213
AnonymousLifetimeMode :: PassThrough ,
3194
- |this| {
3214
+ |this, _ | {
3195
3215
(
3196
3216
// Disallow impl Trait in foreign items
3197
3217
this. lower_fn_decl ( fdec, None , false , None ) ,
@@ -3226,7 +3246,12 @@ impl<'a> LoweringContext<'a> {
3226
3246
generics,
3227
3247
fn_def_id,
3228
3248
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
+ ) ,
3230
3255
) ;
3231
3256
( generics, hir:: MethodSig { header, decl } )
3232
3257
}
0 commit comments