use std::collections::BTreeMap;
use std::iter;
use syntax::ast::*;
-use syntax::attr::{ThinAttributes, ThinAttributesExt};
use syntax::ptr::P;
-use syntax::codemap::{respan, Spanned, Span};
+use syntax::codemap::{respan, Spanned};
use syntax::parse::token;
use syntax::std_inject;
use syntax::visit::{self, Visitor};
+use syntax_pos::Span;
pub struct LoweringContext<'a> {
crate_root: Option<&'static str>,
lctx: &'lcx mut LoweringContext<'interner>,
}
- impl<'lcx, 'interner> Visitor<'lcx> for ItemLowerer<'lcx, 'interner> {
- fn visit_item(&mut self, item: &'lcx Item) {
+ impl<'lcx, 'interner> Visitor for ItemLowerer<'lcx, 'interner> {
+ fn visit_item(&mut self, item: &Item) {
self.items.insert(item.id, self.lctx.lower_item(item));
visit::walk_item(self, item);
}
}
}
- fn lower_decl(&mut self, d: &Decl) -> P<hir::Decl> {
- match d.node {
- DeclKind::Local(ref l) => P(Spanned {
- node: hir::DeclLocal(self.lower_local(l)),
- span: d.span,
- }),
- DeclKind::Item(ref it) => P(Spanned {
- node: hir::DeclItem(self.lower_item_id(it)),
- span: d.span,
- }),
- }
- }
-
fn lower_ty_binding(&mut self, b: &TypeBinding) -> hir::TypeBinding {
hir::TypeBinding {
id: b.id,
hir::TypeTraitItem(this.lower_bounds(bounds),
default.as_ref().map(|x| this.lower_ty(x)))
}
+ TraitItemKind::Macro(..) => panic!("Shouldn't exist any more"),
},
span: i.span,
}
pats.iter().map(|x| self.lower_pat(x)).collect(),
ddpos)
}
- PatKind::Path(ref pth) => {
+ PatKind::Path(None, ref pth) => {
hir::PatKind::Path(self.lower_path(pth))
}
- PatKind::QPath(ref qself, ref pth) => {
+ PatKind::Path(Some(ref qself), ref pth) => {
let qself = hir::QSelf {
ty: self.lower_ty(&qself.ty),
position: qself.position,
let make_call = |this: &mut LoweringContext, p, args| {
let path = this.core_path(e.span, p);
- let path = this.expr_path(path, None);
- this.expr_call(e.span, path, args, None)
+ let path = this.expr_path(path, ThinVec::new());
+ this.expr_call(e.span, path, args)
};
let mk_stmt_let = |this: &mut LoweringContext, bind, expr| {
- this.stmt_let(e.span, false, bind, expr, None)
+ this.stmt_let(e.span, false, bind, expr)
};
let mk_stmt_let_mut = |this: &mut LoweringContext, bind, expr| {
- this.stmt_let(e.span, true, bind, expr, None)
+ this.stmt_let(e.span, true, bind, expr)
};
// let placer = <placer_expr> ;
placer_expr,
e.span,
hir::PopUnstableBlock,
- None);
+ ThinVec::new());
mk_stmt_let(self, placer_ident, placer_expr)
};
// let mut place = Placer::make_place(placer);
let (s2, place_binding) = {
- let placer = self.expr_ident(e.span, placer_ident, None, placer_binding);
+ let placer = self.expr_ident(e.span, placer_ident, placer_binding);
let call = make_call(self, &make_place, hir_vec![placer]);
mk_stmt_let_mut(self, place_ident, call)
};
// let p_ptr = Place::pointer(&mut place);
let (s3, p_ptr_binding) = {
- let agent = self.expr_ident(e.span, place_ident, None, place_binding);
- let args = hir_vec![self.expr_mut_addr_of(e.span, agent, None)];
+ let agent = self.expr_ident(e.span, place_ident, place_binding);
+ let args = hir_vec![self.expr_mut_addr_of(e.span, agent)];
let call = make_call(self, &place_pointer, args);
mk_stmt_let(self, p_ptr_ident, call)
};
value_expr,
e.span,
hir::PopUnstableBlock,
- None);
+ ThinVec::new());
self.signal_block_expr(hir_vec![],
value_expr,
e.span,
- hir::PopUnsafeBlock(hir::CompilerGenerated), None)
+ hir::PopUnsafeBlock(hir::CompilerGenerated),
+ ThinVec::new())
};
// push_unsafe!({
// InPlace::finalize(place)
// })
let expr = {
- let ptr = self.expr_ident(e.span, p_ptr_ident, None, p_ptr_binding);
+ let ptr = self.expr_ident(e.span, p_ptr_ident, p_ptr_binding);
let call_move_val_init =
hir::StmtSemi(
make_call(self, &move_val_init, hir_vec![ptr, pop_unsafe_expr]),
self.next_id());
let call_move_val_init = respan(e.span, call_move_val_init);
- let place = self.expr_ident(e.span, place_ident, None, place_binding);
+ let place = self.expr_ident(e.span, place_ident, place_binding);
let call = make_call(self, &inplace_finalize, hir_vec![place]);
self.signal_block_expr(hir_vec![call_move_val_init],
call,
e.span,
- hir::PushUnsafeBlock(hir::CompilerGenerated), None)
+ hir::PushUnsafeBlock(hir::CompilerGenerated),
+ ThinVec::new())
};
return self.signal_block_expr(hir_vec![s1, s2, s3],
rules: hir::DefaultBlock,
span: span,
});
- self.expr_block(blk, None)
+ self.expr_block(blk, ThinVec::new())
}
_ => self.lower_expr(els),
}
expr,
e.span,
hir::PopUnstableBlock,
- None);
+ ThinVec::new());
this.field(token::intern(s), signal_block, ast_expr.span)
}).collect();
let attrs = ast_expr.attrs.clone();
hir_expr,
ast_expr.span,
hir::PushUnstableBlock,
- None)
+ ThinVec::new())
}
use syntax::ast::RangeLimits::*;
hir::ExprPath(hir_qself, self.lower_path(path))
}
ExprKind::Break(opt_ident) => hir::ExprBreak(self.lower_opt_sp_ident(opt_ident)),
- ExprKind::Again(opt_ident) => hir::ExprAgain(self.lower_opt_sp_ident(opt_ident)),
+ ExprKind::Continue(opt_ident) => hir::ExprAgain(self.lower_opt_sp_ident(opt_ident)),
ExprKind::Ret(ref e) => hir::ExprRet(e.as_ref().map(|x| self.lower_expr(x))),
ExprKind::InlineAsm(InlineAsm {
ref inputs,
ex.span = e.span;
}
// merge attributes into the inner expression.
- ex.attrs.update(|attrs| {
- attrs.prepend(e.attrs.clone())
- });
+ let mut attrs = e.attrs.clone();
+ attrs.extend::<Vec<_>>(ex.attrs.into());
+ ex.attrs = attrs;
ex
});
}
// `<pat> => <body>`
let pat_arm = {
let body = self.lower_block(body);
- let body_expr = self.expr_block(body, None);
+ let body_expr = self.expr_block(body, ThinVec::new());
let pat = self.lower_pat(pat);
self.arm(hir_vec![pat], body_expr)
};
attrs: hir_vec![],
pats: hir_vec![pat_under],
guard: Some(cond),
- body: self.expr_block(then, None),
+ body: self.expr_block(then, ThinVec::new()),
});
else_opt.map(|else_opt| (else_opt, true))
}
let else_arm = {
let pat_under = self.pat_wild(e.span);
let else_expr =
- else_opt.unwrap_or_else(|| self.expr_tuple(e.span, hir_vec![], None));
+ else_opt.unwrap_or_else(|| self.expr_tuple(e.span, hir_vec![]));
self.arm(hir_vec![pat_under], else_expr)
};
// `<pat> => <body>`
let pat_arm = {
let body = self.lower_block(body);
- let body_expr = self.expr_block(body, None);
+ let body_expr = self.expr_block(body, ThinVec::new());
let pat = self.lower_pat(pat);
self.arm(hir_vec![pat], body_expr)
};
// `_ => break`
let break_arm = {
let pat_under = self.pat_wild(e.span);
- let break_expr = self.expr_break(e.span, None);
+ let break_expr = self.expr_break(e.span, ThinVec::new());
self.arm(hir_vec![pat_under], break_expr)
};
hir::ExprMatch(sub_expr,
arms,
hir::MatchSource::WhileLetDesugar),
- None);
+ ThinVec::new());
// `[opt_ident]: loop { ... }`
let loop_block = self.block_expr(match_expr);
id: self.next_id(),
node: hir::ExprBlock(body_block),
span: body_span,
- attrs: None,
+ attrs: ThinVec::new(),
});
let pat = self.lower_pat(pat);
let some_pat = self.pat_some(e.span, pat);
// `::std::option::Option::None => break`
let break_arm = {
- let break_expr = self.expr_break(e.span, None);
+ let break_expr = self.expr_break(e.span, ThinVec::new());
let pat = self.pat_none(e.span);
self.arm(hir_vec![pat], break_expr)
};
self.path_global(e.span, strs)
};
- let iter = self.expr_ident(e.span, iter, None, iter_pat.id);
- let ref_mut_iter = self.expr_mut_addr_of(e.span, iter, None);
- let next_path = self.expr_path(next_path, None);
- let next_expr = self.expr_call(e.span,
- next_path,
- hir_vec![ref_mut_iter],
- None);
+ let iter = self.expr_ident(e.span, iter, iter_pat.id);
+ let ref_mut_iter = self.expr_mut_addr_of(e.span, iter);
+ let next_path = self.expr_path(next_path, ThinVec::new());
+ let next_expr = self.expr_call(e.span, next_path, hir_vec![ref_mut_iter]);
let arms = hir_vec![pat_arm, break_arm];
self.expr(e.span,
hir::ExprMatch(next_expr, arms, hir::MatchSource::ForLoopDesugar),
- None)
+ ThinVec::new())
};
// `[opt_ident]: loop { ... }`
let loop_block = self.block_expr(match_expr);
let loop_expr = hir::ExprLoop(loop_block, self.lower_opt_sp_ident(opt_ident));
- let loop_expr =
- P(hir::Expr { id: e.id, node: loop_expr, span: e.span, attrs: None });
+ let loop_expr = P(hir::Expr {
+ id: e.id,
+ node: loop_expr,
+ span: e.span,
+ attrs: ThinVec::new(),
+ });
// `mut iter => { ... }`
let iter_arm = self.arm(hir_vec![iter_pat], loop_expr);
self.path_global(e.span, strs)
};
- let into_iter = self.expr_path(into_iter_path, None);
- self.expr_call(e.span, into_iter, hir_vec![head], None)
+ let into_iter = self.expr_path(into_iter_path, ThinVec::new());
+ self.expr_call(e.span, into_iter, hir_vec![head])
};
let match_expr = self.expr_match(e.span,
into_iter_expr,
hir_vec![iter_arm],
- hir::MatchSource::ForLoopDesugar,
- None);
+ hir::MatchSource::ForLoopDesugar);
// `{ let _result = ...; _result }`
// underscore prevents an unused_variables lint if the head diverges
let result_ident = self.str_to_ident("_result");
let (let_stmt, let_stmt_binding) =
- self.stmt_let(e.span, false, result_ident, match_expr, None);
+ self.stmt_let(e.span, false, result_ident, match_expr);
- let result = self.expr_ident(e.span, result_ident, None, let_stmt_binding);
+ let result = self.expr_ident(e.span, result_ident, let_stmt_binding);
let block = self.block_all(e.span, hir_vec![let_stmt], Some(result));
// add the attributes to the outer returned expr node
return self.expr_block(block, e.attrs.clone());
let ok_arm = {
let val_ident = self.str_to_ident("val");
let val_pat = self.pat_ident(e.span, val_ident);
- let val_expr = self.expr_ident(e.span, val_ident, None, val_pat.id);
+ let val_expr = self.expr_ident(e.span, val_ident, val_pat.id);
let ok_pat = self.pat_ok(e.span, val_pat);
self.arm(hir_vec![ok_pat], val_expr)
let from_expr = {
let path = self.std_path(&["convert", "From", "from"]);
let path = self.path_global(e.span, path);
- let from = self.expr_path(path, None);
- let err_expr = self.expr_ident(e.span, err_ident, None, err_local.id);
+ let from = self.expr_path(path, ThinVec::new());
+ let err_expr = self.expr_ident(e.span, err_ident, err_local.id);
- self.expr_call(e.span, from, hir_vec![err_expr], None)
+ self.expr_call(e.span, from, hir_vec![err_expr])
};
let err_expr = {
let path = self.std_path(&["result", "Result", "Err"]);
let path = self.path_global(e.span, path);
- let err_ctor = self.expr_path(path, None);
- self.expr_call(e.span, err_ctor, hir_vec![from_expr], None)
+ let err_ctor = self.expr_path(path, ThinVec::new());
+ self.expr_call(e.span, err_ctor, hir_vec![from_expr])
};
let err_pat = self.pat_err(e.span, err_local);
let ret_expr = self.expr(e.span,
- hir::Expr_::ExprRet(Some(err_expr)), None);
-
+ hir::Expr_::ExprRet(Some(err_expr)),
+ ThinVec::new());
self.arm(hir_vec![err_pat], ret_expr)
};
return self.expr_match(e.span, sub_expr, hir_vec![err_arm, ok_arm],
- hir::MatchSource::TryDesugar, None);
+ hir::MatchSource::TryDesugar);
}
ExprKind::Mac(_) => panic!("Shouldn't exist here"),
fn lower_stmt(&mut self, s: &Stmt) -> hir::Stmt {
match s.node {
- StmtKind::Decl(ref d, id) => {
- Spanned {
- node: hir::StmtDecl(self.lower_decl(d), id),
+ StmtKind::Local(ref l) => Spanned {
+ node: hir::StmtDecl(P(Spanned {
+ node: hir::DeclLocal(self.lower_local(l)),
span: s.span,
- }
- }
- StmtKind::Expr(ref e, id) => {
+ }), s.id),
+ span: s.span,
+ },
+ StmtKind::Item(ref it) => Spanned {
+ node: hir::StmtDecl(P(Spanned {
+ node: hir::DeclItem(self.lower_item_id(it)),
+ span: s.span,
+ }), s.id),
+ span: s.span,
+ },
+ StmtKind::Expr(ref e) => {
Spanned {
- node: hir::StmtExpr(self.lower_expr(e), id),
+ node: hir::StmtExpr(self.lower_expr(e), s.id),
span: s.span,
}
}
- StmtKind::Semi(ref e, id) => {
+ StmtKind::Semi(ref e) => {
Spanned {
- node: hir::StmtSemi(self.lower_expr(e), id),
+ node: hir::StmtSemi(self.lower_expr(e), s.id),
span: s.span,
}
}
}
}
- fn expr_break(&mut self, span: Span, attrs: ThinAttributes) -> P<hir::Expr> {
+ fn expr_break(&mut self, span: Span, attrs: ThinVec<Attribute>) -> P<hir::Expr> {
self.expr(span, hir::ExprBreak(None), attrs)
}
- fn expr_call(&mut self,
- span: Span,
- e: P<hir::Expr>,
- args: hir::HirVec<P<hir::Expr>>,
- attrs: ThinAttributes)
+ fn expr_call(&mut self, span: Span, e: P<hir::Expr>, args: hir::HirVec<P<hir::Expr>>)
-> P<hir::Expr> {
- self.expr(span, hir::ExprCall(e, args), attrs)
+ self.expr(span, hir::ExprCall(e, args), ThinVec::new())
}
- fn expr_ident(&mut self, span: Span, id: Name, attrs: ThinAttributes, binding: NodeId)
- -> P<hir::Expr> {
+ fn expr_ident(&mut self, span: Span, id: Name, binding: NodeId) -> P<hir::Expr> {
let expr_path = hir::ExprPath(None, self.path_ident(span, id));
- let expr = self.expr(span, expr_path, attrs);
+ let expr = self.expr(span, expr_path, ThinVec::new());
let def = self.resolver.definitions().map(|defs| {
Def::Local(defs.local_def_id(binding), binding)
expr
}
- fn expr_mut_addr_of(&mut self, span: Span, e: P<hir::Expr>, attrs: ThinAttributes)
- -> P<hir::Expr> {
- self.expr(span, hir::ExprAddrOf(hir::MutMutable, e), attrs)
+ fn expr_mut_addr_of(&mut self, span: Span, e: P<hir::Expr>) -> P<hir::Expr> {
+ self.expr(span, hir::ExprAddrOf(hir::MutMutable, e), ThinVec::new())
}
- fn expr_path(&mut self, path: hir::Path, attrs: ThinAttributes) -> P<hir::Expr> {
+ fn expr_path(&mut self, path: hir::Path, attrs: ThinVec<Attribute>) -> P<hir::Expr> {
let def = self.resolver.resolve_generated_global_path(&path, true);
let expr = self.expr(path.span, hir::ExprPath(None, path), attrs);
self.resolver.record_resolution(expr.id, def);
span: Span,
arg: P<hir::Expr>,
arms: hir::HirVec<hir::Arm>,
- source: hir::MatchSource,
- attrs: ThinAttributes)
+ source: hir::MatchSource)
-> P<hir::Expr> {
- self.expr(span, hir::ExprMatch(arg, arms, source), attrs)
+ self.expr(span, hir::ExprMatch(arg, arms, source), ThinVec::new())
}
- fn expr_block(&mut self, b: P<hir::Block>, attrs: ThinAttributes) -> P<hir::Expr> {
+ fn expr_block(&mut self, b: P<hir::Block>, attrs: ThinVec<Attribute>) -> P<hir::Expr> {
self.expr(b.span, hir::ExprBlock(b), attrs)
}
- fn expr_tuple(&mut self, sp: Span, exprs: hir::HirVec<P<hir::Expr>>, attrs: ThinAttributes)
- -> P<hir::Expr> {
- self.expr(sp, hir::ExprTup(exprs), attrs)
+ fn expr_tuple(&mut self, sp: Span, exprs: hir::HirVec<P<hir::Expr>>) -> P<hir::Expr> {
+ self.expr(sp, hir::ExprTup(exprs), ThinVec::new())
}
fn expr_struct(&mut self,
path: hir::Path,
fields: hir::HirVec<hir::Field>,
e: Option<P<hir::Expr>>,
- attrs: ThinAttributes) -> P<hir::Expr> {
+ attrs: ThinVec<Attribute>) -> P<hir::Expr> {
let def = self.resolver.resolve_generated_global_path(&path, false);
let expr = self.expr(sp, hir::ExprStruct(path, fields, e), attrs);
self.resolver.record_resolution(expr.id, def);
expr
}
- fn expr(&mut self, span: Span, node: hir::Expr_, attrs: ThinAttributes) -> P<hir::Expr> {
+ fn expr(&mut self, span: Span, node: hir::Expr_, attrs: ThinVec<Attribute>) -> P<hir::Expr> {
P(hir::Expr {
id: self.next_id(),
node: node,
})
}
- fn stmt_let(&mut self,
- sp: Span,
- mutbl: bool,
- ident: Name,
- ex: P<hir::Expr>,
- attrs: ThinAttributes)
+ fn stmt_let(&mut self, sp: Span, mutbl: bool, ident: Name, ex: P<hir::Expr>)
-> (hir::Stmt, NodeId) {
let pat = if mutbl {
self.pat_ident_binding_mode(sp, ident, hir::BindByValue(hir::MutMutable))
init: Some(ex),
id: self.next_id(),
span: sp,
- attrs: attrs,
+ attrs: ThinVec::new(),
});
let decl = respan(sp, hir::DeclLocal(local));
(respan(sp, hir::StmtDecl(P(decl), self.next_id())), pat_id)
expr: P<hir::Expr>,
span: Span,
rule: hir::BlockCheckMode,
- attrs: ThinAttributes)
+ attrs: ThinVec<Attribute>)
-> P<hir::Expr> {
let id = self.next_id();
let block = P(hir::Block {