From: Matthew Jasper Date: Tue, 2 Apr 2019 21:29:28 +0000 (+0100) Subject: Handle the visibility/lint scope distinction better X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=af6a9a2c62ba2e7fe54f53884b94fcd2f9a9265b;p=rust.git 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. --- diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 8dba7491bf5..591f713f81f 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -1313,10 +1313,8 @@ fn lower_token(&mut self, token: Token, span: Span) -> TokenStream { } fn lower_arm(&mut self, arm: &Arm) -> hir::Arm { - let LoweredNodeId { node_id: _, hir_id } = self.next_id(); - hir::Arm { - hir_id, + hir_id: self.next_id(), attrs: self.lower_attrs(&arm.attrs), pats: arm.pats.iter().map(|x| self.lower_pat(x)).collect(), guard: match arm.guard { @@ -5027,10 +5025,8 @@ fn lower_trait_bound_modifier(&mut self, f: TraitBoundModifier) -> hir::TraitBou // Helper methods for building HIR. fn arm(&mut self, pats: hir::HirVec>, expr: P) -> hir::Arm { - let LoweredNodeId { node_id: _, hir_id } = self.next_id(); - hir::Arm { - hir_id, + hir_id: self.next_id(), attrs: hir_vec![], pats, guard: None, diff --git a/src/librustc_mir/build/block.rs b/src/librustc_mir/build/block.rs index d93223a4292..b5bab158534 100644 --- a/src/librustc_mir/build/block.rs +++ b/src/librustc_mir/build/block.rs @@ -113,31 +113,39 @@ fn ast_block_stmts(&mut self, let remainder_span = remainder_scope.span(this.hir.tcx(), &this.hir.region_scope_tree); - let scope; + let visibility_scope = + Some(this.new_source_scope(remainder_span, LintLevel::Inherited, None)); // Evaluate the initializer, if present. if let Some(init) = initializer { let initializer_span = init.span(); - scope = this.declare_bindings( - None, - remainder_span, - lint_level, - &pattern, - ArmHasGuard(false), - Some((None, initializer_span)), - ); unpack!(block = this.in_opt_scope( opt_destruction_scope.map(|de|(de, source_info)), |this| { let scope = (init_scope, source_info); this.in_scope(scope, lint_level, |this| { + this.declare_bindings( + visibility_scope, + remainder_span, + &pattern, + ArmHasGuard(false), + Some((None, initializer_span)), + ); this.expr_into_pattern(block, pattern, init) }) })); } else { - scope = this.declare_bindings( - None, remainder_span, lint_level, &pattern, - ArmHasGuard(false), None); + let scope = (init_scope, source_info); + unpack!(this.in_scope(scope, lint_level, |this| { + this.declare_bindings( + visibility_scope, + remainder_span, + &pattern, + ArmHasGuard(false), + None, + ); + block.unit() + })); debug!("ast_block_stmts: pattern={:?}", pattern); this.visit_bindings( @@ -149,8 +157,8 @@ fn ast_block_stmts(&mut self, }) } - // Enter the source scope, after evaluating the initializer. - if let Some(source_scope) = scope { + // Enter the visibility scope, after evaluating the initializer. + if let Some(source_scope) = visibility_scope { this.source_scope = source_scope; } } diff --git a/src/librustc_mir/build/matches/mod.rs b/src/librustc_mir/build/matches/mod.rs index 51d5c96083d..93a702dc44e 100644 --- a/src/librustc_mir/build/matches/mod.rs +++ b/src/librustc_mir/build/matches/mod.rs @@ -259,12 +259,15 @@ pub fn match_expr( let scope = self.declare_bindings( None, body.span, - LintLevel::Inherited, &arm.patterns[0], ArmHasGuard(arm.guard.is_some()), Some((Some(&scrutinee_place), scrutinee_span)), ); + if let Some(source_scope) = scope { + this.source_scope = source_scope; + } + for candidate in candidates { self.bind_and_guard_matched_candidate( candidate, @@ -275,9 +278,6 @@ pub fn match_expr( ); } - if let Some(source_scope) = scope { - self.source_scope = source_scope; - } unpack!(arm_block = self.into(destination, arm_block, body)); @@ -489,33 +489,20 @@ pub fn declare_bindings( &mut self, mut visibility_scope: Option, scope_span: Span, - lint_level: LintLevel, pattern: &Pattern<'tcx>, has_guard: ArmHasGuard, opt_match_place: Option<(Option<&Place<'tcx>>, Span)>, ) -> Option { - assert!( - !(visibility_scope.is_some() && lint_level.is_explicit()), - "can't have both a visibility and a lint scope at the same time" - ); - let mut scope = self.source_scope; debug!("declare_bindings: pattern={:?}", pattern); self.visit_bindings( &pattern, UserTypeProjections::none(), &mut |this, mutability, name, mode, var, span, ty, user_ty| { if visibility_scope.is_none() { - // If we have lints, create a new source scope - // that marks the lints for the locals. See the comment - // on the `source_info` field for why this is needed. - if lint_level.is_explicit() { - scope = this.new_source_scope(scope_span, lint_level, None); - } - visibility_scope = Some(this.new_source_scope(scope_span, - LintLevel::Inherited, - None)); + visibility_scope = + Some(this.new_source_scope(scope_span, LintLevel::Inherited, None)); } - let source_info = SourceInfo { span, scope }; + let source_info = SourceInfo { span, this.source_scope }; let visibility_scope = visibility_scope.unwrap(); this.declare_binding( source_info, diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs index b432ed47d0b..8cd4ac0ad3a 100644 --- a/src/librustc_mir/build/mod.rs +++ b/src/librustc_mir/build/mod.rs @@ -945,10 +945,13 @@ fn args_and_body(&mut self, self.var_indices.insert(var, LocalsForNode::One(local)); } _ => { - scope = self.declare_bindings(scope, ast_body.span, - LintLevel::Inherited, &pattern, - matches::ArmHasGuard(false), - Some((Some(&place), span))); + scope = self.declare_bindings( + scope, + ast_body.span, + &pattern, + matches::ArmHasGuard(false), + Some((Some(&place), span)), + ); unpack!(block = self.place_into_pattern(block, pattern, &place, false)); } } diff --git a/src/librustc_mir/hair/mod.rs b/src/librustc_mir/hair/mod.rs index d4f139e103a..8e19913f4df 100644 --- a/src/librustc_mir/hair/mod.rs +++ b/src/librustc_mir/hair/mod.rs @@ -31,15 +31,6 @@ pub enum LintLevel { Explicit(hir::HirId) } -impl LintLevel { - pub fn is_explicit(self) -> bool { - match self { - LintLevel::Inherited => false, - LintLevel::Explicit(_) => true - } - } -} - #[derive(Clone, Debug)] pub struct Block<'tcx> { pub targeted_by_break: bool, @@ -311,6 +302,8 @@ pub struct Arm<'tcx> { pub guard: Option>, pub body: ExprRef<'tcx>, pub lint_level: LintLevel, + pub scope: region::Scope, + pub span: Span, } #[derive(Clone, Debug)] diff --git a/src/test/mir-opt/box_expr.rs b/src/test/mir-opt/box_expr.rs index d4852db6d47..ee6adfefe3e 100644 --- a/src/test/mir-opt/box_expr.rs +++ b/src/test/mir-opt/box_expr.rs @@ -22,13 +22,11 @@ fn drop(&mut self) { // END RUST SOURCE // START rustc.main.ElaborateDrops.before.mir // let mut _0: (); +// let _1: std::boxed::Box; // let mut _2: std::boxed::Box; // let mut _3: (); // let mut _4: std::boxed::Box; // scope 1 { -// let _1: std::boxed::Box; -// } -// scope 2 { // } // bb0: { // StorageLive(_1); diff --git a/src/test/mir-opt/issue-41110.rs b/src/test/mir-opt/issue-41110.rs index 023440af0eb..0b678be2ab3 100644 --- a/src/test/mir-opt/issue-41110.rs +++ b/src/test/mir-opt/issue-41110.rs @@ -29,27 +29,24 @@ fn other(self, s: Self) {} // END RUST SOURCE // START rustc.main.ElaborateDrops.after.mir // let mut _0: (); +// let _1: (); // let mut _2: S; // let mut _3: S; // let mut _4: S; // let mut _5: bool; // scope 1 { -// let _1: (); -// } -// scope 2 { // } // ... // bb0: { // END rustc.main.ElaborateDrops.after.mir // START rustc.test.ElaborateDrops.after.mir // let mut _0: (); +// let _1: S; // let mut _3: (); // let mut _4: S; // let mut _5: S; // let mut _6: bool; // ... -// let _1: S; -// ... // let mut _2: S; // ... // bb0: { diff --git a/src/test/mir-opt/issue-49232.rs b/src/test/mir-opt/issue-49232.rs index 29446d2ecc2..3910183dee7 100644 --- a/src/test/mir-opt/issue-49232.rs +++ b/src/test/mir-opt/issue-49232.rs @@ -18,14 +18,12 @@ fn main() { // fn main() -> (){ // let mut _0: (); // let mut _1: (); +// let _2: i32; // let mut _3: bool; // let mut _4: !; // let mut _5: (); // let mut _6: &i32; // scope 1 { -// let _2: i32; -// } -// scope 2 { // } // bb0: { // goto -> bb1; diff --git a/src/test/mir-opt/packed-struct-drop-aligned.rs b/src/test/mir-opt/packed-struct-drop-aligned.rs index 7e8c58e64c2..da73cc96348 100644 --- a/src/test/mir-opt/packed-struct-drop-aligned.rs +++ b/src/test/mir-opt/packed-struct-drop-aligned.rs @@ -18,15 +18,13 @@ fn drop(&mut self) {} // START rustc.main.EraseRegions.before.mir // fn main() -> () { // let mut _0: (); +// let mut _1: Packed; // let mut _2: Aligned; // let mut _3: Droppy; // let mut _4: Aligned; // let mut _5: Droppy; // let mut _6: Aligned; // scope 1 { -// let mut _1: Packed; -// } -// scope 2 { // } // // bb0: {