]> git.lizzy.rs Git - rust.git/commitdiff
Handle the visibility/lint scope distinction better
authorMatthew Jasper <mjjasper1@gmail.com>
Tue, 2 Apr 2019 21:29:28 +0000 (22:29 +0100)
committerMatthew Jasper <mjjasper1@gmail.com>
Tue, 21 May 2019 18:37:38 +0000 (19:37 +0100)
* Don't generate an extra lint scope for each `let` statement.
* Place match guards inside the visiblility scope of the bindings for
  their arm.

src/librustc/hir/lowering.rs
src/librustc_mir/build/block.rs
src/librustc_mir/build/matches/mod.rs
src/librustc_mir/build/mod.rs
src/librustc_mir/hair/mod.rs
src/test/mir-opt/box_expr.rs
src/test/mir-opt/issue-41110.rs
src/test/mir-opt/issue-49232.rs
src/test/mir-opt/packed-struct-drop-aligned.rs

index 8dba7491bf5047046e85d34657890faccc6643df..591f713f81f79bc39f0e284f4e10e4457f7e7a12 100644 (file)
@@ -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<P<hir::Pat>>, expr: P<hir::Expr>) -> 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,
index d93223a4292c4399f7233ac9acb0004b04071af1..b5bab1585342a1cacf4329ee69aacafcf31d31e1 100644 (file)
@@ -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;
                     }
                 }
index 51d5c96083d8f61b6b15b28b9a5278cae7242372..93a702dc44e25254f7f90387ad9a7fde57ea13a2 100644 (file)
@@ -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<SourceScope>,
         scope_span: Span,
-        lint_level: LintLevel,
         pattern: &Pattern<'tcx>,
         has_guard: ArmHasGuard,
         opt_match_place: Option<(Option<&Place<'tcx>>, Span)>,
     ) -> Option<SourceScope> {
-        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,
index b432ed47d0b8d42b0e6519c6e9ec46cff786b35e..8cd4ac0ad3ade249dd0ee862a76a328fee2fd5d4 100644 (file)
@@ -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));
                     }
                 }
index d4f139e103a641a12d665f0e8cf05ec2e96f0255..8e19913f4df26d30ab8611cef310842cce27677f 100644 (file)
@@ -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<Guard<'tcx>>,
     pub body: ExprRef<'tcx>,
     pub lint_level: LintLevel,
+    pub scope: region::Scope,
+    pub span: Span,
 }
 
 #[derive(Clone, Debug)]
index d4852db6d475e39736104ebc1de375729077b62e..ee6adfefe3e360b3a0ec00bd878d1fceb2de619e 100644 (file)
@@ -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<S>;
 //     let mut _2: std::boxed::Box<S>;
 //     let mut _3: ();
 //     let mut _4: std::boxed::Box<S>;
 //     scope 1 {
-//         let _1: std::boxed::Box<S>;
-//     }
-//     scope 2 {
 //     }
 //     bb0: {
 //         StorageLive(_1);
index 023440af0eb10d014549346c9008271b594b7dbe..0b678be2ab3197ea4f8c1b34b6204c546e16f7fa 100644 (file)
@@ -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: {
index 29446d2ecc23e5d9180ee6f47957cbde30d42977..3910183dee789bc17dac1fd8e348bbee0e2c49e4 100644 (file)
@@ -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;
index 7e8c58e64c28d60d2689682e094f927291c0da75..da73cc96348f059e4c15e29ce839204b2b824ed4 100644 (file)
@@ -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: {