@@ -106,6 +106,7 @@ pub struct LoweringContext<'a> {
106106 loop_scopes : Vec < NodeId > ,
107107 is_in_loop_condition : bool ,
108108 is_in_trait_impl : bool ,
109+ is_in_dyn_type : bool ,
109110
110111 /// What to do when we encounter either an "anonymous lifetime
111112 /// reference". The term "anonymous" is meant to encompass both
@@ -195,20 +196,17 @@ enum ImplTraitContext<'a> {
195196 /// (e.g., for consts and statics).
196197 Existential ( Option < DefId > /* fn def-ID */ ) ,
197198
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-
204199 /// `impl Trait` is not accepted in this position.
205200 Disallowed ( ImplTraitPosition ) ,
206201}
207202
208203/// Position in which `impl Trait` is disallowed. Used for error reporting.
209204#[ derive( Debug , Copy , Clone , PartialEq , Eq ) ]
210205enum ImplTraitPosition {
206+ /// Disallowed in `let` / `const` / `static` bindings.
211207 Binding ,
208+
209+ /// All other posiitons.
212210 Other ,
213211}
214212
@@ -223,7 +221,6 @@ impl<'a> ImplTraitContext<'a> {
223221 match self {
224222 Universal ( params) => Universal ( params) ,
225223 Existential ( fn_def_id) => Existential ( * fn_def_id) ,
226- AssociatedTy => AssociatedTy ,
227224 Disallowed ( pos) => Disallowed ( * pos) ,
228225 }
229226 }
@@ -256,6 +253,8 @@ pub fn lower_crate(
256253 catch_scopes : Vec :: new ( ) ,
257254 loop_scopes : Vec :: new ( ) ,
258255 is_in_loop_condition : false ,
256+ is_in_trait_impl : false ,
257+ is_in_dyn_type : false ,
259258 anonymous_lifetime_mode : AnonymousLifetimeMode :: PassThrough ,
260259 type_def_lifetime_params : Default :: default ( ) ,
261260 current_module : CRATE_NODE_ID ,
@@ -265,7 +264,6 @@ pub fn lower_crate(
265264 is_generator : false ,
266265 is_async_body : false ,
267266 current_item : None ,
268- is_in_trait_impl : false ,
269267 lifetimes_to_define : Vec :: new ( ) ,
270268 is_collecting_in_band_lifetimes : false ,
271269 in_scope_lifetimes : Vec :: new ( ) ,
@@ -1230,6 +1228,20 @@ impl<'a> LoweringContext<'a> {
12301228 result
12311229 }
12321230
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+
12331245 fn with_new_scopes < T , F > ( & mut self , f : F ) -> T
12341246 where
12351247 F : FnOnce ( & mut LoweringContext < ' _ > ) -> T ,
@@ -1353,24 +1365,58 @@ impl<'a> LoweringContext<'a> {
13531365 c : & AssocTyConstraint ,
13541366 itctx : ImplTraitContext < ' _ > )
13551367 -> hir:: TypeBinding {
1368+ debug ! ( "lower_assoc_ty_constraint(constraint={:?}, itctx={:?})" , c, itctx) ;
1369+
13561370 let ty = match c. kind {
13571371 AssocTyConstraintKind :: Equality { ref ty } => self . lower_ty ( ty, itctx) ,
13581372 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+ }
13741420 }
13751421 } ;
13761422
@@ -1477,23 +1523,26 @@ impl<'a> LoweringContext<'a> {
14771523 }
14781524 TyKind :: TraitObject ( ref bounds, kind) => {
14791525 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 ( ) ) )
14901532 }
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+ } ) ;
14971546 if kind != TraitObjectSyntax :: Dyn {
14981547 self . maybe_lint_bare_trait ( t. span , t. id , false ) ;
14991548 }
@@ -1544,16 +1593,6 @@ impl<'a> LoweringContext<'a> {
15441593 } ) ,
15451594 ) )
15461595 }
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- }
15571596 ImplTraitContext :: Disallowed ( pos) => {
15581597 let allowed_in = if self . sess . features_untracked ( )
15591598 . impl_trait_in_bindings {
@@ -2407,7 +2446,8 @@ impl<'a> LoweringContext<'a> {
24072446 FunctionRetTy :: Ty ( ref ty) => match in_band_ty_params {
24082447 Some ( ( def_id, _) ) if impl_trait_return_allow => {
24092448 hir:: Return ( self . lower_ty ( ty,
2410- ImplTraitContext :: Existential ( Some ( def_id) ) ) )
2449+ ImplTraitContext :: Existential ( Some ( def_id) )
2450+ ) )
24112451 }
24122452 _ => {
24132453 hir:: Return ( self . lower_ty ( ty, ImplTraitContext :: disallowed ( ) ) )
@@ -2770,7 +2810,7 @@ impl<'a> LoweringContext<'a> {
27702810
27712811 let kind = hir:: GenericParamKind :: Type {
27722812 default : default. as_ref ( ) . map ( |x| {
2773- self . lower_ty ( x, ImplTraitContext :: disallowed ( ) )
2813+ self . lower_ty ( x, ImplTraitContext :: Existential ( None ) )
27742814 } ) ,
27752815 synthetic : param. attrs . iter ( )
27762816 . filter ( |attr| attr. check_name ( sym:: rustc_synthetic) )
@@ -3275,39 +3315,43 @@ impl<'a> LoweringContext<'a> {
32753315 ItemKind :: ForeignMod ( ref nm) => hir:: ItemKind :: ForeignMod ( self . lower_foreign_mod ( nm) ) ,
32763316 ItemKind :: GlobalAsm ( ref ga) => hir:: ItemKind :: GlobalAsm ( self . lower_global_asm ( ga) ) ,
32773317 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 ( ) ) ,
32803320 ) ,
32813321 ItemKind :: Existential ( ref b, ref generics) => hir:: ItemKind :: Existential (
32823322 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 ) ) ,
32853327 impl_trait_fn : None ,
32863328 origin : hir:: ExistTyOrigin :: ExistentialType ,
32873329 } ,
32883330 ) ,
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+ } ,
32993343 ItemKind :: Struct ( ref struct_def, ref generics) => {
33003344 let struct_def = self . lower_variant_data ( struct_def) ;
33013345 hir:: ItemKind :: Struct (
33023346 struct_def,
3303- self . lower_generics ( generics, ImplTraitContext :: AssociatedTy ) ,
3347+ self . lower_generics ( generics, ImplTraitContext :: disallowed ( ) ) ,
33043348 )
33053349 }
33063350 ItemKind :: Union ( ref vdata, ref generics) => {
33073351 let vdata = self . lower_variant_data ( vdata) ;
33083352 hir:: ItemKind :: Union (
33093353 vdata,
3310- self . lower_generics ( generics, ImplTraitContext :: AssociatedTy ) ,
3354+ self . lower_generics ( generics, ImplTraitContext :: disallowed ( ) ) ,
33113355 )
33123356 }
33133357 ItemKind :: Impl (
@@ -3675,9 +3719,9 @@ impl<'a> LoweringContext<'a> {
36753719 ( generics, hir:: TraitItemKind :: Method ( sig, hir:: TraitMethod :: Provided ( body_id) ) )
36763720 }
36773721 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 ( ) ) ;
36793723 let node = hir:: TraitItemKind :: Type (
3680- self . lower_param_bounds ( bounds, ImplTraitContext :: AssociatedTy ) ,
3724+ self . lower_param_bounds ( bounds, ImplTraitContext :: disallowed ( ) ) ,
36813725 default
36823726 . as_ref ( )
36833727 . map ( |x| self . lower_ty ( x, ImplTraitContext :: disallowed ( ) ) ) ,
0 commit comments