Skip to content

Commit efa06f3

Browse files
authored
Rollup merge of #91640 - cjgillot:in-band-collect, r=oli-obk
Simplify collection of in-band lifetimes Split from #91403 r? `@oli-obk`
2 parents 1839c1a + 54ff721 commit efa06f3

File tree

14 files changed

+211
-199
lines changed

14 files changed

+211
-199
lines changed

compiler/rustc_ast_lowering/src/item.rs

+2-7
Original file line numberDiff line numberDiff line change
@@ -247,12 +247,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
247247
AnonymousLifetimeMode::PassThrough,
248248
|this, idty| {
249249
let ret_id = asyncness.opt_return_id();
250-
this.lower_fn_decl(
251-
&decl,
252-
Some((fn_def_id.to_def_id(), idty)),
253-
true,
254-
ret_id,
255-
)
250+
this.lower_fn_decl(&decl, Some((fn_def_id, idty)), true, ret_id)
256251
},
257252
);
258253
let sig = hir::FnSig {
@@ -1264,7 +1259,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
12641259
|this, idty| {
12651260
this.lower_fn_decl(
12661261
&sig.decl,
1267-
Some((fn_def_id.to_def_id(), idty)),
1262+
Some((fn_def_id, idty)),
12681263
impl_trait_return_allow,
12691264
is_async,
12701265
)

compiler/rustc_ast_lowering/src/lib.rs

+87-105
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ enum ImplTraitContext<'b, 'a> {
228228
ReturnPositionOpaqueTy {
229229
/// `DefId` for the parent function, used to look up necessary
230230
/// information later.
231-
fn_def_id: DefId,
231+
fn_def_id: LocalDefId,
232232
/// Origin: Either OpaqueTyOrigin::FnReturn or OpaqueTyOrigin::AsyncFn,
233233
origin: hir::OpaqueTyOrigin,
234234
},
@@ -646,31 +646,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
646646
/// parameter while `f` is running (and restored afterwards).
647647
fn collect_in_band_defs<T>(
648648
&mut self,
649-
parent_def_id: LocalDefId,
650-
anonymous_lifetime_mode: AnonymousLifetimeMode,
651-
f: impl FnOnce(&mut Self) -> (Vec<hir::GenericParam<'hir>>, T),
652-
) -> (Vec<hir::GenericParam<'hir>>, T) {
653-
assert!(!self.is_collecting_in_band_lifetimes);
654-
assert!(self.lifetimes_to_define.is_empty());
655-
let old_anonymous_lifetime_mode = self.anonymous_lifetime_mode;
656-
657-
self.anonymous_lifetime_mode = anonymous_lifetime_mode;
658-
self.is_collecting_in_band_lifetimes = true;
659-
660-
let (in_band_ty_params, res) = f(self);
661-
662-
self.is_collecting_in_band_lifetimes = false;
663-
self.anonymous_lifetime_mode = old_anonymous_lifetime_mode;
664-
665-
let lifetimes_to_define = self.lifetimes_to_define.split_off(0);
649+
f: impl FnOnce(&mut Self) -> T,
650+
) -> (Vec<(Span, ParamName)>, T) {
651+
let was_collecting = std::mem::replace(&mut self.is_collecting_in_band_lifetimes, true);
652+
let len = self.lifetimes_to_define.len();
666653

667-
let params = lifetimes_to_define
668-
.into_iter()
669-
.map(|(span, hir_name)| self.lifetime_to_generic_param(span, hir_name, parent_def_id))
670-
.chain(in_band_ty_params.into_iter())
671-
.collect();
654+
let res = f(self);
672655

673-
(params, res)
656+
let lifetimes_to_define = self.lifetimes_to_define.split_off(len);
657+
self.is_collecting_in_band_lifetimes = was_collecting;
658+
(lifetimes_to_define, res)
674659
}
675660

676661
/// Converts a lifetime into a new generic parameter.
@@ -785,27 +770,39 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
785770
anonymous_lifetime_mode: AnonymousLifetimeMode,
786771
f: impl FnOnce(&mut Self, &mut Vec<hir::GenericParam<'hir>>) -> T,
787772
) -> (hir::Generics<'hir>, T) {
788-
let (in_band_defs, (mut lowered_generics, res)) =
789-
self.with_in_scope_lifetime_defs(&generics.params, |this| {
790-
this.collect_in_band_defs(parent_def_id, anonymous_lifetime_mode, |this| {
791-
let mut params = Vec::new();
792-
// Note: it is necessary to lower generics *before* calling `f`.
793-
// When lowering `async fn`, there's a final step when lowering
794-
// the return type that assumes that all in-scope lifetimes have
795-
// already been added to either `in_scope_lifetimes` or
796-
// `lifetimes_to_define`. If we swapped the order of these two,
797-
// in-band-lifetimes introduced by generics or where-clauses
798-
// wouldn't have been added yet.
799-
let generics = this.lower_generics_mut(
800-
generics,
801-
ImplTraitContext::Universal(&mut params, this.current_hir_id_owner),
802-
);
803-
let res = f(this, &mut params);
804-
(params, (generics, res))
773+
let (lifetimes_to_define, (mut lowered_generics, impl_trait_defs, res)) = self
774+
.collect_in_band_defs(|this| {
775+
this.with_anonymous_lifetime_mode(anonymous_lifetime_mode, |this| {
776+
this.with_in_scope_lifetime_defs(&generics.params, |this| {
777+
let mut impl_trait_defs = Vec::new();
778+
// Note: it is necessary to lower generics *before* calling `f`.
779+
// When lowering `async fn`, there's a final step when lowering
780+
// the return type that assumes that all in-scope lifetimes have
781+
// already been added to either `in_scope_lifetimes` or
782+
// `lifetimes_to_define`. If we swapped the order of these two,
783+
// in-band-lifetimes introduced by generics or where-clauses
784+
// wouldn't have been added yet.
785+
let generics = this.lower_generics_mut(
786+
generics,
787+
ImplTraitContext::Universal(
788+
&mut impl_trait_defs,
789+
this.current_hir_id_owner,
790+
),
791+
);
792+
let res = f(this, &mut impl_trait_defs);
793+
(generics, impl_trait_defs, res)
794+
})
805795
})
806796
});
807797

808-
lowered_generics.params.extend(in_band_defs);
798+
lowered_generics.params.extend(
799+
lifetimes_to_define
800+
.into_iter()
801+
.map(|(span, hir_name)| {
802+
self.lifetime_to_generic_param(span, hir_name, parent_def_id)
803+
})
804+
.chain(impl_trait_defs),
805+
);
809806

810807
let lowered_generics = lowered_generics.into_generics(self.arena);
811808
(lowered_generics, res)
@@ -1380,7 +1377,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
13801377
fn lower_opaque_impl_trait(
13811378
&mut self,
13821379
span: Span,
1383-
fn_def_id: Option<DefId>,
1380+
fn_def_id: Option<LocalDefId>,
13841381
origin: hir::OpaqueTyOrigin,
13851382
opaque_ty_node_id: NodeId,
13861383
capturable_lifetimes: Option<&FxHashSet<hir::LifetimeName>>,
@@ -1452,7 +1449,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
14521449
span: lctx.lower_span(span),
14531450
},
14541451
bounds: hir_bounds,
1455-
impl_trait_fn: fn_def_id,
14561452
origin,
14571453
};
14581454

@@ -1522,7 +1518,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
15221518
fn lower_fn_decl(
15231519
&mut self,
15241520
decl: &FnDecl,
1525-
mut in_band_ty_params: Option<(DefId, &mut Vec<hir::GenericParam<'hir>>)>,
1521+
mut in_band_ty_params: Option<(LocalDefId, &mut Vec<hir::GenericParam<'hir>>)>,
15261522
impl_trait_return_allow: bool,
15271523
make_ret_async: Option<NodeId>,
15281524
) -> &'hir hir::FnDecl<'hir> {
@@ -1580,7 +1576,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
15801576
Some((def_id, _)) if impl_trait_return_allow => {
15811577
ImplTraitContext::ReturnPositionOpaqueTy {
15821578
fn_def_id: def_id,
1583-
origin: hir::OpaqueTyOrigin::FnReturn,
1579+
origin: hir::OpaqueTyOrigin::FnReturn(def_id),
15841580
}
15851581
}
15861582
_ => ImplTraitContext::disallowed(),
@@ -1635,7 +1631,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
16351631
fn lower_async_fn_ret_ty(
16361632
&mut self,
16371633
output: &FnRetTy,
1638-
fn_def_id: DefId,
1634+
fn_def_id: LocalDefId,
16391635
opaque_ty_node_id: NodeId,
16401636
) -> hir::FnRetTy<'hir> {
16411637
debug!(
@@ -1689,18 +1685,29 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
16891685
// this is because the elided lifetimes from the return type
16901686
// should be figured out using the ordinary elision rules, and
16911687
// this desugaring achieves that.
1688+
1689+
debug!("lower_async_fn_ret_ty: in_scope_lifetimes={:#?}", self.in_scope_lifetimes);
1690+
debug!("lower_async_fn_ret_ty: lifetimes_to_define={:#?}", self.lifetimes_to_define);
1691+
1692+
// Calculate all the lifetimes that should be captured
1693+
// by the opaque type. This should include all in-scope
1694+
// lifetime parameters, including those defined in-band.
16921695
//
1693-
// The variable `input_lifetimes_count` tracks the number of
1694-
// lifetime parameters to the opaque type *not counting* those
1695-
// lifetimes elided in the return type. This includes those
1696-
// that are explicitly declared (`in_scope_lifetimes`) and
1697-
// those elided lifetimes we found in the arguments (current
1698-
// content of `lifetimes_to_define`). Next, we will process
1699-
// the return type, which will cause `lifetimes_to_define` to
1700-
// grow.
1701-
let input_lifetimes_count = self.in_scope_lifetimes.len() + self.lifetimes_to_define.len();
1702-
1703-
let mut lifetime_params = Vec::new();
1696+
// `lifetime_params` is a vector of tuple (span, parameter name, lifetime name).
1697+
1698+
// Input lifetime like `'a` or `'1`:
1699+
let mut lifetime_params: Vec<_> = self
1700+
.in_scope_lifetimes
1701+
.iter()
1702+
.cloned()
1703+
.map(|name| (name.ident().span, name, hir::LifetimeName::Param(name)))
1704+
.chain(
1705+
self.lifetimes_to_define
1706+
.iter()
1707+
.map(|&(span, name)| (span, name, hir::LifetimeName::Param(name))),
1708+
)
1709+
.collect();
1710+
17041711
self.with_hir_id_owner(opaque_ty_node_id, |this| {
17051712
// We have to be careful to get elision right here. The
17061713
// idea is that we create a lifetime parameter for each
@@ -1710,34 +1717,26 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
17101717
//
17111718
// Then, we will create `fn foo(..) -> Foo<'_, '_>`, and
17121719
// hence the elision takes place at the fn site.
1713-
let future_bound = this
1714-
.with_anonymous_lifetime_mode(AnonymousLifetimeMode::CreateParameter, |this| {
1715-
this.lower_async_fn_output_type_to_future_bound(output, fn_def_id, span)
1720+
let (lifetimes_to_define, future_bound) =
1721+
this.with_anonymous_lifetime_mode(AnonymousLifetimeMode::CreateParameter, |this| {
1722+
this.collect_in_band_defs(|this| {
1723+
this.lower_async_fn_output_type_to_future_bound(output, fn_def_id, span)
1724+
})
17161725
});
1717-
17181726
debug!("lower_async_fn_ret_ty: future_bound={:#?}", future_bound);
1727+
debug!("lower_async_fn_ret_ty: lifetimes_to_define={:#?}", lifetimes_to_define);
17191728

1720-
// Calculate all the lifetimes that should be captured
1721-
// by the opaque type. This should include all in-scope
1722-
// lifetime parameters, including those defined in-band.
1723-
//
1724-
// Note: this must be done after lowering the output type,
1725-
// as the output type may introduce new in-band lifetimes.
1726-
lifetime_params = this
1727-
.in_scope_lifetimes
1728-
.iter()
1729-
.cloned()
1730-
.map(|name| (name.ident().span, name))
1731-
.chain(this.lifetimes_to_define.iter().cloned())
1732-
.collect();
1733-
1734-
debug!("lower_async_fn_ret_ty: in_scope_lifetimes={:#?}", this.in_scope_lifetimes);
1735-
debug!("lower_async_fn_ret_ty: lifetimes_to_define={:#?}", this.lifetimes_to_define);
1729+
lifetime_params.extend(
1730+
// Output lifetime like `'_`:
1731+
lifetimes_to_define
1732+
.into_iter()
1733+
.map(|(span, name)| (span, name, hir::LifetimeName::Implicit(false))),
1734+
);
17361735
debug!("lower_async_fn_ret_ty: lifetime_params={:#?}", lifetime_params);
17371736

17381737
let generic_params =
1739-
this.arena.alloc_from_iter(lifetime_params.iter().map(|(span, hir_name)| {
1740-
this.lifetime_to_generic_param(*span, *hir_name, opaque_ty_def_id)
1738+
this.arena.alloc_from_iter(lifetime_params.iter().map(|&(span, hir_name, _)| {
1739+
this.lifetime_to_generic_param(span, hir_name, opaque_ty_def_id)
17411740
}));
17421741

17431742
let opaque_ty_item = hir::OpaqueTy {
@@ -1747,8 +1746,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
17471746
span: this.lower_span(span),
17481747
},
17491748
bounds: arena_vec![this; future_bound],
1750-
impl_trait_fn: Some(fn_def_id),
1751-
origin: hir::OpaqueTyOrigin::AsyncFn,
1749+
origin: hir::OpaqueTyOrigin::AsyncFn(fn_def_id),
17521750
};
17531751

17541752
trace!("exist ty from async fn def id: {:#?}", opaque_ty_def_id);
@@ -1771,25 +1769,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
17711769
//
17721770
// For the "output" lifetime parameters, we just want to
17731771
// generate `'_`.
1774-
let mut generic_args = Vec::with_capacity(lifetime_params.len());
1775-
generic_args.extend(lifetime_params[..input_lifetimes_count].iter().map(
1776-
|&(span, hir_name)| {
1777-
// Input lifetime like `'a` or `'1`:
1772+
let generic_args =
1773+
self.arena.alloc_from_iter(lifetime_params.into_iter().map(|(span, _, name)| {
17781774
GenericArg::Lifetime(hir::Lifetime {
17791775
hir_id: self.next_id(),
17801776
span: self.lower_span(span),
1781-
name: hir::LifetimeName::Param(hir_name),
1777+
name,
17821778
})
1783-
},
1784-
));
1785-
generic_args.extend(lifetime_params[input_lifetimes_count..].iter().map(|&(span, _)|
1786-
// Output lifetime like `'_`.
1787-
GenericArg::Lifetime(hir::Lifetime {
1788-
hir_id: self.next_id(),
1789-
span: self.lower_span(span),
1790-
name: hir::LifetimeName::Implicit(false),
1791-
})));
1792-
let generic_args = self.arena.alloc_from_iter(generic_args);
1779+
}));
17931780

17941781
// Create the `Foo<...>` reference itself. Note that the `type
17951782
// Foo = impl Trait` is, internally, created as a child of the
@@ -1805,7 +1792,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
18051792
fn lower_async_fn_output_type_to_future_bound(
18061793
&mut self,
18071794
output: &FnRetTy,
1808-
fn_def_id: DefId,
1795+
fn_def_id: LocalDefId,
18091796
span: Span,
18101797
) -> hir::GenericBound<'hir> {
18111798
// Compute the `T` in `Future<Output = T>` from the return type.
@@ -1816,7 +1803,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
18161803
// generates.
18171804
let context = ImplTraitContext::ReturnPositionOpaqueTy {
18181805
fn_def_id,
1819-
origin: hir::OpaqueTyOrigin::FnReturn,
1806+
origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id),
18201807
};
18211808
self.lower_ty(ty, context)
18221809
}
@@ -2453,17 +2440,12 @@ impl<'hir> GenericArgsCtor<'hir> {
24532440
}
24542441
}
24552442

2443+
#[tracing::instrument(level = "debug")]
24562444
fn lifetimes_from_impl_trait_bounds(
24572445
opaque_ty_id: NodeId,
24582446
bounds: hir::GenericBounds<'_>,
24592447
lifetimes_to_include: Option<&FxHashSet<hir::LifetimeName>>,
24602448
) -> Vec<(hir::LifetimeName, Span)> {
2461-
debug!(
2462-
"lifetimes_from_impl_trait_bounds(opaque_ty_id={:?}, \
2463-
bounds={:#?})",
2464-
opaque_ty_id, bounds,
2465-
);
2466-
24672449
// This visitor walks over `impl Trait` bounds and creates defs for all lifetimes that
24682450
// appear in the bounds, excluding lifetimes that are created within the bounds.
24692451
// E.g., `'a`, `'b`, but not `'c` in `impl for<'c> SomeTrait<'a, 'b, 'c>`.

compiler/rustc_borrowck/src/region_infer/opaque_types.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ fn check_opaque_type_parameter_valid(
173173
// fn foo<l0..'ln>() -> foo::<'static..'static>::Foo<'l0..'lm>.
174174
//
175175
// which would error here on all of the `'static` args.
176-
OpaqueTyOrigin::FnReturn | OpaqueTyOrigin::AsyncFn => return true,
176+
OpaqueTyOrigin::FnReturn(..) | OpaqueTyOrigin::AsyncFn(..) => return true,
177177
// Check these
178178
OpaqueTyOrigin::TyAlias => {}
179179
}

compiler/rustc_hir/src/hir.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -2248,17 +2248,16 @@ pub struct BareFnTy<'hir> {
22482248
pub struct OpaqueTy<'hir> {
22492249
pub generics: Generics<'hir>,
22502250
pub bounds: GenericBounds<'hir>,
2251-
pub impl_trait_fn: Option<DefId>,
22522251
pub origin: OpaqueTyOrigin,
22532252
}
22542253

22552254
/// From whence the opaque type came.
22562255
#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, HashStable_Generic)]
22572256
pub enum OpaqueTyOrigin {
22582257
/// `-> impl Trait`
2259-
FnReturn,
2258+
FnReturn(LocalDefId),
22602259
/// `async fn`
2261-
AsyncFn,
2260+
AsyncFn(LocalDefId),
22622261
/// type aliases: `type Foo = impl Trait;`
22632262
TyAlias,
22642263
}
@@ -2809,7 +2808,9 @@ impl ItemKind<'_> {
28092808
Some(match *self {
28102809
ItemKind::Fn(_, ref generics, _)
28112810
| ItemKind::TyAlias(_, ref generics)
2812-
| ItemKind::OpaqueTy(OpaqueTy { ref generics, impl_trait_fn: None, .. })
2811+
| ItemKind::OpaqueTy(OpaqueTy {
2812+
ref generics, origin: OpaqueTyOrigin::TyAlias, ..
2813+
})
28132814
| ItemKind::Enum(_, ref generics)
28142815
| ItemKind::Struct(_, ref generics)
28152816
| ItemKind::Union(_, ref generics)

compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
107107
kind:
108108
hir::ItemKind::OpaqueTy(hir::OpaqueTy {
109109
bounds,
110-
origin: hir::OpaqueTyOrigin::AsyncFn,
110+
origin: hir::OpaqueTyOrigin::AsyncFn(..),
111111
..
112112
}),
113113
..

0 commit comments

Comments
 (0)