@@ -1361,26 +1361,73 @@ impl<'a> LoweringContext<'a> {
1361
1361
}
1362
1362
}
1363
1363
1364
+ /// Given an associated type constraint like one of these:
1365
+ ///
1366
+ /// ```
1367
+ /// T: Iterator<Item: Debug>
1368
+ /// ^^^^^^^^^^^
1369
+ /// T: Iterator<Item = Debug>
1370
+ /// ^^^^^^^^^^^^
1371
+ /// ```
1372
+ ///
1373
+ /// returns a `hir::TypeBinding` representing `Item`.
1364
1374
fn lower_assoc_ty_constraint ( & mut self ,
1365
1375
c : & AssocTyConstraint ,
1366
1376
itctx : ImplTraitContext < ' _ > )
1367
1377
-> hir:: TypeBinding {
1368
1378
debug ! ( "lower_assoc_ty_constraint(constraint={:?}, itctx={:?})" , c, itctx) ;
1369
1379
1380
+ // Convert to a type representing the `T::Item` value.
1370
1381
let ty = match c. kind {
1371
1382
AssocTyConstraintKind :: Equality { ref ty } => self . lower_ty ( ty, itctx) ,
1372
1383
AssocTyConstraintKind :: Bound { ref bounds } => {
1373
- let ( existential_desugaring, itctx) = match itctx {
1384
+ // Piggy-back on the impl trait context to figure out
1385
+ // the correct behavior.
1386
+ let ( desugar_to_impl_trait, itctx) = match itctx {
1387
+ // We are in the return position:
1388
+ //
1389
+ // fn foo() -> impl Iterator<Item: Debug>
1390
+ //
1391
+ // so desugar to
1392
+ //
1393
+ // fn foo() -> impl Iterator<Item = impl Debug>
1374
1394
ImplTraitContext :: Existential ( _) => ( true , itctx) ,
1395
+
1396
+ // We are in the argument position, but within a dyn type:
1397
+ //
1398
+ // fn foo(x: dyn Iterator<Item: Debug>)
1399
+ //
1400
+ // so desugar to
1401
+ //
1402
+ // fn foo(x: dyn Iterator<Item = impl Debug>)
1375
1403
ImplTraitContext :: Universal ( _) if self . is_in_dyn_type => ( true , itctx) ,
1404
+
1405
+ // In `type Foo = dyn Iterator<Item: Debug>` we
1406
+ // desugar to `type Foo = dyn Iterator<Item = impl
1407
+ // Debug>` but we have to override the "impl trait
1408
+ // context" to permit `impl Debug` in this
1409
+ // position (it desugars then to an existential
1410
+ // type).
1411
+ //
1376
1412
// FIXME: this is only needed until `impl Trait` is allowed in type aliases.
1377
1413
ImplTraitContext :: Disallowed ( _) if self . is_in_dyn_type =>
1378
1414
( true , ImplTraitContext :: Existential ( None ) ) ,
1415
+
1416
+ // We are in the argument position, but not within a dyn type:
1417
+ //
1418
+ // fn foo(x: impl Iterator<Item: Debug>)
1419
+ //
1420
+ // so we leave it as is and this gets expanded in
1421
+ // astconv to a bound like `<T as Iterator>::Item:
1422
+ // Debug` where `T` is the type parameter for the
1423
+ // `impl Iterator`.
1379
1424
_ => ( false , itctx) ,
1380
1425
} ;
1381
1426
1382
- if existential_desugaring {
1383
- // Desugar `AssocTy: Bounds` into `AssocTy = impl Bounds`.
1427
+ if desugar_to_impl_trait {
1428
+ // Desugar `AssocTy: Bounds` into `AssocTy = impl
1429
+ // Bounds`. We do this by constructing the HIR
1430
+ // for "impl bounds" and then lowering that.
1384
1431
1385
1432
let impl_trait_node_id = self . sess . next_node_id ( ) ;
1386
1433
let parent_def_index = self . current_hir_id_owner . last ( ) . unwrap ( ) . 0 ;
0 commit comments