about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthew Jasper <mjjasper1@gmail.com>2019-03-30 22:54:29 +0000
committerMatthew Jasper <mjjasper1@gmail.com>2019-05-21 19:37:38 +0100
commit4bfb0453f537b2927574f29bdf90c9a22ea98add (patch)
tree9b1cef2e6ae38d055ee3a31f2dee48c25264030e
parent615c23f6ecc07e87501f2f52190e3fb08b50a17e (diff)
downloadrust-4bfb0453f537b2927574f29bdf90c9a22ea98add.tar.gz
rust-4bfb0453f537b2927574f29bdf90c9a22ea98add.zip
Give match arms an HirId and a Span
-rw-r--r--src/librustc/hir/intravisit.rs1
-rw-r--r--src/librustc/hir/lowering.rs8
-rw-r--r--src/librustc/hir/map/collector.rs10
-rw-r--r--src/librustc/hir/map/mod.rs7
-rw-r--r--src/librustc/hir/mod.rs4
-rw-r--r--src/librustc/hir/print.rs2
-rw-r--r--src/librustc_passes/hir_stats.rs2
-rw-r--r--src/librustc_typeck/check/_match.rs15
-rw-r--r--src/libsyntax/ast.rs1
-rw-r--r--src/libsyntax/ext/build.rs3
-rw-r--r--src/libsyntax/mut_visit.rs6
-rw-r--r--src/libsyntax/parse/parser.rs4
12 files changed, 53 insertions, 10 deletions
diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs
index 38d6d710868..517c99f99ef 100644
--- a/src/librustc/hir/intravisit.rs
+++ b/src/librustc/hir/intravisit.rs
@@ -1102,6 +1102,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
 }
 
 pub fn walk_arm<'v, V: Visitor<'v>>(visitor: &mut V, arm: &'v Arm) {
+    visitor.visit_id(arm.hir_id);
     walk_list!(visitor, visit_pat, &arm.pats);
     if let Some(ref g) = arm.guard {
         match g {
diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index 3ec4d4e8cc8..8dba7491bf5 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -1313,7 +1313,10 @@ impl<'a> LoweringContext<'a> {
     }
 
     fn lower_arm(&mut self, arm: &Arm) -> hir::Arm {
+        let LoweredNodeId { node_id: _, hir_id } = self.next_id();
+
         hir::Arm {
+            hir_id,
             attrs: self.lower_attrs(&arm.attrs),
             pats: arm.pats.iter().map(|x| self.lower_pat(x)).collect(),
             guard: match arm.guard {
@@ -1321,6 +1324,7 @@ impl<'a> LoweringContext<'a> {
                 _ => None,
             },
             body: P(self.lower_expr(&arm.body)),
+            span: arm.span,
         }
     }
 
@@ -5023,10 +5027,14 @@ impl<'a> LoweringContext<'a> {
     // 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,
             attrs: hir_vec![],
             pats,
             guard: None,
+            span: expr.span,
             body: expr,
         }
     }
diff --git a/src/librustc/hir/map/collector.rs b/src/librustc/hir/map/collector.rs
index eeba628b3bf..b5203f9ec1f 100644
--- a/src/librustc/hir/map/collector.rs
+++ b/src/librustc/hir/map/collector.rs
@@ -430,6 +430,16 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
         });
     }
 
+    fn visit_arm(&mut self, arm: &'hir Arm) {
+        let node = Node::Arm(arm);
+
+        self.insert(arm.span, arm.hir_id, node);
+
+        self.with_parent(arm.hir_id, |this| {
+            intravisit::walk_arm(this, arm);
+        });
+    }
+
     fn visit_anon_const(&mut self, constant: &'hir AnonConst) {
         self.insert(DUMMY_SP, constant.hir_id, Node::AnonConst(constant));
 
diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs
index 4b94f772554..d8fe90d4048 100644
--- a/src/librustc/hir/map/mod.rs
+++ b/src/librustc/hir/map/mod.rs
@@ -373,6 +373,7 @@ impl<'hir> Map<'hir> {
             Node::Pat(_) |
             Node::Binding(_) |
             Node::Local(_) |
+            Node::Arm(_) |
             Node::Lifetime(_) |
             Node::Visibility(_) |
             Node::Block(_) |
@@ -1000,6 +1001,7 @@ impl<'hir> Map<'hir> {
             Some(Node::Field(ref f)) => Some(&f.attrs[..]),
             Some(Node::Expr(ref e)) => Some(&*e.attrs),
             Some(Node::Stmt(ref s)) => Some(s.node.attrs()),
+            Some(Node::Arm(ref a)) => Some(&*a.attrs),
             Some(Node::GenericParam(param)) => Some(&param.attrs[..]),
             // Unit/tuple structs/variants take the attributes straight from
             // the struct/variant definition.
@@ -1073,6 +1075,7 @@ impl<'hir> Map<'hir> {
             Some(Node::TraitRef(tr)) => tr.path.span,
             Some(Node::Binding(pat)) => pat.span,
             Some(Node::Pat(pat)) => pat.span,
+            Some(Node::Arm(arm)) => arm.span,
             Some(Node::Block(block)) => block.span,
             Some(Node::Ctor(..)) => match self.find_by_hir_id(
                 self.get_parent_node_by_hir_id(hir_id))
@@ -1288,6 +1291,7 @@ impl<'a> print::State<'a> {
             Node::TraitRef(a)     => self.print_trait_ref(&a),
             Node::Binding(a)      |
             Node::Pat(a)          => self.print_pat(&a),
+            Node::Arm(a)          => self.print_arm(&a),
             Node::Block(a)        => {
                 use syntax::print::pprust::PrintState;
 
@@ -1417,6 +1421,9 @@ fn hir_id_to_string(map: &Map<'_>, id: HirId, include_id: bool) -> String {
         Some(Node::Pat(_)) => {
             format!("pat {}{}", map.hir_to_pretty_string(id), id_str)
         }
+        Some(Node::Arm(_)) => {
+            format!("arm {}{}", map.hir_to_pretty_string(id), id_str)
+        }
         Some(Node::Block(_)) => {
             format!("block {}{}", map.hir_to_pretty_string(id), id_str)
         }
diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs
index 57304c5ed37..08feea3ccce 100644
--- a/src/librustc/hir/mod.rs
+++ b/src/librustc/hir/mod.rs
@@ -1228,6 +1228,9 @@ pub struct Local {
 /// `<pats> (if <guard>) => <body>`.
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct Arm {
+    #[stable_hasher(ignore)]
+    pub hir_id: HirId,
+    pub span: Span,
     pub attrs: HirVec<Attribute>,
     /// Multiple patterns can be combined with `|`
     pub pats: HirVec<P<Pat>>,
@@ -2656,6 +2659,7 @@ pub enum Node<'hir> {
     TraitRef(&'hir TraitRef),
     Binding(&'hir Pat),
     Pat(&'hir Pat),
+    Arm(&'hir Arm),
     Block(&'hir Block),
     Local(&'hir Local),
     MacroDef(&'hir MacroDef),
diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs
index 8a9028e5443..ef9fee5cab6 100644
--- a/src/librustc/hir/print.rs
+++ b/src/librustc/hir/print.rs
@@ -1862,7 +1862,7 @@ impl<'a> State<'a> {
         self.ann.post(self, AnnNode::Pat(pat))
     }
 
-    fn print_arm(&mut self, arm: &hir::Arm) -> io::Result<()> {
+    pub fn print_arm(&mut self, arm: &hir::Arm) -> io::Result<()> {
         // I have no idea why this check is necessary, but here it
         // is :(
         if arm.attrs.is_empty() {
diff --git a/src/librustc_passes/hir_stats.rs b/src/librustc_passes/hir_stats.rs
index c74314ce0c4..0088c97679c 100644
--- a/src/librustc_passes/hir_stats.rs
+++ b/src/librustc_passes/hir_stats.rs
@@ -149,7 +149,7 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
     }
 
     fn visit_arm(&mut self, a: &'v hir::Arm) {
-        self.record("Arm", Id::None, a);
+        self.record("Arm", Id::Node(a.hir_id), a);
         hir_visit::walk_arm(self, a)
     }
 
diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs
index a69f639e894..99b350b8332 100644
--- a/src/librustc_typeck/check/_match.rs
+++ b/src/librustc_typeck/check/_match.rs
@@ -781,14 +781,17 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
     fn maybe_get_coercion_reason(&self, hir_id: hir::HirId, span: Span) -> Option<(Span, String)> {
         use hir::Node::{Block, Item, Local};
 
-        let node = self.tcx.hir().get_by_hir_id(self.tcx.hir().get_parent_node_by_hir_id(
-            self.tcx.hir().get_parent_node_by_hir_id(hir_id),
-        ));
+        let hir = self.tcx.hir();
+        let arm_id = hir.get_parent_node_by_hir_id(hir_id);
+        let match_id = hir.get_parent_node_by_hir_id(arm_id);
+        let containing_id = hir.get_parent_node_by_hir_id(match_id);
+
+        let node = hir.get_by_hir_id(containing_id);
         if let Block(block) = node {
             // check that the body's parent is an fn
-            let parent = self.tcx.hir().get_by_hir_id(
-                self.tcx.hir().get_parent_node_by_hir_id(
-                    self.tcx.hir().get_parent_node_by_hir_id(block.hir_id),
+            let parent = hir.get_by_hir_id(
+                hir.get_parent_node_by_hir_id(
+                    hir.get_parent_node_by_hir_id(block.hir_id),
                 ),
             );
             if let (Some(expr), Item(hir::Item {
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index a6bb47bef87..e2c2c46abf6 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -908,6 +908,7 @@ pub struct Arm {
     pub pats: Vec<P<Pat>>,
     pub guard: Option<Guard>,
     pub body: P<Expr>,
+    pub span: Span,
 }
 
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs
index d24106f697e..cb967a76822 100644
--- a/src/libsyntax/ext/build.rs
+++ b/src/libsyntax/ext/build.rs
@@ -890,12 +890,13 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
         self.pat_tuple_struct(span, path, vec![pat])
     }
 
-    fn arm(&self, _span: Span, pats: Vec<P<ast::Pat>>, expr: P<ast::Expr>) -> ast::Arm {
+    fn arm(&self, span: Span, pats: Vec<P<ast::Pat>>, expr: P<ast::Expr>) -> ast::Arm {
         ast::Arm {
             attrs: vec![],
             pats,
             guard: None,
             body: expr,
+            span,
         }
     }
 
diff --git a/src/libsyntax/mut_visit.rs b/src/libsyntax/mut_visit.rs
index f587e63e12b..cb21014ec76 100644
--- a/src/libsyntax/mut_visit.rs
+++ b/src/libsyntax/mut_visit.rs
@@ -392,11 +392,15 @@ pub fn noop_visit_use_tree<T: MutVisitor>(use_tree: &mut UseTree, vis: &mut T) {
     vis.visit_span(span);
 }
 
-pub fn noop_visit_arm<T: MutVisitor>(Arm { attrs, pats, guard, body }: &mut Arm, vis: &mut T) {
+pub fn noop_visit_arm<T: MutVisitor>(
+    Arm { attrs, pats, guard, body, span }: &mut Arm,
+    vis: &mut T,
+) {
     visit_attrs(attrs, vis);
     visit_vec(pats, |pat| vis.visit_pat(pat));
     visit_opt(guard, |guard| vis.visit_guard(guard));
     vis.visit_expr(body);
+    vis.visit_span(span);
 }
 
 pub fn noop_visit_guard<T: MutVisitor>(g: &mut Guard, vis: &mut T) {
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 24d120376de..ba36783e11e 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -3946,6 +3946,7 @@ impl<'a> Parser<'a> {
 
     crate fn parse_arm(&mut self) -> PResult<'a, Arm> {
         let attrs = self.parse_outer_attributes()?;
+        let lo = self.span;
         let pats = self.parse_pats()?;
         let guard = if self.eat_keyword(keywords::If) {
             Some(Guard::If(self.parse_expr()?))
@@ -3965,6 +3966,8 @@ impl<'a> Parser<'a> {
         let require_comma = classify::expr_requires_semi_to_be_stmt(&expr)
             && self.token != token::CloseDelim(token::Brace);
 
+        let hi = self.span;
+
         if require_comma {
             let cm = self.sess.source_map();
             self.expect_one_of(&[token::Comma], &[token::CloseDelim(token::Brace)])
@@ -4008,6 +4011,7 @@ impl<'a> Parser<'a> {
             pats,
             guard,
             body: expr,
+            span: lo.to(hi),
         })
     }