Skip to content

Commit 42bcd41

Browse files
committed
Auto merge of rust-lang#97598 - spastorino:simplify-universal-impl-trait-lowering, r=cjgillot
Simplify universal impl trait lowering Closes rust-lang#96644 r? `@cjgillot`
2 parents e714405 + 15a82d6 commit 42bcd41

File tree

3 files changed

+194
-267
lines changed

3 files changed

+194
-267
lines changed

Diff for: compiler/rustc_ast_lowering/src/item.rs

+137-135
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> {
8383
task_context: None,
8484
current_item: None,
8585
captured_lifetimes: None,
86+
impl_trait_defs: Vec::new(),
87+
impl_trait_bounds: Vec::new(),
8688
allow_try_trait: Some([sym::try_trait_v2, sym::yeet_desugar_details][..].into()),
8789
allow_gen_future: Some([sym::gen_future][..].into()),
8890
allow_into_future: Some([sym::into_future][..].into()),
@@ -264,16 +266,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
264266
let body_id =
265267
this.lower_maybe_async_body(span, &decl, asyncness, body.as_deref());
266268

267-
let (generics, decl) =
268-
this.add_implicit_generics(generics, id, |this, idty, idpb| {
269-
let ret_id = asyncness.opt_return_id();
270-
this.lower_fn_decl(
271-
&decl,
272-
Some((id, idty, idpb)),
273-
FnDeclKind::Fn,
274-
ret_id,
275-
)
276-
});
269+
let itctx = ImplTraitContext::Universal(this.current_hir_id_owner);
270+
let (generics, decl) = this.lower_generics(generics, id, itctx, |this| {
271+
let ret_id = asyncness.opt_return_id();
272+
this.lower_fn_decl(&decl, Some(id), FnDeclKind::Fn, ret_id)
273+
});
277274
let sig = hir::FnSig {
278275
decl,
279276
header: this.lower_fn_header(header),
@@ -311,57 +308,59 @@ impl<'hir> LoweringContext<'_, 'hir> {
311308
//
312309
// type Foo = Foo1
313310
// opaque type Foo1: Trait
314-
let ty = self.lower_ty(ty, ImplTraitContext::TypeAliasesOpaqueTy);
315311
let mut generics = generics.clone();
316312
add_ty_alias_where_clause(&mut generics, where_clauses, true);
317-
let generics = self.lower_generics(
313+
let (generics, ty) = self.lower_generics(
318314
&generics,
315+
id,
319316
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
317+
|this| this.lower_ty(ty, ImplTraitContext::TypeAliasesOpaqueTy),
320318
);
321319
hir::ItemKind::TyAlias(ty, generics)
322320
}
323321
ItemKind::TyAlias(box TyAlias {
324322
ref generics, ref where_clauses, ty: None, ..
325323
}) => {
326-
let ty = self.arena.alloc(self.ty(span, hir::TyKind::Err));
327324
let mut generics = generics.clone();
328325
add_ty_alias_where_clause(&mut generics, *where_clauses, true);
329-
let generics = self.lower_generics(
326+
let (generics, ty) = self.lower_generics(
330327
&generics,
328+
id,
331329
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
330+
|this| this.arena.alloc(this.ty(span, hir::TyKind::Err)),
332331
);
333332
hir::ItemKind::TyAlias(ty, generics)
334333
}
335-
ItemKind::Enum(ref enum_definition, ref generics) => hir::ItemKind::Enum(
336-
hir::EnumDef {
337-
variants: self.arena.alloc_from_iter(
338-
enum_definition.variants.iter().map(|x| self.lower_variant(x)),
339-
),
340-
},
341-
self.lower_generics(
334+
ItemKind::Enum(ref enum_definition, ref generics) => {
335+
let (generics, variants) = self.lower_generics(
342336
generics,
337+
id,
343338
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
344-
),
345-
),
339+
|this| {
340+
this.arena.alloc_from_iter(
341+
enum_definition.variants.iter().map(|x| this.lower_variant(x)),
342+
)
343+
},
344+
);
345+
hir::ItemKind::Enum(hir::EnumDef { variants }, generics)
346+
}
346347
ItemKind::Struct(ref struct_def, ref generics) => {
347-
let struct_def = self.lower_variant_data(hir_id, struct_def);
348-
hir::ItemKind::Struct(
349-
struct_def,
350-
self.lower_generics(
351-
generics,
352-
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
353-
),
354-
)
348+
let (generics, struct_def) = self.lower_generics(
349+
generics,
350+
id,
351+
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
352+
|this| this.lower_variant_data(hir_id, struct_def),
353+
);
354+
hir::ItemKind::Struct(struct_def, generics)
355355
}
356356
ItemKind::Union(ref vdata, ref generics) => {
357-
let vdata = self.lower_variant_data(hir_id, vdata);
358-
hir::ItemKind::Union(
359-
vdata,
360-
self.lower_generics(
361-
generics,
362-
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
363-
),
364-
)
357+
let (generics, vdata) = self.lower_generics(
358+
generics,
359+
id,
360+
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
361+
|this| this.lower_variant_data(hir_id, vdata),
362+
);
363+
hir::ItemKind::Union(vdata, generics)
365364
}
366365
ItemKind::Impl(box Impl {
367366
unsafety,
@@ -386,8 +385,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
386385
// method, it will not be considered an in-band
387386
// lifetime to be added, but rather a reference to a
388387
// parent lifetime.
388+
let itctx = ImplTraitContext::Universal(self.current_hir_id_owner);
389389
let (generics, (trait_ref, lowered_ty)) =
390-
self.add_implicit_generics(ast_generics, id, |this, _, _| {
390+
self.lower_generics(ast_generics, id, itctx, |this| {
391391
let trait_ref = trait_ref.as_ref().map(|trait_ref| {
392392
this.lower_trait_ref(
393393
trait_ref,
@@ -432,34 +432,38 @@ impl<'hir> LoweringContext<'_, 'hir> {
432432
ref bounds,
433433
ref items,
434434
}) => {
435-
let bounds = self.lower_param_bounds(
436-
bounds,
437-
ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
435+
let (generics, (unsafety, items, bounds)) = self.lower_generics(
436+
generics,
437+
id,
438+
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
439+
|this| {
440+
let bounds = this.lower_param_bounds(
441+
bounds,
442+
ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
443+
);
444+
let items = this.arena.alloc_from_iter(
445+
items.iter().map(|item| this.lower_trait_item_ref(item)),
446+
);
447+
let unsafety = this.lower_unsafety(unsafety);
448+
(unsafety, items, bounds)
449+
},
438450
);
439-
let items = self
440-
.arena
441-
.alloc_from_iter(items.iter().map(|item| self.lower_trait_item_ref(item)));
442-
hir::ItemKind::Trait(
443-
is_auto,
444-
self.lower_unsafety(unsafety),
445-
self.lower_generics(
446-
generics,
447-
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
448-
),
449-
bounds,
450-
items,
451-
)
451+
hir::ItemKind::Trait(is_auto, unsafety, generics, bounds, items)
452452
}
453-
ItemKind::TraitAlias(ref generics, ref bounds) => hir::ItemKind::TraitAlias(
454-
self.lower_generics(
453+
ItemKind::TraitAlias(ref generics, ref bounds) => {
454+
let (generics, bounds) = self.lower_generics(
455455
generics,
456+
id,
456457
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
457-
),
458-
self.lower_param_bounds(
459-
bounds,
460-
ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
461-
),
462-
),
458+
|this| {
459+
this.lower_param_bounds(
460+
bounds,
461+
ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
462+
)
463+
},
464+
);
465+
hir::ItemKind::TraitAlias(generics, bounds)
466+
}
463467
ItemKind::MacroDef(MacroDef { ref body, macro_rules }) => {
464468
let body = P(self.lower_mac_args(body));
465469
let macro_kind = self.resolver.decl_macro_kind(self.resolver.local_def_id(id));
@@ -651,8 +655,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
651655
kind: match i.kind {
652656
ForeignItemKind::Fn(box Fn { ref sig, ref generics, .. }) => {
653657
let fdec = &sig.decl;
658+
let itctx = ImplTraitContext::Universal(self.current_hir_id_owner);
654659
let (generics, (fn_dec, fn_args)) =
655-
self.add_implicit_generics(generics, i.id, |this, _, _| {
660+
self.lower_generics(generics, i.id, itctx, |this| {
656661
(
657662
// Disallow `impl Trait` in foreign items.
658663
this.lower_fn_decl(fdec, None, FnDeclKind::ExternFn, None),
@@ -789,24 +794,25 @@ impl<'hir> LoweringContext<'_, 'hir> {
789794
ref ty,
790795
..
791796
}) => {
792-
let ty = ty.as_ref().map(|x| {
793-
self.lower_ty(x, ImplTraitContext::Disallowed(ImplTraitPosition::Type))
794-
});
795797
let mut generics = generics.clone();
796798
add_ty_alias_where_clause(&mut generics, where_clauses, false);
797-
let generics = self.lower_generics(
799+
self.lower_generics(
798800
&generics,
801+
i.id,
799802
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
800-
);
801-
let kind = hir::TraitItemKind::Type(
802-
self.lower_param_bounds(
803-
bounds,
804-
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
805-
),
806-
ty,
807-
);
808-
809-
(generics, kind)
803+
|this| {
804+
let ty = ty.as_ref().map(|x| {
805+
this.lower_ty(x, ImplTraitContext::Disallowed(ImplTraitPosition::Type))
806+
});
807+
hir::TraitItemKind::Type(
808+
this.lower_param_bounds(
809+
bounds,
810+
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
811+
),
812+
ty,
813+
)
814+
},
815+
)
810816
}
811817
AssocItemKind::MacCall(..) => panic!("macro item shouldn't exist at this point"),
812818
};
@@ -876,21 +882,21 @@ impl<'hir> LoweringContext<'_, 'hir> {
876882
AssocItemKind::TyAlias(box TyAlias { generics, where_clauses, ty, .. }) => {
877883
let mut generics = generics.clone();
878884
add_ty_alias_where_clause(&mut generics, *where_clauses, false);
879-
let generics = self.lower_generics(
885+
self.lower_generics(
880886
&generics,
887+
i.id,
881888
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
882-
);
883-
let kind = match ty {
884-
None => {
885-
let ty = self.arena.alloc(self.ty(i.span, hir::TyKind::Err));
886-
hir::ImplItemKind::TyAlias(ty)
887-
}
888-
Some(ty) => {
889-
let ty = self.lower_ty(ty, ImplTraitContext::TypeAliasesOpaqueTy);
890-
hir::ImplItemKind::TyAlias(ty)
891-
}
892-
};
893-
(generics, kind)
889+
|this| match ty {
890+
None => {
891+
let ty = this.arena.alloc(this.ty(i.span, hir::TyKind::Err));
892+
hir::ImplItemKind::TyAlias(ty)
893+
}
894+
Some(ty) => {
895+
let ty = this.lower_ty(ty, ImplTraitContext::TypeAliasesOpaqueTy);
896+
hir::ImplItemKind::TyAlias(ty)
897+
}
898+
},
899+
)
894900
}
895901
AssocItemKind::MacCall(..) => panic!("`TyMac` should have been expanded by now"),
896902
};
@@ -1231,8 +1237,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
12311237
is_async: Option<NodeId>,
12321238
) -> (&'hir hir::Generics<'hir>, hir::FnSig<'hir>) {
12331239
let header = self.lower_fn_header(sig.header);
1234-
let (generics, decl) = self.add_implicit_generics(generics, id, |this, idty, idpb| {
1235-
this.lower_fn_decl(&sig.decl, Some((id, idty, idpb)), kind, is_async)
1240+
let itctx = ImplTraitContext::Universal(self.current_hir_id_owner);
1241+
let (generics, decl) = self.lower_generics(generics, id, itctx, |this| {
1242+
this.lower_fn_decl(&sig.decl, Some(id), kind, is_async)
12361243
});
12371244
(generics, hir::FnSig { header, decl, span: self.lower_span(sig.span) })
12381245
}
@@ -1289,11 +1296,18 @@ impl<'hir> LoweringContext<'_, 'hir> {
12891296
}
12901297
}
12911298

1292-
pub(super) fn lower_generics_mut(
1299+
/// Return the pair of the lowered `generics` as `hir::Generics` and the evaluation of `f` with
1300+
/// the carried impl trait definitions and bounds.
1301+
fn lower_generics<T>(
12931302
&mut self,
12941303
generics: &Generics,
1295-
mut itctx: ImplTraitContext<'_, 'hir>,
1296-
) -> GenericsCtor<'hir> {
1304+
parent_node_id: NodeId,
1305+
itctx: ImplTraitContext,
1306+
f: impl FnOnce(&mut Self) -> T,
1307+
) -> (&'hir hir::Generics<'hir>, T) {
1308+
debug_assert!(self.impl_trait_defs.is_empty());
1309+
debug_assert!(self.impl_trait_bounds.is_empty());
1310+
12971311
// Error if `?Trait` bounds in where clauses don't refer directly to type parameters.
12981312
// Note: we used to clone these bounds directly onto the type parameter (and avoid lowering
12991313
// these into hir when we lower thee where clauses), but this makes it quite difficult to
@@ -1341,9 +1355,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
13411355
}
13421356
}
13431357

1344-
let mut predicates = SmallVec::new();
1358+
let mut predicates: SmallVec<[hir::WherePredicate<'hir>; 4]> = SmallVec::new();
13451359
predicates.extend(generics.params.iter().filter_map(|param| {
1346-
let bounds = self.lower_param_bounds(&param.bounds, itctx.reborrow());
1360+
let bounds = self.lower_param_bounds(&param.bounds, itctx);
13471361
self.lower_generic_bound_predicate(
13481362
param.ident,
13491363
param.id,
@@ -1360,22 +1374,31 @@ impl<'hir> LoweringContext<'_, 'hir> {
13601374
.map(|predicate| self.lower_where_predicate(predicate)),
13611375
);
13621376

1363-
GenericsCtor {
1364-
params: self.lower_generic_params_mut(&generics.params).collect(),
1365-
predicates,
1366-
has_where_clause: !generics.where_clause.predicates.is_empty(),
1367-
where_clause_span: self.lower_span(generics.where_clause.span),
1368-
span: self.lower_span(generics.span),
1369-
}
1370-
}
1377+
let mut params: Vec<_> = self.lower_generic_params_mut(&generics.params).collect();
1378+
let has_where_clause = !generics.where_clause.predicates.is_empty();
1379+
let where_clause_span = self.lower_span(generics.where_clause.span);
1380+
let span = self.lower_span(generics.span);
1381+
let res = f(self);
13711382

1372-
pub(super) fn lower_generics(
1373-
&mut self,
1374-
generics: &Generics,
1375-
itctx: ImplTraitContext<'_, 'hir>,
1376-
) -> &'hir hir::Generics<'hir> {
1377-
let generics_ctor = self.lower_generics_mut(generics, itctx);
1378-
generics_ctor.into_generics(self.arena)
1383+
let extra_lifetimes = self.resolver.take_extra_lifetime_params(parent_node_id);
1384+
let impl_trait_defs = std::mem::take(&mut self.impl_trait_defs);
1385+
params.extend(extra_lifetimes.into_iter().filter_map(|(ident, node_id, res)| {
1386+
self.lifetime_res_to_generic_param(ident, node_id, res)
1387+
}));
1388+
params.extend(impl_trait_defs.into_iter());
1389+
1390+
let impl_trait_bounds = std::mem::take(&mut self.impl_trait_bounds);
1391+
predicates.extend(impl_trait_bounds.into_iter());
1392+
1393+
let lowered_generics = self.arena.alloc(hir::Generics {
1394+
params: self.arena.alloc_from_iter(params),
1395+
predicates: self.arena.alloc_from_iter(predicates),
1396+
has_where_clause,
1397+
where_clause_span,
1398+
span,
1399+
});
1400+
1401+
(lowered_generics, res)
13791402
}
13801403

13811404
pub(super) fn lower_generic_bound_predicate(
@@ -1491,24 +1514,3 @@ impl<'hir> LoweringContext<'_, 'hir> {
14911514
}
14921515
}
14931516
}
1494-
1495-
/// Helper struct for delayed construction of Generics.
1496-
pub(super) struct GenericsCtor<'hir> {
1497-
pub(super) params: SmallVec<[hir::GenericParam<'hir>; 4]>,
1498-
pub(super) predicates: SmallVec<[hir::WherePredicate<'hir>; 4]>,
1499-
has_where_clause: bool,
1500-
where_clause_span: Span,
1501-
span: Span,
1502-
}
1503-
1504-
impl<'hir> GenericsCtor<'hir> {
1505-
pub(super) fn into_generics(self, arena: &'hir Arena<'hir>) -> &'hir hir::Generics<'hir> {
1506-
arena.alloc(hir::Generics {
1507-
params: arena.alloc_from_iter(self.params),
1508-
predicates: arena.alloc_from_iter(self.predicates),
1509-
has_where_clause: self.has_where_clause,
1510-
where_clause_span: self.where_clause_span,
1511-
span: self.span,
1512-
})
1513-
}
1514-
}

0 commit comments

Comments
 (0)