Skip to content

Commit 953da9d

Browse files
committed
Remove some global state from the lowering pass
1 parent 5945851 commit 953da9d

File tree

1 file changed

+69
-52
lines changed

1 file changed

+69
-52
lines changed

src/librustc/hir/lowering.rs

Lines changed: 69 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -109,13 +109,6 @@ pub struct LoweringContext<'a> {
109109
/// written at all (e.g., `&T` or `std::cell::Ref<T>`).
110110
anonymous_lifetime_mode: AnonymousLifetimeMode,
111111

112-
// This is a list of in-band type definitions being generated by
113-
// Argument-position `impl Trait`.
114-
// When traversing a signature such as `fn foo(x: impl Trait)`,
115-
// we record `impl Trait` as a new type parameter, then later
116-
// add it on to `foo`s generics.
117-
in_band_ty_params: Vec<hir::TyParam>,
118-
119112
// Used to create lifetime definitions from in-band lifetime usages.
120113
// e.g. `fn foo(x: &'x u8) -> &'x u8` to `fn foo<'x>(x: &'x u8) -> &'x u8`
121114
// When a named lifetime is encountered in a function or impl header and
@@ -170,26 +163,41 @@ pub trait Resolver {
170163
) -> hir::Path;
171164
}
172165

173-
#[derive(Clone, Copy, Debug)]
174-
enum ImplTraitContext {
166+
#[derive(Debug)]
167+
enum ImplTraitContext<'a> {
175168
/// Treat `impl Trait` as shorthand for a new universal generic parameter.
176169
/// Example: `fn foo(x: impl Debug)`, where `impl Debug` is conceptually
177170
/// equivalent to a fresh universal parameter like `fn foo<T: Debug>(x: T)`.
178171
///
179172
/// We store a DefId here so we can look up necessary information later
180-
Universal(DefId),
173+
///
174+
/// Newly generated parameters should be inserted into the given `Vec`
175+
Universal(DefId, &'a mut Vec<hir::TyParam>),
181176

182177
/// Treat `impl Trait` as shorthand for a new universal existential parameter.
183178
/// Example: `fn foo() -> impl Debug`, where `impl Debug` is conceptually
184179
/// equivalent to a fresh existential parameter like `abstract type T; fn foo() -> T`.
185180
///
186181
/// We store a DefId here so we can look up necessary information later
187-
Existential(DefId),
182+
///
183+
/// All generics of the surrounding function must go into the generated existential type
184+
Existential(DefId, &'a [hir::TyParam]),
188185

189186
/// `impl Trait` is not accepted in this position.
190187
Disallowed,
191188
}
192189

190+
impl<'a> ImplTraitContext<'a> {
191+
fn reborrow(&'b mut self) -> ImplTraitContext<'b> {
192+
use self::ImplTraitContext::*;
193+
match self {
194+
Universal(did, params) => Universal(*did, params),
195+
Existential(did, params) => Existential(*did, params),
196+
Disallowed => Disallowed,
197+
}
198+
}
199+
}
200+
193201
pub fn lower_crate(
194202
sess: &Session,
195203
cstore: &CrateStore,
@@ -225,7 +233,6 @@ pub fn lower_crate(
225233
node_id_to_hir_id: IndexVec::new(),
226234
is_generator: false,
227235
is_in_trait_impl: false,
228-
in_band_ty_params: Vec::new(),
229236
lifetimes_to_define: Vec::new(),
230237
is_collecting_in_band_lifetimes: false,
231238
in_scope_lifetimes: Vec::new(),
@@ -645,7 +652,7 @@ impl<'a> LoweringContext<'a> {
645652
f: F,
646653
) -> (Vec<hir::GenericParam>, T)
647654
where
648-
F: FnOnce(&mut LoweringContext) -> T,
655+
F: FnOnce(&mut LoweringContext) -> (Vec<hir::TyParam>, T),
649656
{
650657
assert!(!self.is_collecting_in_band_lifetimes);
651658
assert!(self.lifetimes_to_define.is_empty());
@@ -656,13 +663,11 @@ impl<'a> LoweringContext<'a> {
656663
self.anonymous_lifetime_mode = anonymous_lifetime_mode;
657664
}
658665

659-
assert!(self.in_band_ty_params.is_empty());
660-
let res = f(self);
666+
let (in_band_ty_params, res) = f(self);
661667

662668
self.is_collecting_in_band_lifetimes = false;
663669
self.anonymous_lifetime_mode = old_anonymous_lifetime_mode;
664670

665-
let in_band_ty_params = self.in_band_ty_params.split_off(0);
666671
let lifetimes_to_define = self.lifetimes_to_define.split_off(0);
667672

668673
let params = lifetimes_to_define
@@ -804,17 +809,22 @@ impl<'a> LoweringContext<'a> {
804809
f: F,
805810
) -> (hir::Generics, T)
806811
where
807-
F: FnOnce(&mut LoweringContext) -> T,
812+
F: FnOnce(&mut LoweringContext, &mut Vec<hir::TyParam>) -> T,
808813
{
809814
let (in_band_defs, (mut lowered_generics, res)) = self.with_in_scope_lifetime_defs(
810815
generics.params.iter().filter_map(|p| match p {
811816
GenericParam::Lifetime(ld) => Some(ld),
812817
_ => None,
813818
}),
814819
|this| {
815-
let itctx = ImplTraitContext::Universal(parent_id);
816820
this.collect_in_band_defs(parent_id, anonymous_lifetime_mode, |this| {
817-
(this.lower_generics(generics, itctx), f(this))
821+
let mut params = Vec::new();
822+
let generics = this.lower_generics(
823+
generics,
824+
ImplTraitContext::Universal(parent_id, &mut params),
825+
);
826+
let res = f(this, &mut params);
827+
(params, (generics, res))
818828
})
819829
},
820830
);
@@ -1037,7 +1047,7 @@ impl<'a> LoweringContext<'a> {
10371047
}
10381048
}
10391049

1040-
fn lower_ty(&mut self, t: &Ty, itctx: ImplTraitContext) -> P<hir::Ty> {
1050+
fn lower_ty(&mut self, t: &Ty, mut itctx: ImplTraitContext) -> P<hir::Ty> {
10411051
let kind = match t.node {
10421052
TyKind::Infer => hir::TyInfer,
10431053
TyKind::Err => hir::TyErr,
@@ -1077,7 +1087,7 @@ impl<'a> LoweringContext<'a> {
10771087
),
10781088
TyKind::Never => hir::TyNever,
10791089
TyKind::Tup(ref tys) => {
1080-
hir::TyTup(tys.iter().map(|ty| self.lower_ty(ty, itctx)).collect())
1090+
hir::TyTup(tys.iter().map(|ty| self.lower_ty(ty, itctx.reborrow())).collect())
10811091
}
10821092
TyKind::Paren(ref ty) => {
10831093
return self.lower_ty(ty, itctx);
@@ -1111,7 +1121,7 @@ impl<'a> LoweringContext<'a> {
11111121
.iter()
11121122
.filter_map(|bound| match *bound {
11131123
TraitTyParamBound(ref ty, TraitBoundModifier::None) => {
1114-
Some(self.lower_poly_trait_ref(ty, itctx))
1124+
Some(self.lower_poly_trait_ref(ty, itctx.reborrow()))
11151125
}
11161126
TraitTyParamBound(_, TraitBoundModifier::Maybe) => None,
11171127
RegionTyParamBound(ref lifetime) => {
@@ -1132,7 +1142,7 @@ impl<'a> LoweringContext<'a> {
11321142
TyKind::ImplTrait(exist_ty_node_id, ref bounds) => {
11331143
let span = t.span;
11341144
match itctx {
1135-
ImplTraitContext::Existential(fn_def_id) => {
1145+
ImplTraitContext::Existential(fn_def_id, _) => {
11361146
// Make sure we know that some funky desugaring has been going on here.
11371147
// This is a first: there is code in other places like for loop
11381148
// desugaring that explicitly states that we don't want to track that.
@@ -1214,7 +1224,7 @@ impl<'a> LoweringContext<'a> {
12141224
)
12151225
})
12161226
}
1217-
ImplTraitContext::Universal(def_id) => {
1227+
ImplTraitContext::Universal(def_id, in_band_ty_params) => {
12181228
let def_node_id = self.next_id().node_id;
12191229

12201230
// Add a definition for the in-band TyParam
@@ -1227,10 +1237,13 @@ impl<'a> LoweringContext<'a> {
12271237
span,
12281238
);
12291239

1230-
let hir_bounds = self.lower_bounds(bounds, itctx);
1240+
let hir_bounds = self.lower_bounds(
1241+
bounds,
1242+
ImplTraitContext::Universal(def_id, in_band_ty_params),
1243+
);
12311244
// Set the name to `impl Bound1 + Bound2`
12321245
let name = Symbol::intern(&pprust::ty_to_string(t));
1233-
self.in_band_ty_params.push(hir::TyParam {
1246+
in_band_ty_params.push(hir::TyParam {
12341247
name,
12351248
id: def_node_id,
12361249
bounds: hir_bounds,
@@ -1472,10 +1485,10 @@ impl<'a> LoweringContext<'a> {
14721485
qself: &Option<QSelf>,
14731486
p: &Path,
14741487
param_mode: ParamMode,
1475-
itctx: ImplTraitContext,
1488+
mut itctx: ImplTraitContext,
14761489
) -> hir::QPath {
14771490
let qself_position = qself.as_ref().map(|q| q.position);
1478-
let qself = qself.as_ref().map(|q| self.lower_ty(&q.ty, itctx));
1491+
let qself = qself.as_ref().map(|q| self.lower_ty(&q.ty, itctx.reborrow()));
14791492

14801493
let resolution = self.resolver
14811494
.get_resolution(id)
@@ -1562,7 +1575,7 @@ impl<'a> LoweringContext<'a> {
15621575
param_mode,
15631576
num_lifetimes,
15641577
parenthesized_generic_args,
1565-
itctx,
1578+
itctx.reborrow(),
15661579
)
15671580
})
15681581
.collect(),
@@ -1605,7 +1618,7 @@ impl<'a> LoweringContext<'a> {
16051618
param_mode,
16061619
0,
16071620
ParenthesizedGenericArgs::Warn,
1608-
itctx,
1621+
itctx.reborrow(),
16091622
));
16101623
let qpath = hir::QPath::TypeRelative(ty, segment);
16111624

@@ -1713,7 +1726,7 @@ impl<'a> LoweringContext<'a> {
17131726
&mut self,
17141727
data: &AngleBracketedParameterData,
17151728
param_mode: ParamMode,
1716-
itctx: ImplTraitContext,
1729+
mut itctx: ImplTraitContext,
17171730
) -> (hir::PathParameters, bool) {
17181731
let &AngleBracketedParameterData {
17191732
ref lifetimes,
@@ -1724,10 +1737,10 @@ impl<'a> LoweringContext<'a> {
17241737
(
17251738
hir::PathParameters {
17261739
lifetimes: self.lower_lifetimes(lifetimes),
1727-
types: types.iter().map(|ty| self.lower_ty(ty, itctx)).collect(),
1740+
types: types.iter().map(|ty| self.lower_ty(ty, itctx.reborrow())).collect(),
17281741
bindings: bindings
17291742
.iter()
1730-
.map(|b| self.lower_ty_binding(b, itctx))
1743+
.map(|b| self.lower_ty_binding(b, itctx.reborrow()))
17311744
.collect(),
17321745
parenthesized: false,
17331746
},
@@ -1835,7 +1848,7 @@ impl<'a> LoweringContext<'a> {
18351848
fn lower_fn_decl(
18361849
&mut self,
18371850
decl: &FnDecl,
1838-
fn_def_id: Option<DefId>,
1851+
mut in_band_ty_params: Option<(DefId, &mut Vec<hir::TyParam>)>,
18391852
impl_trait_return_allow: bool,
18401853
) -> P<hir::FnDecl> {
18411854
// NOTE: The two last parameters here have to do with impl Trait. If fn_def_id is Some,
@@ -1849,17 +1862,17 @@ impl<'a> LoweringContext<'a> {
18491862
inputs: decl.inputs
18501863
.iter()
18511864
.map(|arg| {
1852-
if let Some(def_id) = fn_def_id {
1853-
self.lower_ty(&arg.ty, ImplTraitContext::Universal(def_id))
1865+
if let Some((def_id, ibty)) = in_band_ty_params.as_mut() {
1866+
self.lower_ty(&arg.ty, ImplTraitContext::Universal(*def_id, ibty))
18541867
} else {
18551868
self.lower_ty(&arg.ty, ImplTraitContext::Disallowed)
18561869
}
18571870
})
18581871
.collect(),
18591872
output: match decl.output {
1860-
FunctionRetTy::Ty(ref ty) => match fn_def_id {
1861-
Some(def_id) if impl_trait_return_allow => {
1862-
hir::Return(self.lower_ty(ty, ImplTraitContext::Existential(def_id)))
1873+
FunctionRetTy::Ty(ref ty) => match in_band_ty_params {
1874+
Some((def_id, ref mut ibty)) if impl_trait_return_allow => {
1875+
hir::Return(self.lower_ty(ty, ImplTraitContext::Existential(def_id, ibty)))
18631876
}
18641877
_ => hir::Return(self.lower_ty(ty, ImplTraitContext::Disallowed)),
18651878
},
@@ -1894,7 +1907,7 @@ impl<'a> LoweringContext<'a> {
18941907
&mut self,
18951908
tp: &TyParam,
18961909
add_bounds: &[TyParamBound],
1897-
itctx: ImplTraitContext,
1910+
mut itctx: ImplTraitContext,
18981911
) -> hir::TyParam {
18991912
let mut name = self.lower_ident(tp.ident);
19001913

@@ -1905,11 +1918,11 @@ impl<'a> LoweringContext<'a> {
19051918
name = Symbol::gensym("Self");
19061919
}
19071920

1908-
let mut bounds = self.lower_bounds(&tp.bounds, itctx);
1921+
let mut bounds = self.lower_bounds(&tp.bounds, itctx.reborrow());
19091922
if !add_bounds.is_empty() {
19101923
bounds = bounds
19111924
.into_iter()
1912-
.chain(self.lower_bounds(add_bounds, itctx).into_iter())
1925+
.chain(self.lower_bounds(add_bounds, itctx.reborrow()).into_iter())
19131926
.collect();
19141927
}
19151928

@@ -1984,7 +1997,7 @@ impl<'a> LoweringContext<'a> {
19841997
&mut self,
19851998
params: &Vec<GenericParam>,
19861999
add_bounds: &NodeMap<Vec<TyParamBound>>,
1987-
itctx: ImplTraitContext,
2000+
mut itctx: ImplTraitContext,
19882001
) -> hir::HirVec<hir::GenericParam> {
19892002
params
19902003
.iter()
@@ -1995,7 +2008,7 @@ impl<'a> LoweringContext<'a> {
19952008
GenericParam::Type(ref ty_param) => hir::GenericParam::Type(self.lower_ty_param(
19962009
ty_param,
19972010
add_bounds.get(&ty_param.id).map_or(&[][..], |x| &x),
1998-
itctx,
2011+
itctx.reborrow(),
19992012
)),
20002013
})
20012014
.collect()
@@ -2170,10 +2183,10 @@ impl<'a> LoweringContext<'a> {
21702183
fn lower_poly_trait_ref(
21712184
&mut self,
21722185
p: &PolyTraitRef,
2173-
itctx: ImplTraitContext,
2186+
mut itctx: ImplTraitContext,
21742187
) -> hir::PolyTraitRef {
21752188
let bound_generic_params =
2176-
self.lower_generic_params(&p.bound_generic_params, &NodeMap(), itctx);
2189+
self.lower_generic_params(&p.bound_generic_params, &NodeMap(), itctx.reborrow());
21772190
let trait_ref = self.with_parent_impl_lifetime_defs(
21782191
&bound_generic_params
21792192
.iter()
@@ -2227,11 +2240,11 @@ impl<'a> LoweringContext<'a> {
22272240
fn lower_bounds(
22282241
&mut self,
22292242
bounds: &[TyParamBound],
2230-
itctx: ImplTraitContext,
2243+
mut itctx: ImplTraitContext,
22312244
) -> hir::TyParamBounds {
22322245
bounds
22332246
.iter()
2234-
.map(|bound| self.lower_ty_param_bound(bound, itctx))
2247+
.map(|bound| self.lower_ty_param_bound(bound, itctx.reborrow()))
22352248
.collect()
22362249
}
22372250

@@ -2308,7 +2321,7 @@ impl<'a> LoweringContext<'a> {
23082321
generics,
23092322
fn_def_id,
23102323
AnonymousLifetimeMode::PassThrough,
2311-
|this| this.lower_fn_decl(decl, Some(fn_def_id), true),
2324+
|this, idty| this.lower_fn_decl(decl, Some((fn_def_id, idty)), true),
23122325
);
23132326

23142327
hir::ItemFn(
@@ -2380,7 +2393,7 @@ impl<'a> LoweringContext<'a> {
23802393
ast_generics,
23812394
def_id,
23822395
AnonymousLifetimeMode::CreateParameter,
2383-
|this| {
2396+
|this, _| {
23842397
let trait_ref = trait_ref.as_ref().map(|trait_ref| {
23852398
this.lower_trait_ref(trait_ref, ImplTraitContext::Disallowed)
23862399
});
@@ -2878,7 +2891,7 @@ impl<'a> LoweringContext<'a> {
28782891
generics,
28792892
def_id,
28802893
AnonymousLifetimeMode::PassThrough,
2881-
|this| {
2894+
|this, _| {
28822895
(
28832896
// Disallow impl Trait in foreign items
28842897
this.lower_fn_decl(fdec, None, false),
@@ -2913,7 +2926,11 @@ impl<'a> LoweringContext<'a> {
29132926
generics,
29142927
fn_def_id,
29152928
AnonymousLifetimeMode::PassThrough,
2916-
|this| this.lower_fn_decl(&sig.decl, Some(fn_def_id), impl_trait_return_allow),
2929+
|this, idty| this.lower_fn_decl(
2930+
&sig.decl,
2931+
Some((fn_def_id, idty)),
2932+
impl_trait_return_allow,
2933+
),
29172934
);
29182935
(
29192936
generics,

0 commit comments

Comments
 (0)