@@ -109,13 +109,6 @@ pub struct LoweringContext<'a> {
109
109
/// written at all (e.g., `&T` or `std::cell::Ref<T>`).
110
110
anonymous_lifetime_mode : AnonymousLifetimeMode ,
111
111
112
- // This is a list of in-band type definitions being generated by
113
- // Argument-position `impl Trait`.
114
- // When traversing a signature such as `fn foo(x: impl Trait)`,
115
- // we record `impl Trait` as a new type parameter, then later
116
- // add it on to `foo`s generics.
117
- in_band_ty_params : Vec < hir:: TyParam > ,
118
-
119
112
// Used to create lifetime definitions from in-band lifetime usages.
120
113
// e.g. `fn foo(x: &'x u8) -> &'x u8` to `fn foo<'x>(x: &'x u8) -> &'x u8`
121
114
// When a named lifetime is encountered in a function or impl header and
@@ -170,26 +163,41 @@ pub trait Resolver {
170
163
) -> hir:: Path ;
171
164
}
172
165
173
- #[ derive( Clone , Copy , Debug ) ]
174
- enum ImplTraitContext {
166
+ #[ derive( Debug ) ]
167
+ enum ImplTraitContext < ' a > {
175
168
/// Treat `impl Trait` as shorthand for a new universal generic parameter.
176
169
/// Example: `fn foo(x: impl Debug)`, where `impl Debug` is conceptually
177
170
/// equivalent to a fresh universal parameter like `fn foo<T: Debug>(x: T)`.
178
171
///
179
172
/// We store a DefId here so we can look up necessary information later
180
- Universal ( DefId ) ,
173
+ ///
174
+ /// Newly generated parameters should be inserted into the given `Vec`
175
+ Universal ( DefId , & ' a mut Vec < hir:: TyParam > ) ,
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
184
179
/// equivalent to a fresh existential parameter like `abstract type T; fn foo() -> T`.
185
180
///
186
181
/// We store a DefId here so we can look up necessary information later
187
- Existential ( DefId ) ,
182
+ ///
183
+ /// All generics of the surrounding function must go into the generated existential type
184
+ Existential ( DefId , & ' a [ hir:: TyParam ] ) ,
188
185
189
186
/// `impl Trait` is not accepted in this position.
190
187
Disallowed ,
191
188
}
192
189
190
+ impl < ' a > ImplTraitContext < ' a > {
191
+ fn reborrow ( & ' b mut self ) -> ImplTraitContext < ' b > {
192
+ use self :: ImplTraitContext :: * ;
193
+ match self {
194
+ Universal ( did, params) => Universal ( * did, params) ,
195
+ Existential ( did, params) => Existential ( * did, params) ,
196
+ Disallowed => Disallowed ,
197
+ }
198
+ }
199
+ }
200
+
193
201
pub fn lower_crate (
194
202
sess : & Session ,
195
203
cstore : & CrateStore ,
@@ -225,7 +233,6 @@ pub fn lower_crate(
225
233
node_id_to_hir_id : IndexVec :: new ( ) ,
226
234
is_generator : false ,
227
235
is_in_trait_impl : false ,
228
- in_band_ty_params : Vec :: new ( ) ,
229
236
lifetimes_to_define : Vec :: new ( ) ,
230
237
is_collecting_in_band_lifetimes : false ,
231
238
in_scope_lifetimes : Vec :: new ( ) ,
@@ -645,7 +652,7 @@ impl<'a> LoweringContext<'a> {
645
652
f : F ,
646
653
) -> ( Vec < hir:: GenericParam > , T )
647
654
where
648
- F : FnOnce ( & mut LoweringContext ) -> T ,
655
+ F : FnOnce ( & mut LoweringContext ) -> ( Vec < hir :: TyParam > , T ) ,
649
656
{
650
657
assert ! ( !self . is_collecting_in_band_lifetimes) ;
651
658
assert ! ( self . lifetimes_to_define. is_empty( ) ) ;
@@ -656,13 +663,11 @@ impl<'a> LoweringContext<'a> {
656
663
self . anonymous_lifetime_mode = anonymous_lifetime_mode;
657
664
}
658
665
659
- assert ! ( self . in_band_ty_params. is_empty( ) ) ;
660
- let res = f ( self ) ;
666
+ let ( in_band_ty_params, res) = f ( self ) ;
661
667
662
668
self . is_collecting_in_band_lifetimes = false ;
663
669
self . anonymous_lifetime_mode = old_anonymous_lifetime_mode;
664
670
665
- let in_band_ty_params = self . in_band_ty_params . split_off ( 0 ) ;
666
671
let lifetimes_to_define = self . lifetimes_to_define . split_off ( 0 ) ;
667
672
668
673
let params = lifetimes_to_define
@@ -804,17 +809,22 @@ impl<'a> LoweringContext<'a> {
804
809
f : F ,
805
810
) -> ( hir:: Generics , T )
806
811
where
807
- F : FnOnce ( & mut LoweringContext ) -> T ,
812
+ F : FnOnce ( & mut LoweringContext , & mut Vec < hir :: TyParam > ) -> T ,
808
813
{
809
814
let ( in_band_defs, ( mut lowered_generics, res) ) = self . with_in_scope_lifetime_defs (
810
815
generics. params . iter ( ) . filter_map ( |p| match p {
811
816
GenericParam :: Lifetime ( ld) => Some ( ld) ,
812
817
_ => None ,
813
818
} ) ,
814
819
|this| {
815
- let itctx = ImplTraitContext :: Universal ( parent_id) ;
816
820
this. collect_in_band_defs ( parent_id, anonymous_lifetime_mode, |this| {
817
- ( this. lower_generics ( generics, itctx) , f ( this) )
821
+ let mut params = Vec :: new ( ) ;
822
+ let generics = this. lower_generics (
823
+ generics,
824
+ ImplTraitContext :: Universal ( parent_id, & mut params) ,
825
+ ) ;
826
+ let res = f ( this, & mut params) ;
827
+ ( params, ( generics, res) )
818
828
} )
819
829
} ,
820
830
) ;
@@ -1037,7 +1047,7 @@ impl<'a> LoweringContext<'a> {
1037
1047
}
1038
1048
}
1039
1049
1040
- fn lower_ty ( & mut self , t : & Ty , itctx : ImplTraitContext ) -> P < hir:: Ty > {
1050
+ fn lower_ty ( & mut self , t : & Ty , mut itctx : ImplTraitContext ) -> P < hir:: Ty > {
1041
1051
let kind = match t. node {
1042
1052
TyKind :: Infer => hir:: TyInfer ,
1043
1053
TyKind :: Err => hir:: TyErr ,
@@ -1077,7 +1087,7 @@ impl<'a> LoweringContext<'a> {
1077
1087
) ,
1078
1088
TyKind :: Never => hir:: TyNever ,
1079
1089
TyKind :: Tup ( ref tys) => {
1080
- hir:: TyTup ( tys. iter ( ) . map ( |ty| self . lower_ty ( ty, itctx) ) . collect ( ) )
1090
+ hir:: TyTup ( tys. iter ( ) . map ( |ty| self . lower_ty ( ty, itctx. reborrow ( ) ) ) . collect ( ) )
1081
1091
}
1082
1092
TyKind :: Paren ( ref ty) => {
1083
1093
return self . lower_ty ( ty, itctx) ;
@@ -1111,7 +1121,7 @@ impl<'a> LoweringContext<'a> {
1111
1121
. iter ( )
1112
1122
. filter_map ( |bound| match * bound {
1113
1123
TraitTyParamBound ( ref ty, TraitBoundModifier :: None ) => {
1114
- Some ( self . lower_poly_trait_ref ( ty, itctx) )
1124
+ Some ( self . lower_poly_trait_ref ( ty, itctx. reborrow ( ) ) )
1115
1125
}
1116
1126
TraitTyParamBound ( _, TraitBoundModifier :: Maybe ) => None ,
1117
1127
RegionTyParamBound ( ref lifetime) => {
@@ -1132,7 +1142,7 @@ impl<'a> LoweringContext<'a> {
1132
1142
TyKind :: ImplTrait ( exist_ty_node_id, ref bounds) => {
1133
1143
let span = t. span ;
1134
1144
match itctx {
1135
- ImplTraitContext :: Existential ( fn_def_id) => {
1145
+ ImplTraitContext :: Existential ( fn_def_id, _ ) => {
1136
1146
// Make sure we know that some funky desugaring has been going on here.
1137
1147
// This is a first: there is code in other places like for loop
1138
1148
// desugaring that explicitly states that we don't want to track that.
@@ -1214,7 +1224,7 @@ impl<'a> LoweringContext<'a> {
1214
1224
)
1215
1225
} )
1216
1226
}
1217
- ImplTraitContext :: Universal ( def_id) => {
1227
+ ImplTraitContext :: Universal ( def_id, in_band_ty_params ) => {
1218
1228
let def_node_id = self . next_id ( ) . node_id ;
1219
1229
1220
1230
// Add a definition for the in-band TyParam
@@ -1227,10 +1237,13 @@ impl<'a> LoweringContext<'a> {
1227
1237
span,
1228
1238
) ;
1229
1239
1230
- let hir_bounds = self . lower_bounds ( bounds, itctx) ;
1240
+ let hir_bounds = self . lower_bounds (
1241
+ bounds,
1242
+ ImplTraitContext :: Universal ( def_id, in_band_ty_params) ,
1243
+ ) ;
1231
1244
// Set the name to `impl Bound1 + Bound2`
1232
1245
let name = Symbol :: intern ( & pprust:: ty_to_string ( t) ) ;
1233
- self . in_band_ty_params . push ( hir:: TyParam {
1246
+ in_band_ty_params. push ( hir:: TyParam {
1234
1247
name,
1235
1248
id : def_node_id,
1236
1249
bounds : hir_bounds,
@@ -1472,10 +1485,10 @@ impl<'a> LoweringContext<'a> {
1472
1485
qself : & Option < QSelf > ,
1473
1486
p : & Path ,
1474
1487
param_mode : ParamMode ,
1475
- itctx : ImplTraitContext ,
1488
+ mut itctx : ImplTraitContext ,
1476
1489
) -> hir:: QPath {
1477
1490
let qself_position = qself. as_ref ( ) . map ( |q| q. position ) ;
1478
- let qself = qself. as_ref ( ) . map ( |q| self . lower_ty ( & q. ty , itctx) ) ;
1491
+ let qself = qself. as_ref ( ) . map ( |q| self . lower_ty ( & q. ty , itctx. reborrow ( ) ) ) ;
1479
1492
1480
1493
let resolution = self . resolver
1481
1494
. get_resolution ( id)
@@ -1562,7 +1575,7 @@ impl<'a> LoweringContext<'a> {
1562
1575
param_mode,
1563
1576
num_lifetimes,
1564
1577
parenthesized_generic_args,
1565
- itctx,
1578
+ itctx. reborrow ( ) ,
1566
1579
)
1567
1580
} )
1568
1581
. collect ( ) ,
@@ -1605,7 +1618,7 @@ impl<'a> LoweringContext<'a> {
1605
1618
param_mode,
1606
1619
0 ,
1607
1620
ParenthesizedGenericArgs :: Warn ,
1608
- itctx,
1621
+ itctx. reborrow ( ) ,
1609
1622
) ) ;
1610
1623
let qpath = hir:: QPath :: TypeRelative ( ty, segment) ;
1611
1624
@@ -1713,7 +1726,7 @@ impl<'a> LoweringContext<'a> {
1713
1726
& mut self ,
1714
1727
data : & AngleBracketedParameterData ,
1715
1728
param_mode : ParamMode ,
1716
- itctx : ImplTraitContext ,
1729
+ mut itctx : ImplTraitContext ,
1717
1730
) -> ( hir:: PathParameters , bool ) {
1718
1731
let & AngleBracketedParameterData {
1719
1732
ref lifetimes,
@@ -1724,10 +1737,10 @@ impl<'a> LoweringContext<'a> {
1724
1737
(
1725
1738
hir:: PathParameters {
1726
1739
lifetimes : self . lower_lifetimes ( lifetimes) ,
1727
- types : types. iter ( ) . map ( |ty| self . lower_ty ( ty, itctx) ) . collect ( ) ,
1740
+ types : types. iter ( ) . map ( |ty| self . lower_ty ( ty, itctx. reborrow ( ) ) ) . collect ( ) ,
1728
1741
bindings : bindings
1729
1742
. iter ( )
1730
- . map ( |b| self . lower_ty_binding ( b, itctx) )
1743
+ . map ( |b| self . lower_ty_binding ( b, itctx. reborrow ( ) ) )
1731
1744
. collect ( ) ,
1732
1745
parenthesized : false ,
1733
1746
} ,
@@ -1835,7 +1848,7 @@ impl<'a> LoweringContext<'a> {
1835
1848
fn lower_fn_decl (
1836
1849
& mut self ,
1837
1850
decl : & FnDecl ,
1838
- fn_def_id : Option < DefId > ,
1851
+ mut in_band_ty_params : Option < ( DefId , & mut Vec < hir :: TyParam > ) > ,
1839
1852
impl_trait_return_allow : bool ,
1840
1853
) -> P < hir:: FnDecl > {
1841
1854
// NOTE: The two last parameters here have to do with impl Trait. If fn_def_id is Some,
@@ -1849,17 +1862,17 @@ impl<'a> LoweringContext<'a> {
1849
1862
inputs : decl. inputs
1850
1863
. iter ( )
1851
1864
. map ( |arg| {
1852
- if let Some ( def_id) = fn_def_id {
1853
- self . lower_ty ( & arg. ty , ImplTraitContext :: Universal ( def_id) )
1865
+ if let Some ( ( def_id, ibty ) ) = in_band_ty_params . as_mut ( ) {
1866
+ self . lower_ty ( & arg. ty , ImplTraitContext :: Universal ( * def_id, ibty ) )
1854
1867
} else {
1855
1868
self . lower_ty ( & arg. ty , ImplTraitContext :: Disallowed )
1856
1869
}
1857
1870
} )
1858
1871
. collect ( ) ,
1859
1872
output : match decl. output {
1860
- FunctionRetTy :: Ty ( ref ty) => match fn_def_id {
1861
- Some ( def_id) if impl_trait_return_allow => {
1862
- hir:: Return ( self . lower_ty ( ty, ImplTraitContext :: Existential ( def_id) ) )
1873
+ FunctionRetTy :: Ty ( ref ty) => match in_band_ty_params {
1874
+ Some ( ( def_id, ref mut ibty ) ) if impl_trait_return_allow => {
1875
+ hir:: Return ( self . lower_ty ( ty, ImplTraitContext :: Existential ( def_id, ibty ) ) )
1863
1876
}
1864
1877
_ => hir:: Return ( self . lower_ty ( ty, ImplTraitContext :: Disallowed ) ) ,
1865
1878
} ,
@@ -1894,7 +1907,7 @@ impl<'a> LoweringContext<'a> {
1894
1907
& mut self ,
1895
1908
tp : & TyParam ,
1896
1909
add_bounds : & [ TyParamBound ] ,
1897
- itctx : ImplTraitContext ,
1910
+ mut itctx : ImplTraitContext ,
1898
1911
) -> hir:: TyParam {
1899
1912
let mut name = self . lower_ident ( tp. ident ) ;
1900
1913
@@ -1905,11 +1918,11 @@ impl<'a> LoweringContext<'a> {
1905
1918
name = Symbol :: gensym ( "Self" ) ;
1906
1919
}
1907
1920
1908
- let mut bounds = self . lower_bounds ( & tp. bounds , itctx) ;
1921
+ let mut bounds = self . lower_bounds ( & tp. bounds , itctx. reborrow ( ) ) ;
1909
1922
if !add_bounds. is_empty ( ) {
1910
1923
bounds = bounds
1911
1924
. into_iter ( )
1912
- . chain ( self . lower_bounds ( add_bounds, itctx) . into_iter ( ) )
1925
+ . chain ( self . lower_bounds ( add_bounds, itctx. reborrow ( ) ) . into_iter ( ) )
1913
1926
. collect ( ) ;
1914
1927
}
1915
1928
@@ -1984,7 +1997,7 @@ impl<'a> LoweringContext<'a> {
1984
1997
& mut self ,
1985
1998
params : & Vec < GenericParam > ,
1986
1999
add_bounds : & NodeMap < Vec < TyParamBound > > ,
1987
- itctx : ImplTraitContext ,
2000
+ mut itctx : ImplTraitContext ,
1988
2001
) -> hir:: HirVec < hir:: GenericParam > {
1989
2002
params
1990
2003
. iter ( )
@@ -1995,7 +2008,7 @@ impl<'a> LoweringContext<'a> {
1995
2008
GenericParam :: Type ( ref ty_param) => hir:: GenericParam :: Type ( self . lower_ty_param (
1996
2009
ty_param,
1997
2010
add_bounds. get ( & ty_param. id ) . map_or ( & [ ] [ ..] , |x| & x) ,
1998
- itctx,
2011
+ itctx. reborrow ( ) ,
1999
2012
) ) ,
2000
2013
} )
2001
2014
. collect ( )
@@ -2170,10 +2183,10 @@ impl<'a> LoweringContext<'a> {
2170
2183
fn lower_poly_trait_ref (
2171
2184
& mut self ,
2172
2185
p : & PolyTraitRef ,
2173
- itctx : ImplTraitContext ,
2186
+ mut itctx : ImplTraitContext ,
2174
2187
) -> hir:: PolyTraitRef {
2175
2188
let bound_generic_params =
2176
- self . lower_generic_params ( & p. bound_generic_params , & NodeMap ( ) , itctx) ;
2189
+ self . lower_generic_params ( & p. bound_generic_params , & NodeMap ( ) , itctx. reborrow ( ) ) ;
2177
2190
let trait_ref = self . with_parent_impl_lifetime_defs (
2178
2191
& bound_generic_params
2179
2192
. iter ( )
@@ -2227,11 +2240,11 @@ impl<'a> LoweringContext<'a> {
2227
2240
fn lower_bounds (
2228
2241
& mut self ,
2229
2242
bounds : & [ TyParamBound ] ,
2230
- itctx : ImplTraitContext ,
2243
+ mut itctx : ImplTraitContext ,
2231
2244
) -> hir:: TyParamBounds {
2232
2245
bounds
2233
2246
. iter ( )
2234
- . map ( |bound| self . lower_ty_param_bound ( bound, itctx) )
2247
+ . map ( |bound| self . lower_ty_param_bound ( bound, itctx. reborrow ( ) ) )
2235
2248
. collect ( )
2236
2249
}
2237
2250
@@ -2308,7 +2321,7 @@ impl<'a> LoweringContext<'a> {
2308
2321
generics,
2309
2322
fn_def_id,
2310
2323
AnonymousLifetimeMode :: PassThrough ,
2311
- |this| this. lower_fn_decl ( decl, Some ( fn_def_id) , true ) ,
2324
+ |this, idty | this. lower_fn_decl ( decl, Some ( ( fn_def_id, idty ) ) , true ) ,
2312
2325
) ;
2313
2326
2314
2327
hir:: ItemFn (
@@ -2380,7 +2393,7 @@ impl<'a> LoweringContext<'a> {
2380
2393
ast_generics,
2381
2394
def_id,
2382
2395
AnonymousLifetimeMode :: CreateParameter ,
2383
- |this| {
2396
+ |this, _ | {
2384
2397
let trait_ref = trait_ref. as_ref ( ) . map ( |trait_ref| {
2385
2398
this. lower_trait_ref ( trait_ref, ImplTraitContext :: Disallowed )
2386
2399
} ) ;
@@ -2878,7 +2891,7 @@ impl<'a> LoweringContext<'a> {
2878
2891
generics,
2879
2892
def_id,
2880
2893
AnonymousLifetimeMode :: PassThrough ,
2881
- |this| {
2894
+ |this, _ | {
2882
2895
(
2883
2896
// Disallow impl Trait in foreign items
2884
2897
this. lower_fn_decl ( fdec, None , false ) ,
@@ -2913,7 +2926,11 @@ impl<'a> LoweringContext<'a> {
2913
2926
generics,
2914
2927
fn_def_id,
2915
2928
AnonymousLifetimeMode :: PassThrough ,
2916
- |this| this. lower_fn_decl ( & sig. decl , Some ( fn_def_id) , impl_trait_return_allow) ,
2929
+ |this, idty| this. lower_fn_decl (
2930
+ & sig. decl ,
2931
+ Some ( ( fn_def_id, idty) ) ,
2932
+ impl_trait_return_allow,
2933
+ ) ,
2917
2934
) ;
2918
2935
(
2919
2936
generics,
0 commit comments