about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDavid Wood <david@davidtw.co>2019-03-12 16:53:33 +0100
committerDavid Wood <david@davidtw.co>2019-04-21 09:48:11 +0100
commit41c6bb1096abb026d496c2136bb18c001eca46fe (patch)
tree18bc1364d09a1e9ac054d312355af65ca5139c72
parent8b57be1bb3be3be5ac431ed9a0a310d2023b1c9d (diff)
downloadrust-41c6bb1096abb026d496c2136bb18c001eca46fe.tar.gz
rust-41c6bb1096abb026d496c2136bb18c001eca46fe.zip
Introduce `LocalSource` into the AST.
This will be used to keep track of the origin of a local in the AST. In
particular, it will be used by `async fn` lowering for the locals in
`let <pat>: <ty> = __arg0;` statements.
-rw-r--r--src/librustc/hir/lowering.rs9
-rw-r--r--src/librustc/hir/mod.rs11
-rw-r--r--src/librustc/ich/impls_hir.rs1
-rw-r--r--src/librustc_mir/hair/pattern/check_match.rs1
-rw-r--r--src/libsyntax/ast.rs11
-rw-r--r--src/libsyntax/ext/build.rs3
-rw-r--r--src/libsyntax/mut_visit.rs10
-rw-r--r--src/libsyntax/parse/parser.rs3
-rw-r--r--src/libsyntax_ext/deriving/debug.rs1
9 files changed, 46 insertions, 4 deletions
diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index 42ad571cf28..e4cf3cfc63d 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -2224,10 +2224,17 @@ impl<'a> LoweringContext<'a> {
             init: l.init.as_ref().map(|e| P(self.lower_expr(e))),
             span: l.span,
             attrs: l.attrs.clone(),
-            source: hir::LocalSource::Normal,
+            source: self.lower_local_source(l.source),
         }, ids)
     }
 
+    fn lower_local_source(&mut self, ls: LocalSource) -> hir::LocalSource {
+        match ls {
+            LocalSource::Normal => hir::LocalSource::Normal,
+            LocalSource::AsyncFn => hir::LocalSource::AsyncFn,
+        }
+    }
+
     fn lower_mutability(&mut self, m: Mutability) -> hir::Mutability {
         match m {
             Mutability::Mutable => hir::MutMutable,
diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs
index 7ed8c08c923..e873663a613 100644
--- a/src/librustc/hir/mod.rs
+++ b/src/librustc/hir/mod.rs
@@ -1583,6 +1583,17 @@ pub enum LocalSource {
     Normal,
     /// A desugared `for _ in _ { .. }` loop.
     ForLoopDesugar,
+    /// When lowering async functions, we create locals within the `async move` so that
+    /// all arguments are dropped after the future is polled.
+    ///
+    /// ```ignore (pseudo-Rust)
+    /// async fn foo(<pattern> @ x: Type) {
+    ///     async move {
+    ///         let <pattern> = x;
+    ///     }
+    /// }
+    /// ```
+    AsyncFn,
 }
 
 /// Hints at the original code for a `match _ { .. }`.
diff --git a/src/librustc/ich/impls_hir.rs b/src/librustc/ich/impls_hir.rs
index 9491a073b8f..65795d2b136 100644
--- a/src/librustc/ich/impls_hir.rs
+++ b/src/librustc/ich/impls_hir.rs
@@ -435,4 +435,3 @@ impl<'hir> HashStable<StableHashingContext<'hir>> for attr::OptimizeAttr {
         mem::discriminant(self).hash_stable(hcx, hasher);
     }
 }
-
diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs
index 7ded973701e..c4f07d9c544 100644
--- a/src/librustc_mir/hair/pattern/check_match.rs
+++ b/src/librustc_mir/hair/pattern/check_match.rs
@@ -76,6 +76,7 @@ impl<'a, 'tcx> Visitor<'tcx> for MatchVisitor<'a, 'tcx> {
         self.check_irrefutable(&loc.pat, match loc.source {
             hir::LocalSource::Normal => "local binding",
             hir::LocalSource::ForLoopDesugar => "`for` loop binding",
+            hir::LocalSource::AsyncFn => "async fn binding",
         });
 
         // Check legality of move bindings and `@` patterns.
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 0668730b3ef..2fe0ebcdd28 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -888,6 +888,17 @@ pub struct Local {
     pub id: NodeId,
     pub span: Span,
     pub attrs: ThinVec<Attribute>,
+    /// Origin of this local variable.
+    pub source: LocalSource,
+}
+
+#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug)]
+pub enum LocalSource {
+    /// Local was parsed from source.
+    Normal,
+    /// Within `ast::IsAsync::Async`, a local is generated that will contain the moved arguments
+    /// of an `async fn`.
+    AsyncFn,
 }
 
 /// An arm of a 'match'.
diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs
index 614967bdeb4..029c45eaa72 100644
--- a/src/libsyntax/ext/build.rs
+++ b/src/libsyntax/ext/build.rs
@@ -526,6 +526,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
             id: ast::DUMMY_NODE_ID,
             span: sp,
             attrs: ThinVec::new(),
+            source: ast::LocalSource::Normal,
         });
         ast::Stmt {
             id: ast::DUMMY_NODE_ID,
@@ -554,6 +555,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
             id: ast::DUMMY_NODE_ID,
             span: sp,
             attrs: ThinVec::new(),
+            source: ast::LocalSource::Normal,
         });
         ast::Stmt {
             id: ast::DUMMY_NODE_ID,
@@ -571,6 +573,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
             id: ast::DUMMY_NODE_ID,
             span,
             attrs: ThinVec::new(),
+            source: ast::LocalSource::Normal,
         });
         ast::Stmt {
             id: ast::DUMMY_NODE_ID,
diff --git a/src/libsyntax/mut_visit.rs b/src/libsyntax/mut_visit.rs
index 784d0049ac5..87826ccc891 100644
--- a/src/libsyntax/mut_visit.rs
+++ b/src/libsyntax/mut_visit.rs
@@ -208,6 +208,10 @@ pub trait MutVisitor: Sized {
         noop_visit_local(l, self);
     }
 
+    fn visit_local_source(&mut self, l: &mut LocalSource) {
+        noop_visit_local_source(l, self);
+    }
+
     fn visit_mac(&mut self, _mac: &mut Mac) {
         panic!("visit_mac disabled by default");
         // N.B., see note about macros above. If you really want a visitor that
@@ -511,13 +515,17 @@ pub fn noop_visit_parenthesized_parameter_data<T: MutVisitor>(args: &mut Parenth
 }
 
 pub fn noop_visit_local<T: MutVisitor>(local: &mut P<Local>, vis: &mut T) {
-    let Local { id, pat, ty, init, span, attrs } = local.deref_mut();
+    let Local { id, pat, ty, init, span, attrs, source } = local.deref_mut();
     vis.visit_id(id);
     vis.visit_pat(pat);
     visit_opt(ty, |ty| vis.visit_ty(ty));
     visit_opt(init, |init| vis.visit_expr(init));
     vis.visit_span(span);
     visit_thin_attrs(attrs, vis);
+    vis.visit_local_source(source);
+}
+
+pub fn noop_visit_local_source<T: MutVisitor>(_local_source: &mut LocalSource, _vis: &mut T) {
 }
 
 pub fn noop_visit_attribute<T: MutVisitor>(attr: &mut Attribute, vis: &mut T) {
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 8feab373e71..8620627765f 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -14,7 +14,7 @@ use crate::ast::{GenericParam, GenericParamKind};
 use crate::ast::GenericArg;
 use crate::ast::{Ident, ImplItem, IsAsync, IsAuto, Item, ItemKind};
 use crate::ast::{Label, Lifetime, Lit, LitKind};
-use crate::ast::Local;
+use crate::ast::{Local, LocalSource};
 use crate::ast::MacStmtStyle;
 use crate::ast::{Mac, Mac_, MacDelimiter};
 use crate::ast::{MutTy, Mutability};
@@ -5029,6 +5029,7 @@ impl<'a> Parser<'a> {
             id: ast::DUMMY_NODE_ID,
             span: lo.to(hi),
             attrs,
+            source: LocalSource::Normal,
         }))
     }
 
diff --git a/src/libsyntax_ext/deriving/debug.rs b/src/libsyntax_ext/deriving/debug.rs
index 7c47c6ff79a..2fc1fc9140d 100644
--- a/src/libsyntax_ext/deriving/debug.rs
+++ b/src/libsyntax_ext/deriving/debug.rs
@@ -128,6 +128,7 @@ fn stmt_let_undescore(cx: &mut ExtCtxt<'_>, sp: Span, expr: P<ast::Expr>) -> ast
         id: ast::DUMMY_NODE_ID,
         span: sp,
         attrs: ThinVec::new(),
+        source: ast::LocalSource::Normal,
     });
     ast::Stmt {
         id: ast::DUMMY_NODE_ID,