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:
parent
8b57be1bb3
commit
41c6bb1096
9 changed files with 46 additions and 4 deletions
|
@ -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,
|
||||
|
|
|
@ -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 _ { .. }`.
|
||||
|
|
|
@ -435,4 +435,3 @@ impl<'hir> HashStable<StableHashingContext<'hir>> for attr::OptimizeAttr {
|
|||
mem::discriminant(self).hash_stable(hcx, hasher);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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'.
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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,
|
||||
}))
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue