From 41c6bb1096abb026d496c2136bb18c001eca46fe Mon Sep 17 00:00:00 2001 From: David Wood Date: Tue, 12 Mar 2019 16:53:33 +0100 Subject: [PATCH] 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 : = __arg0;` statements. --- src/librustc/hir/lowering.rs | 9 ++++++++- src/librustc/hir/mod.rs | 11 +++++++++++ src/librustc/ich/impls_hir.rs | 1 - src/librustc_mir/hair/pattern/check_match.rs | 1 + src/libsyntax/ast.rs | 11 +++++++++++ src/libsyntax/ext/build.rs | 3 +++ src/libsyntax/mut_visit.rs | 10 +++++++++- src/libsyntax/parse/parser.rs | 3 ++- src/libsyntax_ext/deriving/debug.rs | 1 + 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( @ x: Type) { + /// async move { + /// let = 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> 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, + /// 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(args: &mut Parenth } pub fn noop_visit_local(local: &mut P, 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(_local_source: &mut LocalSource, _vis: &mut T) { } pub fn noop_visit_attribute(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 id: ast::DUMMY_NODE_ID, span: sp, attrs: ThinVec::new(), + source: ast::LocalSource::Normal, }); ast::Stmt { id: ast::DUMMY_NODE_ID,