1
Fork 0

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.
This commit is contained in:
David Wood 2019-03-12 16:53:33 +01:00
parent 8b57be1bb3
commit 41c6bb1096
No known key found for this signature in database
GPG key ID: 01760B4F9F53F154
9 changed files with 46 additions and 4 deletions

View file

@ -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,

View file

@ -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 _ { .. }`.

View file

@ -435,4 +435,3 @@ impl<'hir> HashStable<StableHashingContext<'hir>> for attr::OptimizeAttr {
mem::discriminant(self).hash_stable(hcx, hasher);
}
}

View file

@ -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.

View file

@ -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'.

View file

@ -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,

View file

@ -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) {

View file

@ -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,
}))
}

View file

@ -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,