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))),
|
init: l.init.as_ref().map(|e| P(self.lower_expr(e))),
|
||||||
span: l.span,
|
span: l.span,
|
||||||
attrs: l.attrs.clone(),
|
attrs: l.attrs.clone(),
|
||||||
source: hir::LocalSource::Normal,
|
source: self.lower_local_source(l.source),
|
||||||
}, ids)
|
}, 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 {
|
fn lower_mutability(&mut self, m: Mutability) -> hir::Mutability {
|
||||||
match m {
|
match m {
|
||||||
Mutability::Mutable => hir::MutMutable,
|
Mutability::Mutable => hir::MutMutable,
|
||||||
|
|
|
@ -1583,6 +1583,17 @@ pub enum LocalSource {
|
||||||
Normal,
|
Normal,
|
||||||
/// A desugared `for _ in _ { .. }` loop.
|
/// A desugared `for _ in _ { .. }` loop.
|
||||||
ForLoopDesugar,
|
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 _ { .. }`.
|
/// 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);
|
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 {
|
self.check_irrefutable(&loc.pat, match loc.source {
|
||||||
hir::LocalSource::Normal => "local binding",
|
hir::LocalSource::Normal => "local binding",
|
||||||
hir::LocalSource::ForLoopDesugar => "`for` loop binding",
|
hir::LocalSource::ForLoopDesugar => "`for` loop binding",
|
||||||
|
hir::LocalSource::AsyncFn => "async fn binding",
|
||||||
});
|
});
|
||||||
|
|
||||||
// Check legality of move bindings and `@` patterns.
|
// Check legality of move bindings and `@` patterns.
|
||||||
|
|
|
@ -888,6 +888,17 @@ pub struct Local {
|
||||||
pub id: NodeId,
|
pub id: NodeId,
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
pub attrs: ThinVec<Attribute>,
|
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'.
|
/// An arm of a 'match'.
|
||||||
|
|
|
@ -526,6 +526,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
||||||
id: ast::DUMMY_NODE_ID,
|
id: ast::DUMMY_NODE_ID,
|
||||||
span: sp,
|
span: sp,
|
||||||
attrs: ThinVec::new(),
|
attrs: ThinVec::new(),
|
||||||
|
source: ast::LocalSource::Normal,
|
||||||
});
|
});
|
||||||
ast::Stmt {
|
ast::Stmt {
|
||||||
id: ast::DUMMY_NODE_ID,
|
id: ast::DUMMY_NODE_ID,
|
||||||
|
@ -554,6 +555,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
||||||
id: ast::DUMMY_NODE_ID,
|
id: ast::DUMMY_NODE_ID,
|
||||||
span: sp,
|
span: sp,
|
||||||
attrs: ThinVec::new(),
|
attrs: ThinVec::new(),
|
||||||
|
source: ast::LocalSource::Normal,
|
||||||
});
|
});
|
||||||
ast::Stmt {
|
ast::Stmt {
|
||||||
id: ast::DUMMY_NODE_ID,
|
id: ast::DUMMY_NODE_ID,
|
||||||
|
@ -571,6 +573,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
||||||
id: ast::DUMMY_NODE_ID,
|
id: ast::DUMMY_NODE_ID,
|
||||||
span,
|
span,
|
||||||
attrs: ThinVec::new(),
|
attrs: ThinVec::new(),
|
||||||
|
source: ast::LocalSource::Normal,
|
||||||
});
|
});
|
||||||
ast::Stmt {
|
ast::Stmt {
|
||||||
id: ast::DUMMY_NODE_ID,
|
id: ast::DUMMY_NODE_ID,
|
||||||
|
|
|
@ -208,6 +208,10 @@ pub trait MutVisitor: Sized {
|
||||||
noop_visit_local(l, self);
|
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) {
|
fn visit_mac(&mut self, _mac: &mut Mac) {
|
||||||
panic!("visit_mac disabled by default");
|
panic!("visit_mac disabled by default");
|
||||||
// N.B., see note about macros above. If you really want a visitor that
|
// 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) {
|
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_id(id);
|
||||||
vis.visit_pat(pat);
|
vis.visit_pat(pat);
|
||||||
visit_opt(ty, |ty| vis.visit_ty(ty));
|
visit_opt(ty, |ty| vis.visit_ty(ty));
|
||||||
visit_opt(init, |init| vis.visit_expr(init));
|
visit_opt(init, |init| vis.visit_expr(init));
|
||||||
vis.visit_span(span);
|
vis.visit_span(span);
|
||||||
visit_thin_attrs(attrs, vis);
|
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) {
|
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::GenericArg;
|
||||||
use crate::ast::{Ident, ImplItem, IsAsync, IsAuto, Item, ItemKind};
|
use crate::ast::{Ident, ImplItem, IsAsync, IsAuto, Item, ItemKind};
|
||||||
use crate::ast::{Label, Lifetime, Lit, LitKind};
|
use crate::ast::{Label, Lifetime, Lit, LitKind};
|
||||||
use crate::ast::Local;
|
use crate::ast::{Local, LocalSource};
|
||||||
use crate::ast::MacStmtStyle;
|
use crate::ast::MacStmtStyle;
|
||||||
use crate::ast::{Mac, Mac_, MacDelimiter};
|
use crate::ast::{Mac, Mac_, MacDelimiter};
|
||||||
use crate::ast::{MutTy, Mutability};
|
use crate::ast::{MutTy, Mutability};
|
||||||
|
@ -5029,6 +5029,7 @@ impl<'a> Parser<'a> {
|
||||||
id: ast::DUMMY_NODE_ID,
|
id: ast::DUMMY_NODE_ID,
|
||||||
span: lo.to(hi),
|
span: lo.to(hi),
|
||||||
attrs,
|
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,
|
id: ast::DUMMY_NODE_ID,
|
||||||
span: sp,
|
span: sp,
|
||||||
attrs: ThinVec::new(),
|
attrs: ThinVec::new(),
|
||||||
|
source: ast::LocalSource::Normal,
|
||||||
});
|
});
|
||||||
ast::Stmt {
|
ast::Stmt {
|
||||||
id: ast::DUMMY_NODE_ID,
|
id: ast::DUMMY_NODE_ID,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue