@@ -1361,26 +1361,73 @@ impl<'a> LoweringContext<'a> {
13611361 }
13621362 }
13631363
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`.
13641374 fn lower_assoc_ty_constraint ( & mut self ,
13651375 c : & AssocTyConstraint ,
13661376 itctx : ImplTraitContext < ' _ > )
13671377 -> hir:: TypeBinding {
13681378 debug ! ( "lower_assoc_ty_constraint(constraint={:?}, itctx={:?})" , c, itctx) ;
13691379
1380+ // Convert to a type representing the `T::Item` value.
13701381 let ty = match c. kind {
13711382 AssocTyConstraintKind :: Equality { ref ty } => self . lower_ty ( ty, itctx) ,
13721383 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>
13741394 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>)
13751403 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+ //
13761412 // FIXME: this is only needed until `impl Trait` is allowed in type aliases.
13771413 ImplTraitContext :: Disallowed ( _) if self . is_in_dyn_type =>
13781414 ( 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`.
13791424 _ => ( false , itctx) ,
13801425 } ;
13811426
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.
13841431
13851432 let impl_trait_node_id = self . sess . next_node_id ( ) ;
13861433 let parent_def_index = self . current_hir_id_owner . last ( ) . unwrap ( ) . 0 ;
0 commit comments