Merging my book edits recent commits.
This commit is contained in:
commit
763cec21f0
305 changed files with 4841 additions and 3650 deletions
44
mk/crates.mk
44
mk/crates.mk
|
|
@ -57,10 +57,10 @@ TARGET_CRATES := libc std term \
|
|||
panic_abort panic_unwind unwind
|
||||
RUSTC_CRATES := rustc rustc_typeck rustc_mir rustc_borrowck rustc_resolve rustc_driver \
|
||||
rustc_trans rustc_back rustc_llvm rustc_privacy rustc_lint \
|
||||
rustc_data_structures rustc_platform_intrinsics \
|
||||
rustc_data_structures rustc_platform_intrinsics rustc_errors \
|
||||
rustc_plugin rustc_metadata rustc_passes rustc_save_analysis \
|
||||
rustc_const_eval rustc_const_math rustc_incremental
|
||||
HOST_CRATES := syntax syntax_ext $(RUSTC_CRATES) rustdoc fmt_macros \
|
||||
HOST_CRATES := syntax syntax_ext syntax_pos $(RUSTC_CRATES) rustdoc fmt_macros \
|
||||
flate arena graphviz rbml log serialize
|
||||
TOOLS := compiletest rustdoc rustc rustbook error_index_generator
|
||||
|
||||
|
|
@ -98,43 +98,45 @@ DEPS_serialize := std log
|
|||
DEPS_term := std
|
||||
DEPS_test := std getopts term native:rust_test_helpers
|
||||
|
||||
DEPS_syntax := std term serialize log arena libc rustc_bitflags rustc_unicode
|
||||
DEPS_syntax_ext := syntax fmt_macros
|
||||
DEPS_syntax := std term serialize log arena libc rustc_bitflags rustc_unicode rustc_errors syntax_pos
|
||||
DEPS_syntax_ext := syntax syntax_pos rustc_errors fmt_macros
|
||||
DEPS_syntax_pos := serialize
|
||||
|
||||
DEPS_rustc_const_math := std syntax log serialize
|
||||
DEPS_rustc_const_eval := rustc_const_math rustc syntax log serialize \
|
||||
rustc_back graphviz
|
||||
rustc_back graphviz syntax_pos
|
||||
|
||||
DEPS_rustc := syntax fmt_macros flate arena serialize getopts rbml \
|
||||
log graphviz rustc_llvm rustc_back rustc_data_structures\
|
||||
rustc_const_math
|
||||
rustc_const_math syntax_pos rustc_errors
|
||||
DEPS_rustc_back := std syntax flate log libc
|
||||
DEPS_rustc_borrowck := rustc log graphviz syntax rustc_mir
|
||||
DEPS_rustc_borrowck := rustc log graphviz syntax syntax_pos rustc_errors rustc_mir
|
||||
DEPS_rustc_data_structures := std log serialize
|
||||
DEPS_rustc_driver := arena flate getopts graphviz libc rustc rustc_back rustc_borrowck \
|
||||
rustc_typeck rustc_mir rustc_resolve log syntax serialize rustc_llvm \
|
||||
rustc_trans rustc_privacy rustc_lint rustc_plugin \
|
||||
rustc_metadata syntax_ext rustc_passes rustc_save_analysis rustc_const_eval \
|
||||
rustc_incremental
|
||||
DEPS_rustc_lint := rustc log syntax rustc_const_eval
|
||||
rustc_incremental syntax_pos rustc_errors
|
||||
DEPS_rustc_errors := log libc serialize syntax_pos
|
||||
DEPS_rustc_lint := rustc log syntax syntax_pos rustc_const_eval
|
||||
DEPS_rustc_llvm := native:rustllvm libc std rustc_bitflags
|
||||
DEPS_rustc_metadata := rustc syntax rbml rustc_const_math
|
||||
DEPS_rustc_passes := syntax rustc core rustc_const_eval
|
||||
DEPS_rustc_mir := rustc syntax rustc_const_math rustc_const_eval rustc_bitflags
|
||||
DEPS_rustc_resolve := arena rustc log syntax
|
||||
DEPS_rustc_metadata := rustc syntax syntax_pos rustc_errors rbml rustc_const_math
|
||||
DEPS_rustc_passes := syntax syntax_pos rustc core rustc_const_eval rustc_errors
|
||||
DEPS_rustc_mir := rustc syntax syntax_pos rustc_const_math rustc_const_eval rustc_bitflags
|
||||
DEPS_rustc_resolve := arena rustc log syntax syntax_pos rustc_errors
|
||||
DEPS_rustc_platform_intrinsics := std
|
||||
DEPS_rustc_plugin := rustc rustc_metadata syntax
|
||||
DEPS_rustc_privacy := rustc log syntax
|
||||
DEPS_rustc_plugin := rustc rustc_metadata syntax syntax_pos rustc_errors
|
||||
DEPS_rustc_privacy := rustc log syntax syntax_pos
|
||||
DEPS_rustc_trans := arena flate getopts graphviz libc rustc rustc_back \
|
||||
log syntax serialize rustc_llvm rustc_platform_intrinsics \
|
||||
rustc_const_math rustc_const_eval rustc_incremental
|
||||
DEPS_rustc_incremental := rbml rustc serialize rustc_data_structures
|
||||
DEPS_rustc_save_analysis := rustc log syntax serialize
|
||||
DEPS_rustc_typeck := rustc syntax rustc_platform_intrinsics rustc_const_math \
|
||||
rustc_const_eval
|
||||
rustc_const_math rustc_const_eval rustc_incremental rustc_errors syntax_pos
|
||||
DEPS_rustc_incremental := rbml rustc syntax_pos serialize rustc_data_structures
|
||||
DEPS_rustc_save_analysis := rustc log syntax syntax_pos serialize
|
||||
DEPS_rustc_typeck := rustc syntax syntax_pos rustc_platform_intrinsics rustc_const_math \
|
||||
rustc_const_eval rustc_errors
|
||||
|
||||
DEPS_rustdoc := rustc rustc_driver native:hoedown serialize getopts \
|
||||
test rustc_lint rustc_const_eval
|
||||
test rustc_lint rustc_const_eval syntax_pos
|
||||
|
||||
|
||||
TOOL_DEPS_compiletest := test getopts log serialize
|
||||
|
|
|
|||
|
|
@ -45,11 +45,11 @@ extern crate syntax;
|
|||
extern crate rustc;
|
||||
extern crate rustc_plugin;
|
||||
|
||||
use syntax::codemap::Span;
|
||||
use syntax::parse::token;
|
||||
use syntax::ast::TokenTree;
|
||||
use syntax::ext::base::{ExtCtxt, MacResult, DummyResult, MacEager};
|
||||
use syntax::ext::build::AstBuilder; // trait for expr_usize
|
||||
use syntax_pos::Span;
|
||||
use rustc_plugin::Registry;
|
||||
|
||||
fn expand_rn(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree])
|
||||
|
|
|
|||
|
|
@ -32,9 +32,9 @@ use std::rc::Rc;
|
|||
use syntax::ast;
|
||||
use syntax::ast::Name;
|
||||
use syntax::codemap;
|
||||
use syntax::codemap::Pos;
|
||||
use syntax::parse::token::{self, BinOpToken, DelimToken, Lit, Token};
|
||||
use syntax::parse::lexer::TokenAndSpan;
|
||||
use syntax_pos::Pos;
|
||||
|
||||
fn parse_token_list(file: &str) -> HashMap<String, token::Token> {
|
||||
fn id() -> token::Token {
|
||||
|
|
@ -233,10 +233,10 @@ fn parse_antlr_token(s: &str, tokens: &HashMap<String, token::Token>, surrogate_
|
|||
lo -= surrogate_pairs_pos.binary_search(&(lo as usize)).unwrap_or_else(|x| x) as u32;
|
||||
hi -= surrogate_pairs_pos.binary_search(&(hi as usize)).unwrap_or_else(|x| x) as u32;
|
||||
|
||||
let sp = codemap::Span {
|
||||
lo: codemap::BytePos(lo),
|
||||
hi: codemap::BytePos(hi),
|
||||
expn_id: codemap::NO_EXPANSION
|
||||
let sp = syntax_pos::Span {
|
||||
lo: syntax_pos::BytePos(lo),
|
||||
hi: syntax_pos::BytePos(hi),
|
||||
expn_id: syntax_pos::NO_EXPANSION
|
||||
};
|
||||
|
||||
TokenAndSpan {
|
||||
|
|
|
|||
|
|
@ -19,6 +19,8 @@ rustc_back = { path = "../librustc_back" }
|
|||
rustc_bitflags = { path = "../librustc_bitflags" }
|
||||
rustc_const_math = { path = "../librustc_const_math" }
|
||||
rustc_data_structures = { path = "../librustc_data_structures" }
|
||||
rustc_errors = { path = "../librustc_errors" }
|
||||
rustc_llvm = { path = "../librustc_llvm" }
|
||||
serialize = { path = "../libserialize" }
|
||||
syntax = { path = "../libsyntax" }
|
||||
syntax_pos = { path = "../libsyntax_pos" }
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ impl<'a> CheckAttrVisitor<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, 'v> Visitor<'v> for CheckAttrVisitor<'a> {
|
||||
impl<'a> Visitor for CheckAttrVisitor<'a> {
|
||||
fn visit_item(&mut self, item: &ast::Item) {
|
||||
let target = Target::from_item(item);
|
||||
for attr in &item.attrs {
|
||||
|
|
|
|||
|
|
@ -14,9 +14,9 @@
|
|||
use hir::*;
|
||||
use syntax::ast::{Name, NodeId, DUMMY_NODE_ID, Attribute, Attribute_, MetaItem};
|
||||
use syntax::ast::MetaItemKind;
|
||||
use syntax::attr::ThinAttributesExt;
|
||||
use hir;
|
||||
use syntax::codemap::{respan, Span, Spanned};
|
||||
use syntax_pos::Span;
|
||||
use syntax::codemap::{respan, Spanned};
|
||||
use syntax::ptr::P;
|
||||
use syntax::parse::token::keywords;
|
||||
use syntax::util::move_map::MoveMap;
|
||||
|
|
@ -292,8 +292,11 @@ pub fn noop_fold_view_path<T: Folder>(view_path: P<ViewPath>, fld: &mut T) -> P<
|
|||
})
|
||||
}
|
||||
|
||||
pub fn fold_attrs<T: Folder>(attrs: HirVec<Attribute>, fld: &mut T) -> HirVec<Attribute> {
|
||||
attrs.move_flat_map(|x| fld.fold_attribute(x))
|
||||
pub fn fold_attrs<T, F>(attrs: T, fld: &mut F) -> T
|
||||
where T: Into<Vec<Attribute>> + From<Vec<Attribute>>,
|
||||
F: Folder,
|
||||
{
|
||||
attrs.into().move_flat_map(|x| fld.fold_attribute(x)).into()
|
||||
}
|
||||
|
||||
pub fn noop_fold_arm<T: Folder>(Arm { attrs, pats, guard, body }: Arm, fld: &mut T) -> Arm {
|
||||
|
|
@ -461,7 +464,7 @@ pub fn noop_fold_local<T: Folder>(l: P<Local>, fld: &mut T) -> P<Local> {
|
|||
pat: fld.fold_pat(pat),
|
||||
init: init.map(|e| fld.fold_expr(e)),
|
||||
span: fld.new_span(span),
|
||||
attrs: attrs.map_thin_attrs(|attrs| fold_attrs(attrs.into(), fld).into()),
|
||||
attrs: fold_attrs(attrs, fld),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
@ -1078,7 +1081,7 @@ pub fn noop_fold_expr<T: Folder>(Expr { id, node, span, attrs }: Expr, folder: &
|
|||
}
|
||||
},
|
||||
span: folder.new_span(span),
|
||||
attrs: attrs.map_thin_attrs(|attrs| fold_attrs(attrs.into(), folder).into()),
|
||||
attrs: fold_attrs(attrs, folder),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,8 +27,8 @@
|
|||
|
||||
use syntax::abi::Abi;
|
||||
use syntax::ast::{NodeId, CRATE_NODE_ID, Name, Attribute};
|
||||
use syntax::attr::ThinAttributesExt;
|
||||
use syntax::codemap::{Span, Spanned};
|
||||
use syntax::codemap::Spanned;
|
||||
use syntax_pos::Span;
|
||||
use hir::*;
|
||||
|
||||
use std::cmp;
|
||||
|
|
@ -756,7 +756,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
|
|||
walk_list!(visitor, visit_arm, arms);
|
||||
}
|
||||
ExprClosure(_, ref function_declaration, ref body, _fn_decl_span) => {
|
||||
visitor.visit_fn(FnKind::Closure(expression.attrs.as_attr_slice()),
|
||||
visitor.visit_fn(FnKind::Closure(&expression.attrs),
|
||||
function_declaration,
|
||||
body,
|
||||
expression.span,
|
||||
|
|
|
|||
|
|
@ -50,12 +50,12 @@ use session::Session;
|
|||
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>,
|
||||
|
|
@ -137,8 +137,8 @@ impl<'a> LoweringContext<'a> {
|
|||
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);
|
||||
}
|
||||
|
|
@ -237,19 +237,6 @@ impl<'a> LoweringContext<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
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,
|
||||
|
|
@ -587,10 +574,23 @@ impl<'a> LoweringContext<'a> {
|
|||
}
|
||||
|
||||
fn lower_block(&mut self, b: &Block) -> P<hir::Block> {
|
||||
let mut stmts = Vec::new();
|
||||
let mut expr = None;
|
||||
|
||||
if let Some((last, rest)) = b.stmts.split_last() {
|
||||
stmts = rest.iter().map(|s| self.lower_stmt(s)).collect::<Vec<_>>();
|
||||
let last = self.lower_stmt(last);
|
||||
if let hir::StmtExpr(e, _) = last.node {
|
||||
expr = Some(e);
|
||||
} else {
|
||||
stmts.push(last);
|
||||
}
|
||||
}
|
||||
|
||||
P(hir::Block {
|
||||
id: b.id,
|
||||
stmts: b.stmts.iter().map(|s| self.lower_stmt(s)).collect(),
|
||||
expr: b.expr.as_ref().map(|ref x| self.lower_expr(x)),
|
||||
stmts: stmts.into(),
|
||||
expr: expr,
|
||||
rules: self.lower_block_check_mode(&b.rules),
|
||||
span: b.span,
|
||||
})
|
||||
|
|
@ -683,6 +683,7 @@ impl<'a> LoweringContext<'a> {
|
|||
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,
|
||||
}
|
||||
|
|
@ -866,10 +867,10 @@ impl<'a> LoweringContext<'a> {
|
|||
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,
|
||||
|
|
@ -962,16 +963,16 @@ impl<'a> LoweringContext<'a> {
|
|||
|
||||
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> ;
|
||||
|
|
@ -980,21 +981,21 @@ impl<'a> LoweringContext<'a> {
|
|||
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)
|
||||
};
|
||||
|
|
@ -1005,11 +1006,12 @@ impl<'a> LoweringContext<'a> {
|
|||
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!({
|
||||
|
|
@ -1017,19 +1019,20 @@ impl<'a> LoweringContext<'a> {
|
|||
// 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],
|
||||
|
|
@ -1101,7 +1104,7 @@ impl<'a> LoweringContext<'a> {
|
|||
rules: hir::DefaultBlock,
|
||||
span: span,
|
||||
});
|
||||
self.expr_block(blk, None)
|
||||
self.expr_block(blk, ThinVec::new())
|
||||
}
|
||||
_ => self.lower_expr(els),
|
||||
}
|
||||
|
|
@ -1168,7 +1171,7 @@ impl<'a> LoweringContext<'a> {
|
|||
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();
|
||||
|
|
@ -1180,7 +1183,7 @@ impl<'a> LoweringContext<'a> {
|
|||
hir_expr,
|
||||
ast_expr.span,
|
||||
hir::PushUnstableBlock,
|
||||
None)
|
||||
ThinVec::new())
|
||||
}
|
||||
|
||||
use syntax::ast::RangeLimits::*;
|
||||
|
|
@ -1223,7 +1226,7 @@ impl<'a> LoweringContext<'a> {
|
|||
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,
|
||||
|
|
@ -1267,9 +1270,9 @@ impl<'a> LoweringContext<'a> {
|
|||
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
|
||||
});
|
||||
}
|
||||
|
|
@ -1288,7 +1291,7 @@ impl<'a> LoweringContext<'a> {
|
|||
// `<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)
|
||||
};
|
||||
|
|
@ -1308,7 +1311,7 @@ impl<'a> LoweringContext<'a> {
|
|||
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))
|
||||
}
|
||||
|
|
@ -1339,7 +1342,7 @@ impl<'a> LoweringContext<'a> {
|
|||
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)
|
||||
};
|
||||
|
||||
|
|
@ -1374,7 +1377,7 @@ impl<'a> LoweringContext<'a> {
|
|||
// `<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)
|
||||
};
|
||||
|
|
@ -1382,7 +1385,7 @@ impl<'a> LoweringContext<'a> {
|
|||
// `_ => 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)
|
||||
};
|
||||
|
||||
|
|
@ -1393,7 +1396,7 @@ impl<'a> LoweringContext<'a> {
|
|||
hir::ExprMatch(sub_expr,
|
||||
arms,
|
||||
hir::MatchSource::WhileLetDesugar),
|
||||
None);
|
||||
ThinVec::new());
|
||||
|
||||
// `[opt_ident]: loop { ... }`
|
||||
let loop_block = self.block_expr(match_expr);
|
||||
|
|
@ -1435,7 +1438,7 @@ impl<'a> LoweringContext<'a> {
|
|||
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);
|
||||
|
|
@ -1445,7 +1448,7 @@ impl<'a> LoweringContext<'a> {
|
|||
|
||||
// `::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)
|
||||
};
|
||||
|
|
@ -1461,25 +1464,26 @@ impl<'a> LoweringContext<'a> {
|
|||
|
||||
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);
|
||||
|
|
@ -1492,23 +1496,22 @@ impl<'a> LoweringContext<'a> {
|
|||
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());
|
||||
|
|
@ -1535,7 +1538,7 @@ impl<'a> LoweringContext<'a> {
|
|||
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)
|
||||
|
|
@ -1548,26 +1551,26 @@ impl<'a> LoweringContext<'a> {
|
|||
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"),
|
||||
|
|
@ -1579,21 +1582,29 @@ impl<'a> LoweringContext<'a> {
|
|||
|
||||
fn lower_stmt(&mut self, s: &Stmt) -> hir::Stmt {
|
||||
match s.node {
|
||||
StmtKind::Decl(ref d, id) => {
|
||||
StmtKind::Local(ref l) => Spanned {
|
||||
node: hir::StmtDecl(P(Spanned {
|
||||
node: hir::DeclLocal(self.lower_local(l)),
|
||||
span: s.span,
|
||||
}), 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::StmtDecl(self.lower_decl(d), id),
|
||||
node: hir::StmtExpr(self.lower_expr(e), s.id),
|
||||
span: s.span,
|
||||
}
|
||||
}
|
||||
StmtKind::Expr(ref e, id) => {
|
||||
StmtKind::Semi(ref e) => {
|
||||
Spanned {
|
||||
node: hir::StmtExpr(self.lower_expr(e), id),
|
||||
span: s.span,
|
||||
}
|
||||
}
|
||||
StmtKind::Semi(ref e, id) => {
|
||||
Spanned {
|
||||
node: hir::StmtSemi(self.lower_expr(e), id),
|
||||
node: hir::StmtSemi(self.lower_expr(e), s.id),
|
||||
span: s.span,
|
||||
}
|
||||
}
|
||||
|
|
@ -1682,23 +1693,18 @@ impl<'a> LoweringContext<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
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)
|
||||
|
|
@ -1708,12 +1714,11 @@ impl<'a> LoweringContext<'a> {
|
|||
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);
|
||||
|
|
@ -1724,19 +1729,17 @@ impl<'a> LoweringContext<'a> {
|
|||
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,
|
||||
|
|
@ -1744,14 +1747,14 @@ impl<'a> LoweringContext<'a> {
|
|||
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,
|
||||
|
|
@ -1760,12 +1763,7 @@ impl<'a> LoweringContext<'a> {
|
|||
})
|
||||
}
|
||||
|
||||
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))
|
||||
|
|
@ -1779,7 +1777,7 @@ impl<'a> LoweringContext<'a> {
|
|||
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)
|
||||
|
|
@ -1939,7 +1937,7 @@ impl<'a> LoweringContext<'a> {
|
|||
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 {
|
||||
|
|
|
|||
|
|
@ -27,9 +27,8 @@ use hir::map::{self, Node};
|
|||
use syntax::abi;
|
||||
use hir::{Block, FnDecl};
|
||||
use syntax::ast::{Attribute, Name, NodeId};
|
||||
use syntax::attr::ThinAttributesExt;
|
||||
use hir as ast;
|
||||
use syntax::codemap::Span;
|
||||
use syntax_pos::Span;
|
||||
use hir::intravisit::FnKind;
|
||||
|
||||
/// An FnLikeNode is a Node that is like a fn, in that it has a decl
|
||||
|
|
@ -257,11 +256,7 @@ impl<'a> FnLikeNode<'a> {
|
|||
}
|
||||
map::NodeExpr(e) => match e.node {
|
||||
ast::ExprClosure(_, ref decl, ref block, _fn_decl_span) =>
|
||||
closure(ClosureParts::new(&decl,
|
||||
&block,
|
||||
e.id,
|
||||
e.span,
|
||||
e.attrs.as_attr_slice())),
|
||||
closure(ClosureParts::new(&decl, &block, e.id, e.span, &e.attrs)),
|
||||
_ => bug!("expr FnLikeNode that is not fn-like"),
|
||||
},
|
||||
_ => bug!("other FnLikeNode that is not fn-like"),
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ use hir::def_id::DefId;
|
|||
use middle::cstore::InlinedItem;
|
||||
use std::iter::repeat;
|
||||
use syntax::ast::{NodeId, CRATE_NODE_ID};
|
||||
use syntax::codemap::Span;
|
||||
use syntax_pos::Span;
|
||||
|
||||
/// A Visitor that walks over the HIR and collects Nodes into a HIR map
|
||||
pub struct NodeCollector<'ast> {
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ impl<'ast> DefCollector<'ast> {
|
|||
self.parent_def = parent;
|
||||
}
|
||||
|
||||
fn visit_ast_const_integer(&mut self, expr: &'ast Expr) {
|
||||
fn visit_ast_const_integer(&mut self, expr: &Expr) {
|
||||
// Find the node which will be used after lowering.
|
||||
if let ExprKind::Paren(ref inner) = expr.node {
|
||||
return self.visit_ast_const_integer(inner);
|
||||
|
|
@ -124,8 +124,8 @@ impl<'ast> DefCollector<'ast> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'ast> visit::Visitor<'ast> for DefCollector<'ast> {
|
||||
fn visit_item(&mut self, i: &'ast Item) {
|
||||
impl<'ast> visit::Visitor for DefCollector<'ast> {
|
||||
fn visit_item(&mut self, i: &Item) {
|
||||
debug!("visit_item: {:?}", i);
|
||||
|
||||
// Pick the def data. This need not be unique, but the more
|
||||
|
|
@ -183,7 +183,7 @@ impl<'ast> visit::Visitor<'ast> for DefCollector<'ast> {
|
|||
});
|
||||
}
|
||||
|
||||
fn visit_foreign_item(&mut self, foreign_item: &'ast ForeignItem) {
|
||||
fn visit_foreign_item(&mut self, foreign_item: &ForeignItem) {
|
||||
let def = self.create_def(foreign_item.id, DefPathData::ValueNs(foreign_item.ident.name));
|
||||
|
||||
self.with_parent(def, |this| {
|
||||
|
|
@ -191,7 +191,7 @@ impl<'ast> visit::Visitor<'ast> for DefCollector<'ast> {
|
|||
});
|
||||
}
|
||||
|
||||
fn visit_generics(&mut self, generics: &'ast Generics) {
|
||||
fn visit_generics(&mut self, generics: &Generics) {
|
||||
for ty_param in generics.ty_params.iter() {
|
||||
self.create_def(ty_param.id, DefPathData::TypeParam(ty_param.ident.name));
|
||||
}
|
||||
|
|
@ -199,11 +199,12 @@ impl<'ast> visit::Visitor<'ast> for DefCollector<'ast> {
|
|||
visit::walk_generics(self, generics);
|
||||
}
|
||||
|
||||
fn visit_trait_item(&mut self, ti: &'ast TraitItem) {
|
||||
fn visit_trait_item(&mut self, ti: &TraitItem) {
|
||||
let def_data = match ti.node {
|
||||
TraitItemKind::Method(..) | TraitItemKind::Const(..) =>
|
||||
DefPathData::ValueNs(ti.ident.name),
|
||||
TraitItemKind::Type(..) => DefPathData::TypeNs(ti.ident.name),
|
||||
TraitItemKind::Macro(..) => DefPathData::MacroDef(ti.ident.name),
|
||||
};
|
||||
|
||||
let def = self.create_def(ti.id, def_data);
|
||||
|
|
@ -216,7 +217,7 @@ impl<'ast> visit::Visitor<'ast> for DefCollector<'ast> {
|
|||
});
|
||||
}
|
||||
|
||||
fn visit_impl_item(&mut self, ii: &'ast ImplItem) {
|
||||
fn visit_impl_item(&mut self, ii: &ImplItem) {
|
||||
let def_data = match ii.node {
|
||||
ImplItemKind::Method(..) | ImplItemKind::Const(..) =>
|
||||
DefPathData::ValueNs(ii.ident.name),
|
||||
|
|
@ -234,7 +235,7 @@ impl<'ast> visit::Visitor<'ast> for DefCollector<'ast> {
|
|||
});
|
||||
}
|
||||
|
||||
fn visit_pat(&mut self, pat: &'ast Pat) {
|
||||
fn visit_pat(&mut self, pat: &Pat) {
|
||||
let parent_def = self.parent_def;
|
||||
|
||||
if let PatKind::Ident(_, id, _) = pat.node {
|
||||
|
|
@ -246,7 +247,7 @@ impl<'ast> visit::Visitor<'ast> for DefCollector<'ast> {
|
|||
self.parent_def = parent_def;
|
||||
}
|
||||
|
||||
fn visit_expr(&mut self, expr: &'ast Expr) {
|
||||
fn visit_expr(&mut self, expr: &Expr) {
|
||||
let parent_def = self.parent_def;
|
||||
|
||||
if let ExprKind::Repeat(_, ref count) = expr.node {
|
||||
|
|
@ -262,18 +263,18 @@ impl<'ast> visit::Visitor<'ast> for DefCollector<'ast> {
|
|||
self.parent_def = parent_def;
|
||||
}
|
||||
|
||||
fn visit_ty(&mut self, ty: &'ast Ty) {
|
||||
fn visit_ty(&mut self, ty: &Ty) {
|
||||
if let TyKind::FixedLengthVec(_, ref length) = ty.node {
|
||||
self.visit_ast_const_integer(length);
|
||||
}
|
||||
visit::walk_ty(self, ty);
|
||||
}
|
||||
|
||||
fn visit_lifetime_def(&mut self, def: &'ast LifetimeDef) {
|
||||
fn visit_lifetime_def(&mut self, def: &LifetimeDef) {
|
||||
self.create_def(def.lifetime.id, DefPathData::LifetimeDef(def.lifetime.name));
|
||||
}
|
||||
|
||||
fn visit_macro_def(&mut self, macro_def: &'ast MacroDef) {
|
||||
fn visit_macro_def(&mut self, macro_def: &MacroDef) {
|
||||
self.create_def(macro_def.id, DefPathData::MacroDef(macro_def.ident.name));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,9 +23,9 @@ use hir::def_id::{CRATE_DEF_INDEX, DefId, DefIndex};
|
|||
|
||||
use syntax::abi::Abi;
|
||||
use syntax::ast::{self, Name, NodeId, DUMMY_NODE_ID, };
|
||||
use syntax::attr::ThinAttributesExt;
|
||||
use syntax::codemap::{Span, Spanned};
|
||||
use syntax::codemap::Spanned;
|
||||
use syntax::visit;
|
||||
use syntax_pos::Span;
|
||||
|
||||
use hir::*;
|
||||
use hir::fold::Folder;
|
||||
|
|
@ -577,7 +577,7 @@ impl<'ast> Map<'ast> {
|
|||
Some(NodeTraitItem(ref ti)) => Some(&ti.attrs[..]),
|
||||
Some(NodeImplItem(ref ii)) => Some(&ii.attrs[..]),
|
||||
Some(NodeVariant(ref v)) => Some(&v.node.attrs[..]),
|
||||
Some(NodeExpr(ref e)) => Some(e.attrs.as_attr_slice()),
|
||||
Some(NodeExpr(ref e)) => Some(&*e.attrs),
|
||||
Some(NodeStmt(ref s)) => Some(s.node.attrs()),
|
||||
// unit/tuple structs take the attributes straight from
|
||||
// the struct definition.
|
||||
|
|
|
|||
|
|
@ -36,13 +36,15 @@ use hir::def::Def;
|
|||
use hir::def_id::DefId;
|
||||
use util::nodemap::{NodeMap, FnvHashSet};
|
||||
|
||||
use syntax::codemap::{self, mk_sp, respan, Span, Spanned, ExpnId};
|
||||
use syntax_pos::{mk_sp, Span, ExpnId};
|
||||
use syntax::codemap::{self, respan, Spanned};
|
||||
use syntax::abi::Abi;
|
||||
use syntax::ast::{Name, NodeId, DUMMY_NODE_ID, TokenTree, AsmDialect};
|
||||
use syntax::ast::{Name, NodeId, DUMMY_NODE_ID, AsmDialect};
|
||||
use syntax::ast::{Attribute, Lit, StrStyle, FloatTy, IntTy, UintTy, MetaItem};
|
||||
use syntax::attr::{ThinAttributes, ThinAttributesExt};
|
||||
use syntax::parse::token::{keywords, InternedString};
|
||||
use syntax::ptr::P;
|
||||
use syntax::tokenstream::TokenTree;
|
||||
use syntax::util::ThinVec;
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
use std::fmt;
|
||||
|
|
@ -732,7 +734,7 @@ impl Stmt_ {
|
|||
match *self {
|
||||
StmtDecl(ref d, _) => d.node.attrs(),
|
||||
StmtExpr(ref e, _) |
|
||||
StmtSemi(ref e, _) => e.attrs.as_attr_slice(),
|
||||
StmtSemi(ref e, _) => &e.attrs,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -756,7 +758,7 @@ pub struct Local {
|
|||
pub init: Option<P<Expr>>,
|
||||
pub id: NodeId,
|
||||
pub span: Span,
|
||||
pub attrs: ThinAttributes,
|
||||
pub attrs: ThinVec<Attribute>,
|
||||
}
|
||||
|
||||
pub type Decl = Spanned<Decl_>;
|
||||
|
|
@ -772,7 +774,7 @@ pub enum Decl_ {
|
|||
impl Decl_ {
|
||||
pub fn attrs(&self) -> &[Attribute] {
|
||||
match *self {
|
||||
DeclLocal(ref l) => l.attrs.as_attr_slice(),
|
||||
DeclLocal(ref l) => &l.attrs,
|
||||
DeclItem(_) => &[]
|
||||
}
|
||||
}
|
||||
|
|
@ -817,7 +819,7 @@ pub struct Expr {
|
|||
pub id: NodeId,
|
||||
pub node: Expr_,
|
||||
pub span: Span,
|
||||
pub attrs: ThinAttributes,
|
||||
pub attrs: ThinVec<Attribute>,
|
||||
}
|
||||
|
||||
impl fmt::Debug for Expr {
|
||||
|
|
|
|||
|
|
@ -14,7 +14,8 @@ use hir::{self, PatKind};
|
|||
use ty::TyCtxt;
|
||||
use util::nodemap::FnvHashMap;
|
||||
use syntax::ast;
|
||||
use syntax::codemap::{Span, Spanned, DUMMY_SP};
|
||||
use syntax::codemap::Spanned;
|
||||
use syntax_pos::{Span, DUMMY_SP};
|
||||
|
||||
use std::iter::{Enumerate, ExactSizeIterator};
|
||||
|
||||
|
|
|
|||
|
|
@ -12,8 +12,7 @@ pub use self::AnnNode::*;
|
|||
|
||||
use syntax::abi::Abi;
|
||||
use syntax::ast;
|
||||
use syntax::codemap::{self, CodeMap, BytePos, Spanned};
|
||||
use syntax::errors;
|
||||
use syntax::codemap::{CodeMap, Spanned};
|
||||
use syntax::parse::token::{self, keywords, BinOpToken};
|
||||
use syntax::parse::lexer::comments;
|
||||
use syntax::print::pp::{self, break_offset, word, space, hardbreak};
|
||||
|
|
@ -21,6 +20,8 @@ use syntax::print::pp::{Breaks, eof};
|
|||
use syntax::print::pp::Breaks::{Consistent, Inconsistent};
|
||||
use syntax::print::pprust::{self as ast_pp, PrintState};
|
||||
use syntax::ptr::P;
|
||||
use syntax_pos::{self, BytePos};
|
||||
use errors;
|
||||
|
||||
use hir;
|
||||
use hir::{Crate, PatKind, RegionTyParamBound, SelfKind, TraitTyParamBound, TraitBoundModifier};
|
||||
|
|
@ -368,11 +369,11 @@ impl<'a> State<'a> {
|
|||
self.end() // close the head-box
|
||||
}
|
||||
|
||||
pub fn bclose_(&mut self, span: codemap::Span, indented: usize) -> io::Result<()> {
|
||||
pub fn bclose_(&mut self, span: syntax_pos::Span, indented: usize) -> io::Result<()> {
|
||||
self.bclose_maybe_open(span, indented, true)
|
||||
}
|
||||
pub fn bclose_maybe_open(&mut self,
|
||||
span: codemap::Span,
|
||||
span: syntax_pos::Span,
|
||||
indented: usize,
|
||||
close_box: bool)
|
||||
-> io::Result<()> {
|
||||
|
|
@ -384,7 +385,7 @@ impl<'a> State<'a> {
|
|||
}
|
||||
Ok(())
|
||||
}
|
||||
pub fn bclose(&mut self, span: codemap::Span) -> io::Result<()> {
|
||||
pub fn bclose(&mut self, span: syntax_pos::Span) -> io::Result<()> {
|
||||
self.bclose_(span, indent_unit)
|
||||
}
|
||||
|
||||
|
|
@ -432,7 +433,7 @@ impl<'a> State<'a> {
|
|||
mut get_span: G)
|
||||
-> io::Result<()>
|
||||
where F: FnMut(&mut State, &T) -> io::Result<()>,
|
||||
G: FnMut(&T) -> codemap::Span
|
||||
G: FnMut(&T) -> syntax_pos::Span
|
||||
{
|
||||
self.rbox(0, b)?;
|
||||
let len = elts.len();
|
||||
|
|
@ -859,7 +860,7 @@ impl<'a> State<'a> {
|
|||
enum_definition: &hir::EnumDef,
|
||||
generics: &hir::Generics,
|
||||
name: ast::Name,
|
||||
span: codemap::Span,
|
||||
span: syntax_pos::Span,
|
||||
visibility: &hir::Visibility)
|
||||
-> io::Result<()> {
|
||||
self.head(&visibility_qualified(visibility, "enum"))?;
|
||||
|
|
@ -872,7 +873,7 @@ impl<'a> State<'a> {
|
|||
|
||||
pub fn print_variants(&mut self,
|
||||
variants: &[hir::Variant],
|
||||
span: codemap::Span)
|
||||
span: syntax_pos::Span)
|
||||
-> io::Result<()> {
|
||||
self.bopen()?;
|
||||
for v in variants {
|
||||
|
|
@ -902,7 +903,7 @@ impl<'a> State<'a> {
|
|||
struct_def: &hir::VariantData,
|
||||
generics: &hir::Generics,
|
||||
name: ast::Name,
|
||||
span: codemap::Span,
|
||||
span: syntax_pos::Span,
|
||||
print_finalizer: bool)
|
||||
-> io::Result<()> {
|
||||
self.print_name(name)?;
|
||||
|
|
@ -2237,7 +2238,7 @@ impl<'a> State<'a> {
|
|||
}
|
||||
|
||||
pub fn maybe_print_trailing_comment(&mut self,
|
||||
span: codemap::Span,
|
||||
span: syntax_pos::Span,
|
||||
next_pos: Option<BytePos>)
|
||||
-> io::Result<()> {
|
||||
let cm = match self.cm {
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ use ty::relate::{RelateResult, TypeRelation};
|
|||
use traits::PredicateObligations;
|
||||
|
||||
use syntax::ast;
|
||||
use syntax::codemap::Span;
|
||||
use syntax_pos::Span;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct CombineFields<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
|
||||
|
|
|
|||
|
|
@ -91,10 +91,10 @@ use std::cell::{Cell, RefCell};
|
|||
use std::char::from_u32;
|
||||
use std::fmt;
|
||||
use syntax::ast;
|
||||
use syntax::errors::{DiagnosticBuilder, check_old_skool};
|
||||
use syntax::codemap::{self, Pos, Span};
|
||||
use syntax::parse::token;
|
||||
use syntax::ptr::P;
|
||||
use syntax_pos::{self, Pos, Span};
|
||||
use errors::{DiagnosticBuilder, check_old_skool};
|
||||
|
||||
impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
pub fn note_and_explain_region(self,
|
||||
|
|
@ -1933,6 +1933,6 @@ impl LifeGiver {
|
|||
|
||||
fn name_to_dummy_lifetime(name: ast::Name) -> hir::Lifetime {
|
||||
hir::Lifetime { id: ast::DUMMY_NODE_ID,
|
||||
span: codemap::DUMMY_SP,
|
||||
span: syntax_pos::DUMMY_SP,
|
||||
name: name }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ use super::region_inference::{TaintDirections};
|
|||
use ty::{self, TyCtxt, Binder, TypeFoldable};
|
||||
use ty::error::TypeError;
|
||||
use ty::relate::{Relate, RelateResult, TypeRelation};
|
||||
use syntax::codemap::Span;
|
||||
use syntax_pos::Span;
|
||||
use util::nodemap::{FnvHashMap, FnvHashSet};
|
||||
|
||||
pub struct HrMatchResult<U> {
|
||||
|
|
|
|||
|
|
@ -39,9 +39,8 @@ use rustc_data_structures::unify::{self, UnificationTable};
|
|||
use std::cell::{Cell, RefCell, Ref, RefMut};
|
||||
use std::fmt;
|
||||
use syntax::ast;
|
||||
use syntax::codemap;
|
||||
use syntax::codemap::{Span, DUMMY_SP};
|
||||
use syntax::errors::DiagnosticBuilder;
|
||||
use errors::DiagnosticBuilder;
|
||||
use syntax_pos::{self, Span, DUMMY_SP};
|
||||
use util::nodemap::{FnvHashMap, FnvHashSet, NodeMap};
|
||||
|
||||
use self::combine::CombineFields;
|
||||
|
|
@ -1036,7 +1035,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||
-> UnitResult<'tcx>
|
||||
{
|
||||
self.probe(|_| {
|
||||
let origin = TypeOrigin::Misc(codemap::DUMMY_SP);
|
||||
let origin = TypeOrigin::Misc(syntax_pos::DUMMY_SP);
|
||||
let trace = TypeTrace::types(origin, true, a, b);
|
||||
self.sub(true, trace, &a, &b).map(|_| ())
|
||||
})
|
||||
|
|
@ -1813,7 +1812,7 @@ impl<'a, 'gcx, 'tcx> TypeTrace<'tcx> {
|
|||
|
||||
pub fn dummy(tcx: TyCtxt<'a, 'gcx, 'tcx>) -> TypeTrace<'tcx> {
|
||||
TypeTrace {
|
||||
origin: TypeOrigin::Misc(codemap::DUMMY_SP),
|
||||
origin: TypeOrigin::Misc(syntax_pos::DUMMY_SP),
|
||||
values: Types(ExpectedFound {
|
||||
expected: tcx.types.err,
|
||||
found: tcx.types.err,
|
||||
|
|
@ -1887,7 +1886,7 @@ impl RegionVariableOrigin {
|
|||
Coercion(a) => a,
|
||||
EarlyBoundRegion(a, _) => a,
|
||||
LateBoundRegion(a, _, _) => a,
|
||||
BoundRegionInCoherence(_) => codemap::DUMMY_SP,
|
||||
BoundRegionInCoherence(_) => syntax_pos::DUMMY_SP,
|
||||
UpvarRegion(_, a) => a
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ use self::TypeVariableValue::*;
|
|||
use self::UndoEntry::*;
|
||||
use hir::def_id::{DefId};
|
||||
use ty::{self, Ty};
|
||||
use syntax::codemap::Span;
|
||||
use syntax_pos::Span;
|
||||
|
||||
use std::cmp::min;
|
||||
use std::marker::PhantomData;
|
||||
|
|
|
|||
|
|
@ -55,8 +55,10 @@ extern crate rustc_data_structures;
|
|||
extern crate serialize;
|
||||
extern crate collections;
|
||||
extern crate rustc_const_math;
|
||||
extern crate rustc_errors as errors;
|
||||
#[macro_use] extern crate log;
|
||||
#[macro_use] extern crate syntax;
|
||||
#[macro_use] extern crate syntax_pos;
|
||||
#[macro_use] #[no_link] extern crate rustc_bitflags;
|
||||
|
||||
extern crate serialize as rustc_serialize; // used by deriving
|
||||
|
|
|
|||
|
|
@ -40,11 +40,10 @@ use std::cmp;
|
|||
use std::default::Default as StdDefault;
|
||||
use std::mem;
|
||||
use syntax::attr::{self, AttrMetaMethods};
|
||||
use syntax::codemap::Span;
|
||||
use syntax::errors::DiagnosticBuilder;
|
||||
use syntax::parse::token::InternedString;
|
||||
use syntax::ast;
|
||||
use syntax::attr::ThinAttributesExt;
|
||||
use syntax_pos::Span;
|
||||
use errors::DiagnosticBuilder;
|
||||
use hir;
|
||||
use hir::intravisit as hir_visit;
|
||||
use hir::intravisit::{IdVisitor, IdVisitingOperation};
|
||||
|
|
@ -767,7 +766,7 @@ impl<'a, 'tcx, 'v> hir_visit::Visitor<'v> for LateContext<'a, 'tcx> {
|
|||
}
|
||||
|
||||
fn visit_expr(&mut self, e: &hir::Expr) {
|
||||
self.with_lint_attrs(e.attrs.as_attr_slice(), |cx| {
|
||||
self.with_lint_attrs(&e.attrs, |cx| {
|
||||
run_lints!(cx, check_expr, late_passes, e);
|
||||
hir_visit::walk_expr(cx, e);
|
||||
})
|
||||
|
|
@ -832,7 +831,7 @@ impl<'a, 'tcx, 'v> hir_visit::Visitor<'v> for LateContext<'a, 'tcx> {
|
|||
}
|
||||
|
||||
fn visit_local(&mut self, l: &hir::Local) {
|
||||
self.with_lint_attrs(l.attrs.as_attr_slice(), |cx| {
|
||||
self.with_lint_attrs(&l.attrs, |cx| {
|
||||
run_lints!(cx, check_local, late_passes, l);
|
||||
hir_visit::walk_local(cx, l);
|
||||
})
|
||||
|
|
@ -905,7 +904,7 @@ impl<'a, 'tcx, 'v> hir_visit::Visitor<'v> for LateContext<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, 'v> ast_visit::Visitor<'v> for EarlyContext<'a> {
|
||||
impl<'a> ast_visit::Visitor for EarlyContext<'a> {
|
||||
fn visit_item(&mut self, it: &ast::Item) {
|
||||
self.with_lint_attrs(&it.attrs, |cx| {
|
||||
run_lints!(cx, check_item, early_passes, it);
|
||||
|
|
@ -928,7 +927,7 @@ impl<'a, 'v> ast_visit::Visitor<'v> for EarlyContext<'a> {
|
|||
}
|
||||
|
||||
fn visit_expr(&mut self, e: &ast::Expr) {
|
||||
self.with_lint_attrs(e.attrs.as_attr_slice(), |cx| {
|
||||
self.with_lint_attrs(&e.attrs, |cx| {
|
||||
run_lints!(cx, check_expr, early_passes, e);
|
||||
ast_visit::walk_expr(cx, e);
|
||||
})
|
||||
|
|
@ -939,8 +938,8 @@ impl<'a, 'v> ast_visit::Visitor<'v> for EarlyContext<'a> {
|
|||
ast_visit::walk_stmt(self, s);
|
||||
}
|
||||
|
||||
fn visit_fn(&mut self, fk: ast_visit::FnKind<'v>, decl: &'v ast::FnDecl,
|
||||
body: &'v ast::Block, span: Span, id: ast::NodeId) {
|
||||
fn visit_fn(&mut self, fk: ast_visit::FnKind, decl: &ast::FnDecl,
|
||||
body: &ast::Block, span: Span, id: ast::NodeId) {
|
||||
run_lints!(self, check_fn, early_passes, fk, decl, body, span, id);
|
||||
ast_visit::walk_fn(self, fk, decl, body, span);
|
||||
run_lints!(self, check_fn_post, early_passes, fk, decl, body, span, id);
|
||||
|
|
@ -988,7 +987,7 @@ impl<'a, 'v> ast_visit::Visitor<'v> for EarlyContext<'a> {
|
|||
}
|
||||
|
||||
fn visit_local(&mut self, l: &ast::Local) {
|
||||
self.with_lint_attrs(l.attrs.as_attr_slice(), |cx| {
|
||||
self.with_lint_attrs(&l.attrs, |cx| {
|
||||
run_lints!(cx, check_local, early_passes, l);
|
||||
ast_visit::walk_local(cx, l);
|
||||
})
|
||||
|
|
@ -1005,11 +1004,6 @@ impl<'a, 'v> ast_visit::Visitor<'v> for EarlyContext<'a> {
|
|||
ast_visit::walk_arm(self, a);
|
||||
}
|
||||
|
||||
fn visit_decl(&mut self, d: &ast::Decl) {
|
||||
run_lints!(self, check_decl, early_passes, d);
|
||||
ast_visit::walk_decl(self, d);
|
||||
}
|
||||
|
||||
fn visit_expr_post(&mut self, e: &ast::Expr) {
|
||||
run_lints!(self, check_expr_post, early_passes, e);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ pub use self::LintSource::*;
|
|||
|
||||
use std::hash;
|
||||
use std::ascii::AsciiExt;
|
||||
use syntax::codemap::Span;
|
||||
use syntax_pos::Span;
|
||||
use hir::intravisit::FnKind;
|
||||
use syntax::visit as ast_visit;
|
||||
use syntax::ast;
|
||||
|
|
@ -195,7 +195,6 @@ pub trait EarlyLintPass: LintPass {
|
|||
fn check_stmt(&mut self, _: &EarlyContext, _: &ast::Stmt) { }
|
||||
fn check_arm(&mut self, _: &EarlyContext, _: &ast::Arm) { }
|
||||
fn check_pat(&mut self, _: &EarlyContext, _: &ast::Pat) { }
|
||||
fn check_decl(&mut self, _: &EarlyContext, _: &ast::Decl) { }
|
||||
fn check_expr(&mut self, _: &EarlyContext, _: &ast::Expr) { }
|
||||
fn check_expr_post(&mut self, _: &EarlyContext, _: &ast::Expr) { }
|
||||
fn check_ty(&mut self, _: &EarlyContext, _: &ast::Ty) { }
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
use hir::def::Def;
|
||||
use ty::{Ty, TyCtxt};
|
||||
|
||||
use syntax::codemap::Span;
|
||||
use syntax_pos::Span;
|
||||
use hir as ast;
|
||||
|
||||
impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
|
|
|
|||
|
|
@ -39,9 +39,9 @@ use std::rc::Rc;
|
|||
use std::path::PathBuf;
|
||||
use syntax::ast;
|
||||
use syntax::attr;
|
||||
use syntax::codemap::Span;
|
||||
use syntax::ptr::P;
|
||||
use syntax::parse::token::InternedString;
|
||||
use syntax_pos::Span;
|
||||
use rustc_back::target::Target;
|
||||
use hir;
|
||||
use hir::intravisit::{IdVisitor, IdVisitingOperation, Visitor};
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ use lint;
|
|||
use std::collections::HashSet;
|
||||
use syntax::{ast, codemap};
|
||||
use syntax::attr;
|
||||
use syntax_pos;
|
||||
|
||||
// Any local node that may call something in its body block should be
|
||||
// explored. For example, if it's a live NodeItem that is a
|
||||
|
|
@ -215,7 +216,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
|
|||
impl<'a, 'tcx, 'v> Visitor<'v> for MarkSymbolVisitor<'a, 'tcx> {
|
||||
|
||||
fn visit_variant_data(&mut self, def: &hir::VariantData, _: ast::Name,
|
||||
_: &hir::Generics, _: ast::NodeId, _: codemap::Span) {
|
||||
_: &hir::Generics, _: ast::NodeId, _: syntax_pos::Span) {
|
||||
let has_extern_repr = self.struct_has_extern_repr;
|
||||
let inherited_pub_visibility = self.inherited_pub_visibility;
|
||||
let live_fields = def.fields().iter().filter(|f| {
|
||||
|
|
@ -478,7 +479,7 @@ impl<'a, 'tcx> DeadVisitor<'a, 'tcx> {
|
|||
|
||||
fn warn_dead_code(&mut self,
|
||||
id: ast::NodeId,
|
||||
span: codemap::Span,
|
||||
span: syntax_pos::Span,
|
||||
name: ast::Name,
|
||||
node_type: &str) {
|
||||
let name = name.as_str();
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ use ty::{self, Ty, TyCtxt};
|
|||
use ty::MethodCall;
|
||||
|
||||
use syntax::ast;
|
||||
use syntax::codemap::Span;
|
||||
use syntax_pos::Span;
|
||||
use hir;
|
||||
use hir::intravisit;
|
||||
use hir::intravisit::{FnKind, Visitor};
|
||||
|
|
|
|||
|
|
@ -15,8 +15,8 @@ use hir::def_id::{CRATE_DEF_INDEX};
|
|||
use session::{config, Session};
|
||||
use syntax::ast::NodeId;
|
||||
use syntax::attr;
|
||||
use syntax::codemap::Span;
|
||||
use syntax::entry::EntryPointType;
|
||||
use syntax_pos::Span;
|
||||
use hir::{Item, ItemFn};
|
||||
use hir::intravisit::Visitor;
|
||||
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ use hir::{self, PatKind};
|
|||
|
||||
use syntax::ast;
|
||||
use syntax::ptr::P;
|
||||
use syntax::codemap::Span;
|
||||
use syntax_pos::Span;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// The Delegate trait
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ use ty::layout::{LayoutError, Pointer, SizeSkeleton};
|
|||
|
||||
use syntax::abi::Abi::RustIntrinsic;
|
||||
use syntax::ast;
|
||||
use syntax::codemap::Span;
|
||||
use syntax_pos::Span;
|
||||
use hir::intravisit::{self, Visitor, FnKind};
|
||||
use hir;
|
||||
|
||||
|
|
|
|||
|
|
@ -123,9 +123,10 @@ use std::io::prelude::*;
|
|||
use std::io;
|
||||
use std::rc::Rc;
|
||||
use syntax::ast::{self, NodeId};
|
||||
use syntax::codemap::{BytePos, original_sp, Span};
|
||||
use syntax::codemap::original_sp;
|
||||
use syntax::parse::token::keywords;
|
||||
use syntax::ptr::P;
|
||||
use syntax_pos::{BytePos, Span};
|
||||
|
||||
use hir::Expr;
|
||||
use hir;
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ use hir::{MutImmutable, MutMutable, PatKind};
|
|||
use hir::pat_util::EnumerateAndAdjustIterator;
|
||||
use hir;
|
||||
use syntax::ast;
|
||||
use syntax::codemap::Span;
|
||||
use syntax_pos::Span;
|
||||
|
||||
use std::fmt;
|
||||
use std::rc::Rc;
|
||||
|
|
|
|||
|
|
@ -27,8 +27,9 @@ use std::cell::RefCell;
|
|||
use std::collections::hash_map::Entry;
|
||||
use std::fmt;
|
||||
use std::mem;
|
||||
use syntax::codemap::{self, Span};
|
||||
use syntax::codemap;
|
||||
use syntax::ast::{self, NodeId};
|
||||
use syntax_pos::Span;
|
||||
|
||||
use hir;
|
||||
use hir::intravisit::{self, Visitor, FnKind};
|
||||
|
|
|
|||
|
|
@ -29,8 +29,8 @@ use ty;
|
|||
use std::fmt;
|
||||
use std::mem::replace;
|
||||
use syntax::ast;
|
||||
use syntax::codemap::Span;
|
||||
use syntax::parse::token::keywords;
|
||||
use syntax_pos::Span;
|
||||
use util::nodemap::NodeMap;
|
||||
|
||||
use rustc_data_structures::fnv::FnvHashSet;
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ use hir::def_id::{CRATE_DEF_INDEX, DefId};
|
|||
use ty::{self, TyCtxt};
|
||||
use middle::privacy::AccessLevels;
|
||||
use syntax::parse::token::InternedString;
|
||||
use syntax::codemap::{Span, DUMMY_SP};
|
||||
use syntax_pos::{Span, DUMMY_SP};
|
||||
use syntax::ast;
|
||||
use syntax::ast::{NodeId, Attribute};
|
||||
use syntax::feature_gate::{GateIssue, emit_feature_err, find_lang_feature_accepted_version};
|
||||
|
|
|
|||
|
|
@ -15,8 +15,8 @@ use session::Session;
|
|||
use middle::lang_items;
|
||||
|
||||
use syntax::ast;
|
||||
use syntax::codemap::Span;
|
||||
use syntax::parse::token::InternedString;
|
||||
use syntax_pos::Span;
|
||||
use hir::intravisit::Visitor;
|
||||
use hir::intravisit;
|
||||
use hir;
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ use mir::repr::{Mir, BasicBlock};
|
|||
|
||||
use rustc_serialize as serialize;
|
||||
|
||||
#[derive(Clone)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Cache {
|
||||
predecessors: RefCell<Option<IndexVec<BasicBlock, Vec<BasicBlock>>>>
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,9 @@ use graphviz::IntoCow;
|
|||
use middle::const_val::ConstVal;
|
||||
use rustc_const_math::{ConstUsize, ConstInt, ConstMathErr};
|
||||
use rustc_data_structures::indexed_vec::{IndexVec, Idx};
|
||||
use rustc_data_structures::control_flow_graph::dominators::{Dominators, dominators};
|
||||
use rustc_data_structures::control_flow_graph::{GraphPredecessors, GraphSuccessors};
|
||||
use rustc_data_structures::control_flow_graph::ControlFlowGraph;
|
||||
use hir::def_id::DefId;
|
||||
use ty::subst::Substs;
|
||||
use ty::{self, AdtDef, ClosureSubsts, FnOutput, Region, Ty};
|
||||
|
|
@ -24,8 +27,9 @@ use std::cell::Ref;
|
|||
use std::fmt::{self, Debug, Formatter, Write};
|
||||
use std::{iter, u32};
|
||||
use std::ops::{Index, IndexMut};
|
||||
use std::vec::IntoIter;
|
||||
use syntax::ast::{self, Name};
|
||||
use syntax::codemap::Span;
|
||||
use syntax_pos::Span;
|
||||
|
||||
use super::cache::Cache;
|
||||
|
||||
|
|
@ -54,7 +58,7 @@ macro_rules! newtype_index {
|
|||
}
|
||||
|
||||
/// Lowered representation of a single function.
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable)]
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
||||
pub struct Mir<'tcx> {
|
||||
/// List of basic blocks. References to basic block use a newtyped index type `BasicBlock`
|
||||
/// that indexes into this vector.
|
||||
|
|
@ -145,6 +149,11 @@ impl<'tcx> Mir<'tcx> {
|
|||
Ref::map(self.predecessors(), |p| &p[bb])
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn dominators(&self) -> Dominators<BasicBlock> {
|
||||
dominators(self)
|
||||
}
|
||||
|
||||
/// Maps locals (Arg's, Var's, Temp's and ReturnPointer, in that order)
|
||||
/// to their index in the whole list of locals. This is useful if you
|
||||
/// want to treat all locals the same instead of repeating yourself.
|
||||
|
|
@ -1190,3 +1199,33 @@ fn node_to_string(node_id: ast::NodeId) -> String {
|
|||
fn item_path_str(def_id: DefId) -> String {
|
||||
ty::tls::with(|tcx| tcx.item_path_str(def_id))
|
||||
}
|
||||
|
||||
impl<'tcx> ControlFlowGraph for Mir<'tcx> {
|
||||
|
||||
type Node = BasicBlock;
|
||||
|
||||
fn num_nodes(&self) -> usize { self.basic_blocks.len() }
|
||||
|
||||
fn start_node(&self) -> Self::Node { START_BLOCK }
|
||||
|
||||
fn predecessors<'graph>(&'graph self, node: Self::Node)
|
||||
-> <Self as GraphPredecessors<'graph>>::Iter
|
||||
{
|
||||
self.predecessors_for(node).clone().into_iter()
|
||||
}
|
||||
fn successors<'graph>(&'graph self, node: Self::Node)
|
||||
-> <Self as GraphSuccessors<'graph>>::Iter
|
||||
{
|
||||
self.basic_blocks[node].terminator().successors().into_owned().into_iter()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b> GraphPredecessors<'b> for Mir<'a> {
|
||||
type Item = BasicBlock;
|
||||
type Iter = IntoIter<BasicBlock>;
|
||||
}
|
||||
|
||||
impl<'a, 'b> GraphSuccessors<'b> for Mir<'a> {
|
||||
type Item = BasicBlock;
|
||||
type Iter = IntoIter<BasicBlock>;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ use mir::repr::*;
|
|||
use rustc_const_math::ConstUsize;
|
||||
use rustc_data_structures::tuple_slice::TupleSlice;
|
||||
use rustc_data_structures::indexed_vec::Idx;
|
||||
use syntax::codemap::Span;
|
||||
use syntax_pos::Span;
|
||||
|
||||
// # The MIR Visitor
|
||||
//
|
||||
|
|
|
|||
|
|
@ -26,11 +26,12 @@ use middle::cstore;
|
|||
use syntax::ast::{self, IntTy, UintTy};
|
||||
use syntax::attr;
|
||||
use syntax::attr::AttrMetaMethods;
|
||||
use syntax::errors::{ColorConfig, Handler};
|
||||
use syntax::parse;
|
||||
use syntax::parse::token::InternedString;
|
||||
use syntax::feature_gate::UnstableFeatures;
|
||||
|
||||
use errors::{ColorConfig, Handler};
|
||||
|
||||
use getopts;
|
||||
use std::collections::HashMap;
|
||||
use std::env;
|
||||
|
|
@ -1420,12 +1421,11 @@ mod tests {
|
|||
use middle::cstore::DummyCrateStore;
|
||||
use session::config::{build_configuration, build_session_options};
|
||||
use session::build_session;
|
||||
|
||||
use errors;
|
||||
use std::rc::Rc;
|
||||
use getopts::{getopts, OptGroup};
|
||||
use syntax::attr;
|
||||
use syntax::attr::AttrMetaMethods;
|
||||
use syntax::diagnostics;
|
||||
|
||||
fn optgroups() -> Vec<OptGroup> {
|
||||
super::rustc_optgroups().into_iter()
|
||||
|
|
@ -1442,7 +1442,7 @@ mod tests {
|
|||
Ok(m) => m,
|
||||
Err(f) => panic!("test_switch_implies_cfg_test: {}", f)
|
||||
};
|
||||
let registry = diagnostics::registry::Registry::new(&[]);
|
||||
let registry = errors::registry::Registry::new(&[]);
|
||||
let sessopts = build_session_options(matches);
|
||||
let sess = build_session(sessopts, &dep_graph, None, registry, Rc::new(DummyCrateStore));
|
||||
let cfg = build_configuration(&sess);
|
||||
|
|
@ -1462,7 +1462,7 @@ mod tests {
|
|||
panic!("test_switch_implies_cfg_test_unless_cfg_test: {}", f)
|
||||
}
|
||||
};
|
||||
let registry = diagnostics::registry::Registry::new(&[]);
|
||||
let registry = errors::registry::Registry::new(&[]);
|
||||
let sessopts = build_session_options(matches);
|
||||
let sess = build_session(sessopts, &dep_graph, None, registry,
|
||||
Rc::new(DummyCrateStore));
|
||||
|
|
@ -1479,7 +1479,7 @@ mod tests {
|
|||
let matches = getopts(&[
|
||||
"-Awarnings".to_string()
|
||||
], &optgroups()).unwrap();
|
||||
let registry = diagnostics::registry::Registry::new(&[]);
|
||||
let registry = errors::registry::Registry::new(&[]);
|
||||
let sessopts = build_session_options(&matches);
|
||||
let sess = build_session(sessopts, &dep_graph, None, registry,
|
||||
Rc::new(DummyCrateStore));
|
||||
|
|
@ -1491,7 +1491,7 @@ mod tests {
|
|||
"-Awarnings".to_string(),
|
||||
"-Dwarnings".to_string()
|
||||
], &optgroups()).unwrap();
|
||||
let registry = diagnostics::registry::Registry::new(&[]);
|
||||
let registry = errors::registry::Registry::new(&[]);
|
||||
let sessopts = build_session_options(&matches);
|
||||
let sess = build_session(sessopts, &dep_graph, None, registry,
|
||||
Rc::new(DummyCrateStore));
|
||||
|
|
@ -1502,7 +1502,7 @@ mod tests {
|
|||
let matches = getopts(&[
|
||||
"-Adead_code".to_string()
|
||||
], &optgroups()).unwrap();
|
||||
let registry = diagnostics::registry::Registry::new(&[]);
|
||||
let registry = errors::registry::Registry::new(&[]);
|
||||
let sessopts = build_session_options(&matches);
|
||||
let sess = build_session(sessopts, &dep_graph, None, registry,
|
||||
Rc::new(DummyCrateStore));
|
||||
|
|
|
|||
|
|
@ -21,17 +21,16 @@ use util::nodemap::{NodeMap, FnvHashMap};
|
|||
use mir::transform as mir_pass;
|
||||
|
||||
use syntax::ast::{NodeId, NodeIdAssigner, Name};
|
||||
use syntax::codemap::{Span, MultiSpan};
|
||||
use syntax::errors::{self, DiagnosticBuilder};
|
||||
use syntax::errors::emitter::{Emitter, BasicEmitter, EmitterWriter};
|
||||
use syntax::errors::json::JsonEmitter;
|
||||
use syntax::diagnostics;
|
||||
use errors::{self, DiagnosticBuilder};
|
||||
use errors::emitter::{Emitter, BasicEmitter, EmitterWriter};
|
||||
use syntax::json::JsonEmitter;
|
||||
use syntax::feature_gate;
|
||||
use syntax::parse;
|
||||
use syntax::parse::ParseSess;
|
||||
use syntax::parse::token;
|
||||
use syntax::{ast, codemap};
|
||||
use syntax::feature_gate::AttributeType;
|
||||
use syntax_pos::{Span, MultiSpan};
|
||||
|
||||
use rustc_back::target::Target;
|
||||
use llvm;
|
||||
|
|
@ -424,7 +423,7 @@ fn split_msg_into_multilines(msg: &str) -> Option<String> {
|
|||
pub fn build_session(sopts: config::Options,
|
||||
dep_graph: &DepGraph,
|
||||
local_crate_source_file: Option<PathBuf>,
|
||||
registry: diagnostics::registry::Registry,
|
||||
registry: errors::registry::Registry,
|
||||
cstore: Rc<for<'a> CrateStore<'a>>)
|
||||
-> Session {
|
||||
build_session_with_codemap(sopts,
|
||||
|
|
@ -438,7 +437,7 @@ pub fn build_session(sopts: config::Options,
|
|||
pub fn build_session_with_codemap(sopts: config::Options,
|
||||
dep_graph: &DepGraph,
|
||||
local_crate_source_file: Option<PathBuf>,
|
||||
registry: diagnostics::registry::Registry,
|
||||
registry: errors::registry::Registry,
|
||||
cstore: Rc<for<'a> CrateStore<'a>>,
|
||||
codemap: Rc<codemap::CodeMap>)
|
||||
-> Session {
|
||||
|
|
@ -455,7 +454,10 @@ pub fn build_session_with_codemap(sopts: config::Options,
|
|||
|
||||
let emitter: Box<Emitter> = match sopts.error_format {
|
||||
config::ErrorOutputType::HumanReadable(color_config) => {
|
||||
Box::new(EmitterWriter::stderr(color_config, Some(registry), codemap.clone()))
|
||||
Box::new(EmitterWriter::stderr(color_config,
|
||||
Some(registry),
|
||||
codemap.clone(),
|
||||
errors::snippet::FormatMode::EnvironmentSelected))
|
||||
}
|
||||
config::ErrorOutputType::Json => {
|
||||
Box::new(JsonEmitter::stderr(Some(registry), codemap.clone()))
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ use hir::def_id::DefId;
|
|||
use ty::subst::TypeSpace;
|
||||
use ty::{self, Ty, TyCtxt};
|
||||
use infer::{InferCtxt, TypeOrigin};
|
||||
use syntax::codemap::DUMMY_SP;
|
||||
use syntax_pos::DUMMY_SP;
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
struct InferIsLocal(bool);
|
||||
|
|
|
|||
|
|
@ -37,8 +37,8 @@ use std::cmp;
|
|||
use std::fmt;
|
||||
use syntax::ast;
|
||||
use syntax::attr::{AttributeMethods, AttrMetaMethods};
|
||||
use syntax::codemap::Span;
|
||||
use syntax::errors::DiagnosticBuilder;
|
||||
use syntax_pos::Span;
|
||||
use errors::DiagnosticBuilder;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||
pub struct TraitErrorKey<'tcx> {
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ use infer::InferCtxt;
|
|||
|
||||
use std::rc::Rc;
|
||||
use syntax::ast;
|
||||
use syntax::codemap::{Span, DUMMY_SP};
|
||||
use syntax_pos::{Span, DUMMY_SP};
|
||||
|
||||
pub use self::error_reporting::TraitErrorKey;
|
||||
pub use self::coherence::orphan_check;
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ use middle::region;
|
|||
use ty::subst::{Subst, Substs};
|
||||
use traits::{self, ProjectionMode, ObligationCause, Normalized};
|
||||
use ty::{self, TyCtxt};
|
||||
use syntax::codemap::DUMMY_SP;
|
||||
use syntax_pos::DUMMY_SP;
|
||||
|
||||
pub mod specialization_graph;
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ use hir::def_id::DefId;
|
|||
use infer::InferCtxt;
|
||||
use ty::subst::{Subst, Substs};
|
||||
use ty::{self, Ty, TyCtxt, ToPredicate, ToPolyTraitRef};
|
||||
use syntax::codemap::Span;
|
||||
use syntax_pos::Span;
|
||||
use util::common::ErrorReported;
|
||||
use util::nodemap::FnvHashSet;
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ use ty::{self, Ty, TyCtxt, TypeAndMut, TypeFoldable};
|
|||
use ty::LvaluePreference::{NoPreference};
|
||||
|
||||
use syntax::ast;
|
||||
use syntax::codemap::Span;
|
||||
use syntax_pos::Span;
|
||||
|
||||
use hir;
|
||||
|
||||
|
|
|
|||
|
|
@ -862,7 +862,7 @@ pub mod tls {
|
|||
|
||||
use std::cell::Cell;
|
||||
use std::fmt;
|
||||
use syntax::codemap;
|
||||
use syntax_pos;
|
||||
|
||||
/// Marker types used for the scoped TLS slot.
|
||||
/// The type context cannot be used directly because the scoped TLS
|
||||
|
|
@ -875,7 +875,7 @@ pub mod tls {
|
|||
*const ThreadLocalInterners)>> = Cell::new(None)
|
||||
}
|
||||
|
||||
fn span_debug(span: codemap::Span, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fn span_debug(span: syntax_pos::Span, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
with(|tcx| {
|
||||
write!(f, "{}", tcx.sess.codemap().span_to_string(span))
|
||||
})
|
||||
|
|
@ -884,7 +884,7 @@ pub mod tls {
|
|||
pub fn enter_global<'gcx, F, R>(gcx: GlobalCtxt<'gcx>, f: F) -> R
|
||||
where F: for<'a> FnOnce(TyCtxt<'a, 'gcx, 'gcx>) -> R
|
||||
{
|
||||
codemap::SPAN_DEBUG.with(|span_dbg| {
|
||||
syntax_pos::SPAN_DEBUG.with(|span_dbg| {
|
||||
let original_span_debug = span_dbg.get();
|
||||
span_dbg.set(span_debug);
|
||||
let result = enter(&gcx, &gcx.global_interners, f);
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@ use ty::{self, BoundRegion, Region, Ty, TyCtxt};
|
|||
use std::fmt;
|
||||
use syntax::abi;
|
||||
use syntax::ast::{self, Name};
|
||||
use syntax::codemap::Span;
|
||||
use syntax::errors::DiagnosticBuilder;
|
||||
use errors::DiagnosticBuilder;
|
||||
use syntax_pos::Span;
|
||||
|
||||
use hir;
|
||||
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ use util::common::slice_pat;
|
|||
|
||||
use syntax::ast::{FloatTy, IntTy, UintTy};
|
||||
use syntax::attr;
|
||||
use syntax::codemap::DUMMY_SP;
|
||||
use syntax_pos::DUMMY_SP;
|
||||
|
||||
use std::cmp;
|
||||
use std::fmt;
|
||||
|
|
|
|||
|
|
@ -44,8 +44,8 @@ use std::slice;
|
|||
use std::vec::IntoIter;
|
||||
use syntax::ast::{self, CrateNum, Name, NodeId};
|
||||
use syntax::attr::{self, AttrMetaMethods};
|
||||
use syntax::codemap::{DUMMY_SP, Span};
|
||||
use syntax::parse::token::InternedString;
|
||||
use syntax_pos::{DUMMY_SP, Span};
|
||||
|
||||
use rustc_const_math::ConstInt;
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ use std::fmt;
|
|||
use std::iter::IntoIterator;
|
||||
use std::slice::Iter;
|
||||
use std::vec::{Vec, IntoIter};
|
||||
use syntax::codemap::{Span, DUMMY_SP};
|
||||
use syntax_pos::{Span, DUMMY_SP};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ use std::cmp;
|
|||
use std::hash::{Hash, SipHasher, Hasher};
|
||||
use syntax::ast::{self, Name};
|
||||
use syntax::attr::{self, SignedInt, UnsignedInt};
|
||||
use syntax::codemap::Span;
|
||||
use syntax_pos::Span;
|
||||
|
||||
use hir;
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ use traits;
|
|||
use ty::{self, ToPredicate, Ty, TyCtxt, TypeFoldable};
|
||||
use std::iter::once;
|
||||
use syntax::ast;
|
||||
use syntax::codemap::Span;
|
||||
use syntax_pos::Span;
|
||||
use util::common::ErrorReported;
|
||||
|
||||
/// Returns the set of obligations needed to make `ty` well-formed.
|
||||
|
|
|
|||
|
|
@ -12,7 +12,9 @@ test = false
|
|||
[dependencies]
|
||||
log = { path = "../liblog" }
|
||||
syntax = { path = "../libsyntax" }
|
||||
syntax_pos = { path = "../libsyntax_pos" }
|
||||
graphviz = { path = "../libgraphviz" }
|
||||
rustc = { path = "../librustc" }
|
||||
rustc_data_structures = { path = "../librustc_data_structures" }
|
||||
rustc_mir = { path = "../librustc_mir" }
|
||||
rustc_errors = { path = "../librustc_errors" }
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ use rustc::middle::mem_categorization::Categorization;
|
|||
use rustc::middle::region;
|
||||
use rustc::ty::{self, TyCtxt};
|
||||
use syntax::ast;
|
||||
use syntax::codemap::Span;
|
||||
use syntax_pos::Span;
|
||||
use rustc::hir;
|
||||
|
||||
use std::rc::Rc;
|
||||
|
|
|
|||
|
|
@ -27,8 +27,8 @@ use rustc::middle::mem_categorization as mc;
|
|||
use std::mem;
|
||||
use std::rc::Rc;
|
||||
use syntax::ast;
|
||||
use syntax::codemap::{Span, DUMMY_SP};
|
||||
use syntax::attr::AttrMetaMethods;
|
||||
use syntax_pos::{Span, DUMMY_SP};
|
||||
|
||||
#[derive(PartialEq, Eq, PartialOrd, Ord)]
|
||||
enum Fragment {
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ use rustc::ty;
|
|||
|
||||
use std::rc::Rc;
|
||||
use syntax::ast;
|
||||
use syntax::codemap::Span;
|
||||
use syntax_pos::Span;
|
||||
use rustc::hir::{self, PatKind};
|
||||
|
||||
struct GatherMoveInfo<'tcx> {
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ use rustc::middle::region;
|
|||
use rustc::ty;
|
||||
|
||||
use syntax::ast;
|
||||
use syntax::codemap::Span;
|
||||
use syntax_pos::Span;
|
||||
|
||||
type R = Result<(),()>;
|
||||
|
||||
|
|
|
|||
|
|
@ -25,8 +25,8 @@ use rustc::middle::region;
|
|||
use rustc::ty::{self, TyCtxt};
|
||||
|
||||
use syntax::ast;
|
||||
use syntax::codemap::Span;
|
||||
use syntax::ast::NodeId;
|
||||
use syntax_pos::Span;
|
||||
use rustc::hir;
|
||||
use rustc::hir::Expr;
|
||||
use rustc::hir::intravisit;
|
||||
|
|
|
|||
|
|
@ -14,8 +14,8 @@ use rustc::middle::mem_categorization::Categorization;
|
|||
use rustc::middle::mem_categorization::InteriorOffsetKind as Kind;
|
||||
use rustc::ty;
|
||||
use syntax::ast;
|
||||
use syntax::codemap;
|
||||
use syntax::errors::DiagnosticBuilder;
|
||||
use syntax_pos;
|
||||
use errors::DiagnosticBuilder;
|
||||
use rustc::hir;
|
||||
|
||||
pub struct MoveErrorCollector<'tcx> {
|
||||
|
|
@ -56,7 +56,7 @@ impl<'tcx> MoveError<'tcx> {
|
|||
|
||||
#[derive(Clone)]
|
||||
pub struct MoveSpanAndPath {
|
||||
pub span: codemap::Span,
|
||||
pub span: syntax_pos::Span,
|
||||
pub name: ast::Name,
|
||||
}
|
||||
|
||||
|
|
@ -169,7 +169,7 @@ fn report_cannot_move_out_of<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
|
|||
}
|
||||
|
||||
fn note_move_destination(mut err: DiagnosticBuilder,
|
||||
move_to_span: codemap::Span,
|
||||
move_to_span: syntax_pos::Span,
|
||||
pat_name: ast::Name,
|
||||
is_first_note: bool) -> DiagnosticBuilder {
|
||||
if is_first_note {
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ use rustc::middle::expr_use_visitor as euv;
|
|||
use rustc::middle::mem_categorization as mc;
|
||||
use rustc::middle::mem_categorization::Categorization;
|
||||
use rustc::ty;
|
||||
use syntax::codemap::Span;
|
||||
use syntax_pos::Span;
|
||||
|
||||
use borrowck::ToInteriorKind;
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
use syntax::abi::{Abi};
|
||||
use syntax::ast;
|
||||
use syntax::codemap::Span;
|
||||
use syntax_pos::Span;
|
||||
|
||||
use rustc::ty::{self, TyCtxt};
|
||||
use rustc::mir::repr::{self, Mir};
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ use rustc::middle::const_val::ConstVal;
|
|||
use rustc::middle::lang_items;
|
||||
use rustc::util::nodemap::FnvHashMap;
|
||||
use rustc_data_structures::indexed_vec::Idx;
|
||||
use syntax::codemap::Span;
|
||||
use syntax_pos::Span;
|
||||
|
||||
use std::fmt;
|
||||
use std::u32;
|
||||
|
|
|
|||
|
|
@ -12,8 +12,8 @@ use borrowck::BorrowckCtxt;
|
|||
|
||||
use syntax::ast::{self, MetaItem};
|
||||
use syntax::attr::AttrMetaMethods;
|
||||
use syntax::codemap::{Span, DUMMY_SP};
|
||||
use syntax::ptr::P;
|
||||
use syntax_pos::{Span, DUMMY_SP};
|
||||
|
||||
use rustc::hir;
|
||||
use rustc::hir::intravisit::{FnKind};
|
||||
|
|
|
|||
|
|
@ -43,8 +43,8 @@ use std::mem;
|
|||
use std::rc::Rc;
|
||||
use syntax::ast;
|
||||
use syntax::attr::AttrMetaMethods;
|
||||
use syntax::codemap::{MultiSpan, Span};
|
||||
use syntax::errors::DiagnosticBuilder;
|
||||
use syntax_pos::{MultiSpan, Span};
|
||||
use errors::DiagnosticBuilder;
|
||||
|
||||
use rustc::hir;
|
||||
use rustc::hir::{FnDecl, Block};
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ use std::cell::RefCell;
|
|||
use std::rc::Rc;
|
||||
use std::usize;
|
||||
use syntax::ast;
|
||||
use syntax::codemap::Span;
|
||||
use syntax_pos::Span;
|
||||
use rustc::hir;
|
||||
use rustc::hir::intravisit::IdRange;
|
||||
|
||||
|
|
|
|||
|
|
@ -28,6 +28,8 @@
|
|||
#![feature(question_mark)]
|
||||
#[macro_use] extern crate log;
|
||||
#[macro_use] extern crate syntax;
|
||||
extern crate syntax_pos;
|
||||
extern crate rustc_errors as errors;
|
||||
|
||||
// for "clarity", rename the graphviz crate to dot; graphviz within `borrowck`
|
||||
// refers to the borrowck-specific graphviz adapter traits.
|
||||
|
|
|
|||
|
|
@ -16,3 +16,4 @@ rustc_back = { path = "../librustc_back" }
|
|||
rustc_const_math = { path = "../librustc_const_math" }
|
||||
syntax = { path = "../libsyntax" }
|
||||
graphviz = { path = "../libgraphviz" }
|
||||
syntax_pos = { path = "../libsyntax_pos" }
|
||||
|
|
@ -37,7 +37,8 @@ use rustc::hir::intravisit::{self, IdVisitor, IdVisitingOperation, Visitor, FnKi
|
|||
use rustc_back::slice;
|
||||
|
||||
use syntax::ast::{self, DUMMY_NODE_ID, NodeId};
|
||||
use syntax::codemap::{Span, Spanned, DUMMY_SP};
|
||||
use syntax::codemap::Spanned;
|
||||
use syntax_pos::{Span, DUMMY_SP};
|
||||
use rustc::hir::fold::{Folder, noop_fold_pat};
|
||||
use rustc::hir::print::pat_to_string;
|
||||
use syntax::ptr::P;
|
||||
|
|
@ -451,7 +452,7 @@ fn const_val_to_expr(value: &ConstVal) -> P<hir::Expr> {
|
|||
id: 0,
|
||||
node: hir::ExprLit(P(Spanned { node: node, span: DUMMY_SP })),
|
||||
span: DUMMY_SP,
|
||||
attrs: None,
|
||||
attrs: ast::ThinVec::new(),
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -33,10 +33,10 @@ use syntax::ast;
|
|||
use rustc::hir::{Expr, PatKind};
|
||||
use rustc::hir;
|
||||
use rustc::hir::intravisit::FnKind;
|
||||
use syntax::codemap::Span;
|
||||
use syntax::ptr::P;
|
||||
use syntax::codemap;
|
||||
use syntax::attr::IntType;
|
||||
use syntax_pos::{self, Span};
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::cmp::Ordering;
|
||||
|
|
@ -301,7 +301,7 @@ pub fn const_expr_to_pat<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
let field_pats =
|
||||
try!(fields.iter()
|
||||
.map(|field| Ok(codemap::Spanned {
|
||||
span: codemap::DUMMY_SP,
|
||||
span: syntax_pos::DUMMY_SP,
|
||||
node: hir::FieldPat {
|
||||
name: field.name.node,
|
||||
pat: try!(const_expr_to_pat(tcx, &field.expr,
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@
|
|||
extern crate rustc_back;
|
||||
extern crate rustc_const_math;
|
||||
extern crate graphviz;
|
||||
|
||||
extern crate syntax_pos;
|
||||
extern crate serialize as rustc_serialize; // used by deriving
|
||||
|
||||
// NB: This module needs to be declared first so diagnostics are
|
||||
|
|
|
|||
|
|
@ -0,0 +1,284 @@
|
|||
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
//! Algorithm citation:
|
||||
//! A Simple, Fast Dominance Algorithm.
|
||||
//! Keith D. Cooper, Timothy J. Harvey, and Ken Kennedy
|
||||
//! Rice Computer Science TS-06-33870
|
||||
//! https://www.cs.rice.edu/~keith/EMBED/dom.pdf
|
||||
|
||||
use super::ControlFlowGraph;
|
||||
use super::iterate::reverse_post_order;
|
||||
use super::super::indexed_vec::{IndexVec, Idx};
|
||||
|
||||
use std::fmt;
|
||||
|
||||
#[cfg(test)]
|
||||
mod test;
|
||||
|
||||
pub fn dominators<G: ControlFlowGraph>(graph: &G) -> Dominators<G::Node> {
|
||||
let start_node = graph.start_node();
|
||||
let rpo = reverse_post_order(graph, start_node);
|
||||
dominators_given_rpo(graph, &rpo)
|
||||
}
|
||||
|
||||
pub fn dominators_given_rpo<G: ControlFlowGraph>(graph: &G,
|
||||
rpo: &[G::Node])
|
||||
-> Dominators<G::Node> {
|
||||
let start_node = graph.start_node();
|
||||
assert_eq!(rpo[0], start_node);
|
||||
|
||||
// compute the post order index (rank) for each node
|
||||
let mut post_order_rank: IndexVec<G::Node, usize> = IndexVec::from_elem_n(usize::default(),
|
||||
graph.num_nodes());
|
||||
for (index, node) in rpo.iter().rev().cloned().enumerate() {
|
||||
post_order_rank[node] = index;
|
||||
}
|
||||
|
||||
let mut immediate_dominators: IndexVec<G::Node, Option<G::Node>> =
|
||||
IndexVec::from_elem_n(Option::default(), graph.num_nodes());
|
||||
immediate_dominators[start_node] = Some(start_node);
|
||||
|
||||
let mut changed = true;
|
||||
while changed {
|
||||
changed = false;
|
||||
|
||||
for &node in &rpo[1..] {
|
||||
let mut new_idom = None;
|
||||
for pred in graph.predecessors(node) {
|
||||
if immediate_dominators[pred].is_some() {
|
||||
// (*)
|
||||
// (*) dominators for `pred` have been calculated
|
||||
new_idom = intersect_opt(&post_order_rank,
|
||||
&immediate_dominators,
|
||||
new_idom,
|
||||
Some(pred));
|
||||
}
|
||||
}
|
||||
|
||||
if new_idom != immediate_dominators[node] {
|
||||
immediate_dominators[node] = new_idom;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Dominators {
|
||||
post_order_rank: post_order_rank,
|
||||
immediate_dominators: immediate_dominators,
|
||||
}
|
||||
}
|
||||
|
||||
fn intersect_opt<Node: Idx>(post_order_rank: &IndexVec<Node, usize>,
|
||||
immediate_dominators: &IndexVec<Node, Option<Node>>,
|
||||
node1: Option<Node>,
|
||||
node2: Option<Node>)
|
||||
-> Option<Node> {
|
||||
match (node1, node2) {
|
||||
(None, None) => None,
|
||||
(Some(n), None) | (None, Some(n)) => Some(n),
|
||||
(Some(n1), Some(n2)) => Some(intersect(post_order_rank, immediate_dominators, n1, n2)),
|
||||
}
|
||||
}
|
||||
|
||||
fn intersect<Node: Idx>(post_order_rank: &IndexVec<Node, usize>,
|
||||
immediate_dominators: &IndexVec<Node, Option<Node>>,
|
||||
mut node1: Node,
|
||||
mut node2: Node)
|
||||
-> Node {
|
||||
while node1 != node2 {
|
||||
while post_order_rank[node1] < post_order_rank[node2] {
|
||||
node1 = immediate_dominators[node1].unwrap();
|
||||
}
|
||||
|
||||
while post_order_rank[node2] < post_order_rank[node1] {
|
||||
node2 = immediate_dominators[node2].unwrap();
|
||||
}
|
||||
}
|
||||
return node1;
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Dominators<N: Idx> {
|
||||
post_order_rank: IndexVec<N, usize>,
|
||||
immediate_dominators: IndexVec<N, Option<N>>,
|
||||
}
|
||||
|
||||
impl<Node: Idx> Dominators<Node> {
|
||||
pub fn is_reachable(&self, node: Node) -> bool {
|
||||
self.immediate_dominators[node].is_some()
|
||||
}
|
||||
|
||||
pub fn immediate_dominator(&self, node: Node) -> Node {
|
||||
assert!(self.is_reachable(node), "node {:?} is not reachable", node);
|
||||
self.immediate_dominators[node].unwrap()
|
||||
}
|
||||
|
||||
pub fn dominators(&self, node: Node) -> Iter<Node> {
|
||||
assert!(self.is_reachable(node), "node {:?} is not reachable", node);
|
||||
Iter {
|
||||
dominators: self,
|
||||
node: Some(node),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_dominated_by(&self, node: Node, dom: Node) -> bool {
|
||||
// FIXME -- could be optimized by using post-order-rank
|
||||
self.dominators(node).any(|n| n == dom)
|
||||
}
|
||||
|
||||
pub fn mutual_dominator_node(&self, node1: Node, node2: Node) -> Node {
|
||||
assert!(self.is_reachable(node1),
|
||||
"node {:?} is not reachable",
|
||||
node1);
|
||||
assert!(self.is_reachable(node2),
|
||||
"node {:?} is not reachable",
|
||||
node2);
|
||||
intersect::<Node>(&self.post_order_rank,
|
||||
&self.immediate_dominators,
|
||||
node1,
|
||||
node2)
|
||||
}
|
||||
|
||||
pub fn mutual_dominator<I>(&self, iter: I) -> Option<Node>
|
||||
where I: IntoIterator<Item = Node>
|
||||
{
|
||||
let mut iter = iter.into_iter();
|
||||
iter.next()
|
||||
.map(|dom| iter.fold(dom, |dom, node| self.mutual_dominator_node(dom, node)))
|
||||
}
|
||||
|
||||
pub fn all_immediate_dominators(&self) -> &IndexVec<Node, Option<Node>> {
|
||||
&self.immediate_dominators
|
||||
}
|
||||
|
||||
pub fn dominator_tree(&self) -> DominatorTree<Node> {
|
||||
let elem: Vec<Node> = Vec::new();
|
||||
let mut children: IndexVec<Node, Vec<Node>> =
|
||||
IndexVec::from_elem_n(elem, self.immediate_dominators.len());
|
||||
let mut root = None;
|
||||
for (index, immed_dom) in self.immediate_dominators.iter().enumerate() {
|
||||
let node = Node::new(index);
|
||||
match *immed_dom {
|
||||
None => {
|
||||
// node not reachable
|
||||
}
|
||||
Some(immed_dom) => {
|
||||
if node == immed_dom {
|
||||
root = Some(node);
|
||||
} else {
|
||||
children[immed_dom].push(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
DominatorTree {
|
||||
root: root.unwrap(),
|
||||
children: children,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Iter<'dom, Node: Idx + 'dom> {
|
||||
dominators: &'dom Dominators<Node>,
|
||||
node: Option<Node>,
|
||||
}
|
||||
|
||||
impl<'dom, Node: Idx> Iterator for Iter<'dom, Node> {
|
||||
type Item = Node;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
if let Some(node) = self.node {
|
||||
let dom = self.dominators.immediate_dominator(node);
|
||||
if dom == node {
|
||||
self.node = None; // reached the root
|
||||
} else {
|
||||
self.node = Some(dom);
|
||||
}
|
||||
return Some(node);
|
||||
} else {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct DominatorTree<N: Idx> {
|
||||
root: N,
|
||||
children: IndexVec<N, Vec<N>>,
|
||||
}
|
||||
|
||||
impl<Node: Idx> DominatorTree<Node> {
|
||||
pub fn root(&self) -> Node {
|
||||
self.root
|
||||
}
|
||||
|
||||
pub fn children(&self, node: Node) -> &[Node] {
|
||||
&self.children[node]
|
||||
}
|
||||
|
||||
pub fn iter_children_of(&self, node: Node) -> IterChildrenOf<Node> {
|
||||
IterChildrenOf {
|
||||
tree: self,
|
||||
stack: vec![node],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct IterChildrenOf<'iter, Node: Idx + 'iter> {
|
||||
tree: &'iter DominatorTree<Node>,
|
||||
stack: Vec<Node>,
|
||||
}
|
||||
|
||||
impl<'iter, Node: Idx> Iterator for IterChildrenOf<'iter, Node> {
|
||||
type Item = Node;
|
||||
|
||||
fn next(&mut self) -> Option<Node> {
|
||||
if let Some(node) = self.stack.pop() {
|
||||
self.stack.extend(self.tree.children(node));
|
||||
Some(node)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<Node: Idx> fmt::Debug for DominatorTree<Node> {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
||||
fmt::Debug::fmt(&DominatorTreeNode {
|
||||
tree: self,
|
||||
node: self.root,
|
||||
},
|
||||
fmt)
|
||||
}
|
||||
}
|
||||
|
||||
struct DominatorTreeNode<'tree, Node: Idx> {
|
||||
tree: &'tree DominatorTree<Node>,
|
||||
node: Node,
|
||||
}
|
||||
|
||||
impl<'tree, Node: Idx> fmt::Debug for DominatorTreeNode<'tree, Node> {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
||||
let subtrees: Vec<_> = self.tree
|
||||
.children(self.node)
|
||||
.iter()
|
||||
.map(|&child| {
|
||||
DominatorTreeNode {
|
||||
tree: self.tree,
|
||||
node: child,
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
fmt.debug_tuple("")
|
||||
.field(&self.node)
|
||||
.field(&subtrees)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use super::super::test::TestGraph;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn diamond() {
|
||||
let graph = TestGraph::new(0, &[
|
||||
(0, 1),
|
||||
(0, 2),
|
||||
(1, 3),
|
||||
(2, 3),
|
||||
]);
|
||||
|
||||
let dominators = dominators(&graph);
|
||||
let immediate_dominators = dominators.all_immediate_dominators();
|
||||
assert_eq!(immediate_dominators[0], Some(0));
|
||||
assert_eq!(immediate_dominators[1], Some(0));
|
||||
assert_eq!(immediate_dominators[2], Some(0));
|
||||
assert_eq!(immediate_dominators[3], Some(0));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn paper() {
|
||||
// example from the paper:
|
||||
let graph = TestGraph::new(6, &[
|
||||
(6, 5),
|
||||
(6, 4),
|
||||
(5, 1),
|
||||
(4, 2),
|
||||
(4, 3),
|
||||
(1, 2),
|
||||
(2, 3),
|
||||
(3, 2),
|
||||
(2, 1),
|
||||
]);
|
||||
|
||||
let dominators = dominators(&graph);
|
||||
let immediate_dominators = dominators.all_immediate_dominators();
|
||||
assert_eq!(immediate_dominators[0], None); // <-- note that 0 is not in graph
|
||||
assert_eq!(immediate_dominators[1], Some(6));
|
||||
assert_eq!(immediate_dominators[2], Some(6));
|
||||
assert_eq!(immediate_dominators[3], Some(6));
|
||||
assert_eq!(immediate_dominators[4], Some(6));
|
||||
assert_eq!(immediate_dominators[5], Some(6));
|
||||
assert_eq!(immediate_dominators[6], Some(6));
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use super::ControlFlowGraph;
|
||||
use super::super::indexed_vec::IndexVec;
|
||||
|
||||
#[cfg(test)]
|
||||
mod test;
|
||||
|
||||
pub fn post_order_from<G: ControlFlowGraph>(graph: &G, start_node: G::Node) -> Vec<G::Node> {
|
||||
post_order_from_to(graph, start_node, None)
|
||||
}
|
||||
|
||||
pub fn post_order_from_to<G: ControlFlowGraph>(graph: &G,
|
||||
start_node: G::Node,
|
||||
end_node: Option<G::Node>)
|
||||
-> Vec<G::Node> {
|
||||
let mut visited: IndexVec<G::Node, bool> = IndexVec::from_elem_n(false, graph.num_nodes());
|
||||
let mut result: Vec<G::Node> = Vec::with_capacity(graph.num_nodes());
|
||||
if let Some(end_node) = end_node {
|
||||
visited[end_node] = true;
|
||||
}
|
||||
post_order_walk(graph, start_node, &mut result, &mut visited);
|
||||
result
|
||||
}
|
||||
|
||||
fn post_order_walk<G: ControlFlowGraph>(graph: &G,
|
||||
node: G::Node,
|
||||
result: &mut Vec<G::Node>,
|
||||
visited: &mut IndexVec<G::Node, bool>) {
|
||||
if visited[node] {
|
||||
return;
|
||||
}
|
||||
visited[node] = true;
|
||||
|
||||
for successor in graph.successors(node) {
|
||||
post_order_walk(graph, successor, result, visited);
|
||||
}
|
||||
|
||||
result.push(node);
|
||||
}
|
||||
|
||||
pub fn pre_order_walk<G: ControlFlowGraph>(graph: &G,
|
||||
node: G::Node,
|
||||
result: &mut Vec<G::Node>,
|
||||
visited: &mut IndexVec<G::Node, bool>) {
|
||||
if visited[node] {
|
||||
return;
|
||||
}
|
||||
visited[node] = true;
|
||||
|
||||
result.push(node);
|
||||
|
||||
for successor in graph.successors(node) {
|
||||
pre_order_walk(graph, successor, result, visited);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn reverse_post_order<G: ControlFlowGraph>(graph: &G, start_node: G::Node) -> Vec<G::Node> {
|
||||
let mut vec = post_order_from(graph, start_node);
|
||||
vec.reverse();
|
||||
vec
|
||||
}
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use super::super::test::TestGraph;
|
||||
use super::super::transpose::TransposedGraph;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn diamond_post_order() {
|
||||
let graph = TestGraph::new(0, &[
|
||||
(0, 1),
|
||||
(0, 2),
|
||||
(1, 3),
|
||||
(2, 3),
|
||||
]);
|
||||
|
||||
let result = post_order_from(&graph, 0);
|
||||
assert_eq!(result, vec![3, 1, 2, 0]);
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn rev_post_order_inner_loop() {
|
||||
// 0 -> 1 -> 2 -> 3 -> 5
|
||||
// ^ ^ v |
|
||||
// | 6 <- 4 |
|
||||
// +-----------------+
|
||||
let graph = TestGraph::new(0, &[
|
||||
(0, 1),
|
||||
(1, 2),
|
||||
(2, 3),
|
||||
(3, 5),
|
||||
(3, 1),
|
||||
(2, 4),
|
||||
(4, 6),
|
||||
(6, 2),
|
||||
]);
|
||||
|
||||
let rev_graph = TransposedGraph::new(&graph);
|
||||
|
||||
let result = post_order_from_to(&rev_graph, 6, Some(2));
|
||||
assert_eq!(result, vec![4, 6]);
|
||||
|
||||
let result = post_order_from_to(&rev_graph, 3, Some(1));
|
||||
assert_eq!(result, vec![4, 6, 2, 3]);
|
||||
}
|
||||
|
||||
45
src/librustc_data_structures/control_flow_graph/mod.rs
Normal file
45
src/librustc_data_structures/control_flow_graph/mod.rs
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use super::indexed_vec::Idx;
|
||||
pub use std::slice::Iter;
|
||||
|
||||
pub mod dominators;
|
||||
pub mod iterate;
|
||||
pub mod reachable;
|
||||
mod reference;
|
||||
pub mod transpose;
|
||||
|
||||
#[cfg(test)]
|
||||
mod test;
|
||||
|
||||
pub trait ControlFlowGraph
|
||||
where Self: for<'graph> GraphPredecessors<'graph, Item=<Self as ControlFlowGraph>::Node>,
|
||||
Self: for<'graph> GraphSuccessors<'graph, Item=<Self as ControlFlowGraph>::Node>
|
||||
{
|
||||
type Node: Idx;
|
||||
|
||||
fn num_nodes(&self) -> usize;
|
||||
fn start_node(&self) -> Self::Node;
|
||||
fn predecessors<'graph>(&'graph self, node: Self::Node)
|
||||
-> <Self as GraphPredecessors<'graph>>::Iter;
|
||||
fn successors<'graph>(&'graph self, node: Self::Node)
|
||||
-> <Self as GraphSuccessors<'graph>>::Iter;
|
||||
}
|
||||
|
||||
pub trait GraphPredecessors<'graph> {
|
||||
type Item;
|
||||
type Iter: Iterator<Item=Self::Item>;
|
||||
}
|
||||
|
||||
pub trait GraphSuccessors<'graph> {
|
||||
type Item;
|
||||
type Iter: Iterator<Item=Self::Item>;
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
//! Compute reachability using a simple dataflow propagation.
|
||||
//! Store end-result in a big NxN bit matrix.
|
||||
|
||||
use super::ControlFlowGraph;
|
||||
use super::super::bitvec::BitVector;
|
||||
use super::iterate::reverse_post_order;
|
||||
use super::super::indexed_vec::{IndexVec, Idx};
|
||||
|
||||
#[cfg(test)]
|
||||
mod test;
|
||||
|
||||
pub fn reachable<G: ControlFlowGraph>(graph: &G)
|
||||
-> Reachability<G::Node> {
|
||||
let reverse_post_order = reverse_post_order(graph, graph.start_node());
|
||||
reachable_given_rpo(graph, &reverse_post_order)
|
||||
}
|
||||
|
||||
pub fn reachable_given_rpo<G: ControlFlowGraph>(graph: &G,
|
||||
reverse_post_order: &[G::Node])
|
||||
-> Reachability<G::Node> {
|
||||
let mut reachability = Reachability::new(graph);
|
||||
let mut changed = true;
|
||||
while changed {
|
||||
changed = false;
|
||||
for &node in reverse_post_order.iter().rev() {
|
||||
// every node can reach itself
|
||||
changed |= reachability.bits[node].insert(node.index());
|
||||
|
||||
// and every pred can reach everything node can reach
|
||||
for pred in graph.predecessors(node) {
|
||||
let nodes_bits = reachability.bits[node].clone();
|
||||
changed |= reachability.bits[pred].insert_all(&nodes_bits);
|
||||
}
|
||||
}
|
||||
}
|
||||
reachability
|
||||
}
|
||||
|
||||
pub struct Reachability<Node: Idx> {
|
||||
bits: IndexVec<Node, BitVector>,
|
||||
}
|
||||
|
||||
impl<Node: Idx> Reachability<Node> {
|
||||
fn new<G: ControlFlowGraph>(graph: &G) -> Self {
|
||||
let num_nodes = graph.num_nodes();
|
||||
Reachability {
|
||||
bits: IndexVec::from_elem_n(BitVector::new(num_nodes), num_nodes),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn can_reach(&self, source: Node, target: Node)-> bool {
|
||||
let bit: usize = target.index();
|
||||
self.bits[source].contains(bit)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use super::super::test::TestGraph;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test1() {
|
||||
// 0 -> 1 -> 2 -> 3
|
||||
// ^ v
|
||||
// 6 <- 4 -> 5
|
||||
let graph = TestGraph::new(0, &[
|
||||
(0, 1),
|
||||
(1, 2),
|
||||
(2, 3),
|
||||
(2, 4),
|
||||
(4, 5),
|
||||
(4, 6),
|
||||
(6, 1),
|
||||
]);
|
||||
let reachable = reachable(&graph);
|
||||
assert!((0..6).all(|i| reachable.can_reach(0, i)));
|
||||
assert!((1..6).all(|i| reachable.can_reach(1, i)));
|
||||
assert!((1..6).all(|i| reachable.can_reach(2, i)));
|
||||
assert!((1..6).all(|i| reachable.can_reach(4, i)));
|
||||
assert!((1..6).all(|i| reachable.can_reach(6, i)));
|
||||
assert!(reachable.can_reach(3, 3));
|
||||
assert!(!reachable.can_reach(3, 5));
|
||||
assert!(!reachable.can_reach(5, 3));
|
||||
}
|
||||
|
||||
/// use bigger indices to cross between words in the bit set
|
||||
#[test]
|
||||
fn test2() {
|
||||
// 30 -> 31 -> 32 -> 33
|
||||
// ^ v
|
||||
// 36 <- 34 -> 35
|
||||
let graph = TestGraph::new(30, &[
|
||||
(30, 31),
|
||||
(31, 32),
|
||||
(32, 33),
|
||||
(32, 34),
|
||||
(34, 35),
|
||||
(34, 36),
|
||||
(36, 31),
|
||||
]);
|
||||
let reachable = reachable(&graph);
|
||||
assert!((30..36).all(|i| reachable.can_reach(30, i)));
|
||||
assert!((31..36).all(|i| reachable.can_reach(31, i)));
|
||||
assert!((31..36).all(|i| reachable.can_reach(32, i)));
|
||||
assert!((31..36).all(|i| reachable.can_reach(34, i)));
|
||||
assert!((31..36).all(|i| reachable.can_reach(36, i)));
|
||||
assert!(reachable.can_reach(33, 33));
|
||||
assert!(!reachable.can_reach(33, 35));
|
||||
assert!(!reachable.can_reach(35, 33));
|
||||
}
|
||||
43
src/librustc_data_structures/control_flow_graph/reference.rs
Normal file
43
src/librustc_data_structures/control_flow_graph/reference.rs
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use super::*;
|
||||
|
||||
impl<'graph, G: ControlFlowGraph> ControlFlowGraph for &'graph G {
|
||||
type Node = G::Node;
|
||||
|
||||
fn num_nodes(&self) -> usize {
|
||||
(**self).num_nodes()
|
||||
}
|
||||
|
||||
fn start_node(&self) -> Self::Node {
|
||||
(**self).start_node()
|
||||
}
|
||||
|
||||
fn predecessors<'iter>(&'iter self, node: Self::Node)
|
||||
-> <Self as GraphPredecessors<'iter>>::Iter {
|
||||
(**self).predecessors(node)
|
||||
}
|
||||
|
||||
fn successors<'iter>(&'iter self, node: Self::Node)
|
||||
-> <Self as GraphSuccessors<'iter>>::Iter {
|
||||
(**self).successors(node)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'iter, 'graph, G: ControlFlowGraph> GraphPredecessors<'iter> for &'graph G {
|
||||
type Item = G::Node;
|
||||
type Iter = <G as GraphPredecessors<'iter>>::Iter;
|
||||
}
|
||||
|
||||
impl<'iter, 'graph, G: ControlFlowGraph> GraphSuccessors<'iter> for &'graph G {
|
||||
type Item = G::Node;
|
||||
type Iter = <G as GraphSuccessors<'iter>>::Iter;
|
||||
}
|
||||
78
src/librustc_data_structures/control_flow_graph/test.rs
Normal file
78
src/librustc_data_structures/control_flow_graph/test.rs
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::cmp::max;
|
||||
use std::slice;
|
||||
use std::iter;
|
||||
|
||||
use super::{ControlFlowGraph, GraphPredecessors, GraphSuccessors};
|
||||
|
||||
pub struct TestGraph {
|
||||
num_nodes: usize,
|
||||
start_node: usize,
|
||||
successors: HashMap<usize, Vec<usize>>,
|
||||
predecessors: HashMap<usize, Vec<usize>>,
|
||||
}
|
||||
|
||||
impl TestGraph {
|
||||
pub fn new(start_node: usize, edges: &[(usize, usize)]) -> Self {
|
||||
let mut graph = TestGraph {
|
||||
num_nodes: start_node + 1,
|
||||
start_node: start_node,
|
||||
successors: HashMap::new(),
|
||||
predecessors: HashMap::new()
|
||||
};
|
||||
for &(source, target) in edges {
|
||||
graph.num_nodes = max(graph.num_nodes, source + 1);
|
||||
graph.num_nodes = max(graph.num_nodes, target + 1);
|
||||
graph.successors.entry(source).or_insert(vec![]).push(target);
|
||||
graph.predecessors.entry(target).or_insert(vec![]).push(source);
|
||||
}
|
||||
for node in 0..graph.num_nodes {
|
||||
graph.successors.entry(node).or_insert(vec![]);
|
||||
graph.predecessors.entry(node).or_insert(vec![]);
|
||||
}
|
||||
graph
|
||||
}
|
||||
}
|
||||
|
||||
impl ControlFlowGraph for TestGraph {
|
||||
type Node = usize;
|
||||
|
||||
fn start_node(&self) -> usize {
|
||||
self.start_node
|
||||
}
|
||||
|
||||
fn num_nodes(&self) -> usize {
|
||||
self.num_nodes
|
||||
}
|
||||
|
||||
fn predecessors<'graph>(&'graph self, node: usize)
|
||||
-> <Self as GraphPredecessors<'graph>>::Iter {
|
||||
self.predecessors[&node].iter().cloned()
|
||||
}
|
||||
|
||||
fn successors<'graph>(&'graph self, node: usize)
|
||||
-> <Self as GraphSuccessors<'graph>>::Iter {
|
||||
self.successors[&node].iter().cloned()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'graph> GraphPredecessors<'graph> for TestGraph {
|
||||
type Item = usize;
|
||||
type Iter = iter::Cloned<slice::Iter<'graph, usize>>;
|
||||
}
|
||||
|
||||
impl<'graph> GraphSuccessors<'graph> for TestGraph {
|
||||
type Item = usize;
|
||||
type Iter = iter::Cloned<slice::Iter<'graph, usize>>;
|
||||
}
|
||||
|
||||
59
src/librustc_data_structures/control_flow_graph/transpose.rs
Normal file
59
src/librustc_data_structures/control_flow_graph/transpose.rs
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use super::*;
|
||||
|
||||
pub struct TransposedGraph<G: ControlFlowGraph> {
|
||||
base_graph: G,
|
||||
start_node: G::Node,
|
||||
}
|
||||
|
||||
impl<G: ControlFlowGraph> TransposedGraph<G> {
|
||||
pub fn new(base_graph: G) -> Self {
|
||||
let start_node = base_graph.start_node();
|
||||
Self::with_start(base_graph, start_node)
|
||||
}
|
||||
|
||||
pub fn with_start(base_graph: G, start_node: G::Node) -> Self {
|
||||
TransposedGraph { base_graph: base_graph, start_node: start_node }
|
||||
}
|
||||
}
|
||||
|
||||
impl<G: ControlFlowGraph> ControlFlowGraph for TransposedGraph<G> {
|
||||
type Node = G::Node;
|
||||
|
||||
fn num_nodes(&self) -> usize {
|
||||
self.base_graph.num_nodes()
|
||||
}
|
||||
|
||||
fn start_node(&self) -> Self::Node {
|
||||
self.start_node
|
||||
}
|
||||
|
||||
fn predecessors<'graph>(&'graph self, node: Self::Node)
|
||||
-> <Self as GraphPredecessors<'graph>>::Iter {
|
||||
self.base_graph.successors(node)
|
||||
}
|
||||
|
||||
fn successors<'graph>(&'graph self, node: Self::Node)
|
||||
-> <Self as GraphSuccessors<'graph>>::Iter {
|
||||
self.base_graph.predecessors(node)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'graph, G: ControlFlowGraph> GraphPredecessors<'graph> for TransposedGraph<G> {
|
||||
type Item = G::Node;
|
||||
type Iter = <G as GraphSuccessors<'graph>>::Iter;
|
||||
}
|
||||
|
||||
impl<'graph, G: ControlFlowGraph> GraphSuccessors<'graph> for TransposedGraph<G> {
|
||||
type Item = G::Node;
|
||||
type Iter = <G as GraphPredecessors<'graph>>::Iter;
|
||||
}
|
||||
|
|
@ -8,6 +8,7 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use std::fmt::Debug;
|
||||
use std::iter::{self, FromIterator};
|
||||
use std::slice;
|
||||
use std::marker::PhantomData;
|
||||
|
|
@ -20,7 +21,7 @@ use rustc_serialize as serialize;
|
|||
/// Represents some newtyped `usize` wrapper.
|
||||
///
|
||||
/// (purpose: avoid mixing indexes for different bitvector domains.)
|
||||
pub trait Idx: Copy + 'static {
|
||||
pub trait Idx: Copy + 'static + Eq + Debug {
|
||||
fn new(usize) -> Self;
|
||||
fn index(self) -> usize;
|
||||
}
|
||||
|
|
@ -76,6 +77,13 @@ impl<I: Idx, T> IndexVec<I, T> {
|
|||
IndexVec { raw: vec![elem; universe.len()], _marker: PhantomData }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn from_elem_n(elem: T, n: usize) -> Self
|
||||
where T: Clone
|
||||
{
|
||||
IndexVec { raw: vec![elem; n], _marker: PhantomData }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn push(&mut self, d: T) -> I {
|
||||
let idx = I::new(self.len());
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ pub mod unify;
|
|||
pub mod fnv;
|
||||
pub mod tuple_slice;
|
||||
pub mod veccell;
|
||||
pub mod control_flow_graph;
|
||||
|
||||
// See comments in src/librustc/lib.rs
|
||||
#[doc(hidden)]
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ rustc = { path = "../librustc" }
|
|||
rustc_back = { path = "../librustc_back" }
|
||||
rustc_borrowck = { path = "../librustc_borrowck" }
|
||||
rustc_const_eval = { path = "../librustc_const_eval" }
|
||||
rustc_errors = { path = "../librustc_errors" }
|
||||
rustc_lint = { path = "../librustc_lint" }
|
||||
rustc_llvm = { path = "../librustc_llvm" }
|
||||
rustc_mir = { path = "../librustc_mir" }
|
||||
|
|
@ -32,3 +33,4 @@ rustc_metadata = { path = "../librustc_metadata" }
|
|||
serialize = { path = "../libserialize" }
|
||||
syntax = { path = "../libsyntax" }
|
||||
syntax_ext = { path = "../libsyntax_ext" }
|
||||
syntax_pos = { path = "../libsyntax_pos" }
|
||||
|
|
@ -763,6 +763,9 @@ pub fn phase_2_configure_and_expand<'a>(sess: &Session,
|
|||
}
|
||||
|
||||
pub fn assign_node_ids(sess: &Session, krate: ast::Crate) -> ast::Crate {
|
||||
use syntax::ptr::P;
|
||||
use syntax::util::move_map::MoveMap;
|
||||
|
||||
struct NodeIdAssigner<'a> {
|
||||
sess: &'a Session,
|
||||
}
|
||||
|
|
@ -772,6 +775,27 @@ pub fn assign_node_ids(sess: &Session, krate: ast::Crate) -> ast::Crate {
|
|||
assert_eq!(old_id, ast::DUMMY_NODE_ID);
|
||||
self.sess.next_node_id()
|
||||
}
|
||||
|
||||
fn fold_block(&mut self, block: P<ast::Block>) -> P<ast::Block> {
|
||||
block.map(|mut block| {
|
||||
block.id = self.new_id(block.id);
|
||||
|
||||
let stmt = block.stmts.pop();
|
||||
block.stmts = block.stmts.move_flat_map(|s| self.fold_stmt(s).into_iter());
|
||||
if let Some(ast::Stmt { node: ast::StmtKind::Expr(expr), span, .. }) = stmt {
|
||||
let expr = self.fold_expr(expr);
|
||||
block.stmts.push(ast::Stmt {
|
||||
id: expr.id,
|
||||
node: ast::StmtKind::Expr(expr),
|
||||
span: span,
|
||||
});
|
||||
} else if let Some(stmt) = stmt {
|
||||
block.stmts.extend(self.fold_stmt(stmt));
|
||||
}
|
||||
|
||||
block
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
let krate = time(sess.time_passes(),
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ extern crate rustc;
|
|||
extern crate rustc_back;
|
||||
extern crate rustc_borrowck;
|
||||
extern crate rustc_const_eval;
|
||||
extern crate rustc_errors as errors;
|
||||
extern crate rustc_passes;
|
||||
extern crate rustc_lint;
|
||||
extern crate rustc_plugin;
|
||||
|
|
@ -60,6 +61,7 @@ extern crate log;
|
|||
#[macro_use]
|
||||
extern crate syntax;
|
||||
extern crate syntax_ext;
|
||||
extern crate syntax_pos;
|
||||
|
||||
use driver::CompileController;
|
||||
use pretty::{PpMode, UserIdentifiedItem};
|
||||
|
|
@ -92,11 +94,12 @@ use std::thread;
|
|||
|
||||
use rustc::session::early_error;
|
||||
|
||||
use syntax::{ast, errors, diagnostics};
|
||||
use syntax::codemap::{CodeMap, FileLoader, RealFileLoader, MultiSpan};
|
||||
use syntax::errors::emitter::Emitter;
|
||||
use syntax::{ast, json};
|
||||
use syntax::codemap::{CodeMap, FileLoader, RealFileLoader};
|
||||
use syntax::feature_gate::{GatedCfg, UnstableFeatures};
|
||||
use syntax::parse::{self, PResult, token};
|
||||
use syntax_pos::MultiSpan;
|
||||
use errors::emitter::Emitter;
|
||||
|
||||
#[cfg(test)]
|
||||
pub mod test;
|
||||
|
|
@ -290,7 +293,7 @@ pub trait CompilerCalls<'a> {
|
|||
fn early_callback(&mut self,
|
||||
_: &getopts::Matches,
|
||||
_: &config::Options,
|
||||
_: &diagnostics::registry::Registry,
|
||||
_: &errors::registry::Registry,
|
||||
_: ErrorOutputType)
|
||||
-> Compilation {
|
||||
Compilation::Continue
|
||||
|
|
@ -329,7 +332,7 @@ pub trait CompilerCalls<'a> {
|
|||
_: &config::Options,
|
||||
_: &Option<PathBuf>,
|
||||
_: &Option<PathBuf>,
|
||||
_: &diagnostics::registry::Registry)
|
||||
_: &errors::registry::Registry)
|
||||
-> Option<(Input, Option<PathBuf>)> {
|
||||
None
|
||||
}
|
||||
|
|
@ -344,7 +347,7 @@ pub trait CompilerCalls<'a> {
|
|||
pub struct RustcDefaultCalls;
|
||||
|
||||
fn handle_explain(code: &str,
|
||||
descriptions: &diagnostics::registry::Registry,
|
||||
descriptions: &errors::registry::Registry,
|
||||
output: ErrorOutputType) {
|
||||
let normalised = if code.starts_with("E") {
|
||||
code.to_string()
|
||||
|
|
@ -374,7 +377,7 @@ fn check_cfg(sopts: &config::Options,
|
|||
config::ErrorOutputType::HumanReadable(color_config) => {
|
||||
Box::new(errors::emitter::BasicEmitter::stderr(color_config))
|
||||
}
|
||||
config::ErrorOutputType::Json => Box::new(errors::json::JsonEmitter::basic()),
|
||||
config::ErrorOutputType::Json => Box::new(json::JsonEmitter::basic()),
|
||||
};
|
||||
|
||||
let mut saw_invalid_predicate = false;
|
||||
|
|
@ -401,7 +404,7 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls {
|
|||
fn early_callback(&mut self,
|
||||
matches: &getopts::Matches,
|
||||
sopts: &config::Options,
|
||||
descriptions: &diagnostics::registry::Registry,
|
||||
descriptions: &errors::registry::Registry,
|
||||
output: ErrorOutputType)
|
||||
-> Compilation {
|
||||
if let Some(ref code) = matches.opt_str("explain") {
|
||||
|
|
@ -418,7 +421,7 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls {
|
|||
sopts: &config::Options,
|
||||
odir: &Option<PathBuf>,
|
||||
ofile: &Option<PathBuf>,
|
||||
descriptions: &diagnostics::registry::Registry)
|
||||
descriptions: &errors::registry::Registry)
|
||||
-> Option<(Input, Option<PathBuf>)> {
|
||||
match matches.free.len() {
|
||||
0 => {
|
||||
|
|
@ -1081,8 +1084,8 @@ fn exit_on_err() -> ! {
|
|||
panic!();
|
||||
}
|
||||
|
||||
pub fn diagnostics_registry() -> diagnostics::registry::Registry {
|
||||
use syntax::diagnostics::registry::Registry;
|
||||
pub fn diagnostics_registry() -> errors::registry::Registry {
|
||||
use errors::registry::Registry;
|
||||
|
||||
let mut all_errors = Vec::new();
|
||||
all_errors.extend_from_slice(&rustc::DIAGNOSTICS);
|
||||
|
|
|
|||
|
|
@ -31,12 +31,12 @@ use rustc_mir::pretty::write_mir_pretty;
|
|||
use rustc_mir::graphviz::write_mir_graphviz;
|
||||
|
||||
use syntax::ast::{self, BlockCheckMode};
|
||||
use syntax::codemap;
|
||||
use syntax::fold::{self, Folder};
|
||||
use syntax::print::{pp, pprust};
|
||||
use syntax::print::pprust::PrintState;
|
||||
use syntax::ptr::P;
|
||||
use syntax::util::small_vector::SmallVector;
|
||||
use syntax_pos;
|
||||
|
||||
use graphviz as dot;
|
||||
|
||||
|
|
@ -657,11 +657,14 @@ impl fold::Folder for ReplaceBodyWithLoop {
|
|||
fn fold_block(&mut self, b: P<ast::Block>) -> P<ast::Block> {
|
||||
fn expr_to_block(rules: ast::BlockCheckMode, e: Option<P<ast::Expr>>) -> P<ast::Block> {
|
||||
P(ast::Block {
|
||||
expr: e,
|
||||
stmts: vec![],
|
||||
stmts: e.map(|e| ast::Stmt {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
span: e.span,
|
||||
node: ast::StmtKind::Expr(e),
|
||||
}).into_iter().collect(),
|
||||
rules: rules,
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
span: codemap::DUMMY_SP,
|
||||
span: syntax_pos::DUMMY_SP,
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -671,8 +674,8 @@ impl fold::Folder for ReplaceBodyWithLoop {
|
|||
let loop_expr = P(ast::Expr {
|
||||
node: ast::ExprKind::Loop(empty_block, None),
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
span: codemap::DUMMY_SP,
|
||||
attrs: None,
|
||||
span: syntax_pos::DUMMY_SP,
|
||||
attrs: ast::ThinVec::new(),
|
||||
});
|
||||
|
||||
expr_to_block(b.rules, Some(loop_expr))
|
||||
|
|
|
|||
|
|
@ -31,12 +31,13 @@ use rustc::session::{self, config};
|
|||
use std::rc::Rc;
|
||||
use syntax::ast;
|
||||
use syntax::abi::Abi;
|
||||
use syntax::codemap::{CodeMap, DUMMY_SP};
|
||||
use syntax::errors;
|
||||
use syntax::errors::emitter::{CoreEmitter, Emitter};
|
||||
use syntax::errors::{Level, RenderSpan};
|
||||
use syntax::codemap::CodeMap;
|
||||
use errors;
|
||||
use errors::emitter::{CoreEmitter, Emitter};
|
||||
use errors::{Level, RenderSpan};
|
||||
use syntax::parse::token;
|
||||
use syntax::feature_gate::UnstableFeatures;
|
||||
use syntax_pos::DUMMY_SP;
|
||||
|
||||
use rustc::hir;
|
||||
|
||||
|
|
|
|||
14
src/librustc_errors/Cargo.toml
Normal file
14
src/librustc_errors/Cargo.toml
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
[package]
|
||||
authors = ["The Rust Project Developers"]
|
||||
name = "rustc_errors"
|
||||
version = "0.0.0"
|
||||
|
||||
[lib]
|
||||
name = "rustc_errors"
|
||||
path = "lib.rs"
|
||||
crate-type = ["dylib"]
|
||||
|
||||
[dependencies]
|
||||
log = { path = "../liblog" }
|
||||
serialize = { path = "../libserialize" }
|
||||
syntax_pos = { path = "../libsyntax_pos" }
|
||||
|
|
@ -10,14 +10,14 @@
|
|||
|
||||
use self::Destination::*;
|
||||
|
||||
use codemap::{self, COMMAND_LINE_SP, DUMMY_SP, Span, MultiSpan};
|
||||
use diagnostics;
|
||||
use syntax_pos::{COMMAND_LINE_SP, DUMMY_SP, Span, MultiSpan, LineInfo};
|
||||
use registry;
|
||||
|
||||
use errors::check_old_skool;
|
||||
use errors::{Level, RenderSpan, CodeSuggestion, DiagnosticBuilder};
|
||||
use errors::RenderSpan::*;
|
||||
use errors::Level::*;
|
||||
use errors::snippet::{RenderedLineKind, SnippetData, Style};
|
||||
use check_old_skool;
|
||||
use {Level, RenderSpan, CodeSuggestion, DiagnosticBuilder, CodeMapper};
|
||||
use RenderSpan::*;
|
||||
use Level::*;
|
||||
use snippet::{RenderedLineKind, SnippetData, Style, FormatMode};
|
||||
|
||||
use std::{cmp, fmt};
|
||||
use std::io::prelude::*;
|
||||
|
|
@ -151,15 +151,15 @@ impl BasicEmitter {
|
|||
|
||||
pub struct EmitterWriter {
|
||||
dst: Destination,
|
||||
registry: Option<diagnostics::registry::Registry>,
|
||||
cm: Rc<codemap::CodeMap>,
|
||||
registry: Option<registry::Registry>,
|
||||
cm: Rc<CodeMapper>,
|
||||
|
||||
/// Is this the first error emitted thus far? If not, we emit a
|
||||
/// `\n` before the top-level errors.
|
||||
first: bool,
|
||||
|
||||
// For now, allow an old-school mode while we transition
|
||||
old_school: bool,
|
||||
format_mode: FormatMode
|
||||
}
|
||||
|
||||
impl CoreEmitter for EmitterWriter {
|
||||
|
|
@ -193,36 +193,36 @@ macro_rules! println_maybe_styled {
|
|||
|
||||
impl EmitterWriter {
|
||||
pub fn stderr(color_config: ColorConfig,
|
||||
registry: Option<diagnostics::registry::Registry>,
|
||||
code_map: Rc<codemap::CodeMap>)
|
||||
registry: Option<registry::Registry>,
|
||||
code_map: Rc<CodeMapper>,
|
||||
format_mode: FormatMode)
|
||||
-> EmitterWriter {
|
||||
let old_school = check_old_skool();
|
||||
if color_config.use_color() {
|
||||
let dst = Destination::from_stderr();
|
||||
EmitterWriter { dst: dst,
|
||||
registry: registry,
|
||||
cm: code_map,
|
||||
first: true,
|
||||
old_school: old_school }
|
||||
format_mode: format_mode.clone() }
|
||||
} else {
|
||||
EmitterWriter { dst: Raw(Box::new(io::stderr())),
|
||||
registry: registry,
|
||||
cm: code_map,
|
||||
first: true,
|
||||
old_school: old_school }
|
||||
format_mode: format_mode.clone() }
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new(dst: Box<Write + Send>,
|
||||
registry: Option<diagnostics::registry::Registry>,
|
||||
code_map: Rc<codemap::CodeMap>)
|
||||
registry: Option<registry::Registry>,
|
||||
code_map: Rc<CodeMapper>,
|
||||
format_mode: FormatMode)
|
||||
-> EmitterWriter {
|
||||
let old_school = check_old_skool();
|
||||
EmitterWriter { dst: Raw(dst),
|
||||
registry: registry,
|
||||
cm: code_map,
|
||||
first: true,
|
||||
old_school: old_school }
|
||||
format_mode: format_mode.clone() }
|
||||
}
|
||||
|
||||
fn emit_message_(&mut self,
|
||||
|
|
@ -233,11 +233,17 @@ impl EmitterWriter {
|
|||
is_header: bool,
|
||||
show_snippet: bool)
|
||||
-> io::Result<()> {
|
||||
let old_school = match self.format_mode {
|
||||
FormatMode::NewErrorFormat => false,
|
||||
FormatMode::OriginalErrorFormat => true,
|
||||
FormatMode::EnvironmentSelected => check_old_skool()
|
||||
};
|
||||
|
||||
if is_header {
|
||||
if self.first {
|
||||
self.first = false;
|
||||
} else {
|
||||
if !self.old_school {
|
||||
if !old_school {
|
||||
write!(self.dst, "\n")?;
|
||||
}
|
||||
}
|
||||
|
|
@ -248,7 +254,7 @@ impl EmitterWriter {
|
|||
.and_then(|registry| registry.find_description(code))
|
||||
.is_some() => {
|
||||
let code_with_explain = String::from("--explain ") + code;
|
||||
if self.old_school {
|
||||
if old_school {
|
||||
let loc = match rsp.span().primary_span() {
|
||||
Some(COMMAND_LINE_SP) | Some(DUMMY_SP) => "".to_string(),
|
||||
Some(ps) => self.cm.span_to_string(ps),
|
||||
|
|
@ -261,7 +267,7 @@ impl EmitterWriter {
|
|||
}
|
||||
}
|
||||
_ => {
|
||||
if self.old_school {
|
||||
if old_school {
|
||||
let loc = match rsp.span().primary_span() {
|
||||
Some(COMMAND_LINE_SP) | Some(DUMMY_SP) => "".to_string(),
|
||||
Some(ps) => self.cm.span_to_string(ps),
|
||||
|
|
@ -303,7 +309,7 @@ impl EmitterWriter {
|
|||
}
|
||||
}
|
||||
}
|
||||
if self.old_school {
|
||||
if old_school {
|
||||
match code {
|
||||
Some(code) if self.registry.as_ref()
|
||||
.and_then(|registry| registry.find_description(code))
|
||||
|
|
@ -326,11 +332,13 @@ impl EmitterWriter {
|
|||
|
||||
fn highlight_suggestion(&mut self, suggestion: &CodeSuggestion) -> io::Result<()>
|
||||
{
|
||||
use std::borrow::Borrow;
|
||||
|
||||
let primary_span = suggestion.msp.primary_span().unwrap();
|
||||
let lines = self.cm.span_to_lines(primary_span).unwrap();
|
||||
assert!(!lines.lines.is_empty());
|
||||
|
||||
let complete = suggestion.splice_lines(&self.cm);
|
||||
let complete = suggestion.splice_lines(self.cm.borrow());
|
||||
let line_count = cmp::min(lines.lines.len(), MAX_HIGHLIGHT_LINES);
|
||||
let display_lines = &lines.lines[..line_count];
|
||||
|
||||
|
|
@ -356,19 +364,27 @@ impl EmitterWriter {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn highlight_lines(&mut self,
|
||||
pub fn highlight_lines(&mut self,
|
||||
msp: &MultiSpan,
|
||||
lvl: Level)
|
||||
-> io::Result<()>
|
||||
{
|
||||
let old_school = match self.format_mode {
|
||||
FormatMode::NewErrorFormat => false,
|
||||
FormatMode::OriginalErrorFormat => true,
|
||||
FormatMode::EnvironmentSelected => check_old_skool()
|
||||
};
|
||||
|
||||
let mut snippet_data = SnippetData::new(self.cm.clone(),
|
||||
msp.primary_span());
|
||||
if self.old_school {
|
||||
msp.primary_span(),
|
||||
self.format_mode.clone());
|
||||
if old_school {
|
||||
let mut output_vec = vec![];
|
||||
|
||||
for span_label in msp.span_labels() {
|
||||
let mut snippet_data = SnippetData::new(self.cm.clone(),
|
||||
Some(span_label.span));
|
||||
Some(span_label.span),
|
||||
self.format_mode.clone());
|
||||
|
||||
snippet_data.push(span_label.span,
|
||||
span_label.is_primary,
|
||||
|
|
@ -430,7 +446,7 @@ impl EmitterWriter {
|
|||
}
|
||||
}
|
||||
|
||||
fn line_num_max_digits(line: &codemap::LineInfo) -> usize {
|
||||
fn line_num_max_digits(line: &LineInfo) -> usize {
|
||||
let mut max_line_num = line.line_index + 1;
|
||||
let mut digits = 0;
|
||||
while max_line_num > 0 {
|
||||
|
|
@ -617,255 +633,3 @@ impl Write for Destination {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use errors::{Level, CodeSuggestion};
|
||||
use super::EmitterWriter;
|
||||
use codemap::{mk_sp, CodeMap, Span, MultiSpan, BytePos, NO_EXPANSION};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::io::{self, Write};
|
||||
use std::str::from_utf8;
|
||||
use std::rc::Rc;
|
||||
|
||||
struct Sink(Arc<Mutex<Vec<u8>>>);
|
||||
impl Write for Sink {
|
||||
fn write(&mut self, data: &[u8]) -> io::Result<usize> {
|
||||
Write::write(&mut *self.0.lock().unwrap(), data)
|
||||
}
|
||||
fn flush(&mut self) -> io::Result<()> { Ok(()) }
|
||||
}
|
||||
|
||||
/// Given a string like " ^~~~~~~~~~~~ ", produces a span
|
||||
/// coverting that range. The idea is that the string has the same
|
||||
/// length as the input, and we uncover the byte positions. Note
|
||||
/// that this can span lines and so on.
|
||||
fn span_from_selection(input: &str, selection: &str) -> Span {
|
||||
assert_eq!(input.len(), selection.len());
|
||||
let left_index = selection.find('~').unwrap() as u32;
|
||||
let right_index = selection.rfind('~').map(|x|x as u32).unwrap_or(left_index);
|
||||
Span { lo: BytePos(left_index), hi: BytePos(right_index + 1), expn_id: NO_EXPANSION }
|
||||
}
|
||||
|
||||
// Diagnostic doesn't align properly in span where line number increases by one digit
|
||||
#[test]
|
||||
fn test_hilight_suggestion_issue_11715() {
|
||||
let data = Arc::new(Mutex::new(Vec::new()));
|
||||
let cm = Rc::new(CodeMap::new());
|
||||
let mut ew = EmitterWriter::new(Box::new(Sink(data.clone())), None, cm.clone());
|
||||
let content = "abcdefg
|
||||
koksi
|
||||
line3
|
||||
line4
|
||||
cinq
|
||||
line6
|
||||
line7
|
||||
line8
|
||||
line9
|
||||
line10
|
||||
e-lä-vän
|
||||
tolv
|
||||
dreizehn
|
||||
";
|
||||
let file = cm.new_filemap_and_lines("dummy.txt", None, content);
|
||||
let start = file.lines.borrow()[10];
|
||||
let end = file.lines.borrow()[11];
|
||||
let sp = mk_sp(start, end);
|
||||
let lvl = Level::Error;
|
||||
println!("highlight_lines");
|
||||
ew.highlight_lines(&sp.into(), lvl).unwrap();
|
||||
println!("done");
|
||||
let vec = data.lock().unwrap().clone();
|
||||
let vec: &[u8] = &vec;
|
||||
let str = from_utf8(vec).unwrap();
|
||||
println!("r#\"\n{}\"#", str);
|
||||
assert_eq!(str, &r#"
|
||||
--> dummy.txt:11:1
|
||||
|>
|
||||
11 |> e-lä-vän
|
||||
|> ^
|
||||
"#[1..]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_single_span_splice() {
|
||||
// Test that a `MultiSpan` containing a single span splices a substition correctly
|
||||
let cm = CodeMap::new();
|
||||
let inputtext = "aaaaa\nbbbbBB\nCCC\nDDDDDddddd\neee\n";
|
||||
let selection = " \n ~~\n~~~\n~~~~~ \n \n";
|
||||
cm.new_filemap_and_lines("blork.rs", None, inputtext);
|
||||
let sp = span_from_selection(inputtext, selection);
|
||||
let msp: MultiSpan = sp.into();
|
||||
|
||||
// check that we are extracting the text we thought we were extracting
|
||||
assert_eq!(&cm.span_to_snippet(sp).unwrap(), "BB\nCCC\nDDDDD");
|
||||
|
||||
let substitute = "ZZZZZZ".to_owned();
|
||||
let expected = "bbbbZZZZZZddddd";
|
||||
let suggest = CodeSuggestion {
|
||||
msp: msp,
|
||||
substitutes: vec![substitute],
|
||||
};
|
||||
assert_eq!(suggest.splice_lines(&cm), expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_multi_span_splice() {
|
||||
// Test that a `MultiSpan` containing multiple spans splices a substition correctly
|
||||
let cm = CodeMap::new();
|
||||
let inputtext = "aaaaa\nbbbbBB\nCCC\nDDDDDddddd\neee\n";
|
||||
let selection1 = " \n \n \n \n ~ \n"; // intentionally out of order
|
||||
let selection2 = " \n ~~\n~~~\n~~~~~ \n \n";
|
||||
cm.new_filemap_and_lines("blork.rs", None, inputtext);
|
||||
let sp1 = span_from_selection(inputtext, selection1);
|
||||
let sp2 = span_from_selection(inputtext, selection2);
|
||||
let msp: MultiSpan = MultiSpan::from_spans(vec![sp1, sp2]);
|
||||
|
||||
let expected = "bbbbZZZZZZddddd\neXYZe";
|
||||
let suggest = CodeSuggestion {
|
||||
msp: msp,
|
||||
substitutes: vec!["ZZZZZZ".to_owned(),
|
||||
"XYZ".to_owned()]
|
||||
};
|
||||
|
||||
assert_eq!(suggest.splice_lines(&cm), expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_multispan_highlight() {
|
||||
let data = Arc::new(Mutex::new(Vec::new()));
|
||||
let cm = Rc::new(CodeMap::new());
|
||||
let mut diag = EmitterWriter::new(Box::new(Sink(data.clone())), None, cm.clone());
|
||||
|
||||
let inp = "_____aaaaaa____bbbbbb__cccccdd_";
|
||||
let sp1 = " ~~~~~~ ";
|
||||
let sp2 = " ~~~~~~ ";
|
||||
let sp3 = " ~~~~~ ";
|
||||
let sp4 = " ~~~~ ";
|
||||
let sp34 = " ~~~~~~~ ";
|
||||
|
||||
let expect_start = &r#"
|
||||
--> dummy.txt:1:6
|
||||
|>
|
||||
1 |> _____aaaaaa____bbbbbb__cccccdd_
|
||||
|> ^^^^^^ ^^^^^^ ^^^^^^^
|
||||
"#[1..];
|
||||
|
||||
let span = |sp, expected| {
|
||||
let sp = span_from_selection(inp, sp);
|
||||
assert_eq!(&cm.span_to_snippet(sp).unwrap(), expected);
|
||||
sp
|
||||
};
|
||||
cm.new_filemap_and_lines("dummy.txt", None, inp);
|
||||
let sp1 = span(sp1, "aaaaaa");
|
||||
let sp2 = span(sp2, "bbbbbb");
|
||||
let sp3 = span(sp3, "ccccc");
|
||||
let sp4 = span(sp4, "ccdd");
|
||||
let sp34 = span(sp34, "cccccdd");
|
||||
|
||||
let spans = vec![sp1, sp2, sp3, sp4];
|
||||
|
||||
let test = |expected, highlight: &mut FnMut()| {
|
||||
data.lock().unwrap().clear();
|
||||
highlight();
|
||||
let vec = data.lock().unwrap().clone();
|
||||
let actual = from_utf8(&vec[..]).unwrap();
|
||||
println!("actual=\n{}", actual);
|
||||
assert_eq!(actual, expected);
|
||||
};
|
||||
|
||||
let msp = MultiSpan::from_spans(vec![sp1, sp2, sp34]);
|
||||
test(expect_start, &mut || {
|
||||
diag.highlight_lines(&msp, Level::Error).unwrap();
|
||||
});
|
||||
test(expect_start, &mut || {
|
||||
let msp = MultiSpan::from_spans(spans.clone());
|
||||
diag.highlight_lines(&msp, Level::Error).unwrap();
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_huge_multispan_highlight() {
|
||||
let data = Arc::new(Mutex::new(Vec::new()));
|
||||
let cm = Rc::new(CodeMap::new());
|
||||
let mut diag = EmitterWriter::new(Box::new(Sink(data.clone())), None, cm.clone());
|
||||
|
||||
let inp = "aaaaa\n\
|
||||
aaaaa\n\
|
||||
aaaaa\n\
|
||||
bbbbb\n\
|
||||
ccccc\n\
|
||||
xxxxx\n\
|
||||
yyyyy\n\
|
||||
_____\n\
|
||||
ddd__eee_\n\
|
||||
elided\n\
|
||||
__f_gg";
|
||||
let file = cm.new_filemap_and_lines("dummy.txt", None, inp);
|
||||
|
||||
let span = |lo, hi, (off_lo, off_hi)| {
|
||||
let lines = file.lines.borrow();
|
||||
let (mut lo, mut hi): (BytePos, BytePos) = (lines[lo], lines[hi]);
|
||||
lo.0 += off_lo;
|
||||
hi.0 += off_hi;
|
||||
mk_sp(lo, hi)
|
||||
};
|
||||
let sp0 = span(4, 6, (0, 5));
|
||||
let sp1 = span(0, 6, (0, 5));
|
||||
let sp2 = span(8, 8, (0, 3));
|
||||
let sp3 = span(8, 8, (5, 8));
|
||||
let sp4 = span(10, 10, (2, 3));
|
||||
let sp5 = span(10, 10, (4, 6));
|
||||
|
||||
let expect0 = &r#"
|
||||
--> dummy.txt:5:1
|
||||
|>
|
||||
5 |> ccccc
|
||||
|> ^
|
||||
...
|
||||
9 |> ddd__eee_
|
||||
|> ^^^ ^^^
|
||||
10 |> elided
|
||||
11 |> __f_gg
|
||||
|> ^ ^^
|
||||
"#[1..];
|
||||
|
||||
let expect = &r#"
|
||||
--> dummy.txt:1:1
|
||||
|>
|
||||
1 |> aaaaa
|
||||
|> ^
|
||||
...
|
||||
9 |> ddd__eee_
|
||||
|> ^^^ ^^^
|
||||
10 |> elided
|
||||
11 |> __f_gg
|
||||
|> ^ ^^
|
||||
"#[1..];
|
||||
|
||||
macro_rules! test {
|
||||
($expected: expr, $highlight: expr) => ({
|
||||
data.lock().unwrap().clear();
|
||||
$highlight();
|
||||
let vec = data.lock().unwrap().clone();
|
||||
let actual = from_utf8(&vec[..]).unwrap();
|
||||
println!("actual:");
|
||||
println!("{}", actual);
|
||||
println!("expected:");
|
||||
println!("{}", $expected);
|
||||
assert_eq!(&actual[..], &$expected[..]);
|
||||
});
|
||||
}
|
||||
|
||||
let msp0 = MultiSpan::from_spans(vec![sp0, sp2, sp3, sp4, sp5]);
|
||||
let msp = MultiSpan::from_spans(vec![sp1, sp2, sp3, sp4, sp5]);
|
||||
|
||||
test!(expect0, || {
|
||||
diag.highlight_lines(&msp0, Level::Error).unwrap();
|
||||
});
|
||||
test!(expect, || {
|
||||
diag.highlight_lines(&msp, Level::Error).unwrap();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -8,24 +8,50 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
pub use errors::emitter::ColorConfig;
|
||||
#![crate_name = "rustc_errors"]
|
||||
#![unstable(feature = "rustc_private", issue = "27812")]
|
||||
#![crate_type = "dylib"]
|
||||
#![crate_type = "rlib"]
|
||||
#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
|
||||
html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
|
||||
html_root_url = "https://doc.rust-lang.org/nightly/")]
|
||||
#![cfg_attr(not(stage0), deny(warnings))]
|
||||
|
||||
#![feature(custom_attribute)]
|
||||
#![allow(unused_attributes)]
|
||||
#![feature(rustc_private)]
|
||||
#![feature(staged_api)]
|
||||
#![feature(question_mark)]
|
||||
#![feature(range_contains)]
|
||||
#![feature(libc)]
|
||||
#![feature(unicode)]
|
||||
|
||||
extern crate serialize;
|
||||
extern crate term;
|
||||
#[macro_use] extern crate log;
|
||||
#[macro_use] extern crate libc;
|
||||
extern crate rustc_unicode;
|
||||
extern crate serialize as rustc_serialize; // used by deriving
|
||||
extern crate syntax_pos;
|
||||
|
||||
pub use emitter::ColorConfig;
|
||||
|
||||
use self::Level::*;
|
||||
use self::RenderSpan::*;
|
||||
|
||||
use codemap::{self, CodeMap, MultiSpan, NO_EXPANSION, Span};
|
||||
use diagnostics;
|
||||
use errors::emitter::{Emitter, EmitterWriter};
|
||||
use emitter::{Emitter, EmitterWriter};
|
||||
|
||||
use std::cell::{RefCell, Cell};
|
||||
use std::{error, fmt};
|
||||
use std::rc::Rc;
|
||||
use std::thread::panicking;
|
||||
use term;
|
||||
|
||||
pub mod emitter;
|
||||
pub mod json;
|
||||
pub mod snippet;
|
||||
pub mod registry;
|
||||
|
||||
use syntax_pos::{BytePos, Loc, FileLinesResult, FileName, MultiSpan, Span, NO_EXPANSION };
|
||||
use syntax_pos::{MacroBacktrace};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum RenderSpan {
|
||||
|
|
@ -43,8 +69,16 @@ pub enum RenderSpan {
|
|||
|
||||
#[derive(Clone)]
|
||||
pub struct CodeSuggestion {
|
||||
msp: MultiSpan,
|
||||
substitutes: Vec<String>,
|
||||
pub msp: MultiSpan,
|
||||
pub substitutes: Vec<String>,
|
||||
}
|
||||
|
||||
pub trait CodeMapper {
|
||||
fn lookup_char_pos(&self, pos: BytePos) -> Loc;
|
||||
fn span_to_lines(&self, sp: Span) -> FileLinesResult;
|
||||
fn span_to_string(&self, sp: Span) -> String;
|
||||
fn span_to_filename(&self, sp: Span) -> FileName;
|
||||
fn macro_backtrace(&self, span: Span) -> Vec<MacroBacktrace>;
|
||||
}
|
||||
|
||||
impl RenderSpan {
|
||||
|
|
@ -59,8 +93,8 @@ impl RenderSpan {
|
|||
|
||||
impl CodeSuggestion {
|
||||
/// Returns the assembled code suggestion.
|
||||
pub fn splice_lines(&self, cm: &CodeMap) -> String {
|
||||
use codemap::{CharPos, Loc, Pos};
|
||||
pub fn splice_lines(&self, cm: &CodeMapper) -> String {
|
||||
use syntax_pos::{CharPos, Loc, Pos};
|
||||
|
||||
fn push_trailing(buf: &mut String, line_opt: Option<&str>,
|
||||
lo: &Loc, hi_opt: Option<&Loc>) {
|
||||
|
|
@ -181,20 +215,20 @@ impl error::Error for ExplicitBug {
|
|||
#[derive(Clone)]
|
||||
pub struct DiagnosticBuilder<'a> {
|
||||
handler: &'a Handler,
|
||||
level: Level,
|
||||
message: String,
|
||||
code: Option<String>,
|
||||
span: MultiSpan,
|
||||
children: Vec<SubDiagnostic>,
|
||||
pub level: Level,
|
||||
pub message: String,
|
||||
pub code: Option<String>,
|
||||
pub span: MultiSpan,
|
||||
pub children: Vec<SubDiagnostic>,
|
||||
}
|
||||
|
||||
/// For example a note attached to an error.
|
||||
#[derive(Clone)]
|
||||
struct SubDiagnostic {
|
||||
level: Level,
|
||||
message: String,
|
||||
span: MultiSpan,
|
||||
render_span: Option<RenderSpan>,
|
||||
pub struct SubDiagnostic {
|
||||
pub level: Level,
|
||||
pub message: String,
|
||||
pub span: MultiSpan,
|
||||
pub render_span: Option<RenderSpan>,
|
||||
}
|
||||
|
||||
impl<'a> DiagnosticBuilder<'a> {
|
||||
|
|
@ -386,12 +420,13 @@ pub struct Handler {
|
|||
|
||||
impl Handler {
|
||||
pub fn with_tty_emitter(color_config: ColorConfig,
|
||||
registry: Option<diagnostics::registry::Registry>,
|
||||
registry: Option<registry::Registry>,
|
||||
can_emit_warnings: bool,
|
||||
treat_err_as_bug: bool,
|
||||
cm: Rc<codemap::CodeMap>)
|
||||
cm: Rc<CodeMapper>)
|
||||
-> Handler {
|
||||
let emitter = Box::new(EmitterWriter::stderr(color_config, registry, cm));
|
||||
let emitter = Box::new(EmitterWriter::stderr(color_config, registry, cm,
|
||||
snippet::FormatMode::EnvironmentSelected));
|
||||
Handler::with_emitter(can_emit_warnings, treat_err_as_bug, emitter)
|
||||
}
|
||||
|
||||
|
|
@ -662,7 +697,7 @@ impl fmt::Display for Level {
|
|||
}
|
||||
|
||||
impl Level {
|
||||
fn color(self) -> term::color::Color {
|
||||
pub fn color(self) -> term::color::Color {
|
||||
match self {
|
||||
Bug | Fatal | PhaseFatal | Error => term::color::BRIGHT_RED,
|
||||
Warning => term::color::YELLOW,
|
||||
|
|
@ -672,7 +707,7 @@ impl Level {
|
|||
}
|
||||
}
|
||||
|
||||
fn to_str(self) -> &'static str {
|
||||
pub fn to_str(self) -> &'static str {
|
||||
match self {
|
||||
Bug => "error: internal compiler error",
|
||||
Fatal | PhaseFatal | Error => "error",
|
||||
|
|
@ -10,18 +10,25 @@
|
|||
|
||||
// Code for annotating snippets.
|
||||
|
||||
use codemap::{CharPos, CodeMap, FileMap, LineInfo, Span};
|
||||
use errors::check_old_skool;
|
||||
use syntax_pos::{Span, FileMap, CharPos, LineInfo};
|
||||
use check_old_skool;
|
||||
use CodeMapper;
|
||||
use std::cmp;
|
||||
use std::rc::Rc;
|
||||
use std::mem;
|
||||
|
||||
mod test;
|
||||
#[derive(Clone)]
|
||||
pub enum FormatMode {
|
||||
NewErrorFormat,
|
||||
OriginalErrorFormat,
|
||||
EnvironmentSelected
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct SnippetData {
|
||||
codemap: Rc<CodeMap>,
|
||||
codemap: Rc<CodeMapper>,
|
||||
files: Vec<FileInfo>,
|
||||
format_mode: FormatMode,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
|
|
@ -36,6 +43,10 @@ pub struct FileInfo {
|
|||
primary_span: Option<Span>,
|
||||
|
||||
lines: Vec<Line>,
|
||||
|
||||
/// The type of error format to render. We keep it here so that
|
||||
/// it's easy to configure for both tests and regular usage
|
||||
format_mode: FormatMode,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
|
|
@ -111,8 +122,9 @@ pub enum RenderedLineKind {
|
|||
}
|
||||
|
||||
impl SnippetData {
|
||||
pub fn new(codemap: Rc<CodeMap>,
|
||||
primary_span: Option<Span>) // (*)
|
||||
pub fn new(codemap: Rc<CodeMapper>,
|
||||
primary_span: Option<Span>,
|
||||
format_mode: FormatMode) // (*)
|
||||
-> Self {
|
||||
// (*) The primary span indicates the file that must appear
|
||||
// first, and which will have a line number etc in its
|
||||
|
|
@ -126,7 +138,8 @@ impl SnippetData {
|
|||
|
||||
let mut data = SnippetData {
|
||||
codemap: codemap.clone(),
|
||||
files: vec![]
|
||||
files: vec![],
|
||||
format_mode: format_mode.clone()
|
||||
};
|
||||
if let Some(primary_span) = primary_span {
|
||||
let lo = codemap.lookup_char_pos(primary_span.lo);
|
||||
|
|
@ -135,6 +148,7 @@ impl SnippetData {
|
|||
file: lo.file,
|
||||
primary_span: Some(primary_span),
|
||||
lines: vec![],
|
||||
format_mode: format_mode.clone(),
|
||||
});
|
||||
}
|
||||
data
|
||||
|
|
@ -167,6 +181,7 @@ impl SnippetData {
|
|||
file: file_map.clone(),
|
||||
lines: vec![],
|
||||
primary_span: None,
|
||||
format_mode: self.format_mode.clone()
|
||||
});
|
||||
self.files.last_mut().unwrap()
|
||||
}
|
||||
|
|
@ -178,7 +193,7 @@ impl SnippetData {
|
|||
self.files.iter()
|
||||
.flat_map(|f| f.render_file_lines(&self.codemap))
|
||||
.collect();
|
||||
prepend_prefixes(&mut rendered_lines);
|
||||
prepend_prefixes(&mut rendered_lines, &self.format_mode);
|
||||
trim_lines(&mut rendered_lines);
|
||||
rendered_lines
|
||||
}
|
||||
|
|
@ -454,8 +469,12 @@ impl FileInfo {
|
|||
return line_index - first_line_index;
|
||||
}
|
||||
|
||||
fn render_file_lines(&self, codemap: &Rc<CodeMap>) -> Vec<RenderedLine> {
|
||||
let old_school = check_old_skool();
|
||||
fn render_file_lines(&self, codemap: &Rc<CodeMapper>) -> Vec<RenderedLine> {
|
||||
let old_school = match self.format_mode {
|
||||
FormatMode::OriginalErrorFormat => true,
|
||||
FormatMode::NewErrorFormat => false,
|
||||
FormatMode::EnvironmentSelected => check_old_skool()
|
||||
};
|
||||
|
||||
// As a first step, we elide any instance of more than one
|
||||
// continuous unannotated line.
|
||||
|
|
@ -591,7 +610,12 @@ impl FileInfo {
|
|||
}
|
||||
|
||||
fn render_line(&self, line: &Line) -> Vec<RenderedLine> {
|
||||
let old_school = check_old_skool();
|
||||
let old_school = match self.format_mode {
|
||||
FormatMode::OriginalErrorFormat => true,
|
||||
FormatMode::NewErrorFormat => false,
|
||||
FormatMode::EnvironmentSelected => check_old_skool()
|
||||
};
|
||||
|
||||
let source_string = self.file.get_line(line.line_index)
|
||||
.unwrap_or("");
|
||||
let source_kind = RenderedLineKind::SourceText {
|
||||
|
|
@ -776,8 +800,12 @@ impl FileInfo {
|
|||
}
|
||||
}
|
||||
|
||||
fn prepend_prefixes(rendered_lines: &mut [RenderedLine]) {
|
||||
let old_school = check_old_skool();
|
||||
fn prepend_prefixes(rendered_lines: &mut [RenderedLine], format_mode: &FormatMode) {
|
||||
let old_school = match *format_mode {
|
||||
FormatMode::OriginalErrorFormat => true,
|
||||
FormatMode::NewErrorFormat => false,
|
||||
FormatMode::EnvironmentSelected => check_old_skool()
|
||||
};
|
||||
if old_school {
|
||||
return;
|
||||
}
|
||||
|
|
@ -16,3 +16,4 @@ rustc_data_structures = { path = "../librustc_data_structures" }
|
|||
serialize = { path = "../libserialize" }
|
||||
log = { path = "../liblog" }
|
||||
syntax = { path = "../libsyntax" }
|
||||
syntax_pos = { path = "../libsyntax_pos" }
|
||||
|
|
@ -57,8 +57,8 @@ use std::fs::File;
|
|||
use std::io::Write;
|
||||
use syntax::ast;
|
||||
use syntax::attr::AttrMetaMethods;
|
||||
use syntax::codemap::Span;
|
||||
use syntax::parse::token::InternedString;
|
||||
use syntax_pos::Span;
|
||||
|
||||
const IF_THIS_CHANGED: &'static str = "rustc_if_this_changed";
|
||||
const THEN_THIS_WOULD_NEED: &'static str = "rustc_then_this_would_need";
|
||||
|
|
|
|||
|
|
@ -114,8 +114,8 @@ mod svh_visitor {
|
|||
pub use self::SawStmtComponent::*;
|
||||
use self::SawAbiComponent::*;
|
||||
use syntax::ast::{self, Name, NodeId};
|
||||
use syntax::codemap::Span;
|
||||
use syntax::parse::token;
|
||||
use syntax_pos::Span;
|
||||
use rustc::ty::TyCtxt;
|
||||
use rustc::hir;
|
||||
use rustc::hir::*;
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ extern crate serialize as rustc_serialize;
|
|||
|
||||
#[macro_use] extern crate log;
|
||||
#[macro_use] extern crate syntax;
|
||||
extern crate syntax_pos;
|
||||
|
||||
mod assert_dep_graph;
|
||||
mod calculate_svh;
|
||||
|
|
|
|||
|
|
@ -15,3 +15,4 @@ rustc = { path = "../librustc" }
|
|||
rustc_back = { path = "../librustc_back" }
|
||||
rustc_const_eval = { path = "../librustc_const_eval" }
|
||||
syntax = { path = "../libsyntax" }
|
||||
syntax_pos = { path = "../libsyntax_pos" }
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ use lint::{LintPass, LateLintPass};
|
|||
|
||||
use syntax::ast;
|
||||
use syntax::attr::{self, AttrMetaMethods};
|
||||
use syntax::codemap::Span;
|
||||
use syntax_pos::Span;
|
||||
|
||||
use rustc::hir::{self, PatKind};
|
||||
use rustc::hir::intravisit::FnKind;
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue