Skip to content

Commit af6a9a2

Browse files
committed
Handle the visibility/lint scope distinction better
* Don't generate an extra lint scope for each `let` statement. * Place match guards inside the visiblility scope of the bindings for their arm.
1 parent e784595 commit af6a9a2

File tree

9 files changed

+45
-67
lines changed

9 files changed

+45
-67
lines changed

src/librustc/hir/lowering.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1313,10 +1313,8 @@ impl<'a> LoweringContext<'a> {
13131313
}
13141314

13151315
fn lower_arm(&mut self, arm: &Arm) -> hir::Arm {
1316-
let LoweredNodeId { node_id: _, hir_id } = self.next_id();
1317-
13181316
hir::Arm {
1319-
hir_id,
1317+
hir_id: self.next_id(),
13201318
attrs: self.lower_attrs(&arm.attrs),
13211319
pats: arm.pats.iter().map(|x| self.lower_pat(x)).collect(),
13221320
guard: match arm.guard {
@@ -5027,10 +5025,8 @@ impl<'a> LoweringContext<'a> {
50275025
// Helper methods for building HIR.
50285026

50295027
fn arm(&mut self, pats: hir::HirVec<P<hir::Pat>>, expr: P<hir::Expr>) -> hir::Arm {
5030-
let LoweredNodeId { node_id: _, hir_id } = self.next_id();
5031-
50325028
hir::Arm {
5033-
hir_id,
5029+
hir_id: self.next_id(),
50345030
attrs: hir_vec![],
50355031
pats,
50365032
guard: None,

src/librustc_mir/build/block.rs

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -113,31 +113,39 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
113113
let remainder_span = remainder_scope.span(this.hir.tcx(),
114114
&this.hir.region_scope_tree);
115115

116-
let scope;
116+
let visibility_scope =
117+
Some(this.new_source_scope(remainder_span, LintLevel::Inherited, None));
117118

118119
// Evaluate the initializer, if present.
119120
if let Some(init) = initializer {
120121
let initializer_span = init.span();
121122

122-
scope = this.declare_bindings(
123-
None,
124-
remainder_span,
125-
lint_level,
126-
&pattern,
127-
ArmHasGuard(false),
128-
Some((None, initializer_span)),
129-
);
130123
unpack!(block = this.in_opt_scope(
131124
opt_destruction_scope.map(|de|(de, source_info)), |this| {
132125
let scope = (init_scope, source_info);
133126
this.in_scope(scope, lint_level, |this| {
127+
this.declare_bindings(
128+
visibility_scope,
129+
remainder_span,
130+
&pattern,
131+
ArmHasGuard(false),
132+
Some((None, initializer_span)),
133+
);
134134
this.expr_into_pattern(block, pattern, init)
135135
})
136136
}));
137137
} else {
138-
scope = this.declare_bindings(
139-
None, remainder_span, lint_level, &pattern,
140-
ArmHasGuard(false), None);
138+
let scope = (init_scope, source_info);
139+
unpack!(this.in_scope(scope, lint_level, |this| {
140+
this.declare_bindings(
141+
visibility_scope,
142+
remainder_span,
143+
&pattern,
144+
ArmHasGuard(false),
145+
None,
146+
);
147+
block.unit()
148+
}));
141149

142150
debug!("ast_block_stmts: pattern={:?}", pattern);
143151
this.visit_bindings(
@@ -149,8 +157,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
149157
})
150158
}
151159

152-
// Enter the source scope, after evaluating the initializer.
153-
if let Some(source_scope) = scope {
160+
// Enter the visibility scope, after evaluating the initializer.
161+
if let Some(source_scope) = visibility_scope {
154162
this.source_scope = source_scope;
155163
}
156164
}

src/librustc_mir/build/matches/mod.rs

Lines changed: 7 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -259,12 +259,15 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
259259
let scope = self.declare_bindings(
260260
None,
261261
body.span,
262-
LintLevel::Inherited,
263262
&arm.patterns[0],
264263
ArmHasGuard(arm.guard.is_some()),
265264
Some((Some(&scrutinee_place), scrutinee_span)),
266265
);
267266

267+
if let Some(source_scope) = scope {
268+
this.source_scope = source_scope;
269+
}
270+
268271
for candidate in candidates {
269272
self.bind_and_guard_matched_candidate(
270273
candidate,
@@ -275,9 +278,6 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
275278
);
276279
}
277280

278-
if let Some(source_scope) = scope {
279-
self.source_scope = source_scope;
280-
}
281281

282282
unpack!(arm_block = self.into(destination, arm_block, body));
283283

@@ -489,33 +489,20 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
489489
&mut self,
490490
mut visibility_scope: Option<SourceScope>,
491491
scope_span: Span,
492-
lint_level: LintLevel,
493492
pattern: &Pattern<'tcx>,
494493
has_guard: ArmHasGuard,
495494
opt_match_place: Option<(Option<&Place<'tcx>>, Span)>,
496495
) -> Option<SourceScope> {
497-
assert!(
498-
!(visibility_scope.is_some() && lint_level.is_explicit()),
499-
"can't have both a visibility and a lint scope at the same time"
500-
);
501-
let mut scope = self.source_scope;
502496
debug!("declare_bindings: pattern={:?}", pattern);
503497
self.visit_bindings(
504498
&pattern,
505499
UserTypeProjections::none(),
506500
&mut |this, mutability, name, mode, var, span, ty, user_ty| {
507501
if visibility_scope.is_none() {
508-
// If we have lints, create a new source scope
509-
// that marks the lints for the locals. See the comment
510-
// on the `source_info` field for why this is needed.
511-
if lint_level.is_explicit() {
512-
scope = this.new_source_scope(scope_span, lint_level, None);
513-
}
514-
visibility_scope = Some(this.new_source_scope(scope_span,
515-
LintLevel::Inherited,
516-
None));
502+
visibility_scope =
503+
Some(this.new_source_scope(scope_span, LintLevel::Inherited, None));
517504
}
518-
let source_info = SourceInfo { span, scope };
505+
let source_info = SourceInfo { span, this.source_scope };
519506
let visibility_scope = visibility_scope.unwrap();
520507
this.declare_binding(
521508
source_info,

src/librustc_mir/build/mod.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -945,10 +945,13 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
945945
self.var_indices.insert(var, LocalsForNode::One(local));
946946
}
947947
_ => {
948-
scope = self.declare_bindings(scope, ast_body.span,
949-
LintLevel::Inherited, &pattern,
950-
matches::ArmHasGuard(false),
951-
Some((Some(&place), span)));
948+
scope = self.declare_bindings(
949+
scope,
950+
ast_body.span,
951+
&pattern,
952+
matches::ArmHasGuard(false),
953+
Some((Some(&place), span)),
954+
);
952955
unpack!(block = self.place_into_pattern(block, pattern, &place, false));
953956
}
954957
}

src/librustc_mir/hair/mod.rs

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,6 @@ pub enum LintLevel {
3131
Explicit(hir::HirId)
3232
}
3333

34-
impl LintLevel {
35-
pub fn is_explicit(self) -> bool {
36-
match self {
37-
LintLevel::Inherited => false,
38-
LintLevel::Explicit(_) => true
39-
}
40-
}
41-
}
42-
4334
#[derive(Clone, Debug)]
4435
pub struct Block<'tcx> {
4536
pub targeted_by_break: bool,
@@ -311,6 +302,8 @@ pub struct Arm<'tcx> {
311302
pub guard: Option<Guard<'tcx>>,
312303
pub body: ExprRef<'tcx>,
313304
pub lint_level: LintLevel,
305+
pub scope: region::Scope,
306+
pub span: Span,
314307
}
315308

316309
#[derive(Clone, Debug)]

src/test/mir-opt/box_expr.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,11 @@ impl Drop for S {
2222
// END RUST SOURCE
2323
// START rustc.main.ElaborateDrops.before.mir
2424
// let mut _0: ();
25+
// let _1: std::boxed::Box<S>;
2526
// let mut _2: std::boxed::Box<S>;
2627
// let mut _3: ();
2728
// let mut _4: std::boxed::Box<S>;
2829
// scope 1 {
29-
// let _1: std::boxed::Box<S>;
30-
// }
31-
// scope 2 {
3230
// }
3331
// bb0: {
3432
// StorageLive(_1);

src/test/mir-opt/issue-41110.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,27 +29,24 @@ impl S {
2929
// END RUST SOURCE
3030
// START rustc.main.ElaborateDrops.after.mir
3131
// let mut _0: ();
32+
// let _1: ();
3233
// let mut _2: S;
3334
// let mut _3: S;
3435
// let mut _4: S;
3536
// let mut _5: bool;
3637
// scope 1 {
37-
// let _1: ();
38-
// }
39-
// scope 2 {
4038
// }
4139
// ...
4240
// bb0: {
4341
// END rustc.main.ElaborateDrops.after.mir
4442
// START rustc.test.ElaborateDrops.after.mir
4543
// let mut _0: ();
44+
// let _1: S;
4645
// let mut _3: ();
4746
// let mut _4: S;
4847
// let mut _5: S;
4948
// let mut _6: bool;
5049
// ...
51-
// let _1: S;
52-
// ...
5350
// let mut _2: S;
5451
// ...
5552
// bb0: {

src/test/mir-opt/issue-49232.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,12 @@ fn main() {
1818
// fn main() -> (){
1919
// let mut _0: ();
2020
// let mut _1: ();
21+
// let _2: i32;
2122
// let mut _3: bool;
2223
// let mut _4: !;
2324
// let mut _5: ();
2425
// let mut _6: &i32;
2526
// scope 1 {
26-
// let _2: i32;
27-
// }
28-
// scope 2 {
2927
// }
3028
// bb0: {
3129
// goto -> bb1;

src/test/mir-opt/packed-struct-drop-aligned.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,13 @@ impl Drop for Droppy {
1818
// START rustc.main.EraseRegions.before.mir
1919
// fn main() -> () {
2020
// let mut _0: ();
21+
// let mut _1: Packed;
2122
// let mut _2: Aligned;
2223
// let mut _3: Droppy;
2324
// let mut _4: Aligned;
2425
// let mut _5: Droppy;
2526
// let mut _6: Aligned;
2627
// scope 1 {
27-
// let mut _1: Packed;
28-
// }
29-
// scope 2 {
3028
// }
3129
//
3230
// bb0: {

0 commit comments

Comments
 (0)