@@ -106,6 +106,7 @@ pub struct LoweringContext<'a> {
106
106
loop_scopes : Vec < NodeId > ,
107
107
is_in_loop_condition : bool ,
108
108
is_in_trait_impl : bool ,
109
+ is_in_dyn_type : bool ,
109
110
110
111
/// What to do when we encounter either an "anonymous lifetime
111
112
/// reference". The term "anonymous" is meant to encompass both
@@ -195,20 +196,17 @@ enum ImplTraitContext<'a> {
195
196
/// (e.g., for consts and statics).
196
197
Existential ( Option < DefId > /* fn def-ID */ ) ,
197
198
198
- /// Treat `impl Trait` as a bound on the associated type applied to the trait.
199
- /// Example: `trait Foo { type Bar: Iterator<Item = impl Debug>; }` is conceptually
200
- /// equivalent to `trait Foo where <Self::Bar as Iterator>::Item: Debug
201
- /// { type Bar: Iterator; }`.
202
- AssociatedTy ,
203
-
204
199
/// `impl Trait` is not accepted in this position.
205
200
Disallowed ( ImplTraitPosition ) ,
206
201
}
207
202
208
203
/// Position in which `impl Trait` is disallowed. Used for error reporting.
209
204
#[ derive( Debug , Copy , Clone , PartialEq , Eq ) ]
210
205
enum ImplTraitPosition {
206
+ /// Disallowed in `let` / `const` / `static` bindings.
211
207
Binding ,
208
+
209
+ /// All other posiitons.
212
210
Other ,
213
211
}
214
212
@@ -223,7 +221,6 @@ impl<'a> ImplTraitContext<'a> {
223
221
match self {
224
222
Universal ( params) => Universal ( params) ,
225
223
Existential ( fn_def_id) => Existential ( * fn_def_id) ,
226
- AssociatedTy => AssociatedTy ,
227
224
Disallowed ( pos) => Disallowed ( * pos) ,
228
225
}
229
226
}
@@ -256,6 +253,8 @@ pub fn lower_crate(
256
253
catch_scopes : Vec :: new ( ) ,
257
254
loop_scopes : Vec :: new ( ) ,
258
255
is_in_loop_condition : false ,
256
+ is_in_trait_impl : false ,
257
+ is_in_dyn_type : false ,
259
258
anonymous_lifetime_mode : AnonymousLifetimeMode :: PassThrough ,
260
259
type_def_lifetime_params : Default :: default ( ) ,
261
260
current_module : CRATE_NODE_ID ,
@@ -265,7 +264,6 @@ pub fn lower_crate(
265
264
is_generator : false ,
266
265
is_async_body : false ,
267
266
current_item : None ,
268
- is_in_trait_impl : false ,
269
267
lifetimes_to_define : Vec :: new ( ) ,
270
268
is_collecting_in_band_lifetimes : false ,
271
269
in_scope_lifetimes : Vec :: new ( ) ,
@@ -1230,6 +1228,20 @@ impl<'a> LoweringContext<'a> {
1230
1228
result
1231
1229
}
1232
1230
1231
+ fn with_dyn_type_scope < T , F > ( & mut self , in_scope : bool , f : F ) -> T
1232
+ where
1233
+ F : FnOnce ( & mut LoweringContext < ' _ > ) -> T ,
1234
+ {
1235
+ let was_in_dyn_type = self . is_in_dyn_type ;
1236
+ self . is_in_dyn_type = in_scope;
1237
+
1238
+ let result = f ( self ) ;
1239
+
1240
+ self . is_in_dyn_type = was_in_dyn_type;
1241
+
1242
+ result
1243
+ }
1244
+
1233
1245
fn with_new_scopes < T , F > ( & mut self , f : F ) -> T
1234
1246
where
1235
1247
F : FnOnce ( & mut LoweringContext < ' _ > ) -> T ,
@@ -1353,24 +1365,58 @@ impl<'a> LoweringContext<'a> {
1353
1365
c : & AssocTyConstraint ,
1354
1366
itctx : ImplTraitContext < ' _ > )
1355
1367
-> hir:: TypeBinding {
1368
+ debug ! ( "lower_assoc_ty_constraint(constraint={:?}, itctx={:?})" , c, itctx) ;
1369
+
1356
1370
let ty = match c. kind {
1357
1371
AssocTyConstraintKind :: Equality { ref ty } => self . lower_ty ( ty, itctx) ,
1358
1372
AssocTyConstraintKind :: Bound { ref bounds } => {
1359
- // Desugar `AssocTy: Bounds` into `AssocTy = impl Bounds`.
1360
- let impl_ty_node_id = self . sess . next_node_id ( ) ;
1361
- let parent_def_index = self . current_hir_id_owner . last ( ) . unwrap ( ) . 0 ;
1362
- self . resolver . definitions ( ) . create_def_with_parent (
1363
- parent_def_index,
1364
- impl_ty_node_id,
1365
- DefPathData :: Misc ,
1366
- DefIndexAddressSpace :: High ,
1367
- Mark :: root ( ) ,
1368
- DUMMY_SP ) ;
1369
- self . lower_ty ( & Ty {
1370
- id : self . sess . next_node_id ( ) ,
1371
- node : TyKind :: ImplTrait ( impl_ty_node_id, bounds. clone ( ) ) ,
1372
- span : DUMMY_SP ,
1373
- } , itctx)
1373
+ let ( existential_desugaring, itctx) = match itctx {
1374
+ ImplTraitContext :: Existential ( _) => ( true , itctx) ,
1375
+ ImplTraitContext :: Universal ( _) if self . is_in_dyn_type => ( true , itctx) ,
1376
+ // FIXME: this is only needed until `impl Trait` is allowed in type aliases.
1377
+ ImplTraitContext :: Disallowed ( _) if self . is_in_dyn_type =>
1378
+ ( true , ImplTraitContext :: Existential ( None ) ) ,
1379
+ _ => ( false , itctx) ,
1380
+ } ;
1381
+
1382
+ if existential_desugaring {
1383
+ // Desugar `AssocTy: Bounds` into `AssocTy = impl Bounds`.
1384
+
1385
+ let impl_ty_node_id = self . sess . next_node_id ( ) ;
1386
+ let parent_def_index = self . current_hir_id_owner . last ( ) . unwrap ( ) . 0 ;
1387
+ self . resolver . definitions ( ) . create_def_with_parent (
1388
+ parent_def_index,
1389
+ impl_ty_node_id,
1390
+ DefPathData :: Misc ,
1391
+ DefIndexAddressSpace :: High ,
1392
+ Mark :: root ( ) ,
1393
+ DUMMY_SP
1394
+ ) ;
1395
+
1396
+ self . with_dyn_type_scope ( false , |this| {
1397
+ this. lower_ty (
1398
+ & Ty {
1399
+ id : this. sess . next_node_id ( ) ,
1400
+ node : TyKind :: ImplTrait ( impl_ty_node_id, bounds. clone ( ) ) ,
1401
+ span : DUMMY_SP ,
1402
+ } ,
1403
+ itctx,
1404
+ )
1405
+ } )
1406
+ } else {
1407
+ // Desugar `AssocTy: Bounds` into `AssocTy = ∃ T (T: Bounds)`, where the
1408
+ // "false existential" later desugars into a trait predicate.
1409
+
1410
+ let bounds = self . lower_param_bounds ( bounds, itctx) ;
1411
+
1412
+ let id = self . sess . next_node_id ( ) ;
1413
+ let LoweredNodeId { node_id : _, hir_id } = self . lower_node_id ( id) ;
1414
+ P ( hir:: Ty {
1415
+ hir_id,
1416
+ node : hir:: TyKind :: AssocTyExistential ( bounds) ,
1417
+ span : DUMMY_SP ,
1418
+ } )
1419
+ }
1374
1420
}
1375
1421
} ;
1376
1422
@@ -1477,23 +1523,26 @@ impl<'a> LoweringContext<'a> {
1477
1523
}
1478
1524
TyKind :: TraitObject ( ref bounds, kind) => {
1479
1525
let mut lifetime_bound = None ;
1480
- let bounds = bounds
1481
- . iter ( )
1482
- . filter_map ( |bound| match * bound {
1483
- GenericBound :: Trait ( ref ty, TraitBoundModifier :: None ) => {
1484
- Some ( self . lower_poly_trait_ref ( ty, itctx. reborrow ( ) ) )
1485
- }
1486
- GenericBound :: Trait ( _, TraitBoundModifier :: Maybe ) => None ,
1487
- GenericBound :: Outlives ( ref lifetime) => {
1488
- if lifetime_bound. is_none ( ) {
1489
- lifetime_bound = Some ( self . lower_lifetime ( lifetime) ) ;
1526
+ let ( bounds, lifetime_bound) = self . with_dyn_type_scope ( true , |this| {
1527
+ let bounds = bounds
1528
+ . iter ( )
1529
+ . filter_map ( |bound| match * bound {
1530
+ GenericBound :: Trait ( ref ty, TraitBoundModifier :: None ) => {
1531
+ Some ( this. lower_poly_trait_ref ( ty, itctx. reborrow ( ) ) )
1490
1532
}
1491
- None
1492
- }
1493
- } )
1494
- . collect ( ) ;
1495
- let lifetime_bound =
1496
- lifetime_bound. unwrap_or_else ( || self . elided_dyn_bound ( t. span ) ) ;
1533
+ GenericBound :: Trait ( _, TraitBoundModifier :: Maybe ) => None ,
1534
+ GenericBound :: Outlives ( ref lifetime) => {
1535
+ if lifetime_bound. is_none ( ) {
1536
+ lifetime_bound = Some ( this. lower_lifetime ( lifetime) ) ;
1537
+ }
1538
+ None
1539
+ }
1540
+ } )
1541
+ . collect ( ) ;
1542
+ let lifetime_bound =
1543
+ lifetime_bound. unwrap_or_else ( || this. elided_dyn_bound ( t. span ) ) ;
1544
+ ( bounds, lifetime_bound)
1545
+ } ) ;
1497
1546
if kind != TraitObjectSyntax :: Dyn {
1498
1547
self . maybe_lint_bare_trait ( t. span , t. id , false ) ;
1499
1548
}
@@ -1544,16 +1593,6 @@ impl<'a> LoweringContext<'a> {
1544
1593
} ) ,
1545
1594
) )
1546
1595
}
1547
- ImplTraitContext :: AssociatedTy => {
1548
- let hir_bounds = self . lower_param_bounds (
1549
- bounds,
1550
- ImplTraitContext :: AssociatedTy ,
1551
- ) ;
1552
-
1553
- hir:: TyKind :: AssocTyExistential (
1554
- hir_bounds,
1555
- )
1556
- }
1557
1596
ImplTraitContext :: Disallowed ( pos) => {
1558
1597
let allowed_in = if self . sess . features_untracked ( )
1559
1598
. impl_trait_in_bindings {
@@ -2407,7 +2446,8 @@ impl<'a> LoweringContext<'a> {
2407
2446
FunctionRetTy :: Ty ( ref ty) => match in_band_ty_params {
2408
2447
Some ( ( def_id, _) ) if impl_trait_return_allow => {
2409
2448
hir:: Return ( self . lower_ty ( ty,
2410
- ImplTraitContext :: Existential ( Some ( def_id) ) ) )
2449
+ ImplTraitContext :: Existential ( Some ( def_id) )
2450
+ ) )
2411
2451
}
2412
2452
_ => {
2413
2453
hir:: Return ( self . lower_ty ( ty, ImplTraitContext :: disallowed ( ) ) )
@@ -2770,7 +2810,7 @@ impl<'a> LoweringContext<'a> {
2770
2810
2771
2811
let kind = hir:: GenericParamKind :: Type {
2772
2812
default : default. as_ref ( ) . map ( |x| {
2773
- self . lower_ty ( x, ImplTraitContext :: disallowed ( ) )
2813
+ self . lower_ty ( x, ImplTraitContext :: Existential ( None ) )
2774
2814
} ) ,
2775
2815
synthetic : param. attrs . iter ( )
2776
2816
. filter ( |attr| attr. check_name ( sym:: rustc_synthetic) )
@@ -3275,39 +3315,43 @@ impl<'a> LoweringContext<'a> {
3275
3315
ItemKind :: ForeignMod ( ref nm) => hir:: ItemKind :: ForeignMod ( self . lower_foreign_mod ( nm) ) ,
3276
3316
ItemKind :: GlobalAsm ( ref ga) => hir:: ItemKind :: GlobalAsm ( self . lower_global_asm ( ga) ) ,
3277
3317
ItemKind :: Ty ( ref t, ref generics) => hir:: ItemKind :: Ty (
3278
- self . lower_ty ( t, ImplTraitContext :: AssociatedTy ) ,
3279
- self . lower_generics ( generics, ImplTraitContext :: AssociatedTy ) ,
3318
+ self . lower_ty ( t, ImplTraitContext :: disallowed ( ) ) ,
3319
+ self . lower_generics ( generics, ImplTraitContext :: disallowed ( ) ) ,
3280
3320
) ,
3281
3321
ItemKind :: Existential ( ref b, ref generics) => hir:: ItemKind :: Existential (
3282
3322
hir:: ExistTy {
3283
- generics : self . lower_generics ( generics, ImplTraitContext :: AssociatedTy ) ,
3284
- bounds : self . lower_param_bounds ( b, ImplTraitContext :: AssociatedTy ) ,
3323
+ generics : self . lower_generics ( generics,
3324
+ ImplTraitContext :: Existential ( None ) ) ,
3325
+ bounds : self . lower_param_bounds ( b,
3326
+ ImplTraitContext :: Existential ( None ) ) ,
3285
3327
impl_trait_fn : None ,
3286
3328
origin : hir:: ExistTyOrigin :: ExistentialType ,
3287
3329
} ,
3288
3330
) ,
3289
- ItemKind :: Enum ( ref enum_definition, ref generics) => hir:: ItemKind :: Enum (
3290
- hir:: EnumDef {
3291
- variants : enum_definition
3292
- . variants
3293
- . iter ( )
3294
- . map ( |x| self . lower_variant ( x) )
3295
- . collect ( ) ,
3296
- } ,
3297
- self . lower_generics ( generics, ImplTraitContext :: AssociatedTy ) ,
3298
- ) ,
3331
+ ItemKind :: Enum ( ref enum_definition, ref generics) => {
3332
+ hir:: ItemKind :: Enum (
3333
+ hir:: EnumDef {
3334
+ variants : enum_definition
3335
+ . variants
3336
+ . iter ( )
3337
+ . map ( |x| self . lower_variant ( x) )
3338
+ . collect ( ) ,
3339
+ } ,
3340
+ self . lower_generics ( generics, ImplTraitContext :: disallowed ( ) ) ,
3341
+ )
3342
+ } ,
3299
3343
ItemKind :: Struct ( ref struct_def, ref generics) => {
3300
3344
let struct_def = self . lower_variant_data ( struct_def) ;
3301
3345
hir:: ItemKind :: Struct (
3302
3346
struct_def,
3303
- self . lower_generics ( generics, ImplTraitContext :: AssociatedTy ) ,
3347
+ self . lower_generics ( generics, ImplTraitContext :: disallowed ( ) ) ,
3304
3348
)
3305
3349
}
3306
3350
ItemKind :: Union ( ref vdata, ref generics) => {
3307
3351
let vdata = self . lower_variant_data ( vdata) ;
3308
3352
hir:: ItemKind :: Union (
3309
3353
vdata,
3310
- self . lower_generics ( generics, ImplTraitContext :: AssociatedTy ) ,
3354
+ self . lower_generics ( generics, ImplTraitContext :: disallowed ( ) ) ,
3311
3355
)
3312
3356
}
3313
3357
ItemKind :: Impl (
@@ -3675,9 +3719,9 @@ impl<'a> LoweringContext<'a> {
3675
3719
( generics, hir:: TraitItemKind :: Method ( sig, hir:: TraitMethod :: Provided ( body_id) ) )
3676
3720
}
3677
3721
TraitItemKind :: Type ( ref bounds, ref default) => {
3678
- let generics = self . lower_generics ( & i. generics , ImplTraitContext :: AssociatedTy ) ;
3722
+ let generics = self . lower_generics ( & i. generics , ImplTraitContext :: disallowed ( ) ) ;
3679
3723
let node = hir:: TraitItemKind :: Type (
3680
- self . lower_param_bounds ( bounds, ImplTraitContext :: AssociatedTy ) ,
3724
+ self . lower_param_bounds ( bounds, ImplTraitContext :: disallowed ( ) ) ,
3681
3725
default
3682
3726
. as_ref ( )
3683
3727
. map ( |x| self . lower_ty ( x, ImplTraitContext :: disallowed ( ) ) ) ,
0 commit comments