Skip to content

Commit 7879369

Browse files
committed
Remove some global state from the lowering pass
1 parent 87005c0 commit 7879369

File tree

1 file changed

+76
-51
lines changed

1 file changed

+76
-51
lines changed

src/librustc/hir/lowering.rs

+76-51
Original file line numberDiff line numberDiff line change
@@ -110,13 +110,6 @@ pub struct LoweringContext<'a> {
110110
/// written at all (e.g., `&T` or `std::cell::Ref<T>`).
111111
anonymous_lifetime_mode: AnonymousLifetimeMode,
112112

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

175-
#[derive(Clone, Copy, Debug)]
176-
enum ImplTraitContext {
168+
#[derive(Debug)]
169+
enum ImplTraitContext<'a> {
177170
/// Treat `impl Trait` as shorthand for a new universal generic parameter.
178171
/// Example: `fn foo(x: impl Debug)`, where `impl Debug` is conceptually
179172
/// equivalent to a fresh universal parameter like `fn foo<T: Debug>(x: T)`.
180-
Universal,
173+
///
174+
/// Newly generated parameters should be inserted into the given `Vec`
175+
Universal(&'a mut Vec<hir::GenericParam>),
181176

182177
/// Treat `impl Trait` as shorthand for a new universal existential parameter.
183178
/// Example: `fn foo() -> impl Debug`, where `impl Debug` is conceptually
@@ -190,6 +185,17 @@ enum ImplTraitContext {
190185
Disallowed,
191186
}
192187

188+
impl<'a> ImplTraitContext<'a> {
189+
fn reborrow(&'b mut self) -> ImplTraitContext<'b> {
190+
use self::ImplTraitContext::*;
191+
match self {
192+
Universal(params) => Universal(params),
193+
Existential(did) => Existential(*did),
194+
Disallowed => Disallowed,
195+
}
196+
}
197+
}
198+
193199
pub fn lower_crate(
194200
sess: &Session,
195201
cstore: &CrateStore,
@@ -224,7 +230,6 @@ pub fn lower_crate(
224230
node_id_to_hir_id: IndexVec::new(),
225231
is_generator: false,
226232
is_in_trait_impl: false,
227-
in_band_ty_params: Vec::new(),
228233
lifetimes_to_define: Vec::new(),
229234
is_collecting_in_band_lifetimes: false,
230235
in_scope_lifetimes: Vec::new(),
@@ -645,7 +650,7 @@ impl<'a> LoweringContext<'a> {
645650
f: F,
646651
) -> (Vec<hir::GenericParam>, T)
647652
where
648-
F: FnOnce(&mut LoweringContext) -> T,
653+
F: FnOnce(&mut LoweringContext) -> (Vec<hir::GenericParam>, T),
649654
{
650655
assert!(!self.is_collecting_in_band_lifetimes);
651656
assert!(self.lifetimes_to_define.is_empty());
@@ -656,13 +661,11 @@ impl<'a> LoweringContext<'a> {
656661
self.anonymous_lifetime_mode = anonymous_lifetime_mode;
657662
}
658663

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

662666
self.is_collecting_in_band_lifetimes = false;
663667
self.anonymous_lifetime_mode = old_anonymous_lifetime_mode;
664668

665-
let in_band_ty_params = self.in_band_ty_params.split_off(0);
666669
let lifetimes_to_define = self.lifetimes_to_define.split_off(0);
667670

668671
let params = lifetimes_to_define
@@ -796,14 +799,19 @@ impl<'a> LoweringContext<'a> {
796799
f: F,
797800
) -> (hir::Generics, T)
798801
where
799-
F: FnOnce(&mut LoweringContext) -> T,
802+
F: FnOnce(&mut LoweringContext, &mut Vec<hir::GenericParam>) -> T,
800803
{
801804
let (in_band_defs, (mut lowered_generics, res)) = self.with_in_scope_lifetime_defs(
802805
&generics.params,
803806
|this| {
804-
let itctx = ImplTraitContext::Universal;
805807
this.collect_in_band_defs(parent_id, anonymous_lifetime_mode, |this| {
806-
(this.lower_generics(generics, itctx), f(this))
808+
let mut params = Vec::new();
809+
let generics = this.lower_generics(
810+
generics,
811+
ImplTraitContext::Universal(&mut params),
812+
);
813+
let res = f(this, &mut params);
814+
(params, (generics, res))
807815
})
808816
},
809817
);
@@ -1069,7 +1077,7 @@ impl<'a> LoweringContext<'a> {
10691077
P(self.lower_ty_direct(t, itctx))
10701078
}
10711079

1072-
fn lower_ty_direct(&mut self, t: &Ty, itctx: ImplTraitContext) -> hir::Ty {
1080+
fn lower_ty_direct(&mut self, t: &Ty, mut itctx: ImplTraitContext) -> hir::Ty {
10731081
let kind = match t.node {
10741082
TyKind::Infer => hir::TyInfer,
10751083
TyKind::Err => hir::TyErr,
@@ -1106,7 +1114,9 @@ impl<'a> LoweringContext<'a> {
11061114
),
11071115
TyKind::Never => hir::TyNever,
11081116
TyKind::Tup(ref tys) => {
1109-
hir::TyTup(tys.iter().map(|ty| self.lower_ty_direct(ty, itctx)).collect())
1117+
hir::TyTup(tys.iter().map(|ty| {
1118+
self.lower_ty_direct(ty, itctx.reborrow())
1119+
}).collect())
11101120
}
11111121
TyKind::Paren(ref ty) => {
11121122
return self.lower_ty_direct(ty, itctx);
@@ -1140,7 +1150,7 @@ impl<'a> LoweringContext<'a> {
11401150
.iter()
11411151
.filter_map(|bound| match *bound {
11421152
GenericBound::Trait(ref ty, TraitBoundModifier::None) => {
1143-
Some(self.lower_poly_trait_ref(ty, itctx))
1153+
Some(self.lower_poly_trait_ref(ty, itctx.reborrow()))
11441154
}
11451155
GenericBound::Trait(_, TraitBoundModifier::Maybe) => None,
11461156
GenericBound::Outlives(ref lifetime) => {
@@ -1167,7 +1177,7 @@ impl<'a> LoweringContext<'a> {
11671177
|this| this.lower_param_bounds(bounds, itctx),
11681178
)
11691179
}
1170-
ImplTraitContext::Universal => {
1180+
ImplTraitContext::Universal(in_band_ty_params) => {
11711181
self.lower_node_id(def_node_id);
11721182
// Add a definition for the in-band TyParam
11731183
let def_index = self
@@ -1176,10 +1186,13 @@ impl<'a> LoweringContext<'a> {
11761186
.opt_def_index(def_node_id)
11771187
.unwrap();
11781188

1179-
let hir_bounds = self.lower_param_bounds(bounds, itctx);
1189+
let hir_bounds = self.lower_param_bounds(
1190+
bounds,
1191+
ImplTraitContext::Universal(in_band_ty_params),
1192+
);
11801193
// Set the name to `impl Bound1 + Bound2`
11811194
let ident = Ident::from_str(&pprust::ty_to_string(t)).with_span_pos(span);
1182-
self.in_band_ty_params.push(hir::GenericParam {
1195+
in_band_ty_params.push(hir::GenericParam {
11831196
id: def_node_id,
11841197
name: ParamName::Plain(ident),
11851198
pure_wrt_drop: false,
@@ -1502,10 +1515,10 @@ impl<'a> LoweringContext<'a> {
15021515
qself: &Option<QSelf>,
15031516
p: &Path,
15041517
param_mode: ParamMode,
1505-
itctx: ImplTraitContext,
1518+
mut itctx: ImplTraitContext,
15061519
) -> hir::QPath {
15071520
let qself_position = qself.as_ref().map(|q| q.position);
1508-
let qself = qself.as_ref().map(|q| self.lower_ty(&q.ty, itctx));
1521+
let qself = qself.as_ref().map(|q| self.lower_ty(&q.ty, itctx.reborrow()));
15091522

15101523
let resolution = self.resolver
15111524
.get_resolution(id)
@@ -1592,7 +1605,7 @@ impl<'a> LoweringContext<'a> {
15921605
param_mode,
15931606
num_lifetimes,
15941607
parenthesized_generic_args,
1595-
itctx,
1608+
itctx.reborrow(),
15961609
)
15971610
})
15981611
.collect(),
@@ -1635,7 +1648,7 @@ impl<'a> LoweringContext<'a> {
16351648
param_mode,
16361649
0,
16371650
ParenthesizedGenericArgs::Warn,
1638-
itctx,
1651+
itctx.reborrow(),
16391652
));
16401653
let qpath = hir::QPath::TypeRelative(ty, segment);
16411654

@@ -1752,16 +1765,16 @@ impl<'a> LoweringContext<'a> {
17521765
&mut self,
17531766
data: &AngleBracketedArgs,
17541767
param_mode: ParamMode,
1755-
itctx: ImplTraitContext,
1768+
mut itctx: ImplTraitContext,
17561769
) -> (hir::GenericArgs, bool) {
17571770
let &AngleBracketedArgs { ref args, ref bindings, .. } = data;
17581771
let has_types = args.iter().any(|arg| match arg {
17591772
ast::GenericArg::Type(_) => true,
17601773
_ => false,
17611774
});
17621775
(hir::GenericArgs {
1763-
args: args.iter().map(|a| self.lower_generic_arg(a, itctx)).collect(),
1764-
bindings: bindings.iter().map(|b| self.lower_ty_binding(b, itctx)).collect(),
1776+
args: args.iter().map(|a| self.lower_generic_arg(a, itctx.reborrow())).collect(),
1777+
bindings: bindings.iter().map(|b| self.lower_ty_binding(b, itctx.reborrow())).collect(),
17651778
parenthesized: false,
17661779
},
17671780
!has_types && param_mode == ParamMode::Optional)
@@ -1866,15 +1879,15 @@ impl<'a> LoweringContext<'a> {
18661879
fn lower_fn_decl(
18671880
&mut self,
18681881
decl: &FnDecl,
1869-
fn_def_id: Option<DefId>,
1882+
mut in_band_ty_params: Option<(DefId, &mut Vec<hir::GenericParam>)>,
18701883
impl_trait_return_allow: bool,
18711884
make_ret_async: Option<NodeId>,
18721885
) -> P<hir::FnDecl> {
18731886
let inputs = decl.inputs
18741887
.iter()
18751888
.map(|arg| {
1876-
if fn_def_id.is_some() {
1877-
self.lower_ty_direct(&arg.ty, ImplTraitContext::Universal)
1889+
if let Some((_, ref mut ibty)) = in_band_ty_params {
1890+
self.lower_ty_direct(&arg.ty, ImplTraitContext::Universal(ibty))
18781891
} else {
18791892
self.lower_ty_direct(&arg.ty, ImplTraitContext::Disallowed)
18801893
}
@@ -1883,11 +1896,15 @@ impl<'a> LoweringContext<'a> {
18831896

18841897
let output = if let Some(ret_id) = make_ret_async {
18851898
self.lower_async_fn_ret_ty(
1886-
&inputs, &decl.output, fn_def_id.expect("make_ret_async but no fn_def_id"), ret_id)
1899+
&inputs,
1900+
&decl.output,
1901+
in_band_ty_params.expect("make_ret_async but no fn_def_id").0,
1902+
ret_id,
1903+
)
18871904
} else {
18881905
match decl.output {
1889-
FunctionRetTy::Ty(ref ty) => match fn_def_id {
1890-
Some(def_id) if impl_trait_return_allow => {
1906+
FunctionRetTy::Ty(ref ty) => match in_band_ty_params {
1907+
Some((def_id, _)) if impl_trait_return_allow => {
18911908
hir::Return(self.lower_ty(ty, ImplTraitContext::Existential(def_id)))
18921909
}
18931910
_ => hir::Return(self.lower_ty(ty, ImplTraitContext::Disallowed)),
@@ -2191,17 +2208,19 @@ impl<'a> LoweringContext<'a> {
21912208
&mut self,
21922209
params: &Vec<GenericParam>,
21932210
add_bounds: &NodeMap<Vec<GenericBound>>,
2194-
itctx: ImplTraitContext,
2211+
mut itctx: ImplTraitContext,
21952212
) -> hir::HirVec<hir::GenericParam> {
2196-
params.iter().map(|param| self.lower_generic_param(param, add_bounds, itctx)).collect()
2213+
params.iter().map(|param| {
2214+
self.lower_generic_param(param, add_bounds, itctx.reborrow())
2215+
}).collect()
21972216
}
21982217

21992218
fn lower_generic_param(&mut self,
22002219
param: &GenericParam,
22012220
add_bounds: &NodeMap<Vec<GenericBound>>,
2202-
itctx: ImplTraitContext)
2221+
mut itctx: ImplTraitContext)
22032222
-> hir::GenericParam {
2204-
let mut bounds = self.lower_param_bounds(&param.bounds, itctx);
2223+
let mut bounds = self.lower_param_bounds(&param.bounds, itctx.reborrow());
22052224
match param.kind {
22062225
GenericParamKind::Lifetime => {
22072226
let was_collecting_in_band = self.is_collecting_in_band_lifetimes;
@@ -2238,8 +2257,9 @@ impl<'a> LoweringContext<'a> {
22382257

22392258
let add_bounds = add_bounds.get(&param.id).map_or(&[][..], |x| &x);
22402259
if !add_bounds.is_empty() {
2260+
let params = self.lower_param_bounds(add_bounds, itctx.reborrow()).into_iter();
22412261
bounds = bounds.into_iter()
2242-
.chain(self.lower_param_bounds(add_bounds, itctx).into_iter())
2262+
.chain(params)
22432263
.collect();
22442264
}
22452265

@@ -2434,10 +2454,10 @@ impl<'a> LoweringContext<'a> {
24342454
fn lower_poly_trait_ref(
24352455
&mut self,
24362456
p: &PolyTraitRef,
2437-
itctx: ImplTraitContext,
2457+
mut itctx: ImplTraitContext,
24382458
) -> hir::PolyTraitRef {
24392459
let bound_generic_params =
2440-
self.lower_generic_params(&p.bound_generic_params, &NodeMap(), itctx);
2460+
self.lower_generic_params(&p.bound_generic_params, &NodeMap(), itctx.reborrow());
24412461
let trait_ref = self.with_parent_impl_lifetime_defs(
24422462
&bound_generic_params,
24432463
|this| this.lower_trait_ref(&p.trait_ref, itctx),
@@ -2482,9 +2502,9 @@ impl<'a> LoweringContext<'a> {
24822502
}
24832503
}
24842504

2485-
fn lower_param_bounds(&mut self, bounds: &[GenericBound], itctx: ImplTraitContext)
2505+
fn lower_param_bounds(&mut self, bounds: &[GenericBound], mut itctx: ImplTraitContext)
24862506
-> hir::GenericBounds {
2487-
bounds.iter().map(|bound| self.lower_param_bound(bound, itctx)).collect()
2507+
bounds.iter().map(|bound| self.lower_param_bound(bound, itctx.reborrow())).collect()
24882508
}
24892509

24902510
fn lower_block(&mut self, b: &Block, targeted_by_break: bool) -> P<hir::Block> {
@@ -2585,8 +2605,8 @@ impl<'a> LoweringContext<'a> {
25852605
generics,
25862606
fn_def_id,
25872607
AnonymousLifetimeMode::PassThrough,
2588-
|this| this.lower_fn_decl(
2589-
decl, Some(fn_def_id), true, header.asyncness.opt_return_id())
2608+
|this, idty| this.lower_fn_decl(
2609+
decl, Some((fn_def_id, idty)), true, header.asyncness.opt_return_id()),
25902610
);
25912611

25922612
hir::ItemFn(
@@ -2656,7 +2676,7 @@ impl<'a> LoweringContext<'a> {
26562676
ast_generics,
26572677
def_id,
26582678
AnonymousLifetimeMode::CreateParameter,
2659-
|this| {
2679+
|this, _| {
26602680
let trait_ref = trait_ref.as_ref().map(|trait_ref| {
26612681
this.lower_trait_ref(trait_ref, ImplTraitContext::Disallowed)
26622682
});
@@ -3191,7 +3211,7 @@ impl<'a> LoweringContext<'a> {
31913211
generics,
31923212
def_id,
31933213
AnonymousLifetimeMode::PassThrough,
3194-
|this| {
3214+
|this, _| {
31953215
(
31963216
// Disallow impl Trait in foreign items
31973217
this.lower_fn_decl(fdec, None, false, None),
@@ -3226,7 +3246,12 @@ impl<'a> LoweringContext<'a> {
32263246
generics,
32273247
fn_def_id,
32283248
AnonymousLifetimeMode::PassThrough,
3229-
|cx| cx.lower_fn_decl(&sig.decl, Some(fn_def_id), impl_trait_return_allow, is_async),
3249+
|this, idty| this.lower_fn_decl(
3250+
&sig.decl,
3251+
Some((fn_def_id, idty)),
3252+
impl_trait_return_allow,
3253+
is_async,
3254+
),
32303255
);
32313256
(generics, hir::MethodSig { header, decl })
32323257
}

0 commit comments

Comments
 (0)