Add an intital HIR and lowering step

This commit is contained in:
Nick Cameron 2015-07-31 00:04:06 -07:00
parent cfd76b364c
commit facdf2ebb1
160 changed files with 13917 additions and 4451 deletions

View File

@ -56,7 +56,7 @@ TARGET_CRATES := libc std flate arena term \
alloc_system
RUSTC_CRATES := rustc rustc_typeck 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_front rustc_platform_intrinsics
HOST_CRATES := syntax $(RUSTC_CRATES) rustdoc fmt_macros
TOOLS := compiletest rustdoc rustc rustbook error-index-generator
@ -71,23 +71,24 @@ DEPS_graphviz := std
DEPS_syntax := std term serialize log fmt_macros arena libc rustc_bitflags
DEPS_rustc_driver := arena flate getopts graphviz libc rustc rustc_back rustc_borrowck \
rustc_typeck rustc_resolve log syntax serialize rustc_llvm \
rustc_trans rustc_privacy rustc_lint
rustc_trans rustc_privacy rustc_lint rustc_front
DEPS_rustc_trans := arena flate getopts graphviz libc rustc rustc_back \
log syntax serialize rustc_llvm rustc_platform_intrinsics
DEPS_rustc_typeck := rustc syntax rustc_platform_intrinsics
DEPS_rustc_borrowck := rustc log graphviz syntax
DEPS_rustc_resolve := rustc log syntax
DEPS_rustc_privacy := rustc log syntax
log syntax serialize rustc_llvm rustc_front rustc_platform_intrinsics
DEPS_rustc_typeck := rustc syntax rustc_front rustc_platform_intrinsics
DEPS_rustc_borrowck := rustc rustc_front log graphviz syntax
DEPS_rustc_resolve := rustc rustc_front log syntax
DEPS_rustc_privacy := rustc rustc_front log syntax
DEPS_rustc_lint := rustc log syntax
DEPS_rustc := syntax flate arena serialize getopts rbml \
log graphviz rustc_llvm rustc_back rustc_data_structures
DEPS_rustc_llvm := native:rustllvm libc std rustc_bitflags
DEPS_rustc_platform_intrinsics := rustc rustc_llvm
DEPS_rustc_back := std syntax rustc_llvm flate log libc
DEPS_rustc_back := std syntax rustc_llvm rustc_front flate log libc
DEPS_rustc_front := std syntax log serialize
DEPS_rustc_data_structures := std log serialize
DEPS_rustdoc := rustc rustc_driver native:hoedown serialize getopts \
test rustc_lint
test rustc_lint rustc_front
DEPS_rustc_bitflags := core
DEPS_flate := std native:miniz
DEPS_arena := std

View File

@ -268,7 +268,7 @@ fn run_pretty_test(config: &Config, props: &TestProps, testfile: &Path) {
// FIXME (#9639): This needs to handle non-utf8 paths
let mut args = vec!("-".to_owned(),
"-Zunstable-options".to_owned(),
"--pretty".to_owned(),
"--unpretty".to_owned(),
pretty_type,
format!("--target={}", config.target),
"-L".to_owned(),

View File

@ -23,12 +23,13 @@
pub use self::Code::*;
use ast_map::{self, Node};
use front::map::{self, Node};
use syntax::abi;
use syntax::ast::{Block, FnDecl, NodeId};
use syntax::ast;
use rustc_front::hir::{Block, FnDecl};
use syntax::ast::{NodeId, Ident};
use rustc_front::hir as ast;
use syntax::codemap::Span;
use syntax::visit::FnKind;
use rustc_front::visit::FnKind;
/// An FnLikeNode is a Node that is like a fn, in that it has a decl
/// and a body (as well as a NodeId, a span, etc).
@ -40,7 +41,7 @@ use syntax::visit::FnKind;
///
/// To construct one, use the `Code::from_node` function.
#[derive(Copy, Clone)]
pub struct FnLikeNode<'a> { node: ast_map::Node<'a> }
pub struct FnLikeNode<'a> { node: map::Node<'a> }
/// MaybeFnLike wraps a method that indicates if an object
/// corresponds to some FnLikeNode.
@ -86,7 +87,7 @@ pub enum Code<'a> {
}
impl<'a> Code<'a> {
pub fn id(&self) -> ast::NodeId {
pub fn id(&self) -> NodeId {
match *self {
FnLikeCode(node) => node.id(),
BlockCode(block) => block.id,
@ -95,7 +96,7 @@ impl<'a> Code<'a> {
/// Attempts to construct a Code from presumed FnLike or Block node input.
pub fn from_node(node: Node) -> Option<Code> {
if let ast_map::NodeBlock(block) = node {
if let map::NodeBlock(block) = node {
Some(BlockCode(block))
} else {
FnLikeNode::from_node(node).map(|fn_like| FnLikeCode(fn_like))
@ -106,7 +107,7 @@ impl<'a> Code<'a> {
/// These are all the components one can extract from a fn item for
/// use when implementing FnLikeNode operations.
struct ItemFnParts<'a> {
ident: ast::Ident,
ident: Ident,
decl: &'a ast::FnDecl,
unsafety: ast::Unsafety,
constness: ast::Constness,
@ -114,7 +115,7 @@ struct ItemFnParts<'a> {
vis: ast::Visibility,
generics: &'a ast::Generics,
body: &'a Block,
id: ast::NodeId,
id: NodeId,
span: Span
}
@ -137,10 +138,10 @@ impl<'a> FnLikeNode<'a> {
/// Attempts to construct a FnLikeNode from presumed FnLike node input.
pub fn from_node(node: Node) -> Option<FnLikeNode> {
let fn_like = match node {
ast_map::NodeItem(item) => item.is_fn_like(),
ast_map::NodeTraitItem(tm) => tm.is_fn_like(),
ast_map::NodeImplItem(_) => true,
ast_map::NodeExpr(e) => e.is_fn_like(),
map::NodeItem(item) => item.is_fn_like(),
map::NodeTraitItem(tm) => tm.is_fn_like(),
map::NodeImplItem(_) => true,
map::NodeExpr(e) => e.is_fn_like(),
_ => false
};
if fn_like {
@ -202,7 +203,7 @@ impl<'a> FnLikeNode<'a> {
fn handle<A, I, M, C>(self, item_fn: I, method: M, closure: C) -> A where
I: FnOnce(ItemFnParts<'a>) -> A,
M: FnOnce(NodeId,
ast::Ident,
Ident,
&'a ast::MethodSig,
Option<ast::Visibility>,
&'a ast::Block,
@ -211,7 +212,7 @@ impl<'a> FnLikeNode<'a> {
C: FnOnce(ClosureParts<'a>) -> A,
{
match self.node {
ast_map::NodeItem(i) => match i.node {
map::NodeItem(i) => match i.node {
ast::ItemFn(ref decl, unsafety, constness, abi, ref generics, ref block) =>
item_fn(ItemFnParts {
id: i.id,
@ -227,13 +228,13 @@ impl<'a> FnLikeNode<'a> {
}),
_ => panic!("item FnLikeNode that is not fn-like"),
},
ast_map::NodeTraitItem(ti) => match ti.node {
map::NodeTraitItem(ti) => match ti.node {
ast::MethodTraitItem(ref sig, Some(ref body)) => {
method(ti.id, ti.ident, sig, None, body, ti.span)
}
_ => panic!("trait method FnLikeNode that is not fn-like"),
},
ast_map::NodeImplItem(ii) => {
map::NodeImplItem(ii) => {
match ii.node {
ast::MethodImplItem(ref sig, ref body) => {
method(ii.id, ii.ident, sig, Some(ii.vis), body, ii.span)
@ -243,7 +244,7 @@ impl<'a> FnLikeNode<'a> {
}
}
}
ast_map::NodeExpr(e) => match e.node {
map::NodeExpr(e) => match e.node {
ast::ExprClosure(_, ref decl, ref block) =>
closure(ClosureParts::new(&**decl, &**block, e.id, e.span)),
_ => panic!("expr FnLikeNode that is not fn-like"),

View File

@ -1,4 +1,4 @@
// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
@ -15,14 +15,17 @@ use self::MapEntry::*;
use metadata::inline::InlinedItem;
use metadata::inline::InlinedItem as II;
use middle::def_id::DefId;
use syntax::abi;
use syntax::ast::*;
use syntax::ast_util;
use syntax::codemap::{DUMMY_SP, Span, Spanned};
use syntax::fold::Folder;
use syntax::ast::{Name, NodeId, Ident, CRATE_NODE_ID, DUMMY_NODE_ID};
use syntax::codemap::{Span, Spanned};
use syntax::parse::token;
use syntax::print::pprust;
use syntax::visit::{self, Visitor};
use rustc_front::hir::*;
use rustc_front::fold::Folder;
use rustc_front::visit::{self, Visitor};
use rustc_front::util;
use rustc_front::print::pprust;
use arena::TypedArena;
use std::cell::RefCell;
@ -159,7 +162,7 @@ impl<'ast> Clone for MapEntry<'ast> {
}
#[derive(Debug)]
struct InlinedParent {
pub struct InlinedParent {
path: Vec<PathElem>,
ii: InlinedItem
}
@ -227,7 +230,7 @@ impl<'ast> MapEntry<'ast> {
/// Stores a crate and any number of inlined items from other crates.
pub struct Forest {
krate: Crate,
pub krate: Crate,
inlined_items: TypedArena<InlinedParent>
}
@ -246,9 +249,10 @@ impl Forest {
/// Represents a mapping from Node IDs to AST elements and their parent
/// Node IDs
#[derive(Clone)]
pub struct Map<'ast> {
/// The backing storage for all the AST nodes.
forest: &'ast Forest,
pub forest: &'ast Forest,
/// NodeIds are sequential integers from 0, so we can be
/// super-compact by storing them in a vector. Not everything with
@ -870,7 +874,7 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
}
fn visit_stmt(&mut self, stmt: &'ast Stmt) {
let id = ast_util::stmt_id(stmt);
let id = util::stmt_id(stmt);
self.insert(id, NodeStmt(stmt));
let parent_node = self.parent_node;
self.parent_node = id;
@ -917,20 +921,7 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
}
}
pub fn map_crate<'ast, F: FoldOps>(forest: &'ast mut Forest, fold_ops: F) -> Map<'ast> {
// Replace the crate with an empty one to take it out.
let krate = mem::replace(&mut forest.krate, Crate {
module: Mod {
inner: DUMMY_SP,
items: vec![],
},
attrs: vec![],
config: vec![],
exported_macros: vec![],
span: DUMMY_SP
});
forest.krate = IdAndSpanUpdater { fold_ops: fold_ops }.fold_crate(krate);
pub fn map_crate<'ast>(forest: &'ast mut Forest) -> Map<'ast> {
let mut collector = NodeCollector {
map: vec![],
parent_node: CRATE_NODE_ID,
@ -974,11 +965,11 @@ pub fn map_decoded_item<'ast, F: FoldOps>(map: &Map<'ast>,
II::Item(i) => II::Item(fld.fold_item(i).expect_one("expected one item")),
II::TraitItem(d, ti) => {
II::TraitItem(fld.fold_ops.new_def_id(d),
fld.fold_trait_item(ti).expect_one("expected one trait item"))
fld.fold_trait_item(ti).expect_one("expected one trait item"))
}
II::ImplItem(d, ii) => {
II::ImplItem(fld.fold_ops.new_def_id(d),
fld.fold_impl_item(ii).expect_one("expected one impl item"))
fld.fold_impl_item(ii).expect_one("expected one impl item"))
}
II::Foreign(i) => II::Foreign(fld.fold_foreign_item(i))
};
@ -1064,7 +1055,6 @@ fn node_id_to_string(map: &Map, id: NodeId, include_id: bool) -> String {
ItemTrait(..) => "trait",
ItemImpl(..) => "impl",
ItemDefaultImpl(..) => "default impl",
ItemMac(..) => "macro"
};
format!("{} {}{}", item_str, path_str, id_str)
}
@ -1091,10 +1081,6 @@ fn node_id_to_string(map: &Map, id: NodeId, include_id: bool) -> String {
map.path_to_string(id),
id_str)
}
MacImplItem(ref mac) => {
format!("method macro {}{}",
pprust::mac_to_string(mac), id_str)
}
}
}
Some(NodeTraitItem(ti)) => {

View File

@ -73,6 +73,7 @@ extern crate graphviz;
extern crate libc;
extern crate rustc_llvm;
extern crate rustc_back;
extern crate rustc_front;
extern crate rustc_data_structures;
extern crate serialize;
extern crate rbml;
@ -101,7 +102,9 @@ pub mod back {
pub use rustc_back::svh;
}
pub mod ast_map;
pub mod front {
pub mod map;
}
pub mod middle {
pub mod astconv_util;

View File

@ -283,6 +283,7 @@ macro_rules! run_lints { ($cx:expr, $f:ident, $($args:expr),*) => ({
/// Parse the lint attributes into a vector, with `Err`s for malformed lint
/// attributes. Writing this as an iterator is an enormous mess.
// See also the hir version just below.
pub fn gather_attrs(attrs: &[ast::Attribute])
-> Vec<Result<(InternedString, Level, Span), Span>> {
let mut out = vec!();
@ -312,6 +313,40 @@ pub fn gather_attrs(attrs: &[ast::Attribute])
}
out
}
// Copy-pasted from the above function :-(
pub fn gather_attrs_from_hir(attrs: &[::rustc_front::hir::Attribute])
-> Vec<Result<(InternedString, Level, Span), Span>> {
use ::rustc_front::attr::AttrMetaMethods;
let mut out = vec!();
for attr in attrs {
let level = match Level::from_str(&attr.name()) {
None => continue,
Some(lvl) => lvl,
};
::rustc_front::attr::mark_used(attr);
let meta = &attr.node.value;
let metas = match meta.node {
::rustc_front::hir::MetaList(_, ref metas) => metas,
_ => {
out.push(Err(meta.span));
continue;
}
};
for meta in metas {
out.push(match meta.node {
::rustc_front::hir::MetaWord(ref lint_name) => {
Ok((lint_name.clone(), level, meta.span))
}
_ => Err(meta.span),
});
}
}
out
}
/// Emit a lint as a warning or an error (or not at all)
/// according to `level`.
@ -696,9 +731,9 @@ impl LintPass for GatherNodeLevels {
///
/// Consumes the `lint_store` field of the `Session`.
pub fn check_crate(tcx: &ty::ctxt,
krate: &ast::Crate,
exported_items: &ExportedItems) {
let krate = tcx.map.krate();
let mut cx = Context::new(tcx, krate, exported_items);
// Visit the whole crate.

View File

@ -38,7 +38,7 @@ use syntax::visit::FnKind;
use syntax::ast;
pub use lint::context::{Context, LintStore, raw_emit_lint, check_crate, gather_attrs,
GatherNodeLevels};
gather_attrs_from_hir, GatherNodeLevels};
/// Specification of a single lint.
#[derive(Copy, Clone, Debug)]

View File

@ -21,6 +21,7 @@ use metadata::decoder;
use metadata::loader;
use metadata::loader::CratePaths;
use util::nodemap::FnvHashMap;
use front::map as hir_map;
use std::cell::{RefCell, Cell};
use std::path::PathBuf;
@ -29,20 +30,22 @@ use std::fs;
use syntax::ast;
use syntax::abi;
use syntax::attr;
use syntax::attr::AttrMetaMethods;
use syntax::codemap::{self, Span, mk_sp, Pos};
use syntax::parse;
use syntax::attr;
use syntax::parse::token::InternedString;
use syntax::visit;
use syntax::util::small_vector::SmallVector;
use ast_map;
use rustc_front::visit;
use rustc_front::hir;
use rustc_front::attr as attr_front;
use rustc_front::attr::AttrMetaMethods;
use rustc_front::lowering::unlower_attribute;
use log;
pub struct LocalCrateReader<'a, 'b:'a> {
sess: &'a Session,
creader: CrateReader<'a>,
ast_map: &'a ast_map::Map<'b>,
ast_map: &'a hir_map::Map<'b>,
}
pub struct CrateReader<'a> {
@ -52,7 +55,7 @@ pub struct CrateReader<'a> {
}
impl<'a, 'b, 'v> visit::Visitor<'v> for LocalCrateReader<'a, 'b> {
fn visit_item(&mut self, a: &ast::Item) {
fn visit_item(&mut self, a: &hir::Item) {
self.process_item(a);
visit::walk_item(self, a);
}
@ -77,6 +80,11 @@ fn should_link(i: &ast::Item) -> bool {
!attr::contains_name(&i.attrs, "no_link")
}
// Dup for the hir
fn should_link_hir(i: &hir::Item) -> bool {
!attr_front::contains_name(&i.attrs, "no_link")
}
struct CrateInfo {
ident: String,
name: String,
@ -188,6 +196,31 @@ impl<'a> CrateReader<'a> {
}
}
// Dup of the above, but for the hir
fn extract_crate_info_hir(&self, i: &hir::Item) -> Option<CrateInfo> {
match i.node {
hir::ItemExternCrate(ref path_opt) => {
debug!("resolving extern crate stmt. ident: {} path_opt: {:?}",
i.ident, path_opt);
let name = match *path_opt {
Some(name) => {
validate_crate_name(Some(self.sess), &name.as_str(),
Some(i.span));
name.to_string()
}
None => i.ident.to_string(),
};
Some(CrateInfo {
ident: i.ident.to_string(),
name: name,
id: i.id,
should_link: should_link_hir(i),
})
}
_ => None
}
}
fn existing_match(&self, name: &str, hash: Option<&Svh>, kind: PathKind)
-> Option<ast::CrateNum> {
let mut ret = None;
@ -295,7 +328,7 @@ impl<'a> CrateReader<'a> {
let attrs = decoder::get_crate_attributes(data);
for attr in &attrs {
if &attr.name()[..] == "staged_api" {
match attr.node.value.node { ast::MetaWord(_) => return true, _ => (/*pass*/) }
match attr.node.value.node { hir::MetaWord(_) => return true, _ => (/*pass*/) }
}
}
@ -425,11 +458,11 @@ impl<'a> CrateReader<'a> {
}
/// Read exported macros.
pub fn read_exported_macros(&mut self, krate: &ast::Item) -> Vec<ast::MacroDef> {
let ci = self.extract_crate_info(krate).unwrap();
let ekrate = self.read_extension_crate(krate.span, &ci);
pub fn read_exported_macros(&mut self, item: &ast::Item) -> Vec<ast::MacroDef> {
let ci = self.extract_crate_info(item).unwrap();
let ekrate = self.read_extension_crate(item.span, &ci);
let source_name = format!("<{} macros>", krate.ident);
let source_name = format!("<{} macros>", item.ident);
let mut macros = vec![];
decoder::each_exported_macro(ekrate.metadata.as_slice(),
&*self.sess.cstore.intr,
@ -449,10 +482,10 @@ impl<'a> CrateReader<'a> {
p.abort_if_errors();
macros.push(ast::MacroDef {
ident: name.ident(),
attrs: attrs,
attrs: attrs.iter().map(|a| unlower_attribute(a)).collect(),
id: ast::DUMMY_NODE_ID,
span: span,
imported_from: Some(krate.ident),
imported_from: Some(item.ident),
// overridden in plugin/load.rs
export: false,
use_locally: false,
@ -639,7 +672,7 @@ impl<'a> CrateReader<'a> {
}
impl<'a, 'b> LocalCrateReader<'a, 'b> {
pub fn new(sess: &'a Session, map: &'a ast_map::Map<'b>) -> LocalCrateReader<'a, 'b> {
pub fn new(sess: &'a Session, map: &'a hir_map::Map<'b>) -> LocalCrateReader<'a, 'b> {
LocalCrateReader {
sess: sess,
creader: CrateReader::new(sess),
@ -650,7 +683,7 @@ impl<'a, 'b> LocalCrateReader<'a, 'b> {
// Traverses an AST, reading all the information about use'd crates and
// extern libraries necessary for later resolving, typechecking, linking,
// etc.
pub fn read_crates(&mut self, krate: &ast::Crate) {
pub fn read_crates(&mut self, krate: &hir::Crate) {
self.process_crate(krate);
visit::walk_crate(self, krate);
self.creader.inject_allocator_crate();
@ -665,7 +698,7 @@ impl<'a, 'b> LocalCrateReader<'a, 'b> {
self.creader.register_statically_included_foreign_items();
}
fn process_crate(&self, c: &ast::Crate) {
fn process_crate(&self, c: &hir::Crate) {
for a in c.attrs.iter().filter(|m| m.name() == "link_args") {
match a.value_str() {
Some(ref linkarg) => self.sess.cstore.add_used_link_args(&linkarg),
@ -674,14 +707,14 @@ impl<'a, 'b> LocalCrateReader<'a, 'b> {
}
}
fn process_item(&mut self, i: &ast::Item) {
fn process_item(&mut self, i: &hir::Item) {
match i.node {
ast::ItemExternCrate(_) => {
if !should_link(i) {
hir::ItemExternCrate(_) => {
if !should_link_hir(i) {
return;
}
match self.creader.extract_crate_info(i) {
match self.creader.extract_crate_info_hir(i) {
Some(info) => {
let (cnum, cmeta, _) = self.creader.resolve_crate(&None,
&info.ident,
@ -698,12 +731,12 @@ impl<'a, 'b> LocalCrateReader<'a, 'b> {
None => ()
}
}
ast::ItemForeignMod(ref fm) => self.process_foreign_mod(i, fm),
hir::ItemForeignMod(ref fm) => self.process_foreign_mod(i, fm),
_ => { }
}
}
fn process_foreign_mod(&mut self, i: &ast::Item, fm: &ast::ForeignMod) {
fn process_foreign_mod(&mut self, i: &hir::Item, fm: &hir::ForeignMod) {
if fm.abi == abi::Rust || fm.abi == abi::RustIntrinsic || fm.abi == abi::PlatformIntrinsic {
return;
}

View File

@ -10,7 +10,7 @@
// Searching for information from the cstore
use ast_map;
use front::map as ast_map;
use metadata::common::*;
use metadata::cstore;
use metadata::decoder;
@ -23,7 +23,8 @@ use rbml;
use rbml::reader;
use std::rc::Rc;
use syntax::ast;
use syntax::attr;
use rustc_front::attr;
use rustc_front::hir;
use syntax::diagnostic::expect;
use std::collections::hash_map::HashMap;
@ -32,7 +33,7 @@ use std::collections::hash_map::HashMap;
pub struct MethodInfo {
pub name: ast::Name,
pub def_id: DefId,
pub vis: ast::Visibility,
pub vis: hir::Visibility,
}
pub fn get_symbol(cstore: &cstore::CStore, def: DefId) -> String {
@ -55,7 +56,7 @@ pub fn each_lang_item<F>(cstore: &cstore::CStore,
pub fn each_child_of_item<F>(cstore: &cstore::CStore,
def_id: DefId,
callback: F) where
F: FnMut(decoder::DefLike, ast::Name, ast::Visibility),
F: FnMut(decoder::DefLike, ast::Name, hir::Visibility),
{
let crate_data = cstore.get_crate_data(def_id.krate);
let get_crate_data = |cnum| {
@ -72,7 +73,7 @@ pub fn each_child_of_item<F>(cstore: &cstore::CStore,
pub fn each_top_level_item_of_crate<F>(cstore: &cstore::CStore,
cnum: ast::CrateNum,
callback: F) where
F: FnMut(decoder::DefLike, ast::Name, ast::Visibility),
F: FnMut(decoder::DefLike, ast::Name, hir::Visibility),
{
let crate_data = cstore.get_crate_data(cnum);
let get_crate_data = |cnum| {
@ -190,7 +191,7 @@ pub fn get_methods_if_impl(cstore: &cstore::CStore,
pub fn get_item_attrs(cstore: &cstore::CStore,
def_id: DefId)
-> Vec<ast::Attribute> {
-> Vec<hir::Attribute> {
let cdata = cstore.get_crate_data(def_id.krate);
decoder::get_item_attrs(&*cdata, def_id.node)
}
@ -201,7 +202,7 @@ pub fn get_struct_field_names(cstore: &cstore::CStore, def: DefId) -> Vec<ast::N
}
pub fn get_struct_field_attrs(cstore: &cstore::CStore, def: DefId) -> HashMap<ast::NodeId,
Vec<ast::Attribute>> {
Vec<hir::Attribute>> {
let cdata = cstore.get_crate_data(def.krate);
decoder::get_struct_field_attrs(&*cdata)
}
@ -269,7 +270,7 @@ pub fn get_field_type<'tcx>(tcx: &ty::ctxt<'tcx>, class_id: DefId,
pub fn get_impl_polarity<'tcx>(tcx: &ty::ctxt<'tcx>,
def: DefId)
-> Option<ast::ImplPolarity>
-> Option<hir::ImplPolarity>
{
let cstore = &tcx.sess.cstore;
let cdata = cstore.get_crate_data(def.krate);

View File

@ -27,12 +27,12 @@ use std::rc::Rc;
use std::path::PathBuf;
use flate::Bytes;
use syntax::ast;
use syntax::attr;
use rustc_front::attr;
use syntax::codemap;
use syntax::parse::token;
use syntax::parse::token::IdentInterner;
use syntax::util::small_vector::SmallVector;
use ast_map;
use front::map as ast_map;
// A map from external crate numbers (as decoded from some crate file) to
// local crate numbers (as generated during this session). Each external

View File

@ -15,7 +15,10 @@
pub use self::DefLike::*;
use self::Family::*;
use ast_map;
use front::map as ast_map;
use rustc_front::print::pprust;
use rustc_front::hir;
use back::svh::Svh;
use metadata::cstore::crate_metadata;
use metadata::common::*;
@ -45,15 +48,15 @@ use std::str;
use rbml::reader;
use rbml;
use serialize::Decodable;
use syntax::abi;
use syntax::attr;
use rustc_front::attr;
use syntax::parse::token::{IdentInterner, special_idents};
use syntax::parse::token;
use syntax::print::pprust;
use syntax::ast;
use syntax::abi;
use syntax::codemap;
use syntax::ptr::P;
pub type Cmd<'a> = &'a crate_metadata;
// A function that takes a def_id relative to the crate being searched and
@ -158,26 +161,26 @@ fn item_family(item: rbml::Doc) -> Family {
}
}
fn item_visibility(item: rbml::Doc) -> ast::Visibility {
fn item_visibility(item: rbml::Doc) -> hir::Visibility {
match reader::maybe_get_doc(item, tag_items_data_item_visibility) {
None => ast::Public,
None => hir::Public,
Some(visibility_doc) => {
match reader::doc_as_u8(visibility_doc) as char {
'y' => ast::Public,
'i' => ast::Inherited,
'y' => hir::Public,
'i' => hir::Inherited,
_ => panic!("unknown visibility character")
}
}
}
}
fn fn_constness(item: rbml::Doc) -> ast::Constness {
fn fn_constness(item: rbml::Doc) -> hir::Constness {
match reader::maybe_get_doc(item, tag_items_data_item_constness) {
None => ast::Constness::NotConst,
None => hir::Constness::NotConst,
Some(constness_doc) => {
match reader::doc_as_u8(constness_doc) as char {
'c' => ast::Constness::Const,
'n' => ast::Constness::NotConst,
'c' => hir::Constness::Const,
'n' => hir::Constness::NotConst,
_ => panic!("unknown constness character")
}
}
@ -343,12 +346,12 @@ fn item_to_def_like(cdata: Cmd, item: rbml::Doc, did: DefId) -> DefLike {
}
}
fn parse_unsafety(item_doc: rbml::Doc) -> ast::Unsafety {
fn parse_unsafety(item_doc: rbml::Doc) -> hir::Unsafety {
let unsafety_doc = reader::get_doc(item_doc, tag_unsafety);
if reader::doc_as_u8(unsafety_doc) != 0 {
ast::Unsafety::Unsafe
hir::Unsafety::Unsafe
} else {
ast::Unsafety::Normal
hir::Unsafety::Normal
}
}
@ -357,12 +360,12 @@ fn parse_paren_sugar(item_doc: rbml::Doc) -> bool {
reader::doc_as_u8(paren_sugar_doc) != 0
}
fn parse_polarity(item_doc: rbml::Doc) -> ast::ImplPolarity {
fn parse_polarity(item_doc: rbml::Doc) -> hir::ImplPolarity {
let polarity_doc = reader::get_doc(item_doc, tag_polarity);
if reader::doc_as_u8(polarity_doc) != 0 {
ast::ImplPolarity::Negative
hir::ImplPolarity::Negative
} else {
ast::ImplPolarity::Positive
hir::ImplPolarity::Positive
}
}
@ -560,7 +563,7 @@ pub fn get_repr_attrs(cdata: Cmd, id: ast::NodeId) -> Vec<attr::ReprAttr> {
pub fn get_impl_polarity<'tcx>(cdata: Cmd,
id: ast::NodeId)
-> Option<ast::ImplPolarity>
-> Option<hir::ImplPolarity>
{
let item_doc = lookup_item(id, cdata.data());
let fam = item_family(item_doc);
@ -633,7 +636,7 @@ fn each_child_of_item_or_crate<F, G>(intr: Rc<IdentInterner>,
item_doc: rbml::Doc,
mut get_crate_data: G,
mut callback: F) where
F: FnMut(DefLike, ast::Name, ast::Visibility),
F: FnMut(DefLike, ast::Name, hir::Visibility),
G: FnMut(ast::CrateNum) -> Rc<crate_metadata>,
{
// Iterate over all children.
@ -722,7 +725,7 @@ fn each_child_of_item_or_crate<F, G>(intr: Rc<IdentInterner>,
let def_like = item_to_def_like(crate_data, child_item_doc, child_def_id);
// These items have a public visibility because they're part of
// a public re-export.
callback(def_like, token::intern(name), ast::Public);
callback(def_like, token::intern(name), hir::Public);
}
}
}
@ -733,7 +736,7 @@ pub fn each_child_of_item<F, G>(intr: Rc<IdentInterner>,
id: ast::NodeId,
get_crate_data: G,
callback: F) where
F: FnMut(DefLike, ast::Name, ast::Visibility),
F: FnMut(DefLike, ast::Name, hir::Visibility),
G: FnMut(ast::CrateNum) -> Rc<crate_metadata>,
{
// Find the item.
@ -756,7 +759,7 @@ pub fn each_top_level_item_of_crate<F, G>(intr: Rc<IdentInterner>,
cdata: Cmd,
get_crate_data: G,
callback: F) where
F: FnMut(DefLike, ast::Name, ast::Visibility),
F: FnMut(DefLike, ast::Name, hir::Visibility),
G: FnMut(ast::CrateNum) -> Rc<crate_metadata>,
{
let root_doc = rbml::Doc::new(cdata.data());
@ -810,10 +813,10 @@ pub fn maybe_get_item_ast<'tcx>(cdata: Cmd, tcx: &ty::ctxt<'tcx>, id: ast::NodeI
}
fn get_explicit_self(item: rbml::Doc) -> ty::ExplicitSelfCategory {
fn get_mutability(ch: u8) -> ast::Mutability {
fn get_mutability(ch: u8) -> hir::Mutability {
match ch as char {
'i' => ast::MutImmutable,
'm' => ast::MutMutable,
'i' => hir::MutImmutable,
'm' => hir::MutMutable,
_ => panic!("unknown mutability character: `{}`", ch as char),
}
}
@ -1074,7 +1077,7 @@ pub fn get_tuple_struct_definition_if_ctor(cdata: Cmd,
pub fn get_item_attrs(cdata: Cmd,
orig_node_id: ast::NodeId)
-> Vec<ast::Attribute> {
-> Vec<hir::Attribute> {
// The attributes for a tuple struct are attached to the definition, not the ctor;
// we assume that someone passing in a tuple struct ctor is actually wanting to
// look at the definition
@ -1084,7 +1087,7 @@ pub fn get_item_attrs(cdata: Cmd,
get_attributes(item)
}
pub fn get_struct_field_attrs(cdata: Cmd) -> HashMap<ast::NodeId, Vec<ast::Attribute>> {
pub fn get_struct_field_attrs(cdata: Cmd) -> HashMap<ast::NodeId, Vec<hir::Attribute>> {
let data = rbml::Doc::new(cdata.data());
let fields = reader::get_doc(data, tag_struct_fields);
reader::tagged_docs(fields, tag_struct_field).map(|field| {
@ -1094,10 +1097,10 @@ pub fn get_struct_field_attrs(cdata: Cmd) -> HashMap<ast::NodeId, Vec<ast::Attri
}).collect()
}
fn struct_field_family_to_visibility(family: Family) -> ast::Visibility {
fn struct_field_family_to_visibility(family: Family) -> hir::Visibility {
match family {
PublicField => ast::Public,
InheritedField => ast::Inherited,
PublicField => hir::Public,
InheritedField => hir::Inherited,
_ => panic!()
}
}
@ -1113,7 +1116,7 @@ pub fn get_struct_field_names(intr: &IdentInterner, cdata: Cmd, id: ast::NodeId)
})).collect()
}
fn get_meta_items(md: rbml::Doc) -> Vec<P<ast::MetaItem>> {
fn get_meta_items(md: rbml::Doc) -> Vec<P<hir::MetaItem>> {
reader::tagged_docs(md, tag_meta_item_word).map(|meta_item_doc| {
let nd = reader::get_doc(meta_item_doc, tag_meta_item_name);
let n = token::intern_and_get_ident(nd.as_str_slice());
@ -1134,7 +1137,7 @@ fn get_meta_items(md: rbml::Doc) -> Vec<P<ast::MetaItem>> {
})).collect()
}
fn get_attributes(md: rbml::Doc) -> Vec<ast::Attribute> {
fn get_attributes(md: rbml::Doc) -> Vec<hir::Attribute> {
match reader::maybe_get_doc(md, tag_attributes) {
Some(attrs_d) => {
reader::tagged_docs(attrs_d, tag_attribute).map(|attr_doc| {
@ -1147,9 +1150,9 @@ fn get_attributes(md: rbml::Doc) -> Vec<ast::Attribute> {
assert_eq!(meta_items.len(), 1);
let meta_item = meta_items.into_iter().nth(0).unwrap();
codemap::Spanned {
node: ast::Attribute_ {
node: hir::Attribute_ {
id: attr::mk_attr_id(),
style: ast::AttrOuter,
style: hir::AttrOuter,
value: meta_item,
is_sugared_doc: is_sugared_doc,
},
@ -1173,7 +1176,7 @@ fn list_crate_attributes(md: rbml::Doc, hash: &Svh,
write!(out, "\n\n")
}
pub fn get_crate_attributes(data: &[u8]) -> Vec<ast::Attribute> {
pub fn get_crate_attributes(data: &[u8]) -> Vec<hir::Attribute> {
get_attributes(rbml::Doc::new(data))
}
@ -1371,7 +1374,7 @@ pub fn get_plugin_registrar_fn(data: &[u8]) -> Option<ast::NodeId> {
}
pub fn each_exported_macro<F>(data: &[u8], intr: &IdentInterner, mut f: F) where
F: FnMut(ast::Name, Vec<ast::Attribute>, String) -> bool,
F: FnMut(ast::Name, Vec<hir::Attribute>, String) -> bool,
{
let macros = reader::get_doc(rbml::Doc::new(data), tag_macro_defs);
for macro_doc in reader::tagged_docs(macros, tag_macro_def) {
@ -1453,8 +1456,8 @@ pub fn is_typedef(cdata: Cmd, id: ast::NodeId) -> bool {
pub fn is_const_fn(cdata: Cmd, id: ast::NodeId) -> bool {
let item_doc = lookup_item(id, cdata.data());
match fn_constness(item_doc) {
ast::Constness::Const => true,
ast::Constness::NotConst => false,
hir::Constness::Const => true,
hir::Constness::NotConst => false,
}
}

View File

@ -13,7 +13,6 @@
#![allow(unused_must_use)] // everything is just a MemWriter, can't fail
#![allow(non_camel_case_types)]
use ast_map::{self, LinkedPath, PathElem, PathElems};
use back::svh::Svh;
use session::config;
use metadata::common::*;
@ -35,17 +34,20 @@ use std::io::prelude::*;
use std::io::{Cursor, SeekFrom};
use std::rc::Rc;
use syntax::abi;
use syntax::ast::{self, NodeId};
use syntax::attr;
use syntax::attr::AttrMetaMethods;
use syntax::ast::{NodeId, Name, CRATE_NODE_ID, CrateNum};
use syntax::diagnostic::SpanHandler;
use syntax::parse::token::special_idents;
use syntax::print::pprust;
use syntax::visit::Visitor;
use syntax::visit;
use syntax;
use rbml::writer::Encoder;
use rustc_front::hir as ast;
use rustc_front::visit::Visitor;
use rustc_front::visit;
use rustc_front::attr;
use rustc_front::attr::AttrMetaMethods;
use front::map::{LinkedPath, PathElem, PathElems};
use front::map as ast_map;
pub type EncodeInlinedItem<'a> =
Box<FnMut(&EncodeContext, &mut Encoder, InlinedItemRef) + 'a>;
@ -72,11 +74,11 @@ pub struct EncodeContext<'a, 'tcx: 'a> {
pub reachable: &'a NodeSet,
}
fn encode_name(rbml_w: &mut Encoder, name: ast::Name) {
fn encode_name(rbml_w: &mut Encoder, name: Name) {
rbml_w.wr_tagged_str(tag_paths_data_name, &name.as_str());
}
fn encode_impl_type_basename(rbml_w: &mut Encoder, name: ast::Name) {
fn encode_impl_type_basename(rbml_w: &mut Encoder, name: Name) {
rbml_w.wr_tagged_str(tag_item_impl_type_basename, &name.as_str());
}
@ -130,7 +132,7 @@ fn encode_item_variances(rbml_w: &mut Encoder,
fn encode_bounds_and_type_for_item<'a, 'tcx>(rbml_w: &mut Encoder,
ecx: &EncodeContext<'a, 'tcx>,
id: ast::NodeId) {
id: NodeId) {
encode_bounds_and_type(rbml_w,
ecx,
&ecx.tcx.lookup_item_type(DefId::local(id)),
@ -343,7 +345,7 @@ fn encode_path<PI: Iterator<Item=PathElem>>(rbml_w: &mut Encoder, path: PI) {
fn encode_reexported_static_method(rbml_w: &mut Encoder,
exp: &def::Export,
method_def_id: DefId,
method_name: ast::Name) {
method_name: Name) {
debug!("(encode reexported static method) {}::{}",
exp.name, method_name);
rbml_w.start_tag(tag_items_data_item_reexport);
@ -500,7 +502,7 @@ fn encode_info_for_mod(ecx: &EncodeContext,
attrs: &[ast::Attribute],
id: NodeId,
path: PathElems,
name: ast::Name,
name: Name,
vis: ast::Visibility) {
rbml_w.start_tag(tag_items_data_item);
encode_def_id(rbml_w, DefId::local(id));
@ -655,7 +657,7 @@ fn encode_info_for_struct<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
fn encode_info_for_struct_ctor(ecx: &EncodeContext,
rbml_w: &mut Encoder,
name: ast::Name,
name: Name,
ctor_id: NodeId,
index: &mut Vec<entry<i64>>,
struct_id: NodeId) {
@ -1475,7 +1477,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
rbml_w.end_tag();
}
}
ast::ItemExternCrate(_) | ast::ItemUse(_) |ast::ItemMac(..) => {
ast::ItemExternCrate(_) | ast::ItemUse(_) => {
// these are encoded separately
}
}
@ -1588,14 +1590,14 @@ fn encode_info_for_items(ecx: &EncodeContext,
let mut index = Vec::new();
rbml_w.start_tag(tag_items_data);
index.push(entry {
val: ast::CRATE_NODE_ID as i64,
val: CRATE_NODE_ID as i64,
pos: rbml_w.mark_stable_position(),
});
encode_info_for_mod(ecx,
rbml_w,
&krate.module,
&[],
ast::CRATE_NODE_ID,
CRATE_NODE_ID,
[].iter().cloned().chain(LinkedPath::empty()),
syntax::parse::token::special_idents::invalid.name,
ast::Public);
@ -1727,7 +1729,7 @@ fn encode_defaulted(rbml_w: &mut Encoder, is_defaulted: bool) {
rbml_w.wr_tagged_u8(tag_defaulted_trait, byte);
}
fn encode_associated_type_names(rbml_w: &mut Encoder, names: &[ast::Name]) {
fn encode_associated_type_names(rbml_w: &mut Encoder, names: &[Name]) {
rbml_w.start_tag(tag_associated_type_names);
for &name in names {
rbml_w.wr_tagged_str(tag_associated_type_name, &name.as_str());
@ -1745,7 +1747,7 @@ fn encode_polarity(rbml_w: &mut Encoder, polarity: ast::ImplPolarity) {
fn encode_crate_deps(rbml_w: &mut Encoder, cstore: &cstore::CStore) {
fn get_ordered_deps(cstore: &cstore::CStore)
-> Vec<(ast::CrateNum, Rc<cstore::crate_metadata>)> {
-> Vec<(CrateNum, Rc<cstore::crate_metadata>)> {
// Pull the cnums and name,vers,hash out of cstore
let mut deps = Vec::new();
cstore.iter_crate_data(|cnum, val| {
@ -1856,7 +1858,7 @@ fn encode_macro_defs(rbml_w: &mut Encoder,
encode_attributes(rbml_w, &def.attrs);
rbml_w.wr_tagged_str(tag_macro_def_body,
&pprust::tts_to_string(&def.body));
&::syntax::print::pprust::tts_to_string(&def.body));
rbml_w.end_tag();
}

View File

@ -9,11 +9,11 @@
// except according to those terms.
use middle::def_id::DefId;
use syntax::ast;
use syntax::ast_util::{IdRange, IdRangeComputingVisitor,
IdVisitor, IdVisitingOperation};
use rustc_front::hir;
use rustc_front::util::IdVisitor;
use syntax::ast_util::{IdRange, IdRangeComputingVisitor, IdVisitingOperation};
use syntax::ptr::P;
use syntax::visit::Visitor;
use rustc_front::visit::Visitor;
use self::InlinedItem::*;
/// The data we save and restore about an inlined item or method. This is not
@ -21,18 +21,18 @@ use self::InlinedItem::*;
/// that we trans.
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub enum InlinedItem {
Item(P<ast::Item>),
TraitItem(DefId /* impl id */, P<ast::TraitItem>),
ImplItem(DefId /* impl id */, P<ast::ImplItem>),
Foreign(P<ast::ForeignItem>),
Item(P<hir::Item>),
TraitItem(DefId /* impl id */, P<hir::TraitItem>),
ImplItem(DefId /* impl id */, P<hir::ImplItem>),
Foreign(P<hir::ForeignItem>),
}
/// A borrowed version of `ast::InlinedItem`.
/// A borrowed version of `hir::InlinedItem`.
pub enum InlinedItemRef<'a> {
Item(&'a ast::Item),
TraitItem(DefId, &'a ast::TraitItem),
ImplItem(DefId, &'a ast::ImplItem),
Foreign(&'a ast::ForeignItem)
Item(&'a hir::Item),
TraitItem(DefId, &'a hir::TraitItem),
ImplItem(DefId, &'a hir::ImplItem),
Foreign(&'a hir::ForeignItem)
}
impl InlinedItem {
@ -62,4 +62,3 @@ impl InlinedItem {
visitor.result()
}
}

View File

@ -14,13 +14,14 @@ use session::Session;
use metadata::creader::CrateReader;
use std::collections::{HashSet, HashMap};
use syntax::ast;
use syntax::attr;
use syntax::codemap::Span;
use syntax::parse::token;
use syntax::ast;
use syntax::attr;
use syntax::visit;
use syntax::visit::Visitor;
use syntax::attr::AttrMetaMethods;
use rustc_front::attr::AttrMetaMethods as FrontAttrMetaMethods;
struct MacroLoader<'a> {
sess: &'a Session,

View File

@ -18,6 +18,8 @@
pub use self::DefIdSource::*;
use rustc_front::hir;
use middle::def_id::DefId;
use middle::region;
use middle::subst;
@ -467,10 +469,10 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> {
}
}
fn parse_mutability(&mut self) -> ast::Mutability {
fn parse_mutability(&mut self) -> hir::Mutability {
match self.peek() {
'm' => { self.next(); ast::MutMutable }
_ => { ast::MutImmutable }
'm' => { self.next(); hir::MutMutable }
_ => { hir::MutImmutable }
}
}
@ -742,10 +744,10 @@ fn parse_defid(buf: &[u8]) -> DefId {
DefId { krate: crate_num, node: def_num }
}
fn parse_unsafety(c: char) -> ast::Unsafety {
fn parse_unsafety(c: char) -> hir::Unsafety {
match c {
'u' => ast::Unsafety::Unsafe,
'n' => ast::Unsafety::Normal,
'u' => hir::Unsafety::Unsafe,
'n' => hir::Unsafety::Normal,
_ => panic!("parse_unsafety: bad unsafety {}", c)
}
}

View File

@ -24,8 +24,9 @@ use middle::ty::ParamTy;
use middle::ty::{self, Ty};
use util::nodemap::FnvHashMap;
use rustc_front::hir;
use syntax::abi::Abi;
use syntax::ast;
use syntax::diagnostic::SpanHandler;
use rbml::writer::Encoder;
@ -64,26 +65,26 @@ pub fn enc_ty<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>, t: Ty<'tcx>) {
ty::TyChar => mywrite!(w, "c"),
ty::TyInt(t) => {
match t {
ast::TyIs => mywrite!(w, "is"),
ast::TyI8 => mywrite!(w, "MB"),
ast::TyI16 => mywrite!(w, "MW"),
ast::TyI32 => mywrite!(w, "ML"),
ast::TyI64 => mywrite!(w, "MD")
hir::TyIs => mywrite!(w, "is"),
hir::TyI8 => mywrite!(w, "MB"),
hir::TyI16 => mywrite!(w, "MW"),
hir::TyI32 => mywrite!(w, "ML"),
hir::TyI64 => mywrite!(w, "MD")
}
}
ty::TyUint(t) => {
match t {
ast::TyUs => mywrite!(w, "us"),
ast::TyU8 => mywrite!(w, "Mb"),
ast::TyU16 => mywrite!(w, "Mw"),
ast::TyU32 => mywrite!(w, "Ml"),
ast::TyU64 => mywrite!(w, "Md")
hir::TyUs => mywrite!(w, "us"),
hir::TyU8 => mywrite!(w, "Mb"),
hir::TyU16 => mywrite!(w, "Mw"),
hir::TyU32 => mywrite!(w, "Ml"),
hir::TyU64 => mywrite!(w, "Md")
}
}
ty::TyFloat(t) => {
match t {
ast::TyF32 => mywrite!(w, "Mf"),
ast::TyF64 => mywrite!(w, "MF"),
hir::TyF32 => mywrite!(w, "Mf"),
hir::TyF64 => mywrite!(w, "MF"),
}
}
ty::TyEnum(def, substs) => {
@ -179,10 +180,10 @@ pub fn enc_ty<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>, t: Ty<'tcx>) {
}
}
fn enc_mutability(w: &mut Encoder, mt: ast::Mutability) {
fn enc_mutability(w: &mut Encoder, mt: hir::Mutability) {
match mt {
ast::MutImmutable => (),
ast::MutMutable => mywrite!(w, "m"),
hir::MutImmutable => (),
hir::MutMutable => mywrite!(w, "m"),
}
}
@ -314,10 +315,10 @@ pub fn enc_trait_ref<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>,
enc_substs(w, cx, s.substs);
}
fn enc_unsafety(w: &mut Encoder, p: ast::Unsafety) {
fn enc_unsafety(w: &mut Encoder, p: hir::Unsafety) {
match p {
ast::Unsafety::Normal => mywrite!(w, "n"),
ast::Unsafety::Unsafe => mywrite!(w, "u"),
hir::Unsafety::Normal => mywrite!(w, "n"),
hir::Unsafety::Unsafe => mywrite!(w, "u"),
}
}

View File

@ -16,7 +16,7 @@
use middle::def;
use middle::ty::{self, Ty};
use syntax::ast;
use rustc_front::hir as ast;
pub const NO_REGIONS: usize = 1;
pub const NO_TPS: usize = 2;

View File

@ -12,7 +12,11 @@
// FIXME: remove this after snapshot, and Results are handled
#![allow(unused_must_use)]
use ast_map;
use front::map as ast_map;
use rustc_front::hir;
use rustc_front::fold;
use rustc_front::fold::Folder;
use metadata::common as c;
use metadata::cstore as cstore;
use session::Session;
@ -33,11 +37,9 @@ use middle::subst;
use middle::subst::VecPerParamSpace;
use middle::ty::{self, Ty};
use syntax::{ast, ast_util, codemap, fold};
use syntax::{ast, ast_util, codemap};
use syntax::codemap::Span;
use syntax::fold::Folder;
use syntax::ptr::P;
use syntax;
use std::cell::Cell;
use std::io::SeekFrom;
@ -53,7 +55,8 @@ use serialize::EncoderHelpers;
#[cfg(test)] use std::io::Cursor;
#[cfg(test)] use syntax::parse;
#[cfg(test)] use syntax::print::pprust;
#[cfg(test)] use rustc_front::print::pprust;
#[cfg(test)] use rustc_front::lowering::lower_item;
struct DecodeContext<'a, 'b, 'tcx: 'a> {
tcx: &'a ty::ctxt<'tcx>,
@ -166,7 +169,7 @@ pub fn decode_inlined_item<'tcx>(cdata: &cstore::crate_metadata,
match *ii {
InlinedItem::Item(ref i) => {
debug!(">>> DECODED ITEM >>>\n{}\n<<< DECODED ITEM <<<",
syntax::print::pprust::item_to_string(&**i));
::rustc_front::print::pprust::item_to_string(&**i));
}
_ => { }
}
@ -360,18 +363,17 @@ fn encode_ast(rbml_w: &mut Encoder, item: &InlinedItem) {
struct NestedItemsDropper;
impl Folder for NestedItemsDropper {
fn fold_block(&mut self, blk: P<ast::Block>) -> P<ast::Block> {
blk.and_then(|ast::Block {id, stmts, expr, rules, span, ..}| {
fn fold_block(&mut self, blk: P<hir::Block>) -> P<hir::Block> {
blk.and_then(|hir::Block {id, stmts, expr, rules, span, ..}| {
let stmts_sans_items = stmts.into_iter().filter_map(|stmt| {
let use_stmt = match stmt.node {
ast::StmtExpr(_, _) | ast::StmtSemi(_, _) => true,
ast::StmtDecl(ref decl, _) => {
hir::StmtExpr(_, _) | hir::StmtSemi(_, _) => true,
hir::StmtDecl(ref decl, _) => {
match decl.node {
ast::DeclLocal(_) => true,
ast::DeclItem(_) => false,
hir::DeclLocal(_) => true,
hir::DeclItem(_) => false,
}
}
ast::StmtMac(..) => panic!("unexpanded macro in astencode")
};
if use_stmt {
Some(stmt)
@ -379,7 +381,7 @@ impl Folder for NestedItemsDropper {
None
}
}).collect();
let blk_sans_items = P(ast::Block {
let blk_sans_items = P(hir::Block {
stmts: stmts_sans_items,
expr: expr,
id: id,
@ -488,7 +490,7 @@ fn encode_freevar_entry(rbml_w: &mut Encoder, fv: &ty::Freevar) {
trait rbml_decoder_helper {
fn read_freevar_entry(&mut self, dcx: &DecodeContext)
-> ty::Freevar;
fn read_capture_mode(&mut self) -> ast::CaptureClause;
fn read_capture_mode(&mut self) -> hir::CaptureClause;
}
impl<'a> rbml_decoder_helper for reader::Decoder<'a> {
@ -498,8 +500,8 @@ impl<'a> rbml_decoder_helper for reader::Decoder<'a> {
fv.tr(dcx)
}
fn read_capture_mode(&mut self) -> ast::CaptureClause {
let cm: ast::CaptureClause = Decodable::decode(self).unwrap();
fn read_capture_mode(&mut self) -> hir::CaptureClause {
let cm: hir::CaptureClause = Decodable::decode(self).unwrap();
cm
}
}
@ -1304,7 +1306,7 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> {
this.read_enum_variant_arg(0, |this| {
Ok(this.read_region(dcx))
}).unwrap();
let m: ast::Mutability =
let m: hir::Mutability =
this.read_enum_variant_arg(1, |this| {
Decodable::decode(this)
}).unwrap();
@ -1312,7 +1314,7 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> {
ty::AutoPtr(dcx.tcx.mk_region(r), m)
}
1 => {
let m: ast::Mutability =
let m: hir::Mutability =
this.read_enum_variant_arg(0, |this| Decodable::decode(this)).unwrap();
ty::AutoUnsafe(m)
@ -1506,14 +1508,14 @@ fn decode_side_tables(dcx: &DecodeContext,
// Testing of astencode_gen
#[cfg(test)]
fn encode_item_ast(rbml_w: &mut Encoder, item: &ast::Item) {
fn encode_item_ast(rbml_w: &mut Encoder, item: &hir::Item) {
rbml_w.start_tag(c::tag_tree as usize);
(*item).encode(rbml_w);
rbml_w.end_tag();
}
#[cfg(test)]
fn decode_item_ast(par_doc: rbml::Doc) -> ast::Item {
fn decode_item_ast(par_doc: rbml::Doc) -> hir::Item {
let chi_doc = par_doc.get(c::tag_tree as usize);
let mut d = reader::Decoder::new(chi_doc);
Decodable::decode(&mut d).unwrap()
@ -1553,8 +1555,7 @@ fn mk_ctxt() -> parse::ParseSess {
}
#[cfg(test)]
fn roundtrip(in_item: Option<P<ast::Item>>) {
let in_item = in_item.unwrap();
fn roundtrip(in_item: P<hir::Item>) {
let mut wr = Cursor::new(Vec::new());
encode_item_ast(&mut Encoder::new(&mut wr), &*in_item);
let rbml_doc = rbml::Doc::new(wr.get_ref());
@ -1566,28 +1567,28 @@ fn roundtrip(in_item: Option<P<ast::Item>>) {
#[test]
fn test_basic() {
let cx = mk_ctxt();
roundtrip(quote_item!(&cx,
roundtrip(lower_item(&quote_item!(&cx,
fn foo() {}
));
).unwrap()));
}
#[test]
fn test_smalltalk() {
let cx = mk_ctxt();
roundtrip(quote_item!(&cx,
roundtrip(lower_item(&quote_item!(&cx,
fn foo() -> isize { 3 + 4 } // first smalltalk program ever executed.
));
).unwrap()));
}
#[test]
fn test_more() {
let cx = mk_ctxt();
roundtrip(quote_item!(&cx,
roundtrip(lower_item(&quote_item!(&cx,
fn foo(x: usize, y: usize) -> usize {
let z = x + y;
return z;
}
));
).unwrap()));
}
#[test]
@ -1599,13 +1600,14 @@ fn test_simplification() {
return alist {eq_fn: eq_int, data: Vec::new()};
}
).unwrap();
let item_in = InlinedItemRef::Item(&*item);
let hir_item = lower_item(&item);
let item_in = InlinedItemRef::Item(&hir_item);
let item_out = simplify_ast(item_in);
let item_exp = InlinedItem::Item(quote_item!(&cx,
let item_exp = InlinedItem::Item(lower_item(&quote_item!(&cx,
fn new_int_alist<B>() -> alist<isize, B> {
return alist {eq_fn: eq_int, data: Vec::new()};
}
).unwrap());
).unwrap()));
match (item_out, item_exp) {
(InlinedItem::Item(item_out), InlinedItem::Item(item_exp)) => {
assert!(pprust::item_to_string(&*item_out) ==

View File

@ -13,7 +13,7 @@
use middle::ty::{self, Ty};
use syntax::ast;
use rustc_front::hir as ast;
/// Types that are represented as ints.
#[derive(Copy, Clone, Debug, PartialEq, Eq)]

View File

@ -14,9 +14,10 @@ use middle::def;
use middle::pat_util;
use middle::ty;
use syntax::ast;
use syntax::ast_util;
use syntax::ptr::P;
use rustc_front::hir;
struct CFGBuilder<'a, 'tcx: 'a> {
tcx: &'a ty::ctxt<'tcx>,
graph: CFGGraph,
@ -32,7 +33,7 @@ struct LoopScope {
}
pub fn construct(tcx: &ty::ctxt,
blk: &ast::Block) -> CFG {
blk: &hir::Block) -> CFG {
let mut graph = graph::Graph::new();
let entry = graph.add_node(CFGNodeData::Entry);
@ -58,7 +59,7 @@ pub fn construct(tcx: &ty::ctxt,
}
impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
fn block(&mut self, blk: &ast::Block, pred: CFGIndex) -> CFGIndex {
fn block(&mut self, blk: &hir::Block, pred: CFGIndex) -> CFGIndex {
let mut stmts_exit = pred;
for stmt in &blk.stmts {
stmts_exit = self.stmt(&**stmt, stmts_exit);
@ -69,95 +70,87 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
self.add_ast_node(blk.id, &[expr_exit])
}
fn stmt(&mut self, stmt: &ast::Stmt, pred: CFGIndex) -> CFGIndex {
fn stmt(&mut self, stmt: &hir::Stmt, pred: CFGIndex) -> CFGIndex {
match stmt.node {
ast::StmtDecl(ref decl, id) => {
hir::StmtDecl(ref decl, id) => {
let exit = self.decl(&**decl, pred);
self.add_ast_node(id, &[exit])
}
ast::StmtExpr(ref expr, id) | ast::StmtSemi(ref expr, id) => {
hir::StmtExpr(ref expr, id) | hir::StmtSemi(ref expr, id) => {
let exit = self.expr(&**expr, pred);
self.add_ast_node(id, &[exit])
}
ast::StmtMac(..) => {
self.tcx.sess.span_bug(stmt.span, "unexpanded macro");
}
}
}
fn decl(&mut self, decl: &ast::Decl, pred: CFGIndex) -> CFGIndex {
fn decl(&mut self, decl: &hir::Decl, pred: CFGIndex) -> CFGIndex {
match decl.node {
ast::DeclLocal(ref local) => {
hir::DeclLocal(ref local) => {
let init_exit = self.opt_expr(&local.init, pred);
self.pat(&*local.pat, init_exit)
}
ast::DeclItem(_) => {
hir::DeclItem(_) => {
pred
}
}
}
fn pat(&mut self, pat: &ast::Pat, pred: CFGIndex) -> CFGIndex {
fn pat(&mut self, pat: &hir::Pat, pred: CFGIndex) -> CFGIndex {
match pat.node {
ast::PatIdent(_, _, None) |
ast::PatEnum(_, None) |
ast::PatQPath(..) |
ast::PatLit(..) |
ast::PatRange(..) |
ast::PatWild(_) => {
hir::PatIdent(_, _, None) |
hir::PatEnum(_, None) |
hir::PatQPath(..) |
hir::PatLit(..) |
hir::PatRange(..) |
hir::PatWild(_) => {
self.add_ast_node(pat.id, &[pred])
}
ast::PatBox(ref subpat) |
ast::PatRegion(ref subpat, _) |
ast::PatIdent(_, _, Some(ref subpat)) => {
hir::PatBox(ref subpat) |
hir::PatRegion(ref subpat, _) |
hir::PatIdent(_, _, Some(ref subpat)) => {
let subpat_exit = self.pat(&**subpat, pred);
self.add_ast_node(pat.id, &[subpat_exit])
}
ast::PatEnum(_, Some(ref subpats)) |
ast::PatTup(ref subpats) => {
hir::PatEnum(_, Some(ref subpats)) |
hir::PatTup(ref subpats) => {
let pats_exit = self.pats_all(subpats.iter(), pred);
self.add_ast_node(pat.id, &[pats_exit])
}
ast::PatStruct(_, ref subpats, _) => {
hir::PatStruct(_, ref subpats, _) => {
let pats_exit =
self.pats_all(subpats.iter().map(|f| &f.node.pat), pred);
self.add_ast_node(pat.id, &[pats_exit])
}
ast::PatVec(ref pre, ref vec, ref post) => {
hir::PatVec(ref pre, ref vec, ref post) => {
let pre_exit = self.pats_all(pre.iter(), pred);
let vec_exit = self.pats_all(vec.iter(), pre_exit);
let post_exit = self.pats_all(post.iter(), vec_exit);
self.add_ast_node(pat.id, &[post_exit])
}
ast::PatMac(_) => {
self.tcx.sess.span_bug(pat.span, "unexpanded macro");
}
}
}
fn pats_all<'b, I: Iterator<Item=&'b P<ast::Pat>>>(&mut self,
fn pats_all<'b, I: Iterator<Item=&'b P<hir::Pat>>>(&mut self,
pats: I,
pred: CFGIndex) -> CFGIndex {
//! Handles case where all of the patterns must match.
pats.fold(pred, |pred, pat| self.pat(&**pat, pred))
}
fn expr(&mut self, expr: &ast::Expr, pred: CFGIndex) -> CFGIndex {
fn expr(&mut self, expr: &hir::Expr, pred: CFGIndex) -> CFGIndex {
match expr.node {
ast::ExprBlock(ref blk) => {
hir::ExprBlock(ref blk) => {
let blk_exit = self.block(&**blk, pred);
self.add_ast_node(expr.id, &[blk_exit])
}
ast::ExprIf(ref cond, ref then, None) => {
hir::ExprIf(ref cond, ref then, None) => {
//
// [pred]
// |
@ -177,7 +170,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
self.add_ast_node(expr.id, &[cond_exit, then_exit]) // 3,4
}
ast::ExprIf(ref cond, ref then, Some(ref otherwise)) => {
hir::ExprIf(ref cond, ref then, Some(ref otherwise)) => {
//
// [pred]
// |
@ -198,11 +191,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
self.add_ast_node(expr.id, &[then_exit, else_exit]) // 4, 5
}
ast::ExprIfLet(..) => {
self.tcx.sess.span_bug(expr.span, "non-desugared ExprIfLet");
}
ast::ExprWhile(ref cond, ref body, _) => {
hir::ExprWhile(ref cond, ref body, _) => {
//
// [pred]
// |
@ -235,15 +224,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
expr_exit
}
ast::ExprWhileLet(..) => {
self.tcx.sess.span_bug(expr.span, "non-desugared ExprWhileLet");
}
ast::ExprForLoop(..) => {
self.tcx.sess.span_bug(expr.span, "non-desugared ExprForLoop");
}
ast::ExprLoop(ref body, _) => {
hir::ExprLoop(ref body, _) => {
//
// [pred]
// |
@ -271,11 +252,11 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
expr_exit
}
ast::ExprMatch(ref discr, ref arms, _) => {
hir::ExprMatch(ref discr, ref arms, _) => {
self.match_(expr.id, &discr, &arms, pred)
}
ast::ExprBinary(op, ref l, ref r) if ast_util::lazy_binop(op.node) => {
hir::ExprBinary(op, ref l, ref r) if ::rustc_front::util::lazy_binop(op.node) => {
//
// [pred]
// |
@ -295,14 +276,14 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
self.add_ast_node(expr.id, &[l_exit, r_exit]) // 3,4
}
ast::ExprRet(ref v) => {
hir::ExprRet(ref v) => {
let v_exit = self.opt_expr(v, pred);
let b = self.add_ast_node(expr.id, &[v_exit]);
self.add_returning_edge(expr, b);
self.add_unreachable_node()
}
ast::ExprBreak(label) => {
hir::ExprBreak(label) => {
let loop_scope = self.find_scope(expr, label);
let b = self.add_ast_node(expr.id, &[pred]);
self.add_exiting_edge(expr, b,
@ -310,7 +291,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
self.add_unreachable_node()
}
ast::ExprAgain(label) => {
hir::ExprAgain(label) => {
let loop_scope = self.find_scope(expr, label);
let a = self.add_ast_node(expr.id, &[pred]);
self.add_exiting_edge(expr, a,
@ -318,68 +299,68 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
self.add_unreachable_node()
}
ast::ExprVec(ref elems) => {
hir::ExprVec(ref elems) => {
self.straightline(expr, pred, elems.iter().map(|e| &**e))
}
ast::ExprCall(ref func, ref args) => {
hir::ExprCall(ref func, ref args) => {
self.call(expr, pred, &**func, args.iter().map(|e| &**e))
}
ast::ExprMethodCall(_, _, ref args) => {
hir::ExprMethodCall(_, _, ref args) => {
self.call(expr, pred, &*args[0], args[1..].iter().map(|e| &**e))
}
ast::ExprIndex(ref l, ref r) |
ast::ExprBinary(_, ref l, ref r) if self.tcx.is_method_call(expr.id) => {
hir::ExprIndex(ref l, ref r) |
hir::ExprBinary(_, ref l, ref r) if self.tcx.is_method_call(expr.id) => {
self.call(expr, pred, &**l, Some(&**r).into_iter())
}
ast::ExprRange(ref start, ref end) => {
hir::ExprRange(ref start, ref end) => {
let fields = start.as_ref().map(|e| &**e).into_iter()
.chain(end.as_ref().map(|e| &**e));
self.straightline(expr, pred, fields)
}
ast::ExprUnary(_, ref e) if self.tcx.is_method_call(expr.id) => {
self.call(expr, pred, &**e, None::<ast::Expr>.iter())
hir::ExprUnary(_, ref e) if self.tcx.is_method_call(expr.id) => {
self.call(expr, pred, &**e, None::<hir::Expr>.iter())
}
ast::ExprTup(ref exprs) => {
hir::ExprTup(ref exprs) => {
self.straightline(expr, pred, exprs.iter().map(|e| &**e))
}
ast::ExprStruct(_, ref fields, ref base) => {
hir::ExprStruct(_, ref fields, ref base) => {
let field_cfg = self.straightline(expr, pred, fields.iter().map(|f| &*f.expr));
self.opt_expr(base, field_cfg)
}
ast::ExprRepeat(ref elem, ref count) => {
hir::ExprRepeat(ref elem, ref count) => {
self.straightline(expr, pred, [elem, count].iter().map(|&e| &**e))
}
ast::ExprAssign(ref l, ref r) |
ast::ExprAssignOp(_, ref l, ref r) => {
hir::ExprAssign(ref l, ref r) |
hir::ExprAssignOp(_, ref l, ref r) => {
self.straightline(expr, pred, [r, l].iter().map(|&e| &**e))
}
ast::ExprBox(Some(ref l), ref r) |
ast::ExprIndex(ref l, ref r) |
ast::ExprBinary(_, ref l, ref r) => { // NB: && and || handled earlier
hir::ExprBox(Some(ref l), ref r) |
hir::ExprIndex(ref l, ref r) |
hir::ExprBinary(_, ref l, ref r) => { // NB: && and || handled earlier
self.straightline(expr, pred, [l, r].iter().map(|&e| &**e))
}
ast::ExprBox(None, ref e) |
ast::ExprAddrOf(_, ref e) |
ast::ExprCast(ref e, _) |
ast::ExprUnary(_, ref e) |
ast::ExprParen(ref e) |
ast::ExprField(ref e, _) |
ast::ExprTupField(ref e, _) => {
hir::ExprBox(None, ref e) |
hir::ExprAddrOf(_, ref e) |
hir::ExprCast(ref e, _) |
hir::ExprUnary(_, ref e) |
hir::ExprParen(ref e) |
hir::ExprField(ref e, _) |
hir::ExprTupField(ref e, _) => {
self.straightline(expr, pred, Some(&**e).into_iter())
}
ast::ExprInlineAsm(ref inline_asm) => {
hir::ExprInlineAsm(ref inline_asm) => {
let inputs = inline_asm.inputs.iter();
let outputs = inline_asm.outputs.iter();
let post_inputs = self.exprs(inputs.map(|a| {
@ -395,19 +376,18 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
self.add_ast_node(expr.id, &[post_outputs])
}
ast::ExprMac(..) |
ast::ExprClosure(..) |
ast::ExprLit(..) |
ast::ExprPath(..) => {
self.straightline(expr, pred, None::<ast::Expr>.iter())
hir::ExprClosure(..) |
hir::ExprLit(..) |
hir::ExprPath(..) => {
self.straightline(expr, pred, None::<hir::Expr>.iter())
}
}
}
fn call<'b, I: Iterator<Item=&'b ast::Expr>>(&mut self,
call_expr: &ast::Expr,
fn call<'b, I: Iterator<Item=&'b hir::Expr>>(&mut self,
call_expr: &hir::Expr,
pred: CFGIndex,
func_or_rcvr: &ast::Expr,
func_or_rcvr: &hir::Expr,
args: I) -> CFGIndex {
let method_call = ty::MethodCall::expr(call_expr.id);
let fn_ty = match self.tcx.tables.borrow().method_map.get(&method_call) {
@ -424,7 +404,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
}
}
fn exprs<'b, I: Iterator<Item=&'b ast::Expr>>(&mut self,
fn exprs<'b, I: Iterator<Item=&'b hir::Expr>>(&mut self,
exprs: I,
pred: CFGIndex) -> CFGIndex {
//! Constructs graph for `exprs` evaluated in order
@ -432,14 +412,14 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
}
fn opt_expr(&mut self,
opt_expr: &Option<P<ast::Expr>>,
opt_expr: &Option<P<hir::Expr>>,
pred: CFGIndex) -> CFGIndex {
//! Constructs graph for `opt_expr` evaluated, if Some
opt_expr.iter().fold(pred, |p, e| self.expr(&**e, p))
}
fn straightline<'b, I: Iterator<Item=&'b ast::Expr>>(&mut self,
expr: &ast::Expr,
fn straightline<'b, I: Iterator<Item=&'b hir::Expr>>(&mut self,
expr: &hir::Expr,
pred: CFGIndex,
subexprs: I) -> CFGIndex {
//! Handles case of an expression that evaluates `subexprs` in order
@ -448,8 +428,8 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
self.add_ast_node(expr.id, &[subexprs_exit])
}
fn match_(&mut self, id: ast::NodeId, discr: &ast::Expr,
arms: &[ast::Arm], pred: CFGIndex) -> CFGIndex {
fn match_(&mut self, id: ast::NodeId, discr: &hir::Expr,
arms: &[hir::Arm], pred: CFGIndex) -> CFGIndex {
// The CFG for match expression is quite complex, so no ASCII
// art for it (yet).
//
@ -579,7 +559,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
}
fn add_exiting_edge(&mut self,
from_expr: &ast::Expr,
from_expr: &hir::Expr,
from_index: CFGIndex,
to_loop: LoopScope,
to_index: CFGIndex) {
@ -594,7 +574,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
}
fn add_returning_edge(&mut self,
_from_expr: &ast::Expr,
_from_expr: &hir::Expr,
from_index: CFGIndex) {
let mut data = CFGEdgeData {
exiting_scopes: vec!(),
@ -606,7 +586,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
}
fn find_scope(&self,
expr: &ast::Expr,
expr: &hir::Expr,
label: Option<ast::Ident>) -> LoopScope {
if label.is_none() {
return *self.loop_scopes.last().unwrap();

View File

@ -18,7 +18,7 @@ use graphviz as dot;
use syntax::ast;
use ast_map;
use front::map as ast_map;
use middle::cfg;
pub type Node<'a> = (cfg::CFGIndex, &'a cfg::CFGNode);

View File

@ -14,6 +14,7 @@
use rustc_data_structures::graph;
use middle::ty;
use syntax::ast;
use rustc_front::hir;
mod construct;
pub mod graphviz;
@ -58,7 +59,7 @@ pub type CFGEdge = graph::Edge<CFGEdgeData>;
impl CFG {
pub fn new(tcx: &ty::ctxt,
blk: &ast::Block) -> CFG {
blk: &hir::Block) -> CFG {
construct::construct(tcx, blk)
}

View File

@ -36,9 +36,10 @@ use middle::traits;
use middle::ty::{self, Ty};
use util::nodemap::NodeMap;
use rustc_front::hir;
use syntax::ast;
use syntax::codemap::Span;
use syntax::visit::{self, FnKind, Visitor};
use rustc_front::visit::{self, FnKind, Visitor};
use std::collections::hash_map::Entry;
use std::cmp::Ordering;
@ -96,7 +97,7 @@ struct CheckCrateVisitor<'a, 'tcx: 'a> {
tcx: &'a ty::ctxt<'tcx>,
mode: Mode,
qualif: ConstQualif,
rvalue_borrows: NodeMap<ast::Mutability>
rvalue_borrows: NodeMap<hir::Mutability>
}
impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> {
@ -125,7 +126,7 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> {
f(&mut euv::ExprUseVisitor::new(self, &infcx))
}
fn global_expr(&mut self, mode: Mode, expr: &ast::Expr) -> ConstQualif {
fn global_expr(&mut self, mode: Mode, expr: &hir::Expr) -> ConstQualif {
assert!(mode != Mode::Var);
match self.tcx.const_qualif_map.borrow_mut().entry(expr.id) {
Entry::Occupied(entry) => return *entry.get(),
@ -143,8 +144,8 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> {
fn fn_like(&mut self,
fk: FnKind,
fd: &ast::FnDecl,
b: &ast::Block,
fd: &hir::FnDecl,
b: &hir::Block,
s: Span,
fn_id: ast::NodeId)
-> ConstQualif {
@ -157,11 +158,11 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> {
}
let mode = match fk {
FnKind::ItemFn(_, _, _, ast::Constness::Const, _, _) => {
FnKind::ItemFn(_, _, _, hir::Constness::Const, _, _) => {
Mode::ConstFn
}
FnKind::Method(_, m, _) => {
if m.constness == ast::Constness::Const {
if m.constness == hir::Constness::Const {
Mode::ConstFn
} else {
Mode::Var
@ -174,7 +175,7 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> {
if mode == Mode::ConstFn {
for arg in &fd.inputs {
match arg.pat.node {
ast::PatIdent(ast::BindByValue(ast::MutImmutable), _, None) => {}
hir::PatIdent(hir::BindByValue(hir::MutImmutable), _, None) => {}
_ => {
span_err!(self.tcx.sess, arg.pat.span, E0022,
"arguments of constant functions can only \
@ -204,7 +205,7 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> {
/// Returns true if the call is to a const fn or method.
fn handle_const_fn_call(&mut self,
expr: &ast::Expr,
expr: &hir::Expr,
def_id: DefId,
ret_ty: Ty<'tcx>)
-> bool {
@ -246,12 +247,12 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> {
}
}
fn record_borrow(&mut self, id: ast::NodeId, mutbl: ast::Mutability) {
fn record_borrow(&mut self, id: ast::NodeId, mutbl: hir::Mutability) {
match self.rvalue_borrows.entry(id) {
Entry::Occupied(mut entry) => {
// Merge the two borrows, taking the most demanding
// one, mutability-wise.
if mutbl == ast::MutMutable {
if mutbl == hir::MutMutable {
entry.insert(mutbl);
}
}
@ -270,7 +271,7 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> {
}
}
fn check_static_mut_type(&self, e: &ast::Expr) {
fn check_static_mut_type(&self, e: &hir::Expr) {
let node_ty = self.tcx.node_id_to_type(e.id);
let tcontents = node_ty.type_contents(self.tcx);
@ -286,7 +287,7 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> {
"mutable statics are not allowed to have {}", suffix);
}
fn check_static_type(&self, e: &ast::Expr) {
fn check_static_type(&self, e: &hir::Expr) {
let ty = self.tcx.node_id_to_type(e.id);
let infcx = infer::new_infer_ctxt(self.tcx, &self.tcx.tables, None, false);
let cause = traits::ObligationCause::new(e.span, e.id, traits::SharedStatic);
@ -302,21 +303,21 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> {
}
impl<'a, 'tcx, 'v> Visitor<'v> for CheckCrateVisitor<'a, 'tcx> {
fn visit_item(&mut self, i: &ast::Item) {
fn visit_item(&mut self, i: &hir::Item) {
debug!("visit_item(item={})", self.tcx.map.node_to_string(i.id));
match i.node {
ast::ItemStatic(_, ast::MutImmutable, ref expr) => {
hir::ItemStatic(_, hir::MutImmutable, ref expr) => {
self.check_static_type(&**expr);
self.global_expr(Mode::Static, &**expr);
}
ast::ItemStatic(_, ast::MutMutable, ref expr) => {
hir::ItemStatic(_, hir::MutMutable, ref expr) => {
self.check_static_mut_type(&**expr);
self.global_expr(Mode::StaticMut, &**expr);
}
ast::ItemConst(_, ref expr) => {
hir::ItemConst(_, ref expr) => {
self.global_expr(Mode::Const, &**expr);
}
ast::ItemEnum(ref enum_definition, _) => {
hir::ItemEnum(ref enum_definition, _) => {
for var in &enum_definition.variants {
if let Some(ref ex) = var.node.disr_expr {
self.global_expr(Mode::Const, &**ex);
@ -329,9 +330,9 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckCrateVisitor<'a, 'tcx> {
}
}
fn visit_trait_item(&mut self, t: &'v ast::TraitItem) {
fn visit_trait_item(&mut self, t: &'v hir::TraitItem) {
match t.node {
ast::ConstTraitItem(_, ref default) => {
hir::ConstTraitItem(_, ref default) => {
if let Some(ref expr) = *default {
self.global_expr(Mode::Const, &*expr);
} else {
@ -342,9 +343,9 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckCrateVisitor<'a, 'tcx> {
}
}
fn visit_impl_item(&mut self, i: &'v ast::ImplItem) {
fn visit_impl_item(&mut self, i: &'v hir::ImplItem) {
match i.node {
ast::ConstImplItem(_, ref expr) => {
hir::ConstImplItem(_, ref expr) => {
self.global_expr(Mode::Const, &*expr);
}
_ => self.with_mode(Mode::Var, |v| visit::walk_impl_item(v, i)),
@ -353,19 +354,19 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckCrateVisitor<'a, 'tcx> {
fn visit_fn(&mut self,
fk: FnKind<'v>,
fd: &'v ast::FnDecl,
b: &'v ast::Block,
fd: &'v hir::FnDecl,
b: &'v hir::Block,
s: Span,
fn_id: ast::NodeId) {
self.fn_like(fk, fd, b, s, fn_id);
}
fn visit_pat(&mut self, p: &ast::Pat) {
fn visit_pat(&mut self, p: &hir::Pat) {
match p.node {
ast::PatLit(ref lit) => {
hir::PatLit(ref lit) => {
self.global_expr(Mode::Const, &**lit);
}
ast::PatRange(ref start, ref end) => {
hir::PatRange(ref start, ref end) => {
self.global_expr(Mode::Const, &**start);
self.global_expr(Mode::Const, &**end);
@ -386,24 +387,20 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckCrateVisitor<'a, 'tcx> {
}
}
fn visit_block(&mut self, block: &ast::Block) {
fn visit_block(&mut self, block: &hir::Block) {
// Check all statements in the block
for stmt in &block.stmts {
let span = match stmt.node {
ast::StmtDecl(ref decl, _) => {
hir::StmtDecl(ref decl, _) => {
match decl.node {
ast::DeclLocal(_) => decl.span,
hir::DeclLocal(_) => decl.span,
// Item statements are allowed
ast::DeclItem(_) => continue
hir::DeclItem(_) => continue
}
}
ast::StmtExpr(ref expr, _) => expr.span,
ast::StmtSemi(ref semi, _) => semi.span,
ast::StmtMac(..) => {
self.tcx.sess.span_bug(stmt.span, "unexpanded statement \
macro in const?!")
}
hir::StmtExpr(ref expr, _) => expr.span,
hir::StmtSemi(ref semi, _) => semi.span,
};
self.add_qualif(ConstQualif::NOT_CONST);
if self.mode != Mode::Var {
@ -415,7 +412,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckCrateVisitor<'a, 'tcx> {
visit::walk_block(self, block);
}
fn visit_expr(&mut self, ex: &ast::Expr) {
fn visit_expr(&mut self, ex: &hir::Expr) {
let mut outer = self.qualif;
self.qualif = ConstQualif::empty();
@ -425,7 +422,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckCrateVisitor<'a, 'tcx> {
// Special-case some expressions to avoid certain flags bubbling up.
match ex.node {
ast::ExprCall(ref callee, ref args) => {
hir::ExprCall(ref callee, ref args) => {
for arg in args {
self.visit_expr(&**arg)
}
@ -436,7 +433,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckCrateVisitor<'a, 'tcx> {
let added = self.qualif - inner;
self.qualif = inner | (added - ConstQualif::NON_ZERO_SIZED);
}
ast::ExprRepeat(ref element, _) => {
hir::ExprRepeat(ref element, _) => {
self.visit_expr(&**element);
// The count is checked elsewhere (typeck).
let count = match node_ty.sty {
@ -448,14 +445,14 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckCrateVisitor<'a, 'tcx> {
self.qualif.remove(ConstQualif::NON_ZERO_SIZED | ConstQualif::PREFER_IN_PLACE);
}
}
ast::ExprMatch(ref discr, ref arms, _) => {
hir::ExprMatch(ref discr, ref arms, _) => {
// Compute the most demanding borrow from all the arms'
// patterns and set that on the discriminator.
let mut borrow = None;
for pat in arms.iter().flat_map(|arm| &arm.pats) {
let pat_borrow = self.rvalue_borrows.remove(&pat.id);
match (borrow, pat_borrow) {
(None, _) | (_, Some(ast::MutMutable)) => {
(None, _) | (_, Some(hir::MutMutable)) => {
borrow = pat_borrow;
}
_ => {}
@ -467,9 +464,9 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckCrateVisitor<'a, 'tcx> {
visit::walk_expr(self, ex);
}
// Division by zero and overflow checking.
ast::ExprBinary(op, _, _) => {
hir::ExprBinary(op, _, _) => {
visit::walk_expr(self, ex);
let div_or_rem = op.node == ast::BiDiv || op.node == ast::BiRem;
let div_or_rem = op.node == hir::BiDiv || op.node == hir::BiRem;
match node_ty.sty {
ty::TyUint(_) | ty::TyInt(_) if div_or_rem => {
if !self.qualif.intersects(ConstQualif::NOT_CONST) {
@ -492,7 +489,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckCrateVisitor<'a, 'tcx> {
// Handle borrows on (or inside the autorefs of) this expression.
match self.rvalue_borrows.remove(&ex.id) {
Some(ast::MutImmutable) => {
Some(hir::MutImmutable) => {
// Constants cannot be borrowed if they contain interior mutability as
// it means that our "silent insertion of statics" could change
// initializer values (very bad).
@ -514,7 +511,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckCrateVisitor<'a, 'tcx> {
self.add_qualif(ConstQualif::HAS_STATIC_BORROWS);
}
}
Some(ast::MutMutable) => {
Some(hir::MutMutable) => {
// `&mut expr` means expr could be mutated, unless it's zero-sized.
if self.qualif.intersects(ConstQualif::NON_ZERO_SIZED) {
if self.mode == Mode::Var {
@ -545,7 +542,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckCrateVisitor<'a, 'tcx> {
/// of a const/static item, it is qualified for promotion
/// instead of producing errors.
fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
e: &ast::Expr, node_ty: Ty<'tcx>) {
e: &hir::Expr, node_ty: Ty<'tcx>) {
match node_ty.sty {
ty::TyStruct(def, _) |
ty::TyEnum(def, _) if def.has_dtor() => {
@ -561,27 +558,27 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
let method_call = ty::MethodCall::expr(e.id);
match e.node {
ast::ExprUnary(..) |
ast::ExprBinary(..) |
ast::ExprIndex(..) if v.tcx.tables.borrow().method_map.contains_key(&method_call) => {
hir::ExprUnary(..) |
hir::ExprBinary(..) |
hir::ExprIndex(..) if v.tcx.tables.borrow().method_map.contains_key(&method_call) => {
v.add_qualif(ConstQualif::NOT_CONST);
if v.mode != Mode::Var {
span_err!(v.tcx.sess, e.span, E0011,
"user-defined operators are not allowed in {}s", v.msg());
}
}
ast::ExprBox(..) |
ast::ExprUnary(ast::UnUniq, _) => {
hir::ExprBox(..) |
hir::ExprUnary(hir::UnUniq, _) => {
v.add_qualif(ConstQualif::NOT_CONST);
if v.mode != Mode::Var {
span_err!(v.tcx.sess, e.span, E0010,
"allocations are not allowed in {}s", v.msg());
}
}
ast::ExprUnary(op, ref inner) => {
hir::ExprUnary(op, ref inner) => {
match v.tcx.node_id_to_type(inner.id).sty {
ty::TyRawPtr(_) => {
assert!(op == ast::UnDeref);
assert!(op == hir::UnDeref);
v.add_qualif(ConstQualif::NOT_CONST);
if v.mode != Mode::Var {
@ -592,12 +589,12 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
_ => {}
}
}
ast::ExprBinary(op, ref lhs, _) => {
hir::ExprBinary(op, ref lhs, _) => {
match v.tcx.node_id_to_type(lhs.id).sty {
ty::TyRawPtr(_) => {
assert!(op.node == ast::BiEq || op.node == ast::BiNe ||
op.node == ast::BiLe || op.node == ast::BiLt ||
op.node == ast::BiGe || op.node == ast::BiGt);
assert!(op.node == hir::BiEq || op.node == hir::BiNe ||
op.node == hir::BiLe || op.node == hir::BiLt ||
op.node == hir::BiGe || op.node == hir::BiGt);
v.add_qualif(ConstQualif::NOT_CONST);
if v.mode != Mode::Var {
@ -608,7 +605,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
_ => {}
}
}
ast::ExprCast(ref from, _) => {
hir::ExprCast(ref from, _) => {
debug!("Checking const cast(id={})", from.id);
match v.tcx.cast_kinds.borrow().get(&from.id) {
None => v.tcx.sess.span_bug(e.span, "no kind for cast"),
@ -622,7 +619,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
_ => {}
}
}
ast::ExprPath(..) => {
hir::ExprPath(..) => {
let def = v.tcx.def_map.borrow().get(&e.id).map(|d| d.full_def());
match def {
Some(def::DefVariant(_, _, _)) => {
@ -677,12 +674,12 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
}
}
}
ast::ExprCall(ref callee, _) => {
hir::ExprCall(ref callee, _) => {
let mut callee = &**callee;
loop {
callee = match callee.node {
ast::ExprParen(ref inner) => &**inner,
ast::ExprBlock(ref block) => match block.expr {
hir::ExprParen(ref inner) => &**inner,
hir::ExprBlock(ref block) => match block.expr {
Some(ref tail) => &**tail,
None => break
},
@ -720,7 +717,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
}
}
}
ast::ExprMethodCall(..) => {
hir::ExprMethodCall(..) => {
let method = v.tcx.tables.borrow().method_map[&method_call];
let is_const = match v.tcx.impl_or_trait_item(method.def_id).container() {
ty::ImplContainer(_) => v.handle_const_fn_call(e, method.def_id, node_ty),
@ -735,23 +732,23 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
}
}
}
ast::ExprStruct(..) => {
hir::ExprStruct(..) => {
let did = v.tcx.def_map.borrow().get(&e.id).map(|def| def.def_id());
if did == v.tcx.lang_items.unsafe_cell_type() {
v.add_qualif(ConstQualif::MUTABLE_MEM);
}
}
ast::ExprLit(_) |
ast::ExprAddrOf(..) => {
hir::ExprLit(_) |
hir::ExprAddrOf(..) => {
v.add_qualif(ConstQualif::NON_ZERO_SIZED);
}
ast::ExprRepeat(..) => {
hir::ExprRepeat(..) => {
v.add_qualif(ConstQualif::PREFER_IN_PLACE);
}
ast::ExprClosure(..) => {
hir::ExprClosure(..) => {
// Paths in constant contexts cannot refer to local variables,
// as there are none, and thus closures can't have upvars there.
if v.tcx.with_freevars(e.id, |fv| !fv.is_empty()) {
@ -761,38 +758,34 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
}
}
ast::ExprBlock(_) |
ast::ExprIndex(..) |
ast::ExprField(..) |
ast::ExprTupField(..) |
ast::ExprVec(_) |
ast::ExprParen(..) |
ast::ExprTup(..) => {}
hir::ExprBlock(_) |
hir::ExprIndex(..) |
hir::ExprField(..) |
hir::ExprTupField(..) |
hir::ExprVec(_) |
hir::ExprParen(..) |
hir::ExprTup(..) => {}
// Conditional control flow (possible to implement).
ast::ExprMatch(..) |
ast::ExprIf(..) |
ast::ExprIfLet(..) |
hir::ExprMatch(..) |
hir::ExprIf(..) |
// Loops (not very meaningful in constants).
ast::ExprWhile(..) |
ast::ExprWhileLet(..) |
ast::ExprForLoop(..) |
ast::ExprLoop(..) |
hir::ExprWhile(..) |
hir::ExprLoop(..) |
// More control flow (also not very meaningful).
ast::ExprBreak(_) |
ast::ExprAgain(_) |
ast::ExprRet(_) |
hir::ExprBreak(_) |
hir::ExprAgain(_) |
hir::ExprRet(_) |
// Miscellaneous expressions that could be implemented.
ast::ExprRange(..) |
hir::ExprRange(..) |
// Expressions with side-effects.
ast::ExprAssign(..) |
ast::ExprAssignOp(..) |
ast::ExprInlineAsm(_) |
ast::ExprMac(_) => {
hir::ExprAssign(..) |
hir::ExprAssignOp(..) |
hir::ExprInlineAsm(_) => {
v.add_qualif(ConstQualif::NOT_CONST);
if v.mode != Mode::Var {
span_err!(v.tcx.sess, e.span, E0019,
@ -803,7 +796,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
}
/// Check the adjustments of an expression
fn check_adjustments<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &ast::Expr) {
fn check_adjustments<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Expr) {
match v.tcx.tables.borrow().adjustments.get(&e.id) {
None | Some(&ty::AdjustReifyFnPointer) | Some(&ty::AdjustUnsafeFnPointer) => {}
Some(&ty::AdjustDerefRef(ty::AutoDerefRef { autoderefs, .. })) => {
@ -891,7 +884,7 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for CheckCrateVisitor<'a, 'tcx> {
break;
}
let mutbl = bk.to_mutbl_lossy();
if mutbl == ast::MutMutable && self.mode == Mode::StaticMut {
if mutbl == hir::MutMutable && self.mode == Mode::StaticMut {
// Mutable slices are the only `&mut` allowed in
// globals, but only in `static mut`, nowhere else.
// FIXME: This exception is really weird... there isn't
@ -940,12 +933,12 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for CheckCrateVisitor<'a, 'tcx> {
_mode: euv::MutateMode) {}
fn matched_pat(&mut self,
_: &ast::Pat,
_: &hir::Pat,
_: mc::cmt,
_: euv::MatchMode) {}
fn consume_pat(&mut self,
_consume_pat: &ast::Pat,
_consume_pat: &hir::Pat,
_cmt: mc::cmt,
_mode: euv::ConsumeMode) {}
}

View File

@ -11,10 +11,10 @@ use self::Context::*;
use session::Session;
use syntax::ast;
use syntax::codemap::Span;
use syntax::visit::Visitor;
use syntax::visit;
use rustc_front::visit::Visitor;
use rustc_front::visit;
use rustc_front::hir;
#[derive(Clone, Copy, PartialEq)]
enum Context {
@ -27,29 +27,29 @@ struct CheckLoopVisitor<'a> {
cx: Context
}
pub fn check_crate(sess: &Session, krate: &ast::Crate) {
pub fn check_crate(sess: &Session, krate: &hir::Crate) {
visit::walk_crate(&mut CheckLoopVisitor { sess: sess, cx: Normal }, krate)
}
impl<'a, 'v> Visitor<'v> for CheckLoopVisitor<'a> {
fn visit_item(&mut self, i: &ast::Item) {
fn visit_item(&mut self, i: &hir::Item) {
self.with_context(Normal, |v| visit::walk_item(v, i));
}
fn visit_expr(&mut self, e: &ast::Expr) {
fn visit_expr(&mut self, e: &hir::Expr) {
match e.node {
ast::ExprWhile(ref e, ref b, _) => {
hir::ExprWhile(ref e, ref b, _) => {
self.visit_expr(&**e);
self.with_context(Loop, |v| v.visit_block(&**b));
}
ast::ExprLoop(ref b, _) => {
hir::ExprLoop(ref b, _) => {
self.with_context(Loop, |v| v.visit_block(&**b));
}
ast::ExprClosure(_, _, ref b) => {
hir::ExprClosure(_, _, ref b) => {
self.with_context(Closure, |v| v.visit_block(&**b));
}
ast::ExprBreak(_) => self.require_loop("break", e.span),
ast::ExprAgain(_) => self.require_loop("continue", e.span),
hir::ExprBreak(_) => self.require_loop("break", e.span),
hir::ExprAgain(_) => self.require_loop("continue", e.span),
_ => visit::walk_expr(self, e)
}
}

View File

@ -31,18 +31,23 @@ use std::cmp::Ordering;
use std::fmt;
use std::iter::{range_inclusive, FromIterator, IntoIterator, repeat};
use std::slice;
use syntax::ast::{self, DUMMY_NODE_ID, NodeId, Pat};
use rustc_front::hir;
use rustc_front::hir::Pat;
use rustc_front::visit::{self, Visitor, FnKind};
use rustc_front::util as front_util;
use syntax::ast::{self, DUMMY_NODE_ID, NodeId};
use syntax::ast_util;
use syntax::codemap::{Span, Spanned, DUMMY_SP};
use syntax::fold::{Folder, noop_fold_pat};
use syntax::print::pprust::pat_to_string;
use rustc_front::fold::{Folder, noop_fold_pat};
use rustc_front::print::pprust::pat_to_string;
use syntax::ptr::P;
use syntax::visit::{self, Visitor, FnKind};
use util::nodemap::FnvHashMap;
pub const DUMMY_WILD_PAT: &'static Pat = &Pat {
id: DUMMY_NODE_ID,
node: ast::PatWild(ast::PatWildSingle),
node: hir::PatWild(hir::PatWildSingle),
span: DUMMY_SP
};
@ -137,14 +142,14 @@ enum WitnessPreference {
}
impl<'a, 'tcx, 'v> Visitor<'v> for MatchCheckCtxt<'a, 'tcx> {
fn visit_expr(&mut self, ex: &ast::Expr) {
fn visit_expr(&mut self, ex: &hir::Expr) {
check_expr(self, ex);
}
fn visit_local(&mut self, l: &ast::Local) {
fn visit_local(&mut self, l: &hir::Local) {
check_local(self, l);
}
fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v ast::FnDecl,
b: &'v ast::Block, s: Span, n: NodeId) {
fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v hir::FnDecl,
b: &'v hir::Block, s: Span, n: NodeId) {
check_fn(self, fk, fd, b, s, n);
}
}
@ -157,10 +162,10 @@ pub fn check_crate(tcx: &ty::ctxt) {
tcx.sess.abort_if_errors();
}
fn check_expr(cx: &mut MatchCheckCtxt, ex: &ast::Expr) {
fn check_expr(cx: &mut MatchCheckCtxt, ex: &hir::Expr) {
visit::walk_expr(cx, ex);
match ex.node {
ast::ExprMatch(ref scrut, ref arms, source) => {
hir::ExprMatch(ref scrut, ref arms, source) => {
for arm in arms {
// First, check legality of move bindings.
check_legality_of_move_bindings(cx,
@ -180,7 +185,7 @@ fn check_expr(cx: &mut MatchCheckCtxt, ex: &ast::Expr) {
(arm.pats.iter().map(|pat| {
static_inliner.fold_pat((*pat).clone())
}).collect(), arm.guard.as_ref().map(|e| &**e))
}).collect::<Vec<(Vec<P<Pat>>, Option<&ast::Expr>)>>();
}).collect::<Vec<(Vec<P<Pat>>, Option<&hir::Expr>)>>();
// Bail out early if inlining failed.
if static_inliner.failed {
@ -231,9 +236,9 @@ fn check_expr(cx: &mut MatchCheckCtxt, ex: &ast::Expr) {
}
fn check_for_bindings_named_the_same_as_variants(cx: &MatchCheckCtxt, pat: &Pat) {
ast_util::walk_pat(pat, |p| {
front_util::walk_pat(pat, |p| {
match p.node {
ast::PatIdent(ast::BindByValue(ast::MutImmutable), ident, None) => {
hir::PatIdent(hir::BindByValue(hir::MutImmutable), ident, None) => {
let pat_ty = cx.tcx.pat_ty(p);
if let ty::TyEnum(edef, _) = pat_ty.sty {
let def = cx.tcx.def_map.borrow().get(&p.id).map(|d| d.full_def());
@ -262,8 +267,8 @@ fn check_for_bindings_named_the_same_as_variants(cx: &MatchCheckCtxt, pat: &Pat)
// Check that we do not match against a static NaN (#6804)
fn check_for_static_nan(cx: &MatchCheckCtxt, pat: &Pat) {
ast_util::walk_pat(pat, |p| {
if let ast::PatLit(ref expr) = p.node {
front_util::walk_pat(pat, |p| {
if let hir::PatLit(ref expr) = p.node {
match eval_const_expr_partial(cx.tcx, &**expr, ExprTypeChecked) {
Ok(ConstVal::Float(f)) if f.is_nan() => {
span_warn!(cx.tcx.sess, p.span, E0003,
@ -290,8 +295,8 @@ fn check_for_static_nan(cx: &MatchCheckCtxt, pat: &Pat) {
// Check for unreachable patterns
fn check_arms(cx: &MatchCheckCtxt,
arms: &[(Vec<P<Pat>>, Option<&ast::Expr>)],
source: ast::MatchSource) {
arms: &[(Vec<P<Pat>>, Option<&hir::Expr>)],
source: hir::MatchSource) {
let mut seen = Matrix(vec![]);
let mut printed_if_let_err = false;
for &(ref pats, guard) in arms {
@ -301,7 +306,7 @@ fn check_arms(cx: &MatchCheckCtxt,
match is_useful(cx, &seen, &v[..], LeaveOutWitness) {
NotUseful => {
match source {
ast::MatchSource::IfLetDesugar { .. } => {
hir::MatchSource::IfLetDesugar { .. } => {
if printed_if_let_err {
// we already printed an irrefutable if-let pattern error.
// We don't want two, that's just confusing.
@ -315,7 +320,7 @@ fn check_arms(cx: &MatchCheckCtxt,
}
},
ast::MatchSource::WhileLetDesugar => {
hir::MatchSource::WhileLetDesugar => {
// find the first arm pattern so we can use its span
let &(ref first_arm_pats, _) = &arms[0];
let first_pat = &first_arm_pats[0];
@ -323,7 +328,7 @@ fn check_arms(cx: &MatchCheckCtxt,
span_err!(cx.tcx.sess, span, E0165, "irrefutable while-let pattern");
},
ast::MatchSource::ForLoopDesugar => {
hir::MatchSource::ForLoopDesugar => {
// this is a bug, because on `match iter.next()` we cover
// `Some(<head>)` and `None`. It's impossible to have an unreachable
// pattern
@ -331,7 +336,7 @@ fn check_arms(cx: &MatchCheckCtxt,
cx.tcx.sess.span_bug(pat.span, "unreachable for-loop pattern")
},
ast::MatchSource::Normal => {
hir::MatchSource::Normal => {
span_err!(cx.tcx.sess, pat.span, E0001, "unreachable pattern")
},
}
@ -350,12 +355,12 @@ fn check_arms(cx: &MatchCheckCtxt,
fn raw_pat<'a>(p: &'a Pat) -> &'a Pat {
match p.node {
ast::PatIdent(_, _, Some(ref s)) => raw_pat(&**s),
hir::PatIdent(_, _, Some(ref s)) => raw_pat(&**s),
_ => p
}
}
fn check_exhaustive(cx: &MatchCheckCtxt, sp: Span, matrix: &Matrix, source: ast::MatchSource) {
fn check_exhaustive(cx: &MatchCheckCtxt, sp: Span, matrix: &Matrix, source: hir::MatchSource) {
match is_useful(cx, matrix, &[DUMMY_WILD_PAT], ConstructWitness) {
UsefulWithWitness(pats) => {
let witness = match &pats[..] {
@ -364,10 +369,10 @@ fn check_exhaustive(cx: &MatchCheckCtxt, sp: Span, matrix: &Matrix, source: ast:
_ => unreachable!()
};
match source {
ast::MatchSource::ForLoopDesugar => {
hir::MatchSource::ForLoopDesugar => {
// `witness` has the form `Some(<head>)`, peel off the `Some`
let witness = match witness.node {
ast::PatEnum(_, Some(ref pats)) => match &pats[..] {
hir::PatEnum(_, Some(ref pats)) => match &pats[..] {
[ref pat] => &**pat,
_ => unreachable!(),
},
@ -394,14 +399,14 @@ fn check_exhaustive(cx: &MatchCheckCtxt, sp: Span, matrix: &Matrix, source: ast:
}
}
fn const_val_to_expr(value: &ConstVal) -> P<ast::Expr> {
fn const_val_to_expr(value: &ConstVal) -> P<hir::Expr> {
let node = match value {
&ConstVal::Bool(b) => ast::LitBool(b),
&ConstVal::Bool(b) => hir::LitBool(b),
_ => unreachable!()
};
P(ast::Expr {
P(hir::Expr {
id: 0,
node: ast::ExprLit(P(Spanned { node: node, span: DUMMY_SP })),
node: hir::ExprLit(P(Spanned { node: node, span: DUMMY_SP })),
span: DUMMY_SP
})
}
@ -440,7 +445,7 @@ impl<'map> ast_util::IdVisitingOperation for RenamingRecorder<'map> {
impl<'a, 'tcx> Folder for StaticInliner<'a, 'tcx> {
fn fold_pat(&mut self, pat: P<Pat>) -> P<Pat> {
return match pat.node {
ast::PatIdent(..) | ast::PatEnum(..) | ast::PatQPath(..) => {
hir::PatIdent(..) | hir::PatEnum(..) | hir::PatQPath(..) => {
let def = self.tcx.def_map.borrow().get(&pat.id).map(|d| d.full_def());
match def {
Some(DefAssociatedConst(did)) |
@ -469,8 +474,8 @@ impl<'a, 'tcx> Folder for StaticInliner<'a, 'tcx> {
_ => noop_fold_pat(pat, self)
};
fn record_renamings(const_expr: &ast::Expr,
substituted_pat: &ast::Pat,
fn record_renamings(const_expr: &hir::Expr,
substituted_pat: &hir::Pat,
renaming_map: &mut FnvHashMap<(NodeId, Span), NodeId>) {
let mut renaming_recorder = RenamingRecorder {
substituted_node_id: substituted_pat.id,
@ -478,7 +483,7 @@ impl<'a, 'tcx> Folder for StaticInliner<'a, 'tcx> {
renaming_map: renaming_map,
};
let mut id_visitor = ast_util::IdVisitor {
let mut id_visitor = front_util::IdVisitor {
operation: &mut renaming_recorder,
pass_through_items: true,
visited_outermost: false,
@ -507,26 +512,26 @@ fn construct_witness<'a,'tcx>(cx: &MatchCheckCtxt<'a,'tcx>, ctor: &Constructor,
let pats_len = pats.len();
let mut pats = pats.into_iter().map(|p| P((*p).clone()));
let pat = match left_ty.sty {
ty::TyTuple(_) => ast::PatTup(pats.collect()),
ty::TyTuple(_) => hir::PatTup(pats.collect()),
ty::TyEnum(adt, _) | ty::TyStruct(adt, _) => {
let v = adt.variant_of_ctor(ctor);
if let VariantKind::Dict = v.kind() {
let field_pats: Vec<_> = v.fields.iter()
.zip(pats)
.filter(|&(_, ref pat)| pat.node != ast::PatWild(ast::PatWildSingle))
.filter(|&(_, ref pat)| pat.node != hir::PatWild(hir::PatWildSingle))
.map(|(field, pat)| Spanned {
span: DUMMY_SP,
node: ast::FieldPat {
node: hir::FieldPat {
ident: ast::Ident::new(field.name),
pat: pat,
is_shorthand: false,
}
}).collect();
let has_more_fields = field_pats.len() < pats_len;
ast::PatStruct(def_to_path(cx.tcx, v.did), field_pats, has_more_fields)
hir::PatStruct(def_to_path(cx.tcx, v.did), field_pats, has_more_fields)
} else {
ast::PatEnum(def_to_path(cx.tcx, v.did), Some(pats.collect()))
hir::PatEnum(def_to_path(cx.tcx, v.did), Some(pats.collect()))
}
}
@ -535,40 +540,40 @@ fn construct_witness<'a,'tcx>(cx: &MatchCheckCtxt<'a,'tcx>, ctor: &Constructor,
ty::TyArray(_, n) => match ctor {
&Single => {
assert_eq!(pats_len, n);
ast::PatVec(pats.collect(), None, vec!())
hir::PatVec(pats.collect(), None, vec!())
},
_ => unreachable!()
},
ty::TySlice(_) => match ctor {
&Slice(n) => {
assert_eq!(pats_len, n);
ast::PatVec(pats.collect(), None, vec!())
hir::PatVec(pats.collect(), None, vec!())
},
_ => unreachable!()
},
ty::TyStr => ast::PatWild(ast::PatWildSingle),
ty::TyStr => hir::PatWild(hir::PatWildSingle),
_ => {
assert_eq!(pats_len, 1);
ast::PatRegion(pats.nth(0).unwrap(), mutbl)
hir::PatRegion(pats.nth(0).unwrap(), mutbl)
}
}
}
ty::TyArray(_, len) => {
assert_eq!(pats_len, len);
ast::PatVec(pats.collect(), None, vec![])
hir::PatVec(pats.collect(), None, vec![])
}
_ => {
match *ctor {
ConstantValue(ref v) => ast::PatLit(const_val_to_expr(v)),
_ => ast::PatWild(ast::PatWildSingle),
ConstantValue(ref v) => hir::PatLit(const_val_to_expr(v)),
_ => hir::PatWild(hir::PatWildSingle),
}
}
};
P(ast::Pat {
P(hir::Pat {
id: 0,
node: pat,
span: DUMMY_SP
@ -658,7 +663,7 @@ fn is_useful(cx: &MatchCheckCtxt,
let left_ty = cx.tcx.pat_ty(&*real_pat);
match real_pat.node {
ast::PatIdent(ast::BindByRef(..), _, _) => {
hir::PatIdent(hir::BindByRef(..), _, _) => {
left_ty.builtin_deref(false).unwrap().ty
}
_ => left_ty,
@ -666,7 +671,7 @@ fn is_useful(cx: &MatchCheckCtxt,
};
let max_slice_length = rows.iter().filter_map(|row| match row[0].node {
ast::PatVec(ref before, _, ref after) => Some(before.len() + after.len()),
hir::PatVec(ref before, _, ref after) => Some(before.len() + after.len()),
_ => None
}).max().map_or(0, |v| v + 1);
@ -747,7 +752,7 @@ fn pat_constructors(cx: &MatchCheckCtxt, p: &Pat,
left_ty: Ty, max_slice_length: usize) -> Vec<Constructor> {
let pat = raw_pat(p);
match pat.node {
ast::PatIdent(..) =>
hir::PatIdent(..) =>
match cx.tcx.def_map.borrow().get(&pat.id).map(|d| d.full_def()) {
Some(DefConst(..)) | Some(DefAssociatedConst(..)) =>
cx.tcx.sess.span_bug(pat.span, "const pattern should've \
@ -756,7 +761,7 @@ fn pat_constructors(cx: &MatchCheckCtxt, p: &Pat,
Some(DefVariant(_, id, _)) => vec!(Variant(id)),
_ => vec!()
},
ast::PatEnum(..) =>
hir::PatEnum(..) =>
match cx.tcx.def_map.borrow().get(&pat.id).map(|d| d.full_def()) {
Some(DefConst(..)) | Some(DefAssociatedConst(..)) =>
cx.tcx.sess.span_bug(pat.span, "const pattern should've \
@ -764,10 +769,10 @@ fn pat_constructors(cx: &MatchCheckCtxt, p: &Pat,
Some(DefVariant(_, id, _)) => vec!(Variant(id)),
_ => vec!(Single)
},
ast::PatQPath(..) =>
hir::PatQPath(..) =>
cx.tcx.sess.span_bug(pat.span, "const pattern should've \
been rewritten"),
ast::PatStruct(..) =>
hir::PatStruct(..) =>
match cx.tcx.def_map.borrow().get(&pat.id).map(|d| d.full_def()) {
Some(DefConst(..)) | Some(DefAssociatedConst(..)) =>
cx.tcx.sess.span_bug(pat.span, "const pattern should've \
@ -775,11 +780,11 @@ fn pat_constructors(cx: &MatchCheckCtxt, p: &Pat,
Some(DefVariant(_, id, _)) => vec!(Variant(id)),
_ => vec!(Single)
},
ast::PatLit(ref expr) =>
hir::PatLit(ref expr) =>
vec!(ConstantValue(eval_const_expr(cx.tcx, &**expr))),
ast::PatRange(ref lo, ref hi) =>
hir::PatRange(ref lo, ref hi) =>
vec!(ConstantRange(eval_const_expr(cx.tcx, &**lo), eval_const_expr(cx.tcx, &**hi))),
ast::PatVec(ref before, ref slice, ref after) =>
hir::PatVec(ref before, ref slice, ref after) =>
match left_ty.sty {
ty::TyArray(_, _) => vec!(Single),
_ => if slice.is_some() {
@ -790,12 +795,10 @@ fn pat_constructors(cx: &MatchCheckCtxt, p: &Pat,
vec!(Slice(before.len() + after.len()))
}
},
ast::PatBox(_) | ast::PatTup(_) | ast::PatRegion(..) =>
hir::PatBox(_) | hir::PatTup(_) | hir::PatRegion(..) =>
vec!(Single),
ast::PatWild(_) =>
hir::PatWild(_) =>
vec!(),
ast::PatMac(_) =>
cx.tcx.sess.bug("unexpanded macro")
}
}
@ -857,10 +860,10 @@ pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat],
id: pat_id, ref node, span: pat_span
} = raw_pat(r[col]);
let head: Option<Vec<&Pat>> = match *node {
ast::PatWild(_) =>
hir::PatWild(_) =>
Some(vec![DUMMY_WILD_PAT; arity]),
ast::PatIdent(_, _, _) => {
hir::PatIdent(_, _, _) => {
let opt_def = cx.tcx.def_map.borrow().get(&pat_id).map(|d| d.full_def());
match opt_def {
Some(DefConst(..)) | Some(DefAssociatedConst(..)) =>
@ -875,7 +878,7 @@ pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat],
}
}
ast::PatEnum(_, ref args) => {
hir::PatEnum(_, ref args) => {
let def = cx.tcx.def_map.borrow().get(&pat_id).unwrap().full_def();
match def {
DefConst(..) | DefAssociatedConst(..) =>
@ -892,12 +895,12 @@ pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat],
}
}
ast::PatQPath(_, _) => {
hir::PatQPath(_, _) => {
cx.tcx.sess.span_bug(pat_span, "const pattern should've \
been rewritten")
}
ast::PatStruct(_, ref pattern_fields, _) => {
hir::PatStruct(_, ref pattern_fields, _) => {
let def = cx.tcx.def_map.borrow().get(&pat_id).unwrap().full_def();
let adt = cx.tcx.node_id_to_type(pat_id).ty_adt_def().unwrap();
let variant = adt.variant_of_ctor(constructor);
@ -914,13 +917,13 @@ pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat],
}
}
ast::PatTup(ref args) =>
hir::PatTup(ref args) =>
Some(args.iter().map(|p| &**p).collect()),
ast::PatBox(ref inner) | ast::PatRegion(ref inner, _) =>
hir::PatBox(ref inner) | hir::PatRegion(ref inner, _) =>
Some(vec![&**inner]),
ast::PatLit(ref expr) => {
hir::PatLit(ref expr) => {
let expr_value = eval_const_expr(cx.tcx, &**expr);
match range_covered_by_constructor(constructor, &expr_value, &expr_value) {
Some(true) => Some(vec![]),
@ -932,7 +935,7 @@ pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat],
}
}
ast::PatRange(ref from, ref to) => {
hir::PatRange(ref from, ref to) => {
let from_value = eval_const_expr(cx.tcx, &**from);
let to_value = eval_const_expr(cx.tcx, &**to);
match range_covered_by_constructor(constructor, &from_value, &to_value) {
@ -945,7 +948,7 @@ pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat],
}
}
ast::PatVec(ref before, ref slice, ref after) => {
hir::PatVec(ref before, ref slice, ref after) => {
match *constructor {
// Fixed-length vectors.
Single => {
@ -976,11 +979,6 @@ pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat],
_ => None
}
}
ast::PatMac(_) => {
span_err!(cx.tcx.sess, pat_span, E0300, "unexpanded macro");
None
}
};
head.map(|mut head| {
head.push_all(&r[..col]);
@ -989,7 +987,7 @@ pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat],
})
}
fn check_local(cx: &mut MatchCheckCtxt, loc: &ast::Local) {
fn check_local(cx: &mut MatchCheckCtxt, loc: &hir::Local) {
visit::walk_local(cx, loc);
let pat = StaticInliner::new(cx.tcx, None).fold_pat(loc.pat.clone());
@ -1002,8 +1000,8 @@ fn check_local(cx: &mut MatchCheckCtxt, loc: &ast::Local) {
fn check_fn(cx: &mut MatchCheckCtxt,
kind: FnKind,
decl: &ast::FnDecl,
body: &ast::Block,
decl: &hir::FnDecl,
body: &hir::Block,
sp: Span,
fn_id: NodeId) {
match kind {
@ -1060,10 +1058,10 @@ fn check_legality_of_move_bindings(cx: &MatchCheckCtxt,
for pat in pats {
pat_bindings(def_map, &**pat, |bm, _, span, _path| {
match bm {
ast::BindByRef(_) => {
hir::BindByRef(_) => {
by_ref_span = Some(span);
}
ast::BindByValue(_) => {
hir::BindByValue(_) => {
}
}
})
@ -1085,10 +1083,10 @@ fn check_legality_of_move_bindings(cx: &MatchCheckCtxt,
};
for pat in pats {
ast_util::walk_pat(&**pat, |p| {
front_util::walk_pat(&**pat, |p| {
if pat_is_binding(def_map, &*p) {
match p.node {
ast::PatIdent(ast::BindByValue(_), _, ref sub) => {
hir::PatIdent(hir::BindByValue(_), _, ref sub) => {
let pat_ty = tcx.node_id_to_type(p.id);
//FIXME: (@jroesch) this code should be floated up as well
let infcx = infer::new_infer_ctxt(cx.tcx,
@ -1099,7 +1097,7 @@ fn check_legality_of_move_bindings(cx: &MatchCheckCtxt,
check_move(p, sub.as_ref().map(|p| &**p));
}
}
ast::PatIdent(ast::BindByRef(_), _, _) => {
hir::PatIdent(hir::BindByRef(_), _, _) => {
}
_ => {
cx.tcx.sess.span_bug(
@ -1119,7 +1117,7 @@ fn check_legality_of_move_bindings(cx: &MatchCheckCtxt,
/// Ensures that a pattern guard doesn't borrow by mutable reference or
/// assign.
fn check_for_mutation_in_guard<'a, 'tcx>(cx: &'a MatchCheckCtxt<'a, 'tcx>,
guard: &ast::Expr) {
guard: &hir::Expr) {
let mut checker = MutationChecker {
cx: cx,
};
@ -1188,7 +1186,7 @@ impl<'a, 'b, 'tcx, 'v> Visitor<'v> for AtBindingPatternVisitor<'a, 'b, 'tcx> {
}
match pat.node {
ast::PatIdent(_, _, Some(_)) => {
hir::PatIdent(_, _, Some(_)) => {
let bindings_were_allowed = self.bindings_allowed;
self.bindings_allowed = false;
visit::walk_pat(self, pat);

View File

@ -18,11 +18,12 @@ use middle::ty::ParameterEnvironment;
use middle::ty;
use syntax::ast;
use rustc_front::hir;
use syntax::codemap::Span;
use syntax::visit;
use rustc_front::visit;
pub fn check_crate(tcx: &ty::ctxt,
krate: &ast::Crate) {
krate: &hir::Crate) {
let mut rvcx = RvalueContext { tcx: tcx };
visit::walk_crate(&mut rvcx, krate);
}
@ -34,8 +35,8 @@ struct RvalueContext<'a, 'tcx: 'a> {
impl<'a, 'tcx, 'v> visit::Visitor<'v> for RvalueContext<'a, 'tcx> {
fn visit_fn(&mut self,
fk: visit::FnKind<'v>,
fd: &'v ast::FnDecl,
b: &'v ast::Block,
fd: &'v hir::FnDecl,
b: &'v hir::Block,
s: Span,
fn_id: ast::NodeId) {
{
@ -73,12 +74,12 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for RvalueContextDelegate<'a, 'tcx> {
}
fn matched_pat(&mut self,
_matched_pat: &ast::Pat,
_matched_pat: &hir::Pat,
_cmt: mc::cmt,
_mode: euv::MatchMode) {}
fn consume_pat(&mut self,
_consume_pat: &ast::Pat,
_consume_pat: &hir::Pat,
_cmt: mc::cmt,
_mode: euv::ConsumeMode) {
}

View File

@ -11,7 +11,7 @@
// This compiler pass detects constants that refer to themselves
// recursively.
use ast_map;
use front::map as ast_map;
use session::Session;
use middle::def::{DefStatic, DefConst, DefAssociatedConst, DefVariant, DefMap};
use util::nodemap::NodeMap;
@ -19,8 +19,9 @@ use util::nodemap::NodeMap;
use syntax::{ast};
use syntax::codemap::Span;
use syntax::feature_gate::emit_feature_err;
use syntax::visit::Visitor;
use syntax::visit;
use rustc_front::visit::Visitor;
use rustc_front::visit;
use rustc_front::hir;
use std::cell::RefCell;
@ -32,19 +33,19 @@ struct CheckCrateVisitor<'a, 'ast: 'a> {
// variant definitions with the discriminant expression that applies to
// each one. If the variant uses the default values (starting from `0`),
// then `None` is stored.
discriminant_map: RefCell<NodeMap<Option<&'ast ast::Expr>>>,
discriminant_map: RefCell<NodeMap<Option<&'ast hir::Expr>>>,
}
impl<'a, 'ast: 'a> Visitor<'ast> for CheckCrateVisitor<'a, 'ast> {
fn visit_item(&mut self, it: &'ast ast::Item) {
fn visit_item(&mut self, it: &'ast hir::Item) {
match it.node {
ast::ItemStatic(..) |
ast::ItemConst(..) => {
hir::ItemStatic(..) |
hir::ItemConst(..) => {
let mut recursion_visitor =
CheckItemRecursionVisitor::new(self, &it.span);
recursion_visitor.visit_item(it);
},
ast::ItemEnum(ref enum_def, ref generics) => {
hir::ItemEnum(ref enum_def, ref generics) => {
// We could process the whole enum, but handling the variants
// with discriminant expressions one by one gives more specific,
// less redundant output.
@ -62,9 +63,9 @@ impl<'a, 'ast: 'a> Visitor<'ast> for CheckCrateVisitor<'a, 'ast> {
visit::walk_item(self, it)
}
fn visit_trait_item(&mut self, ti: &'ast ast::TraitItem) {
fn visit_trait_item(&mut self, ti: &'ast hir::TraitItem) {
match ti.node {
ast::ConstTraitItem(_, ref default) => {
hir::ConstTraitItem(_, ref default) => {
if let Some(_) = *default {
let mut recursion_visitor =
CheckItemRecursionVisitor::new(self, &ti.span);
@ -76,9 +77,9 @@ impl<'a, 'ast: 'a> Visitor<'ast> for CheckCrateVisitor<'a, 'ast> {
visit::walk_trait_item(self, ti)
}
fn visit_impl_item(&mut self, ii: &'ast ast::ImplItem) {
fn visit_impl_item(&mut self, ii: &'ast hir::ImplItem) {
match ii.node {
ast::ConstImplItem(..) => {
hir::ConstImplItem(..) => {
let mut recursion_visitor =
CheckItemRecursionVisitor::new(self, &ii.span);
recursion_visitor.visit_impl_item(ii);
@ -90,7 +91,7 @@ impl<'a, 'ast: 'a> Visitor<'ast> for CheckCrateVisitor<'a, 'ast> {
}
pub fn check_crate<'ast>(sess: &Session,
krate: &'ast ast::Crate,
krate: &'ast hir::Crate,
def_map: &DefMap,
ast_map: &ast_map::Map<'ast>) {
let mut visitor = CheckCrateVisitor {
@ -108,7 +109,7 @@ struct CheckItemRecursionVisitor<'a, 'ast: 'a> {
sess: &'a Session,
ast_map: &'a ast_map::Map<'ast>,
def_map: &'a DefMap,
discriminant_map: &'a RefCell<NodeMap<Option<&'ast ast::Expr>>>,
discriminant_map: &'a RefCell<NodeMap<Option<&'ast hir::Expr>>>,
idstack: Vec<ast::NodeId>,
}
@ -129,7 +130,7 @@ impl<'a, 'ast: 'a> CheckItemRecursionVisitor<'a, 'ast> {
if self.idstack.iter().any(|&x| x == id) {
let any_static = self.idstack.iter().any(|&x| {
if let ast_map::NodeItem(item) = self.ast_map.get(x) {
if let ast::ItemStatic(..) = item.node {
if let hir::ItemStatic(..) = item.node {
true
} else {
false
@ -161,7 +162,7 @@ impl<'a, 'ast: 'a> CheckItemRecursionVisitor<'a, 'ast> {
// So for every variant, we need to track whether there is an expression
// somewhere in the enum definition that controls its discriminant. We do
// this by starting from the end and searching backward.
fn populate_enum_discriminants(&self, enum_definition: &'ast ast::EnumDef) {
fn populate_enum_discriminants(&self, enum_definition: &'ast hir::EnumDef) {
// Get the map, and return if we already processed this enum or if it
// has no variants.
let mut discriminant_map = self.discriminant_map.borrow_mut();
@ -195,18 +196,18 @@ impl<'a, 'ast: 'a> CheckItemRecursionVisitor<'a, 'ast> {
}
impl<'a, 'ast: 'a> Visitor<'ast> for CheckItemRecursionVisitor<'a, 'ast> {
fn visit_item(&mut self, it: &'ast ast::Item) {
fn visit_item(&mut self, it: &'ast hir::Item) {
self.with_item_id_pushed(it.id, |v| visit::walk_item(v, it));
}
fn visit_enum_def(&mut self, enum_definition: &'ast ast::EnumDef,
generics: &'ast ast::Generics) {
fn visit_enum_def(&mut self, enum_definition: &'ast hir::EnumDef,
generics: &'ast hir::Generics) {
self.populate_enum_discriminants(enum_definition);
visit::walk_enum_def(self, enum_definition, generics);
}
fn visit_variant(&mut self, variant: &'ast ast::Variant,
_: &'ast ast::Generics) {
fn visit_variant(&mut self, variant: &'ast hir::Variant,
_: &'ast hir::Generics) {
let variant_id = variant.node.id;
let maybe_expr;
if let Some(get_expr) = self.discriminant_map.borrow().get(&variant_id) {
@ -225,17 +226,17 @@ impl<'a, 'ast: 'a> Visitor<'ast> for CheckItemRecursionVisitor<'a, 'ast> {
}
}
fn visit_trait_item(&mut self, ti: &'ast ast::TraitItem) {
fn visit_trait_item(&mut self, ti: &'ast hir::TraitItem) {
self.with_item_id_pushed(ti.id, |v| visit::walk_trait_item(v, ti));
}
fn visit_impl_item(&mut self, ii: &'ast ast::ImplItem) {
fn visit_impl_item(&mut self, ii: &'ast hir::ImplItem) {
self.with_item_id_pushed(ii.id, |v| visit::walk_impl_item(v, ii));
}
fn visit_expr(&mut self, e: &'ast ast::Expr) {
fn visit_expr(&mut self, e: &'ast hir::Expr) {
match e.node {
ast::ExprPath(..) => {
hir::ExprPath(..) => {
match self.def_map.borrow().get(&e.id).map(|d| d.base_def) {
Some(DefStatic(def_id, _)) |
Some(DefAssociatedConst(def_id)) |
@ -261,7 +262,7 @@ impl<'a, 'ast: 'a> Visitor<'ast> for CheckItemRecursionVisitor<'a, 'ast> {
// the whole enum definition to see what expression that
// might be (if any).
Some(DefVariant(enum_id, variant_id, false)) if enum_id.is_local() => {
if let ast::ItemEnum(ref enum_def, ref generics) =
if let hir::ItemEnum(ref enum_def, ref generics) =
self.ast_map.expect_item(enum_id.local_id()).node {
self.populate_enum_discriminants(enum_def);
let variant = self.ast_map.expect_variant(variant_id.local_id());

View File

@ -14,8 +14,8 @@ use self::ConstVal::*;
use self::ErrKind::*;
use self::EvalHint::*;
use ast_map;
use ast_map::blocks::FnLikeNode;
use front::map as ast_map;
use front::map::blocks::FnLikeNode;
use metadata::csearch;
use metadata::inline::InlinedItem;
use middle::{astencode, def, infer, subst, traits};
@ -25,11 +25,14 @@ use middle::ty::{self, Ty};
use middle::astconv_util::ast_ty_to_prim_ty;
use util::num::ToPrimitive;
use syntax::ast::{self, Expr};
use syntax::codemap::{self, Span};
use syntax::ast;
use rustc_front::hir::Expr;
use rustc_front::hir;
use rustc_front::visit::FnKind;
use syntax::codemap::Span;
use syntax::parse::token::InternedString;
use syntax::ptr::P;
use syntax::visit::FnKind;
use syntax::codemap;
use std::borrow::{Cow, IntoCow};
use std::num::wrapping::OverflowingOps;
@ -56,7 +59,7 @@ fn lookup_variant_by_id<'a>(tcx: &'a ty::ctxt,
enum_def: DefId,
variant_def: DefId)
-> Option<&'a Expr> {
fn variant_expr<'a>(variants: &'a [P<ast::Variant>], id: ast::NodeId)
fn variant_expr<'a>(variants: &'a [P<hir::Variant>], id: ast::NodeId)
-> Option<&'a Expr> {
for variant in variants {
if variant.node.id == id {
@ -70,7 +73,7 @@ fn lookup_variant_by_id<'a>(tcx: &'a ty::ctxt,
match tcx.map.find(enum_def.node) {
None => None,
Some(ast_map::NodeItem(it)) => match it.node {
ast::ItemEnum(ast::EnumDef { ref variants }, _) => {
hir::ItemEnum(hir::EnumDef { ref variants }, _) => {
variant_expr(&variants[..], variant_def.node)
}
_ => None
@ -88,7 +91,7 @@ fn lookup_variant_by_id<'a>(tcx: &'a ty::ctxt,
let expr_id = match csearch::maybe_get_item_ast(tcx, enum_def,
Box::new(|a, b, c, d| astencode::decode_inlined_item(a, b, c, d))) {
csearch::FoundAst::Found(&InlinedItem::Item(ref item)) => match item.node {
ast::ItemEnum(ast::EnumDef { ref variants }, _) => {
hir::ItemEnum(hir::EnumDef { ref variants }, _) => {
// NOTE this doesn't do the right thing, it compares inlined
// NodeId's to the original variant_def's NodeId, but they
// come from different crates, so they will likely never match.
@ -112,13 +115,13 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: &'a ty::ctxt<'tcx>,
match tcx.map.find(def_id.node) {
None => None,
Some(ast_map::NodeItem(it)) => match it.node {
ast::ItemConst(_, ref const_expr) => {
hir::ItemConst(_, ref const_expr) => {
Some(&*const_expr)
}
_ => None
},
Some(ast_map::NodeTraitItem(ti)) => match ti.node {
ast::ConstTraitItem(_, _) => {
hir::ConstTraitItem(_, _) => {
match maybe_ref_id {
// If we have a trait item, and we know the expression
// that's the source of the obligation to resolve it,
@ -144,7 +147,7 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: &'a ty::ctxt<'tcx>,
_ => None
},
Some(ast_map::NodeImplItem(ii)) => match ii.node {
ast::ConstImplItem(_, ref expr) => {
hir::ConstImplItem(_, ref expr) => {
Some(&*expr)
}
_ => None
@ -163,11 +166,11 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: &'a ty::ctxt<'tcx>,
let expr_id = match csearch::maybe_get_item_ast(tcx, def_id,
Box::new(|a, b, c, d| astencode::decode_inlined_item(a, b, c, d))) {
csearch::FoundAst::Found(&InlinedItem::Item(ref item)) => match item.node {
ast::ItemConst(_, ref const_expr) => Some(const_expr.id),
hir::ItemConst(_, ref const_expr) => Some(const_expr.id),
_ => None
},
csearch::FoundAst::Found(&InlinedItem::TraitItem(trait_id, ref ti)) => match ti.node {
ast::ConstTraitItem(_, _) => {
hir::ConstTraitItem(_, _) => {
used_ref_id = true;
match maybe_ref_id {
// As mentioned in the comments above for in-crate
@ -186,7 +189,7 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: &'a ty::ctxt<'tcx>,
_ => None
},
csearch::FoundAst::Found(&InlinedItem::ImplItem(_, ref ii)) => match ii.node {
ast::ConstImplItem(_, ref expr) => Some(expr.id),
hir::ConstImplItem(_, ref expr) => Some(expr.id),
_ => None
},
_ => None
@ -246,11 +249,11 @@ pub fn lookup_const_fn_by_id<'tcx>(tcx: &ty::ctxt<'tcx>, def_id: DefId)
};
match fn_like.kind() {
FnKind::ItemFn(_, _, _, ast::Constness::Const, _, _) => {
FnKind::ItemFn(_, _, _, hir::Constness::Const, _, _) => {
Some(fn_like)
}
FnKind::Method(_, m, _) => {
if m.constness == ast::Constness::Const {
if m.constness == hir::Constness::Const {
Some(fn_like)
} else {
None
@ -288,12 +291,12 @@ impl ConstVal {
}
}
pub fn const_expr_to_pat(tcx: &ty::ctxt, expr: &Expr, span: Span) -> P<ast::Pat> {
pub fn const_expr_to_pat(tcx: &ty::ctxt, expr: &Expr, span: Span) -> P<hir::Pat> {
let pat = match expr.node {
ast::ExprTup(ref exprs) =>
ast::PatTup(exprs.iter().map(|expr| const_expr_to_pat(tcx, &**expr, span)).collect()),
hir::ExprTup(ref exprs) =>
hir::PatTup(exprs.iter().map(|expr| const_expr_to_pat(tcx, &**expr, span)).collect()),
ast::ExprCall(ref callee, ref args) => {
hir::ExprCall(ref callee, ref args) => {
let def = *tcx.def_map.borrow().get(&callee.id).unwrap();
if let Vacant(entry) = tcx.def_map.borrow_mut().entry(expr.id) {
entry.insert(def);
@ -304,33 +307,33 @@ pub fn const_expr_to_pat(tcx: &ty::ctxt, expr: &Expr, span: Span) -> P<ast::Pat>
_ => unreachable!()
};
let pats = args.iter().map(|expr| const_expr_to_pat(tcx, &**expr, span)).collect();
ast::PatEnum(path, Some(pats))
hir::PatEnum(path, Some(pats))
}
ast::ExprStruct(ref path, ref fields, None) => {
hir::ExprStruct(ref path, ref fields, None) => {
let field_pats = fields.iter().map(|field| codemap::Spanned {
span: codemap::DUMMY_SP,
node: ast::FieldPat {
node: hir::FieldPat {
ident: field.ident.node,
pat: const_expr_to_pat(tcx, &*field.expr, span),
is_shorthand: false,
},
}).collect();
ast::PatStruct(path.clone(), field_pats, false)
hir::PatStruct(path.clone(), field_pats, false)
}
ast::ExprVec(ref exprs) => {
hir::ExprVec(ref exprs) => {
let pats = exprs.iter().map(|expr| const_expr_to_pat(tcx, &**expr, span)).collect();
ast::PatVec(pats, None, vec![])
hir::PatVec(pats, None, vec![])
}
ast::ExprPath(_, ref path) => {
hir::ExprPath(_, ref path) => {
let opt_def = tcx.def_map.borrow().get(&expr.id).map(|d| d.full_def());
match opt_def {
Some(def::DefStruct(..)) =>
ast::PatStruct(path.clone(), vec![], false),
hir::PatStruct(path.clone(), vec![], false),
Some(def::DefVariant(..)) =>
ast::PatEnum(path.clone(), None),
hir::PatEnum(path.clone(), None),
_ => {
match lookup_const(tcx, expr) {
Some(actual) => return const_expr_to_pat(tcx, actual, span),
@ -340,9 +343,9 @@ pub fn const_expr_to_pat(tcx: &ty::ctxt, expr: &Expr, span: Span) -> P<ast::Pat>
}
}
_ => ast::PatLit(P(expr.clone()))
_ => hir::PatLit(P(expr.clone()))
};
P(ast::Pat { id: expr.id, node: pat, span: span })
P(hir::Pat { id: expr.id, node: pat, span: span })
}
pub fn eval_const_expr(tcx: &ty::ctxt, e: &Expr) -> ConstVal {
@ -363,10 +366,10 @@ pub struct ConstEvalErr {
pub enum ErrKind {
CannotCast,
CannotCastTo(&'static str),
InvalidOpForBools(ast::BinOp_),
InvalidOpForFloats(ast::BinOp_),
InvalidOpForIntUint(ast::BinOp_),
InvalidOpForUintInt(ast::BinOp_),
InvalidOpForBools(hir::BinOp_),
InvalidOpForFloats(hir::BinOp_),
InvalidOpForIntUint(hir::BinOp_),
InvalidOpForUintInt(hir::BinOp_),
NegateOn(ConstVal),
NotOn(ConstVal),
@ -463,35 +466,35 @@ pub enum IntTy { I8, I16, I32, I64 }
pub enum UintTy { U8, U16, U32, U64 }
impl IntTy {
pub fn from(tcx: &ty::ctxt, t: ast::IntTy) -> IntTy {
let t = if let ast::TyIs = t {
pub fn from(tcx: &ty::ctxt, t: hir::IntTy) -> IntTy {
let t = if let hir::TyIs = t {
tcx.sess.target.int_type
} else {
t
};
match t {
ast::TyIs => unreachable!(),
ast::TyI8 => IntTy::I8,
ast::TyI16 => IntTy::I16,
ast::TyI32 => IntTy::I32,
ast::TyI64 => IntTy::I64,
hir::TyIs => unreachable!(),
hir::TyI8 => IntTy::I8,
hir::TyI16 => IntTy::I16,
hir::TyI32 => IntTy::I32,
hir::TyI64 => IntTy::I64,
}
}
}
impl UintTy {
pub fn from(tcx: &ty::ctxt, t: ast::UintTy) -> UintTy {
let t = if let ast::TyUs = t {
pub fn from(tcx: &ty::ctxt, t: hir::UintTy) -> UintTy {
let t = if let hir::TyUs = t {
tcx.sess.target.uint_type
} else {
t
};
match t {
ast::TyUs => unreachable!(),
ast::TyU8 => UintTy::U8,
ast::TyU16 => UintTy::U16,
ast::TyU32 => UintTy::U32,
ast::TyU64 => UintTy::U64,
hir::TyUs => unreachable!(),
hir::TyU8 => UintTy::U8,
hir::TyU16 => UintTy::U16,
hir::TyU32 => UintTy::U32,
hir::TyU64 => UintTy::U64,
}
}
}
@ -769,7 +772,7 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
});
let result = match e.node {
ast::ExprUnary(ast::UnNeg, ref inner) => {
hir::ExprUnary(hir::UnNeg, ref inner) => {
match try!(eval_const_expr_partial(tcx, &**inner, ty_hint)) {
Float(f) => Float(-f),
Int(n) => try!(const_int_checked_neg(n, e, expr_int_type)),
@ -779,7 +782,7 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
const_val => signal!(e, NegateOn(const_val)),
}
}
ast::ExprUnary(ast::UnNot, ref inner) => {
hir::ExprUnary(hir::UnNot, ref inner) => {
match try!(eval_const_expr_partial(tcx, &**inner, ty_hint)) {
Int(i) => Int(!i),
Uint(i) => const_uint_not(i, expr_uint_type),
@ -787,9 +790,9 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
const_val => signal!(e, NotOn(const_val)),
}
}
ast::ExprBinary(op, ref a, ref b) => {
hir::ExprBinary(op, ref a, ref b) => {
let b_ty = match op.node {
ast::BiShl | ast::BiShr => {
hir::BiShl | hir::BiShr => {
if let ExprTypeChecked = ty_hint {
ExprTypeChecked
} else {
@ -802,84 +805,84 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
try!(eval_const_expr_partial(tcx, &**b, b_ty))) {
(Float(a), Float(b)) => {
match op.node {
ast::BiAdd => Float(a + b),
ast::BiSub => Float(a - b),
ast::BiMul => Float(a * b),
ast::BiDiv => Float(a / b),
ast::BiRem => Float(a % b),
ast::BiEq => fromb(a == b),
ast::BiLt => fromb(a < b),
ast::BiLe => fromb(a <= b),
ast::BiNe => fromb(a != b),
ast::BiGe => fromb(a >= b),
ast::BiGt => fromb(a > b),
hir::BiAdd => Float(a + b),
hir::BiSub => Float(a - b),
hir::BiMul => Float(a * b),
hir::BiDiv => Float(a / b),
hir::BiRem => Float(a % b),
hir::BiEq => fromb(a == b),
hir::BiLt => fromb(a < b),
hir::BiLe => fromb(a <= b),
hir::BiNe => fromb(a != b),
hir::BiGe => fromb(a >= b),
hir::BiGt => fromb(a > b),
_ => signal!(e, InvalidOpForFloats(op.node))
}
}
(Int(a), Int(b)) => {
match op.node {
ast::BiAdd => try!(const_int_checked_add(a,b,e,expr_int_type)),
ast::BiSub => try!(const_int_checked_sub(a,b,e,expr_int_type)),
ast::BiMul => try!(const_int_checked_mul(a,b,e,expr_int_type)),
ast::BiDiv => try!(const_int_checked_div(a,b,e,expr_int_type)),
ast::BiRem => try!(const_int_checked_rem(a,b,e,expr_int_type)),
ast::BiAnd | ast::BiBitAnd => Int(a & b),
ast::BiOr | ast::BiBitOr => Int(a | b),
ast::BiBitXor => Int(a ^ b),
ast::BiShl => try!(const_int_checked_shl(a,b,e,expr_int_type)),
ast::BiShr => try!(const_int_checked_shr(a,b,e,expr_int_type)),
ast::BiEq => fromb(a == b),
ast::BiLt => fromb(a < b),
ast::BiLe => fromb(a <= b),
ast::BiNe => fromb(a != b),
ast::BiGe => fromb(a >= b),
ast::BiGt => fromb(a > b)
hir::BiAdd => try!(const_int_checked_add(a,b,e,expr_int_type)),
hir::BiSub => try!(const_int_checked_sub(a,b,e,expr_int_type)),
hir::BiMul => try!(const_int_checked_mul(a,b,e,expr_int_type)),
hir::BiDiv => try!(const_int_checked_div(a,b,e,expr_int_type)),
hir::BiRem => try!(const_int_checked_rem(a,b,e,expr_int_type)),
hir::BiAnd | hir::BiBitAnd => Int(a & b),
hir::BiOr | hir::BiBitOr => Int(a | b),
hir::BiBitXor => Int(a ^ b),
hir::BiShl => try!(const_int_checked_shl(a,b,e,expr_int_type)),
hir::BiShr => try!(const_int_checked_shr(a,b,e,expr_int_type)),
hir::BiEq => fromb(a == b),
hir::BiLt => fromb(a < b),
hir::BiLe => fromb(a <= b),
hir::BiNe => fromb(a != b),
hir::BiGe => fromb(a >= b),
hir::BiGt => fromb(a > b)
}
}
(Uint(a), Uint(b)) => {
match op.node {
ast::BiAdd => try!(const_uint_checked_add(a,b,e,expr_uint_type)),
ast::BiSub => try!(const_uint_checked_sub(a,b,e,expr_uint_type)),
ast::BiMul => try!(const_uint_checked_mul(a,b,e,expr_uint_type)),
ast::BiDiv => try!(const_uint_checked_div(a,b,e,expr_uint_type)),
ast::BiRem => try!(const_uint_checked_rem(a,b,e,expr_uint_type)),
ast::BiAnd | ast::BiBitAnd => Uint(a & b),
ast::BiOr | ast::BiBitOr => Uint(a | b),
ast::BiBitXor => Uint(a ^ b),
ast::BiShl => try!(const_uint_checked_shl(a,b,e,expr_uint_type)),
ast::BiShr => try!(const_uint_checked_shr(a,b,e,expr_uint_type)),
ast::BiEq => fromb(a == b),
ast::BiLt => fromb(a < b),
ast::BiLe => fromb(a <= b),
ast::BiNe => fromb(a != b),
ast::BiGe => fromb(a >= b),
ast::BiGt => fromb(a > b),
hir::BiAdd => try!(const_uint_checked_add(a,b,e,expr_uint_type)),
hir::BiSub => try!(const_uint_checked_sub(a,b,e,expr_uint_type)),
hir::BiMul => try!(const_uint_checked_mul(a,b,e,expr_uint_type)),
hir::BiDiv => try!(const_uint_checked_div(a,b,e,expr_uint_type)),
hir::BiRem => try!(const_uint_checked_rem(a,b,e,expr_uint_type)),
hir::BiAnd | hir::BiBitAnd => Uint(a & b),
hir::BiOr | hir::BiBitOr => Uint(a | b),
hir::BiBitXor => Uint(a ^ b),
hir::BiShl => try!(const_uint_checked_shl(a,b,e,expr_uint_type)),
hir::BiShr => try!(const_uint_checked_shr(a,b,e,expr_uint_type)),
hir::BiEq => fromb(a == b),
hir::BiLt => fromb(a < b),
hir::BiLe => fromb(a <= b),
hir::BiNe => fromb(a != b),
hir::BiGe => fromb(a >= b),
hir::BiGt => fromb(a > b),
}
}
// shifts can have any integral type as their rhs
(Int(a), Uint(b)) => {
match op.node {
ast::BiShl => try!(const_int_checked_shl_via_uint(a,b,e,expr_int_type)),
ast::BiShr => try!(const_int_checked_shr_via_uint(a,b,e,expr_int_type)),
hir::BiShl => try!(const_int_checked_shl_via_uint(a,b,e,expr_int_type)),
hir::BiShr => try!(const_int_checked_shr_via_uint(a,b,e,expr_int_type)),
_ => signal!(e, InvalidOpForIntUint(op.node)),
}
}
(Uint(a), Int(b)) => {
match op.node {
ast::BiShl => try!(const_uint_checked_shl_via_int(a,b,e,expr_uint_type)),
ast::BiShr => try!(const_uint_checked_shr_via_int(a,b,e,expr_uint_type)),
hir::BiShl => try!(const_uint_checked_shl_via_int(a,b,e,expr_uint_type)),
hir::BiShr => try!(const_uint_checked_shr_via_int(a,b,e,expr_uint_type)),
_ => signal!(e, InvalidOpForUintInt(op.node)),
}
}
(Bool(a), Bool(b)) => {
Bool(match op.node {
ast::BiAnd => a && b,
ast::BiOr => a || b,
ast::BiBitXor => a ^ b,
ast::BiBitAnd => a & b,
ast::BiBitOr => a | b,
ast::BiEq => a == b,
ast::BiNe => a != b,
hir::BiAnd => a && b,
hir::BiOr => a || b,
hir::BiBitXor => a ^ b,
hir::BiBitAnd => a & b,
hir::BiBitOr => a | b,
hir::BiEq => a == b,
hir::BiNe => a != b,
_ => signal!(e, InvalidOpForBools(op.node)),
})
}
@ -887,7 +890,7 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
_ => signal!(e, MiscBinaryOp),
}
}
ast::ExprCast(ref base, ref target_ty) => {
hir::ExprCast(ref base, ref target_ty) => {
let ety = ety.or_else(|| ast_ty_to_prim_ty(tcx, &**target_ty))
.unwrap_or_else(|| {
tcx.sess.span_fatal(target_ty.span,
@ -912,14 +915,14 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
Err(kind) => return Err(ConstEvalErr { span: e.span, kind: kind }),
}
}
ast::ExprPath(..) => {
hir::ExprPath(..) => {
let opt_def = tcx.def_map.borrow().get(&e.id).map(|d| d.full_def());
let (const_expr, const_ty) = match opt_def {
Some(def::DefConst(def_id)) => {
if def_id.is_local() {
match tcx.map.find(def_id.node) {
Some(ast_map::NodeItem(it)) => match it.node {
ast::ItemConst(ref ty, ref expr) => {
hir::ItemConst(ref ty, ref expr) => {
(Some(&**expr), Some(&**ty))
}
_ => (None, None)
@ -935,7 +938,7 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
match tcx.impl_or_trait_item(def_id).container() {
ty::TraitContainer(trait_id) => match tcx.map.find(def_id.node) {
Some(ast_map::NodeTraitItem(ti)) => match ti.node {
ast::ConstTraitItem(ref ty, _) => {
hir::ConstTraitItem(ref ty, _) => {
if let ExprTypeChecked = ty_hint {
let substs = tcx.node_id_item_substs(e.id).substs;
(resolve_trait_associated_const(tcx,
@ -953,7 +956,7 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
},
ty::ImplContainer(_) => match tcx.map.find(def_id.node) {
Some(ast_map::NodeImplItem(ii)) => match ii.node {
ast::ConstImplItem(ref ty, ref expr) => {
hir::ConstImplItem(ref ty, ref expr) => {
(Some(&**expr), Some(&**ty))
}
_ => (None, None)
@ -990,19 +993,19 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
};
try!(eval_const_expr_partial(tcx, const_expr, item_hint))
}
ast::ExprLit(ref lit) => {
hir::ExprLit(ref lit) => {
lit_to_const(&**lit, ety)
}
ast::ExprParen(ref e) => try!(eval_const_expr_partial(tcx, &**e, ty_hint)),
ast::ExprBlock(ref block) => {
hir::ExprParen(ref e) => try!(eval_const_expr_partial(tcx, &**e, ty_hint)),
hir::ExprBlock(ref block) => {
match block.expr {
Some(ref expr) => try!(eval_const_expr_partial(tcx, &**expr, ty_hint)),
None => Int(0)
}
}
ast::ExprTup(_) => Tuple(e.id),
ast::ExprStruct(..) => Struct(e.id),
ast::ExprTupField(ref base, index) => {
hir::ExprTup(_) => Tuple(e.id),
hir::ExprStruct(..) => Struct(e.id),
hir::ExprTupField(ref base, index) => {
let base_hint = if let ExprTypeChecked = ty_hint {
ExprTypeChecked
} else {
@ -1010,7 +1013,7 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
};
if let Ok(c) = eval_const_expr_partial(tcx, base, base_hint) {
if let Tuple(tup_id) = c {
if let ast::ExprTup(ref fields) = tcx.map.expect_expr(tup_id).node {
if let hir::ExprTup(ref fields) = tcx.map.expect_expr(tup_id).node {
if index.node < fields.len() {
return eval_const_expr_partial(tcx, &fields[index.node], base_hint)
} else {
@ -1026,7 +1029,7 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
signal!(base, NonConstPath)
}
}
ast::ExprField(ref base, field_name) => {
hir::ExprField(ref base, field_name) => {
// Get the base expression if it is a struct and it is constant
let base_hint = if let ExprTypeChecked = ty_hint {
ExprTypeChecked
@ -1035,7 +1038,7 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
};
if let Ok(c) = eval_const_expr_partial(tcx, base, base_hint) {
if let Struct(struct_id) = c {
if let ast::ExprStruct(_, ref fields, _) = tcx.map.expect_expr(struct_id).node {
if let hir::ExprStruct(_, ref fields, _) = tcx.map.expect_expr(struct_id).node {
// Check that the given field exists and evaluate it
// if the idents are compared run-pass/issue-19244 fails
if let Some(f) = fields.iter().find(|f| f.ident.node.name
@ -1061,7 +1064,7 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
}
fn resolve_trait_associated_const<'a, 'tcx: 'a>(tcx: &'a ty::ctxt<'tcx>,
ti: &'tcx ast::TraitItem,
ti: &'tcx hir::TraitItem,
trait_id: DefId,
rcvr_substs: subst::Substs<'tcx>)
-> Option<&'tcx Expr>
@ -1110,7 +1113,7 @@ fn resolve_trait_associated_const<'a, 'tcx: 'a>(tcx: &'a ty::ctxt<'tcx>,
.iter().find(|ic| ic.name == ti.ident.name) {
Some(ic) => lookup_const_by_id(tcx, ic.def_id, None),
None => match ti.node {
ast::ConstTraitItem(_, Some(ref expr)) => Some(&*expr),
hir::ConstTraitItem(_, Some(ref expr)) => Some(&*expr),
_ => None,
},
}
@ -1138,60 +1141,60 @@ fn cast_const<'tcx>(tcx: &ty::ctxt<'tcx>, val: ConstVal, ty: Ty) -> CastResult {
// Issue #23890: If isize/usize, then dispatch to appropriate target representation type
match (&ty.sty, tcx.sess.target.int_type, tcx.sess.target.uint_type) {
(&ty::TyInt(ast::TyIs), ast::TyI32, _) => return convert_val!(i32, Int, i64),
(&ty::TyInt(ast::TyIs), ast::TyI64, _) => return convert_val!(i64, Int, i64),
(&ty::TyInt(ast::TyIs), _, _) => panic!("unexpected target.int_type"),
(&ty::TyInt(hir::TyIs), hir::TyI32, _) => return convert_val!(i32, Int, i64),
(&ty::TyInt(hir::TyIs), hir::TyI64, _) => return convert_val!(i64, Int, i64),
(&ty::TyInt(hir::TyIs), _, _) => panic!("unexpected target.int_type"),
(&ty::TyUint(ast::TyUs), _, ast::TyU32) => return convert_val!(u32, Uint, u64),
(&ty::TyUint(ast::TyUs), _, ast::TyU64) => return convert_val!(u64, Uint, u64),
(&ty::TyUint(ast::TyUs), _, _) => panic!("unexpected target.uint_type"),
(&ty::TyUint(hir::TyUs), _, hir::TyU32) => return convert_val!(u32, Uint, u64),
(&ty::TyUint(hir::TyUs), _, hir::TyU64) => return convert_val!(u64, Uint, u64),
(&ty::TyUint(hir::TyUs), _, _) => panic!("unexpected target.uint_type"),
_ => {}
}
match ty.sty {
ty::TyInt(ast::TyIs) => unreachable!(),
ty::TyUint(ast::TyUs) => unreachable!(),
ty::TyInt(hir::TyIs) => unreachable!(),
ty::TyUint(hir::TyUs) => unreachable!(),
ty::TyInt(ast::TyI8) => convert_val!(i8, Int, i64),
ty::TyInt(ast::TyI16) => convert_val!(i16, Int, i64),
ty::TyInt(ast::TyI32) => convert_val!(i32, Int, i64),
ty::TyInt(ast::TyI64) => convert_val!(i64, Int, i64),
ty::TyInt(hir::TyI8) => convert_val!(i8, Int, i64),
ty::TyInt(hir::TyI16) => convert_val!(i16, Int, i64),
ty::TyInt(hir::TyI32) => convert_val!(i32, Int, i64),
ty::TyInt(hir::TyI64) => convert_val!(i64, Int, i64),
ty::TyUint(ast::TyU8) => convert_val!(u8, Uint, u64),
ty::TyUint(ast::TyU16) => convert_val!(u16, Uint, u64),
ty::TyUint(ast::TyU32) => convert_val!(u32, Uint, u64),
ty::TyUint(ast::TyU64) => convert_val!(u64, Uint, u64),
ty::TyUint(hir::TyU8) => convert_val!(u8, Uint, u64),
ty::TyUint(hir::TyU16) => convert_val!(u16, Uint, u64),
ty::TyUint(hir::TyU32) => convert_val!(u32, Uint, u64),
ty::TyUint(hir::TyU64) => convert_val!(u64, Uint, u64),
ty::TyFloat(ast::TyF32) => convert_val!(f32, Float, f64),
ty::TyFloat(ast::TyF64) => convert_val!(f64, Float, f64),
ty::TyFloat(hir::TyF32) => convert_val!(f32, Float, f64),
ty::TyFloat(hir::TyF64) => convert_val!(f64, Float, f64),
_ => Err(ErrKind::CannotCast),
}
}
fn lit_to_const(lit: &ast::Lit, ty_hint: Option<Ty>) -> ConstVal {
fn lit_to_const(lit: &hir::Lit, ty_hint: Option<Ty>) -> ConstVal {
match lit.node {
ast::LitStr(ref s, _) => Str((*s).clone()),
ast::LitBinary(ref data) => {
hir::LitStr(ref s, _) => Str((*s).clone()),
hir::LitBinary(ref data) => {
Binary(data.clone())
}
ast::LitByte(n) => Uint(n as u64),
ast::LitChar(n) => Uint(n as u64),
ast::LitInt(n, ast::SignedIntLit(_, ast::Plus)) => Int(n as i64),
ast::LitInt(n, ast::UnsuffixedIntLit(ast::Plus)) => {
hir::LitByte(n) => Uint(n as u64),
hir::LitChar(n) => Uint(n as u64),
hir::LitInt(n, hir::SignedIntLit(_, hir::Plus)) => Int(n as i64),
hir::LitInt(n, hir::UnsuffixedIntLit(hir::Plus)) => {
match ty_hint.map(|ty| &ty.sty) {
Some(&ty::TyUint(_)) => Uint(n),
_ => Int(n as i64)
}
}
ast::LitInt(n, ast::SignedIntLit(_, ast::Minus)) |
ast::LitInt(n, ast::UnsuffixedIntLit(ast::Minus)) => Int(-(n as i64)),
ast::LitInt(n, ast::UnsignedIntLit(_)) => Uint(n),
ast::LitFloat(ref n, _) |
ast::LitFloatUnsuffixed(ref n) => {
hir::LitInt(n, hir::SignedIntLit(_, hir::Minus)) |
hir::LitInt(n, hir::UnsuffixedIntLit(hir::Minus)) => Int(-(n as i64)),
hir::LitInt(n, hir::UnsignedIntLit(_)) => Uint(n),
hir::LitFloat(ref n, _) |
hir::LitFloatUnsuffixed(ref n) => {
Float(n.parse::<f64>().unwrap() as f64)
}
ast::LitBool(b) => Bool(b)
hir::LitBool(b) => Bool(b)
}
}

View File

@ -23,9 +23,12 @@ use std::io;
use std::usize;
use syntax::ast;
use syntax::ast_util::IdRange;
use syntax::visit;
use syntax::print::{pp, pprust};
use syntax::print::pp;
use util::nodemap::NodeMap;
use rustc_front::hir;
use rustc_front::visit;
use rustc_front::print::pprust;
#[derive(Copy, Clone, Debug)]
pub enum EntryOrExit {
@ -158,7 +161,7 @@ impl<'a, 'tcx, O:DataFlowOperator> pprust::PpAnn for DataFlowContext<'a, 'tcx, O
}
}
fn build_nodeid_to_index(decl: Option<&ast::FnDecl>,
fn build_nodeid_to_index(decl: Option<&hir::FnDecl>,
cfg: &cfg::CFG) -> NodeMap<Vec<CFGIndex>> {
let mut index = NodeMap();
@ -181,7 +184,7 @@ fn build_nodeid_to_index(decl: Option<&ast::FnDecl>,
return index;
fn add_entries_from_fn_decl(index: &mut NodeMap<Vec<CFGIndex>>,
decl: &ast::FnDecl,
decl: &hir::FnDecl,
entry: CFGIndex) {
//! add mappings from the ast nodes for the formal bindings to
//! the entry-node in the graph.
@ -192,7 +195,7 @@ fn build_nodeid_to_index(decl: Option<&ast::FnDecl>,
let mut formals = Formals { entry: entry, index: index };
visit::walk_fn_decl(&mut formals, decl);
impl<'a, 'v> visit::Visitor<'v> for Formals<'a> {
fn visit_pat(&mut self, p: &ast::Pat) {
fn visit_pat(&mut self, p: &hir::Pat) {
self.index.entry(p.id).or_insert(vec![]).push(self.entry);
visit::walk_pat(self, p)
}
@ -222,7 +225,7 @@ pub enum KillFrom {
impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> {
pub fn new(tcx: &'a ty::ctxt<'tcx>,
analysis_name: &'static str,
decl: Option<&ast::FnDecl>,
decl: Option<&hir::FnDecl>,
cfg: &cfg::CFG,
oper: O,
id_range: IdRange,
@ -495,7 +498,7 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> {
impl<'a, 'tcx, O:DataFlowOperator+Clone+'static> DataFlowContext<'a, 'tcx, O> {
// ^^^^^^^^^^^^^ only needed for pretty printing
pub fn propagate(&mut self, cfg: &cfg::CFG, blk: &ast::Block) {
pub fn propagate(&mut self, cfg: &cfg::CFG, blk: &hir::Block) {
//! Performs the data flow analysis.
if self.bits_per_id == 0 {
@ -528,7 +531,7 @@ impl<'a, 'tcx, O:DataFlowOperator+Clone+'static> DataFlowContext<'a, 'tcx, O> {
}
fn pretty_print_to<'b>(&self, wr: Box<io::Write + 'b>,
blk: &ast::Block) -> io::Result<()> {
blk: &hir::Block) -> io::Result<()> {
let mut ps = pprust::rust_printer_annotated(wr, self);
try!(ps.cbox(pprust::indent_unit));
try!(ps.ibox(0));

View File

@ -12,7 +12,11 @@
// closely. The idea is that all reachable symbols are live, codes called
// from live codes are live, and everything else is dead.
use ast_map;
use front::map as ast_map;
use rustc_front::hir;
use rustc_front::visit::{self, Visitor};
use rustc_front::attr::{self, AttrMetaMethods};
use middle::{def, pat_util, privacy, ty};
use middle::def_id::{DefId};
use lint;
@ -20,8 +24,6 @@ use util::nodemap::NodeSet;
use std::collections::HashSet;
use syntax::{ast, codemap};
use syntax::attr::{self, AttrMetaMethods};
use syntax::visit::{self, Visitor};
// 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
@ -109,7 +111,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
self.check_def_id(method.def_id);
}
fn handle_field_access(&mut self, lhs: &ast::Expr, name: ast::Name) {
fn handle_field_access(&mut self, lhs: &hir::Expr, name: ast::Name) {
if let ty::TyStruct(def, _) = self.tcx.expr_ty_adjusted(lhs).sty {
self.live_symbols.insert(def.struct_variant().field_named(name).did.node);
} else {
@ -117,14 +119,14 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
}
}
fn handle_tup_field_access(&mut self, lhs: &ast::Expr, idx: usize) {
fn handle_tup_field_access(&mut self, lhs: &hir::Expr, idx: usize) {
if let ty::TyStruct(def, _) = self.tcx.expr_ty_adjusted(lhs).sty {
self.live_symbols.insert(def.struct_variant().fields[idx].did.node);
}
}
fn handle_field_pattern_match(&mut self, lhs: &ast::Pat,
pats: &[codemap::Spanned<ast::FieldPat>]) {
fn handle_field_pattern_match(&mut self, lhs: &hir::Pat,
pats: &[codemap::Spanned<hir::FieldPat>]) {
let def = self.tcx.def_map.borrow().get(&lhs.id).unwrap().full_def();
let pat_ty = self.tcx.node_id_to_type(lhs.id);
let variant = match pat_ty.sty {
@ -132,7 +134,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
_ => self.tcx.sess.span_bug(lhs.span, "non-ADT in struct pattern")
};
for pat in pats {
if let ast::PatWild(ast::PatWildSingle) = pat.node.pat.node {
if let hir::PatWild(hir::PatWildSingle) = pat.node.pat.node {
continue;
}
self.live_symbols.insert(variant.field_named(pat.node.ident.name).did.node);
@ -166,7 +168,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
match *node {
ast_map::NodeItem(item) => {
match item.node {
ast::ItemStruct(..) => {
hir::ItemStruct(..) => {
self.struct_has_extern_repr = item.attrs.iter().any(|attr| {
attr::find_repr_attrs(self.tcx.sess.diagnostic(), attr)
.contains(&attr::ReprExtern)
@ -174,14 +176,14 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
visit::walk_item(self, &*item);
}
ast::ItemEnum(..) => {
self.inherited_pub_visibility = item.vis == ast::Public;
hir::ItemEnum(..) => {
self.inherited_pub_visibility = item.vis == hir::Public;
visit::walk_item(self, &*item);
}
ast::ItemFn(..)
| ast::ItemTy(..)
| ast::ItemStatic(..)
| ast::ItemConst(..) => {
hir::ItemFn(..)
| hir::ItemTy(..)
| hir::ItemStatic(..)
| hir::ItemConst(..) => {
visit::walk_item(self, &*item);
}
_ => ()
@ -205,13 +207,13 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
impl<'a, 'tcx, 'v> Visitor<'v> for MarkSymbolVisitor<'a, 'tcx> {
fn visit_struct_def(&mut self, def: &ast::StructDef, _: ast::Ident,
_: &ast::Generics, _: ast::NodeId) {
fn visit_struct_def(&mut self, def: &hir::StructDef, _: ast::Ident,
_: &hir::Generics, _: ast::NodeId) {
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| {
has_extern_repr || inherited_pub_visibility || match f.node.kind {
ast::NamedField(_, ast::Public) => true,
hir::NamedField(_, hir::Public) => true,
_ => false
}
});
@ -220,15 +222,15 @@ impl<'a, 'tcx, 'v> Visitor<'v> for MarkSymbolVisitor<'a, 'tcx> {
visit::walk_struct_def(self, def);
}
fn visit_expr(&mut self, expr: &ast::Expr) {
fn visit_expr(&mut self, expr: &hir::Expr) {
match expr.node {
ast::ExprMethodCall(..) => {
hir::ExprMethodCall(..) => {
self.lookup_and_handle_method(expr.id);
}
ast::ExprField(ref lhs, ref ident) => {
hir::ExprField(ref lhs, ref ident) => {
self.handle_field_access(&**lhs, ident.node.name);
}
ast::ExprTupField(ref lhs, idx) => {
hir::ExprTupField(ref lhs, idx) => {
self.handle_tup_field_access(&**lhs, idx.node);
}
_ => ()
@ -237,7 +239,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for MarkSymbolVisitor<'a, 'tcx> {
visit::walk_expr(self, expr);
}
fn visit_arm(&mut self, arm: &ast::Arm) {
fn visit_arm(&mut self, arm: &hir::Arm) {
if arm.pats.len() == 1 {
let pat = &*arm.pats[0];
let variants = pat_util::necessary_variants(&self.tcx.def_map, pat);
@ -254,10 +256,10 @@ impl<'a, 'tcx, 'v> Visitor<'v> for MarkSymbolVisitor<'a, 'tcx> {
}
}
fn visit_pat(&mut self, pat: &ast::Pat) {
fn visit_pat(&mut self, pat: &hir::Pat) {
let def_map = &self.tcx.def_map;
match pat.node {
ast::PatStruct(_, ref fields, _) => {
hir::PatStruct(_, ref fields, _) => {
self.handle_field_pattern_match(pat, fields);
}
_ if pat_util::pat_is_const(def_map, pat) => {
@ -272,24 +274,24 @@ impl<'a, 'tcx, 'v> Visitor<'v> for MarkSymbolVisitor<'a, 'tcx> {
self.ignore_non_const_paths = false;
}
fn visit_path(&mut self, path: &ast::Path, id: ast::NodeId) {
fn visit_path(&mut self, path: &hir::Path, id: ast::NodeId) {
self.lookup_and_handle_definition(&id);
visit::walk_path(self, path);
}
fn visit_item(&mut self, _: &ast::Item) {
fn visit_item(&mut self, _: &hir::Item) {
// Do not recurse into items. These items will be added to the
// worklist and recursed into manually if necessary.
}
}
fn has_allow_dead_code_or_lang_attr(attrs: &[ast::Attribute]) -> bool {
fn has_allow_dead_code_or_lang_attr(attrs: &[hir::Attribute]) -> bool {
if attr::contains_name(attrs, "lang") {
return true;
}
let dead_code = lint::builtin::DEAD_CODE.name_lower();
for attr in lint::gather_attrs(attrs) {
for attr in lint::gather_attrs_from_hir(attrs) {
match attr {
Ok((ref name, lint::Allow, _))
if &name[..] == dead_code => return true,
@ -317,20 +319,20 @@ struct LifeSeeder {
}
impl<'v> Visitor<'v> for LifeSeeder {
fn visit_item(&mut self, item: &ast::Item) {
fn visit_item(&mut self, item: &hir::Item) {
let allow_dead_code = has_allow_dead_code_or_lang_attr(&item.attrs);
if allow_dead_code {
self.worklist.push(item.id);
}
match item.node {
ast::ItemEnum(ref enum_def, _) if allow_dead_code => {
hir::ItemEnum(ref enum_def, _) if allow_dead_code => {
self.worklist.extend(enum_def.variants.iter().map(|variant| variant.node.id));
}
ast::ItemTrait(_, _, _, ref trait_items) => {
hir::ItemTrait(_, _, _, ref trait_items) => {
for trait_item in trait_items {
match trait_item.node {
ast::ConstTraitItem(_, Some(_)) |
ast::MethodTraitItem(_, Some(_)) => {
hir::ConstTraitItem(_, Some(_)) |
hir::MethodTraitItem(_, Some(_)) => {
if has_allow_dead_code_or_lang_attr(&trait_item.attrs) {
self.worklist.push(trait_item.id);
}
@ -339,18 +341,17 @@ impl<'v> Visitor<'v> for LifeSeeder {
}
}
}
ast::ItemImpl(_, _, _, ref opt_trait, _, ref impl_items) => {
hir::ItemImpl(_, _, _, ref opt_trait, _, ref impl_items) => {
for impl_item in impl_items {
match impl_item.node {
ast::ConstImplItem(..) |
ast::MethodImplItem(..) => {
hir::ConstImplItem(..) |
hir::MethodImplItem(..) => {
if opt_trait.is_some() ||
has_allow_dead_code_or_lang_attr(&impl_item.attrs) {
self.worklist.push(impl_item.id);
}
}
ast::TypeImplItem(_) => {}
ast::MacImplItem(_) => panic!("unexpanded macro")
hir::TypeImplItem(_) => {}
}
}
}
@ -363,7 +364,7 @@ impl<'v> Visitor<'v> for LifeSeeder {
fn create_and_seed_worklist(tcx: &ty::ctxt,
exported_items: &privacy::ExportedItems,
reachable_symbols: &NodeSet,
krate: &ast::Crate) -> Vec<ast::NodeId> {
krate: &hir::Crate) -> Vec<ast::NodeId> {
let mut worklist = Vec::new();
// Preferably, we would only need to seed the worklist with reachable
@ -401,7 +402,7 @@ fn create_and_seed_worklist(tcx: &ty::ctxt,
fn find_live(tcx: &ty::ctxt,
exported_items: &privacy::ExportedItems,
reachable_symbols: &NodeSet,
krate: &ast::Crate)
krate: &hir::Crate)
-> Box<HashSet<ast::NodeId>> {
let worklist = create_and_seed_worklist(tcx, exported_items,
reachable_symbols, krate);
@ -410,9 +411,9 @@ fn find_live(tcx: &ty::ctxt,
symbol_visitor.live_symbols
}
fn get_struct_ctor_id(item: &ast::Item) -> Option<ast::NodeId> {
fn get_struct_ctor_id(item: &hir::Item) -> Option<ast::NodeId> {
match item.node {
ast::ItemStruct(ref struct_def, _) => struct_def.ctor_id,
hir::ItemStruct(ref struct_def, _) => struct_def.ctor_id,
_ => None
}
}
@ -423,20 +424,20 @@ struct DeadVisitor<'a, 'tcx: 'a> {
}
impl<'a, 'tcx> DeadVisitor<'a, 'tcx> {
fn should_warn_about_item(&mut self, item: &ast::Item) -> bool {
fn should_warn_about_item(&mut self, item: &hir::Item) -> bool {
let should_warn = match item.node {
ast::ItemStatic(..)
| ast::ItemConst(..)
| ast::ItemFn(..)
| ast::ItemEnum(..)
| ast::ItemStruct(..) => true,
hir::ItemStatic(..)
| hir::ItemConst(..)
| hir::ItemFn(..)
| hir::ItemEnum(..)
| hir::ItemStruct(..) => true,
_ => false
};
let ctor_id = get_struct_ctor_id(item);
should_warn && !self.symbol_is_live(item.id, ctor_id)
}
fn should_warn_about_field(&mut self, node: &ast::StructField_) -> bool {
fn should_warn_about_field(&mut self, node: &hir::StructField_) -> bool {
let is_named = node.ident().is_some();
let field_type = self.tcx.node_id_to_type(node.id);
let is_marker_field = match field_type.ty_to_def_id() {
@ -449,7 +450,7 @@ impl<'a, 'tcx> DeadVisitor<'a, 'tcx> {
&& !has_allow_dead_code_or_lang_attr(&node.attrs)
}
fn should_warn_about_variant(&mut self, variant: &ast::Variant_) -> bool {
fn should_warn_about_variant(&mut self, variant: &hir::Variant_) -> bool {
!self.symbol_is_live(variant.id, None)
&& !has_allow_dead_code_or_lang_attr(&variant.attrs)
}
@ -509,7 +510,7 @@ impl<'a, 'tcx> DeadVisitor<'a, 'tcx> {
}
impl<'a, 'tcx, 'v> Visitor<'v> for DeadVisitor<'a, 'tcx> {
fn visit_item(&mut self, item: &ast::Item) {
fn visit_item(&mut self, item: &hir::Item) {
if self.should_warn_about_item(item) {
self.warn_dead_code(
item.id,
@ -519,7 +520,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for DeadVisitor<'a, 'tcx> {
);
} else {
match item.node {
ast::ItemEnum(ref enum_def, _) => {
hir::ItemEnum(ref enum_def, _) => {
for variant in &enum_def.variants {
if self.should_warn_about_variant(&variant.node) {
self.warn_dead_code(variant.node.id, variant.span,
@ -533,14 +534,14 @@ impl<'a, 'tcx, 'v> Visitor<'v> for DeadVisitor<'a, 'tcx> {
visit::walk_item(self, item);
}
fn visit_foreign_item(&mut self, fi: &ast::ForeignItem) {
fn visit_foreign_item(&mut self, fi: &hir::ForeignItem) {
if !self.symbol_is_live(fi.id, None) {
self.warn_dead_code(fi.id, fi.span, fi.ident.name, fi.node.descriptive_variant());
}
visit::walk_foreign_item(self, fi);
}
fn visit_struct_field(&mut self, field: &ast::StructField) {
fn visit_struct_field(&mut self, field: &hir::StructField) {
if self.should_warn_about_field(&field.node) {
self.warn_dead_code(field.node.id, field.span,
field.node.ident().unwrap().name, "struct field");
@ -549,39 +550,38 @@ impl<'a, 'tcx, 'v> Visitor<'v> for DeadVisitor<'a, 'tcx> {
visit::walk_struct_field(self, field);
}
fn visit_impl_item(&mut self, impl_item: &ast::ImplItem) {
fn visit_impl_item(&mut self, impl_item: &hir::ImplItem) {
match impl_item.node {
ast::ConstImplItem(_, ref expr) => {
hir::ConstImplItem(_, ref expr) => {
if !self.symbol_is_live(impl_item.id, None) {
self.warn_dead_code(impl_item.id, impl_item.span,
impl_item.ident.name, "associated const");
}
visit::walk_expr(self, expr)
}
ast::MethodImplItem(_, ref body) => {
hir::MethodImplItem(_, ref body) => {
if !self.symbol_is_live(impl_item.id, None) {
self.warn_dead_code(impl_item.id, impl_item.span,
impl_item.ident.name, "method");
}
visit::walk_block(self, body)
}
ast::TypeImplItem(..) |
ast::MacImplItem(..) => {}
hir::TypeImplItem(..) => {}
}
}
// Overwrite so that we don't warn the trait item itself.
fn visit_trait_item(&mut self, trait_item: &ast::TraitItem) {
fn visit_trait_item(&mut self, trait_item: &hir::TraitItem) {
match trait_item.node {
ast::ConstTraitItem(_, Some(ref expr)) => {
hir::ConstTraitItem(_, Some(ref expr)) => {
visit::walk_expr(self, expr)
}
ast::MethodTraitItem(_, Some(ref body)) => {
hir::MethodTraitItem(_, Some(ref body)) => {
visit::walk_block(self, body)
}
ast::ConstTraitItem(_, None) |
ast::MethodTraitItem(_, None) |
ast::TypeTraitItem(..) => {}
hir::ConstTraitItem(_, None) |
hir::MethodTraitItem(_, None) |
hir::TypeTraitItem(..) => {}
}
}
}

View File

@ -15,6 +15,7 @@ use middle::privacy::LastPrivate;
use middle::subst::ParamSpace;
use util::nodemap::NodeMap;
use syntax::ast;
use rustc_front::hir;
use std::cell::RefCell;
@ -33,7 +34,7 @@ pub enum Def {
DefTy(DefId, bool /* is_enum */),
DefAssociatedTy(DefId /* trait */, DefId),
DefTrait(DefId),
DefPrimTy(ast::PrimTy),
DefPrimTy(hir::PrimTy),
DefTyParam(ParamSpace, u32, DefId, ast::Name),
DefUse(DefId),
DefUpvar(ast::NodeId, // id of closed over local

View File

@ -18,8 +18,9 @@ use middle::ty::MethodCall;
use syntax::ast;
use syntax::codemap::Span;
use syntax::visit;
use syntax::visit::{FnKind, Visitor};
use rustc_front::hir;
use rustc_front::visit;
use rustc_front::visit::{FnKind, Visitor};
#[derive(Copy, Clone)]
struct UnsafeContext {
@ -42,7 +43,7 @@ enum RootUnsafeContext {
fn type_is_unsafe_function(ty: Ty) -> bool {
match ty.sty {
ty::TyBareFn(_, ref f) => f.unsafety == ast::Unsafety::Unsafe,
ty::TyBareFn(_, ref f) => f.unsafety == hir::Unsafety::Unsafe,
_ => false,
}
}
@ -75,14 +76,14 @@ impl<'a, 'tcx> EffectCheckVisitor<'a, 'tcx> {
}
impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> {
fn visit_fn(&mut self, fn_kind: FnKind<'v>, fn_decl: &'v ast::FnDecl,
block: &'v ast::Block, span: Span, _: ast::NodeId) {
fn visit_fn(&mut self, fn_kind: FnKind<'v>, fn_decl: &'v hir::FnDecl,
block: &'v hir::Block, span: Span, _: ast::NodeId) {
let (is_item_fn, is_unsafe_fn) = match fn_kind {
FnKind::ItemFn(_, _, unsafety, _, _, _) =>
(true, unsafety == ast::Unsafety::Unsafe),
(true, unsafety == hir::Unsafety::Unsafe),
FnKind::Method(_, sig, _) =>
(true, sig.unsafety == ast::Unsafety::Unsafe),
(true, sig.unsafety == hir::Unsafety::Unsafe),
_ => (false, false),
};
@ -98,11 +99,11 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> {
self.unsafe_context = old_unsafe_context
}
fn visit_block(&mut self, block: &ast::Block) {
fn visit_block(&mut self, block: &hir::Block) {
let old_unsafe_context = self.unsafe_context;
match block.rules {
ast::DefaultBlock => {}
ast::UnsafeBlock(source) => {
hir::DefaultBlock => {}
hir::UnsafeBlock(source) => {
// By default only the outermost `unsafe` block is
// "used" and so nested unsafe blocks are pointless
// (the inner ones are unnecessary and we actually
@ -118,15 +119,15 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> {
// external blocks (e.g. `unsafe { println("") }`,
// expands to `unsafe { ... unsafe { ... } }` where
// the inner one is compiler generated).
if self.unsafe_context.root == SafeContext || source == ast::CompilerGenerated {
if self.unsafe_context.root == SafeContext || source == hir::CompilerGenerated {
self.unsafe_context.root = UnsafeBlock(block.id)
}
}
ast::PushUnsafeBlock(..) => {
hir::PushUnsafeBlock(..) => {
self.unsafe_context.push_unsafe_count =
self.unsafe_context.push_unsafe_count.checked_add(1).unwrap();
}
ast::PopUnsafeBlock(..) => {
hir::PopUnsafeBlock(..) => {
self.unsafe_context.push_unsafe_count =
self.unsafe_context.push_unsafe_count.checked_sub(1).unwrap();
}
@ -137,9 +138,9 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> {
self.unsafe_context = old_unsafe_context
}
fn visit_expr(&mut self, expr: &ast::Expr) {
fn visit_expr(&mut self, expr: &hir::Expr) {
match expr.node {
ast::ExprMethodCall(_, _, _) => {
hir::ExprMethodCall(_, _, _) => {
let method_call = MethodCall::expr(expr.id);
let base_type = self.tcx.tables.borrow().method_map[&method_call].ty;
debug!("effect: method call case, base type is {:?}",
@ -149,7 +150,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> {
"invocation of unsafe method")
}
}
ast::ExprCall(ref base, _) => {
hir::ExprCall(ref base, _) => {
let base_type = self.tcx.node_id_to_type(base.id);
debug!("effect: call case, base type is {:?}",
base_type);
@ -157,7 +158,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> {
self.require_unsafe(expr.span, "call to unsafe function")
}
}
ast::ExprUnary(ast::UnDeref, ref base) => {
hir::ExprUnary(hir::UnDeref, ref base) => {
let base_type = self.tcx.node_id_to_type(base.id);
debug!("effect: unary case, base type is {:?}",
base_type);
@ -165,10 +166,10 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> {
self.require_unsafe(expr.span, "dereference of raw pointer")
}
}
ast::ExprInlineAsm(..) => {
hir::ExprInlineAsm(..) => {
self.require_unsafe(expr.span, "use of inline assembly");
}
ast::ExprPath(..) => {
hir::ExprPath(..) => {
if let def::DefStatic(_, true) = self.tcx.resolve_expr(expr) {
self.require_unsafe(expr.span, "use of mutable static");
}

View File

@ -9,15 +9,15 @@
// except according to those terms.
use ast_map;
use front::map as ast_map;
use session::{config, Session};
use syntax;
use syntax::ast::{NodeId, Item};
use syntax::attr;
use syntax::ast::NodeId;
use rustc_front::hir::{Item, ItemFn};
use rustc_front::attr;
use syntax::codemap::Span;
use syntax::entry::EntryPointType;
use syntax::visit;
use syntax::visit::Visitor;
use rustc_front::visit;
use rustc_front::visit::Visitor;
struct EntryContext<'a> {
session: &'a Session,
@ -76,8 +76,33 @@ pub fn find_entry_point(session: &Session, ast_map: &ast_map::Map) {
configure_main(&mut ctxt);
}
// Beware, this is duplicated in libsyntax/entry.rs, make sure to keep
// them in sync.
fn entry_point_type(item: &Item, depth: usize) -> EntryPointType {
match item.node {
ItemFn(..) => {
if attr::contains_name(&item.attrs, "start") {
EntryPointType::Start
} else if attr::contains_name(&item.attrs, "main") {
EntryPointType::MainAttr
} else if item.ident.name == "main" {
if depth == 1 {
// This is a top-level function so can be 'main'
EntryPointType::MainNamed
} else {
EntryPointType::OtherMain
}
} else {
EntryPointType::None
}
}
_ => EntryPointType::None,
}
}
fn find_item(item: &Item, ctxt: &mut EntryContext) {
match syntax::entry::entry_point_type(item, ctxt.depth) {
match entry_point_type(item, ctxt.depth) {
EntryPointType::MainNamed => {
if ctxt.main_fn.is_none() {
ctxt.main_fn = Some((item.id, item.span));

View File

@ -26,7 +26,9 @@ use middle::infer;
use middle::mem_categorization as mc;
use middle::ty;
use syntax::{ast, ast_util};
use rustc_front::hir;
use syntax::ast;
use syntax::ptr::P;
use syntax::codemap::Span;
@ -57,14 +59,14 @@ pub trait Delegate<'tcx> {
// same input pattern structure (though of `consume_pat` can be
// called on a subpart of an input passed to `matched_pat).
fn matched_pat(&mut self,
matched_pat: &ast::Pat,
matched_pat: &hir::Pat,
cmt: mc::cmt<'tcx>,
mode: MatchMode);
// The value found at `cmt` is either copied or moved via the
// pattern binding `consume_pat`, depending on mode.
fn consume_pat(&mut self,
consume_pat: &ast::Pat,
consume_pat: &hir::Pat,
cmt: mc::cmt<'tcx>,
mode: ConsumeMode);
@ -277,23 +279,25 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
typer: &'t infer::InferCtxt<'a, 'tcx>)
-> ExprUseVisitor<'d,'t,'a,'tcx>
{
ExprUseVisitor {
let result = ExprUseVisitor {
typer: typer,
mc: mc::MemCategorizationContext::new(typer),
delegate: delegate,
}
};
result
}
pub fn walk_fn(&mut self,
decl: &ast::FnDecl,
body: &ast::Block) {
decl: &hir::FnDecl,
body: &hir::Block) {
self.walk_arg_patterns(decl, body);
self.walk_block(body);
}
fn walk_arg_patterns(&mut self,
decl: &ast::FnDecl,
body: &ast::Block) {
decl: &hir::FnDecl,
body: &hir::Block) {
for arg in &decl.inputs {
let arg_ty = return_if_err!(self.typer.node_ty(arg.pat.id));
@ -323,13 +327,13 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
self.delegate.consume(consume_id, consume_span, cmt, mode);
}
fn consume_exprs(&mut self, exprs: &Vec<P<ast::Expr>>) {
fn consume_exprs(&mut self, exprs: &Vec<P<hir::Expr>>) {
for expr in exprs {
self.consume_expr(&**expr);
}
}
pub fn consume_expr(&mut self, expr: &ast::Expr) {
pub fn consume_expr(&mut self, expr: &hir::Expr) {
debug!("consume_expr(expr={:?})", expr);
let cmt = return_if_err!(self.mc.cat_expr(expr));
@ -338,8 +342,8 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
}
fn mutate_expr(&mut self,
assignment_expr: &ast::Expr,
expr: &ast::Expr,
assignment_expr: &hir::Expr,
expr: &hir::Expr,
mode: MutateMode) {
let cmt = return_if_err!(self.mc.cat_expr(expr));
self.delegate.mutate(assignment_expr.id, assignment_expr.span, cmt, mode);
@ -347,7 +351,7 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
}
fn borrow_expr(&mut self,
expr: &ast::Expr,
expr: &hir::Expr,
r: ty::Region,
bk: ty::BorrowKind,
cause: LoanCause) {
@ -363,37 +367,37 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
self.walk_expr(expr)
}
fn select_from_expr(&mut self, expr: &ast::Expr) {
fn select_from_expr(&mut self, expr: &hir::Expr) {
self.walk_expr(expr)
}
pub fn walk_expr(&mut self, expr: &ast::Expr) {
pub fn walk_expr(&mut self, expr: &hir::Expr) {
debug!("walk_expr(expr={:?})", expr);
self.walk_adjustment(expr);
match expr.node {
ast::ExprParen(ref subexpr) => {
hir::ExprParen(ref subexpr) => {
self.walk_expr(&**subexpr)
}
ast::ExprPath(..) => { }
hir::ExprPath(..) => { }
ast::ExprUnary(ast::UnDeref, ref base) => { // *base
hir::ExprUnary(hir::UnDeref, ref base) => { // *base
if !self.walk_overloaded_operator(expr, &**base, Vec::new(), PassArgs::ByRef) {
self.select_from_expr(&**base);
}
}
ast::ExprField(ref base, _) => { // base.f
hir::ExprField(ref base, _) => { // base.f
self.select_from_expr(&**base);
}
ast::ExprTupField(ref base, _) => { // base.<n>
hir::ExprTupField(ref base, _) => { // base.<n>
self.select_from_expr(&**base);
}
ast::ExprIndex(ref lhs, ref rhs) => { // lhs[rhs]
hir::ExprIndex(ref lhs, ref rhs) => { // lhs[rhs]
if !self.walk_overloaded_operator(expr,
&**lhs,
vec![&**rhs],
@ -403,29 +407,29 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
}
}
ast::ExprRange(ref start, ref end) => {
hir::ExprRange(ref start, ref end) => {
start.as_ref().map(|e| self.consume_expr(&**e));
end.as_ref().map(|e| self.consume_expr(&**e));
}
ast::ExprCall(ref callee, ref args) => { // callee(args)
hir::ExprCall(ref callee, ref args) => { // callee(args)
self.walk_callee(expr, &**callee);
self.consume_exprs(args);
}
ast::ExprMethodCall(_, _, ref args) => { // callee.m(args)
hir::ExprMethodCall(_, _, ref args) => { // callee.m(args)
self.consume_exprs(args);
}
ast::ExprStruct(_, ref fields, ref opt_with) => {
hir::ExprStruct(_, ref fields, ref opt_with) => {
self.walk_struct_expr(expr, fields, opt_with);
}
ast::ExprTup(ref exprs) => {
hir::ExprTup(ref exprs) => {
self.consume_exprs(exprs);
}
ast::ExprIf(ref cond_expr, ref then_blk, ref opt_else_expr) => {
hir::ExprIf(ref cond_expr, ref then_blk, ref opt_else_expr) => {
self.consume_expr(&**cond_expr);
self.walk_block(&**then_blk);
if let Some(ref else_expr) = *opt_else_expr {
@ -433,11 +437,7 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
}
}
ast::ExprIfLet(..) => {
self.tcx().sess.span_bug(expr.span, "non-desugared ExprIfLet");
}
ast::ExprMatch(ref discr, ref arms, _) => {
hir::ExprMatch(ref discr, ref arms, _) => {
let discr_cmt = return_if_err!(self.mc.cat_expr(&**discr));
self.borrow_expr(&**discr, ty::ReEmpty, ty::ImmBorrow, MatchDiscriminant);
@ -449,11 +449,11 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
}
}
ast::ExprVec(ref exprs) => {
hir::ExprVec(ref exprs) => {
self.consume_exprs(exprs);
}
ast::ExprAddrOf(m, ref base) => { // &base
hir::ExprAddrOf(m, ref base) => { // &base
// make sure that the thing we are pointing out stays valid
// for the lifetime `scope_r` of the resulting ptr:
let expr_ty = return_if_err!(self.typer.node_ty(expr.id));
@ -463,7 +463,7 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
}
}
ast::ExprInlineAsm(ref ia) => {
hir::ExprInlineAsm(ref ia) => {
for &(_, ref input) in &ia.inputs {
self.consume_expr(&**input);
}
@ -474,29 +474,21 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
}
}
ast::ExprBreak(..) |
ast::ExprAgain(..) |
ast::ExprLit(..) => {}
hir::ExprBreak(..) |
hir::ExprAgain(..) |
hir::ExprLit(..) => {}
ast::ExprLoop(ref blk, _) => {
hir::ExprLoop(ref blk, _) => {
self.walk_block(&**blk);
}
ast::ExprWhile(ref cond_expr, ref blk, _) => {
hir::ExprWhile(ref cond_expr, ref blk, _) => {
self.consume_expr(&**cond_expr);
self.walk_block(&**blk);
}
ast::ExprWhileLet(..) => {
self.tcx().sess.span_bug(expr.span, "non-desugared ExprWhileLet");
}
ast::ExprForLoop(..) => {
self.tcx().sess.span_bug(expr.span, "non-desugared ExprForLoop");
}
ast::ExprUnary(op, ref lhs) => {
let pass_args = if ast_util::is_by_value_unop(op) {
hir::ExprUnary(op, ref lhs) => {
let pass_args = if ::rustc_front::util::is_by_value_unop(op) {
PassArgs::ByValue
} else {
PassArgs::ByRef
@ -507,8 +499,8 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
}
}
ast::ExprBinary(op, ref lhs, ref rhs) => {
let pass_args = if ast_util::is_by_value_binop(op.node) {
hir::ExprBinary(op, ref lhs, ref rhs) => {
let pass_args = if ::rustc_front::util::is_by_value_binop(op.node) {
PassArgs::ByValue
} else {
PassArgs::ByRef
@ -520,42 +512,42 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
}
}
ast::ExprBlock(ref blk) => {
hir::ExprBlock(ref blk) => {
self.walk_block(&**blk);
}
ast::ExprRet(ref opt_expr) => {
hir::ExprRet(ref opt_expr) => {
if let Some(ref expr) = *opt_expr {
self.consume_expr(&**expr);
}
}
ast::ExprAssign(ref lhs, ref rhs) => {
hir::ExprAssign(ref lhs, ref rhs) => {
self.mutate_expr(expr, &**lhs, JustWrite);
self.consume_expr(&**rhs);
}
ast::ExprCast(ref base, _) => {
hir::ExprCast(ref base, _) => {
self.consume_expr(&**base);
}
ast::ExprAssignOp(_, ref lhs, ref rhs) => {
hir::ExprAssignOp(_, ref lhs, ref rhs) => {
// This will have to change if/when we support
// overloaded operators for `+=` and so forth.
self.mutate_expr(expr, &**lhs, WriteAndRead);
self.consume_expr(&**rhs);
}
ast::ExprRepeat(ref base, ref count) => {
hir::ExprRepeat(ref base, ref count) => {
self.consume_expr(&**base);
self.consume_expr(&**count);
}
ast::ExprClosure(..) => {
hir::ExprClosure(..) => {
self.walk_captures(expr)
}
ast::ExprBox(ref place, ref base) => {
hir::ExprBox(ref place, ref base) => {
match *place {
Some(ref place) => self.consume_expr(&**place),
None => {}
@ -567,16 +559,10 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
"box with explicit place remains after expansion");
}
}
ast::ExprMac(..) => {
self.tcx().sess.span_bug(
expr.span,
"macro expression remains after expansion");
}
}
}
fn walk_callee(&mut self, call: &ast::Expr, callee: &ast::Expr) {
fn walk_callee(&mut self, call: &hir::Expr, callee: &hir::Expr) {
let callee_ty = return_if_err!(self.typer.expr_ty_adjusted(callee));
debug!("walk_callee: callee={:?} callee_ty={:?}",
callee, callee_ty);
@ -617,33 +603,29 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
}
}
fn walk_stmt(&mut self, stmt: &ast::Stmt) {
fn walk_stmt(&mut self, stmt: &hir::Stmt) {
match stmt.node {
ast::StmtDecl(ref decl, _) => {
hir::StmtDecl(ref decl, _) => {
match decl.node {
ast::DeclLocal(ref local) => {
hir::DeclLocal(ref local) => {
self.walk_local(&**local);
}
ast::DeclItem(_) => {
hir::DeclItem(_) => {
// we don't visit nested items in this visitor,
// only the fn body we were given.
}
}
}
ast::StmtExpr(ref expr, _) |
ast::StmtSemi(ref expr, _) => {
hir::StmtExpr(ref expr, _) |
hir::StmtSemi(ref expr, _) => {
self.consume_expr(&**expr);
}
ast::StmtMac(..) => {
self.tcx().sess.span_bug(stmt.span, "unexpanded stmt macro");
}
}
}
fn walk_local(&mut self, local: &ast::Local) {
fn walk_local(&mut self, local: &hir::Local) {
match local.init {
None => {
let delegate = &mut self.delegate;
@ -667,7 +649,7 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
/// Indicates that the value of `blk` will be consumed, meaning either copied or moved
/// depending on its type.
fn walk_block(&mut self, blk: &ast::Block) {
fn walk_block(&mut self, blk: &hir::Block) {
debug!("walk_block(blk.id={})", blk.id);
for stmt in &blk.stmts {
@ -680,9 +662,9 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
}
fn walk_struct_expr(&mut self,
_expr: &ast::Expr,
fields: &Vec<ast::Field>,
opt_with: &Option<P<ast::Expr>>) {
_expr: &hir::Expr,
fields: &Vec<hir::Field>,
opt_with: &Option<P<hir::Expr>>) {
// Consume the expressions supplying values for each field.
for field in fields {
self.consume_expr(&*field.expr);
@ -727,7 +709,7 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
self.walk_expr(with_expr);
fn contains_field_named(field: ty::FieldDef,
fields: &Vec<ast::Field>)
fields: &Vec<hir::Field>)
-> bool
{
fields.iter().any(
@ -738,7 +720,7 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
// Invoke the appropriate delegate calls for anything that gets
// consumed or borrowed as part of the automatic adjustment
// process.
fn walk_adjustment(&mut self, expr: &ast::Expr) {
fn walk_adjustment(&mut self, expr: &hir::Expr) {
let typer = self.typer;
//NOTE(@jroesch): mixed RefCell borrow causes crash
let adj = typer.adjustments().get(&expr.id).map(|x| x.clone());
@ -764,7 +746,7 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
/// `(*x)` where `x` is of type `Rc<T>`, then this in fact is equivalent to `x.deref()`. Since
/// `deref()` is declared with `&self`, this is an autoref of `x`.
fn walk_autoderefs(&mut self,
expr: &ast::Expr,
expr: &hir::Expr,
autoderefs: usize) {
debug!("walk_autoderefs expr={:?} autoderefs={}", expr, autoderefs);
@ -795,7 +777,7 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
}
fn walk_autoderefref(&mut self,
expr: &ast::Expr,
expr: &hir::Expr,
adj: &ty::AutoDerefRef<'tcx>) {
debug!("walk_autoderefref expr={:?} adj={:?}",
expr,
@ -825,7 +807,7 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
/// `cmt` for the rvalue that will be produced by introduced an
/// autoref.
fn walk_autoref(&mut self,
expr: &ast::Expr,
expr: &hir::Expr,
cmt_base: mc::cmt<'tcx>,
opt_autoref: Option<ty::AutoRef<'tcx>>)
-> mc::cmt<'tcx>
@ -890,9 +872,9 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
// recursively processing the input arguments, and thus the caller
// should not do so.
fn walk_overloaded_operator(&mut self,
expr: &ast::Expr,
receiver: &ast::Expr,
rhs: Vec<&ast::Expr>,
expr: &hir::Expr,
receiver: &hir::Expr,
rhs: Vec<&hir::Expr>,
pass_args: PassArgs)
-> bool
{
@ -927,7 +909,7 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
return true;
}
fn arm_move_mode(&mut self, discr_cmt: mc::cmt<'tcx>, arm: &ast::Arm) -> TrackMatchMode {
fn arm_move_mode(&mut self, discr_cmt: mc::cmt<'tcx>, arm: &hir::Arm) -> TrackMatchMode {
let mut mode = Unknown;
for pat in &arm.pats {
self.determine_pat_move_mode(discr_cmt.clone(), &**pat, &mut mode);
@ -935,7 +917,7 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
mode
}
fn walk_arm(&mut self, discr_cmt: mc::cmt<'tcx>, arm: &ast::Arm, mode: MatchMode) {
fn walk_arm(&mut self, discr_cmt: mc::cmt<'tcx>, arm: &hir::Arm, mode: MatchMode) {
for pat in &arm.pats {
self.walk_pat(discr_cmt.clone(), &**pat, mode);
}
@ -949,7 +931,7 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
/// Walks an pat that occurs in isolation (i.e. top-level of fn
/// arg or let binding. *Not* a match arm or nested pat.)
fn walk_irrefutable_pat(&mut self, cmt_discr: mc::cmt<'tcx>, pat: &ast::Pat) {
fn walk_irrefutable_pat(&mut self, cmt_discr: mc::cmt<'tcx>, pat: &hir::Pat) {
let mut mode = Unknown;
self.determine_pat_move_mode(cmt_discr.clone(), pat, &mut mode);
let mode = mode.match_mode();
@ -961,7 +943,7 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
/// copy, or borrow.
fn determine_pat_move_mode(&mut self,
cmt_discr: mc::cmt<'tcx>,
pat: &ast::Pat,
pat: &hir::Pat,
mode: &mut TrackMatchMode) {
debug!("determine_pat_move_mode cmt_discr={:?} pat={:?}", cmt_discr,
pat);
@ -970,9 +952,9 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
let def_map = &self.tcx().def_map;
if pat_util::pat_is_binding(def_map, pat) {
match pat.node {
ast::PatIdent(ast::BindByRef(_), _, _) =>
hir::PatIdent(hir::BindByRef(_), _, _) =>
mode.lub(BorrowingMatch),
ast::PatIdent(ast::BindByValue(_), _, _) => {
hir::PatIdent(hir::BindByValue(_), _, _) => {
match copy_or_move(self.typer, &cmt_pat, PatBindingMove) {
Copy => mode.lub(CopyingMatch),
Move(_) => mode.lub(MovingMatch),
@ -993,7 +975,7 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
/// also `walk_irrefutable_pat` for patterns that stand alone).
fn walk_pat(&mut self,
cmt_discr: mc::cmt<'tcx>,
pat: &ast::Pat,
pat: &hir::Pat,
match_mode: MatchMode) {
debug!("walk_pat cmt_discr={:?} pat={:?}", cmt_discr,
pat);
@ -1026,14 +1008,14 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
// It is also a borrow or copy/move of the value being matched.
match pat.node {
ast::PatIdent(ast::BindByRef(m), _, _) => {
hir::PatIdent(hir::BindByRef(m), _, _) => {
if let ty::TyRef(&r, _) = pat_ty.sty {
let bk = ty::BorrowKind::from_mutbl(m);
delegate.borrow(pat.id, pat.span, cmt_pat,
r, bk, RefBinding);
}
}
ast::PatIdent(ast::BindByValue(_), _, _) => {
hir::PatIdent(hir::BindByValue(_), _, _) => {
let mode = copy_or_move(typer, &cmt_pat, PatBindingMove);
debug!("walk_pat binding consuming pat");
delegate.consume_pat(pat, cmt_pat, mode);
@ -1046,7 +1028,7 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
}
} else {
match pat.node {
ast::PatVec(_, Some(ref slice_pat), _) => {
hir::PatVec(_, Some(ref slice_pat), _) => {
// The `slice_pat` here creates a slice into
// the original vector. This is effectively a
// borrow of the elements of the vector being
@ -1094,8 +1076,8 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
let tcx = typer.tcx;
match pat.node {
ast::PatEnum(_, _) | ast::PatQPath(..) |
ast::PatIdent(_, _, None) | ast::PatStruct(..) => {
hir::PatEnum(_, _) | hir::PatQPath(..) |
hir::PatIdent(_, _, None) | hir::PatStruct(..) => {
match def_map.get(&pat.id).map(|d| d.full_def()) {
None => {
// no definition found: pat is not a
@ -1169,15 +1151,15 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
}
}
ast::PatIdent(_, _, Some(_)) => {
hir::PatIdent(_, _, Some(_)) => {
// Do nothing; this is a binding (not a enum
// variant or struct), and the cat_pattern call
// will visit the substructure recursively.
}
ast::PatWild(_) | ast::PatTup(..) | ast::PatBox(..) |
ast::PatRegion(..) | ast::PatLit(..) | ast::PatRange(..) |
ast::PatVec(..) | ast::PatMac(..) => {
hir::PatWild(_) | hir::PatTup(..) | hir::PatBox(..) |
hir::PatRegion(..) | hir::PatLit(..) | hir::PatRange(..) |
hir::PatVec(..) => {
// Similarly, each of these cases does not
// correspond to a enum variant or struct, so we
// do not do any `matched_pat` calls for these
@ -1187,7 +1169,7 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
}));
}
fn walk_captures(&mut self, closure_expr: &ast::Expr) {
fn walk_captures(&mut self, closure_expr: &hir::Expr) {
debug!("walk_captures({:?})", closure_expr);
self.tcx().with_freevars(closure_expr.id, |freevars| {

View File

@ -10,7 +10,7 @@
use middle::def_id::DefId;
use middle::ty::{self, Ty};
use syntax::ast;
use rustc_front::hir;
use self::SimplifiedType::*;
@ -19,9 +19,9 @@ use self::SimplifiedType::*;
pub enum SimplifiedType {
BoolSimplifiedType,
CharSimplifiedType,
IntSimplifiedType(ast::IntTy),
UintSimplifiedType(ast::UintTy),
FloatSimplifiedType(ast::FloatTy),
IntSimplifiedType(hir::IntTy),
UintSimplifiedType(hir::UintTy),
FloatSimplifiedType(hir::FloatTy),
EnumSimplifiedType(DefId),
StrSimplifiedType,
VecSimplifiedType,

View File

@ -48,8 +48,8 @@ use middle::ty_fold;
use middle::ty_fold::{TypeFolder, TypeFoldable};
use middle::ty_relate::{self, Relate, RelateResult, TypeRelation};
use syntax::ast;
use syntax::codemap::Span;
use rustc_front::hir;
#[derive(Clone)]
pub struct CombineFields<'a, 'tcx: 'a> {
@ -138,7 +138,7 @@ fn unify_integral_variable<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
fn unify_float_variable<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
vid_is_expected: bool,
vid: ty::FloatVid,
val: ast::FloatTy)
val: hir::FloatTy)
-> RelateResult<'tcx, Ty<'tcx>>
{
try!(infcx
@ -388,7 +388,7 @@ fn int_unification_error<'tcx>(a_is_expected: bool, v: (ty::IntVarValue, ty::Int
}
fn float_unification_error<'tcx>(a_is_expected: bool,
v: (ast::FloatTy, ast::FloatTy))
v: (hir::FloatTy, hir::FloatTy))
-> ty::TypeError<'tcx>
{
let (a, b) = v;

View File

@ -72,7 +72,11 @@ use super::region_inference::ProcessedErrors;
use super::region_inference::SameRegions;
use std::collections::HashSet;
use ast_map;
use front::map as ast_map;
use rustc_front::hir;
use rustc_front::print::pprust;
use middle::def;
use middle::infer;
use middle::region;
@ -84,11 +88,9 @@ use std::cell::{Cell, RefCell};
use std::char::from_u32;
use std::fmt;
use syntax::ast;
use syntax::ast_util::name_to_dummy_lifetime;
use syntax::owned_slice::OwnedSlice;
use syntax::codemap::{Pos, Span};
use syntax::codemap::{self, Pos, Span};
use syntax::parse::token;
use syntax::print::pprust;
use syntax::ptr::P;
impl<'tcx> ty::ctxt<'tcx> {
@ -96,13 +98,13 @@ impl<'tcx> ty::ctxt<'tcx> {
prefix: &str,
region: ty::Region,
suffix: &str) {
fn item_scope_tag(item: &ast::Item) -> &'static str {
fn item_scope_tag(item: &hir::Item) -> &'static str {
match item.node {
ast::ItemImpl(..) => "impl",
ast::ItemStruct(..) => "struct",
ast::ItemEnum(..) => "enum",
ast::ItemTrait(..) => "trait",
ast::ItemFn(..) => "function body",
hir::ItemImpl(..) => "impl",
hir::ItemStruct(..) => "struct",
hir::ItemEnum(..) => "enum",
hir::ItemTrait(..) => "trait",
hir::ItemFn(..) => "function body",
_ => "item"
}
}
@ -128,12 +130,12 @@ impl<'tcx> ty::ctxt<'tcx> {
let tag = match self.map.find(scope.node_id(&self.region_maps)) {
Some(ast_map::NodeBlock(_)) => "block",
Some(ast_map::NodeExpr(expr)) => match expr.node {
ast::ExprCall(..) => "call",
ast::ExprMethodCall(..) => "method call",
ast::ExprMatch(_, _, ast::MatchSource::IfLetDesugar { .. }) => "if let",
ast::ExprMatch(_, _, ast::MatchSource::WhileLetDesugar) => "while let",
ast::ExprMatch(_, _, ast::MatchSource::ForLoopDesugar) => "for",
ast::ExprMatch(..) => "match",
hir::ExprCall(..) => "call",
hir::ExprMethodCall(..) => "method call",
hir::ExprMatch(_, _, hir::MatchSource::IfLetDesugar { .. }) => "if let",
hir::ExprMatch(_, _, hir::MatchSource::WhileLetDesugar) => "while let",
hir::ExprMatch(_, _, hir::MatchSource::ForLoopDesugar) => "for",
hir::ExprMatch(..) => "match",
_ => "expression",
},
Some(ast_map::NodeStmt(_)) => "statement",
@ -275,12 +277,12 @@ trait ErrorReportingHelpers<'tcx> {
origin: &SubregionOrigin<'tcx>);
fn give_expl_lifetime_param(&self,
decl: &ast::FnDecl,
unsafety: ast::Unsafety,
constness: ast::Constness,
decl: &hir::FnDecl,
unsafety: hir::Unsafety,
constness: hir::Constness,
ident: ast::Ident,
opt_explicit_self: Option<&ast::ExplicitSelf_>,
generics: &ast::Generics,
opt_explicit_self: Option<&hir::ExplicitSelf_>,
generics: &hir::Generics,
span: Span);
}
@ -432,7 +434,7 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
match parent_node {
Some(node) => match node {
ast_map::NodeItem(item) => match item.node {
ast::ItemFn(..) => {
hir::ItemFn(..) => {
Some(FreeRegionsFromSameFn::new(fr1, fr2, scope_id))
},
_ => None
@ -944,7 +946,7 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
Some(ref node) => match *node {
ast_map::NodeItem(ref item) => {
match item.node {
ast::ItemFn(ref fn_decl, unsafety, constness, _, ref gen, _) => {
hir::ItemFn(ref fn_decl, unsafety, constness, _, ref gen, _) => {
Some((fn_decl, gen, unsafety, constness,
item.ident, None, item.span))
},
@ -953,7 +955,7 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
}
ast_map::NodeImplItem(item) => {
match item.node {
ast::MethodImplItem(ref sig, _) => {
hir::MethodImplItem(ref sig, _) => {
Some((&sig.decl,
&sig.generics,
sig.unsafety,
@ -962,13 +964,12 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
Some(&sig.explicit_self.node),
item.span))
}
ast::MacImplItem(_) => self.tcx.sess.bug("unexpanded macro"),
_ => None,
}
},
ast_map::NodeTraitItem(item) => {
match item.node {
ast::MethodTraitItem(ref sig, Some(_)) => {
hir::MethodTraitItem(ref sig, Some(_)) => {
Some((&sig.decl,
&sig.generics,
sig.unsafety,
@ -995,7 +996,7 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
}
struct RebuildPathInfo<'a> {
path: &'a ast::Path,
path: &'a hir::Path,
// indexes to insert lifetime on path.lifetimes
indexes: Vec<u32>,
// number of lifetimes we expect to see on the type referred by `path`
@ -1007,9 +1008,9 @@ struct RebuildPathInfo<'a> {
struct Rebuilder<'a, 'tcx: 'a> {
tcx: &'a ty::ctxt<'tcx>,
fn_decl: &'a ast::FnDecl,
expl_self_opt: Option<&'a ast::ExplicitSelf_>,
generics: &'a ast::Generics,
fn_decl: &'a hir::FnDecl,
expl_self_opt: Option<&'a hir::ExplicitSelf_>,
generics: &'a hir::Generics,
same_regions: &'a [SameRegions],
life_giver: &'a LifeGiver,
cur_anon: Cell<u32>,
@ -1023,9 +1024,9 @@ enum FreshOrKept {
impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
fn new(tcx: &'a ty::ctxt<'tcx>,
fn_decl: &'a ast::FnDecl,
expl_self_opt: Option<&'a ast::ExplicitSelf_>,
generics: &'a ast::Generics,
fn_decl: &'a hir::FnDecl,
expl_self_opt: Option<&'a hir::ExplicitSelf_>,
generics: &'a hir::Generics,
same_regions: &'a [SameRegions],
life_giver: &'a LifeGiver)
-> Rebuilder<'a, 'tcx> {
@ -1042,7 +1043,7 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
}
fn rebuild(&self)
-> (ast::FnDecl, Option<ast::ExplicitSelf_>, ast::Generics) {
-> (hir::FnDecl, Option<hir::ExplicitSelf_>, hir::Generics) {
let mut expl_self_opt = self.expl_self_opt.cloned();
let mut inputs = self.fn_decl.inputs.clone();
let mut output = self.fn_decl.output.clone();
@ -1075,7 +1076,7 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
&all_region_names,
ty_params,
where_clause);
let new_fn_decl = ast::FnDecl {
let new_fn_decl = hir::FnDecl {
inputs: inputs,
output: output,
variadic: self.fn_decl.variadic
@ -1085,7 +1086,7 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
fn pick_lifetime(&self,
region_names: &HashSet<ast::Name>)
-> (ast::Lifetime, FreshOrKept) {
-> (hir::Lifetime, FreshOrKept) {
if !region_names.is_empty() {
// It's not necessary to convert the set of region names to a
// vector of string and then sort them. However, it makes the
@ -1158,15 +1159,15 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
}
fn rebuild_ty_params(&self,
ty_params: OwnedSlice<ast::TyParam>,
lifetime: ast::Lifetime,
ty_params: OwnedSlice<hir::TyParam>,
lifetime: hir::Lifetime,
region_names: &HashSet<ast::Name>)
-> OwnedSlice<ast::TyParam> {
-> OwnedSlice<hir::TyParam> {
ty_params.map(|ty_param| {
let bounds = self.rebuild_ty_param_bounds(ty_param.bounds.clone(),
lifetime,
region_names);
ast::TyParam {
hir::TyParam {
ident: ty_param.ident,
id: ty_param.id,
bounds: bounds,
@ -1177,19 +1178,19 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
}
fn rebuild_ty_param_bounds(&self,
ty_param_bounds: OwnedSlice<ast::TyParamBound>,
lifetime: ast::Lifetime,
ty_param_bounds: OwnedSlice<hir::TyParamBound>,
lifetime: hir::Lifetime,
region_names: &HashSet<ast::Name>)
-> OwnedSlice<ast::TyParamBound> {
-> OwnedSlice<hir::TyParamBound> {
ty_param_bounds.map(|tpb| {
match tpb {
&ast::RegionTyParamBound(lt) => {
&hir::RegionTyParamBound(lt) => {
// FIXME -- it's unclear whether I'm supposed to
// substitute lifetime here. I suspect we need to
// be passing down a map.
ast::RegionTyParamBound(lt)
hir::RegionTyParamBound(lt)
}
&ast::TraitTyParamBound(ref poly_tr, modifier) => {
&hir::TraitTyParamBound(ref poly_tr, modifier) => {
let tr = &poly_tr.trait_ref;
let last_seg = tr.path.segments.last().unwrap();
let mut insert = Vec::new();
@ -1207,9 +1208,9 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
region_names: region_names
};
let new_path = self.rebuild_path(rebuild_info, lifetime);
ast::TraitTyParamBound(ast::PolyTraitRef {
hir::TraitTyParamBound(hir::PolyTraitRef {
bound_lifetimes: poly_tr.bound_lifetimes.clone(),
trait_ref: ast::TraitRef {
trait_ref: hir::TraitRef {
path: new_path,
ref_id: tr.ref_id,
},
@ -1221,23 +1222,23 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
}
fn rebuild_expl_self(&self,
expl_self_opt: Option<ast::ExplicitSelf_>,
lifetime: ast::Lifetime,
expl_self_opt: Option<hir::ExplicitSelf_>,
lifetime: hir::Lifetime,
anon_nums: &HashSet<u32>,
region_names: &HashSet<ast::Name>)
-> Option<ast::ExplicitSelf_> {
-> Option<hir::ExplicitSelf_> {
match expl_self_opt {
Some(ref expl_self) => match *expl_self {
ast::SelfRegion(lt_opt, muta, id) => match lt_opt {
hir::SelfRegion(lt_opt, muta, id) => match lt_opt {
Some(lt) => if region_names.contains(&lt.name) {
return Some(ast::SelfRegion(Some(lifetime), muta, id));
return Some(hir::SelfRegion(Some(lifetime), muta, id));
},
None => {
let anon = self.cur_anon.get();
self.inc_and_offset_cur_anon(1);
if anon_nums.contains(&anon) {
self.track_anon(anon);
return Some(ast::SelfRegion(Some(lifetime), muta, id));
return Some(hir::SelfRegion(Some(lifetime), muta, id));
}
}
},
@ -1249,16 +1250,16 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
}
fn rebuild_generics(&self,
generics: &ast::Generics,
add: &Vec<ast::Lifetime>,
generics: &hir::Generics,
add: &Vec<hir::Lifetime>,
keep: &HashSet<ast::Name>,
remove: &HashSet<ast::Name>,
ty_params: OwnedSlice<ast::TyParam>,
where_clause: ast::WhereClause)
-> ast::Generics {
ty_params: OwnedSlice<hir::TyParam>,
where_clause: hir::WhereClause)
-> hir::Generics {
let mut lifetimes = Vec::new();
for lt in add {
lifetimes.push(ast::LifetimeDef { lifetime: *lt,
lifetimes.push(hir::LifetimeDef { lifetime: *lt,
bounds: Vec::new() });
}
for lt in &generics.lifetimes {
@ -1267,7 +1268,7 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
lifetimes.push((*lt).clone());
}
}
ast::Generics {
hir::Generics {
lifetimes: lifetimes,
ty_params: ty_params,
where_clause: where_clause,
@ -1275,16 +1276,16 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
}
fn rebuild_args_ty(&self,
inputs: &[ast::Arg],
lifetime: ast::Lifetime,
inputs: &[hir::Arg],
lifetime: hir::Lifetime,
anon_nums: &HashSet<u32>,
region_names: &HashSet<ast::Name>)
-> Vec<ast::Arg> {
-> Vec<hir::Arg> {
let mut new_inputs = Vec::new();
for arg in inputs {
let new_ty = self.rebuild_arg_ty_or_output(&*arg.ty, lifetime,
anon_nums, region_names);
let possibly_new_arg = ast::Arg {
let possibly_new_arg = hir::Arg {
ty: new_ty,
pat: arg.pat.clone(),
id: arg.id
@ -1294,31 +1295,31 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
new_inputs
}
fn rebuild_output(&self, ty: &ast::FunctionRetTy,
lifetime: ast::Lifetime,
fn rebuild_output(&self, ty: &hir::FunctionRetTy,
lifetime: hir::Lifetime,
anon_nums: &HashSet<u32>,
region_names: &HashSet<ast::Name>) -> ast::FunctionRetTy {
region_names: &HashSet<ast::Name>) -> hir::FunctionRetTy {
match *ty {
ast::Return(ref ret_ty) => ast::Return(
hir::Return(ref ret_ty) => hir::Return(
self.rebuild_arg_ty_or_output(&**ret_ty, lifetime, anon_nums, region_names)
),
ast::DefaultReturn(span) => ast::DefaultReturn(span),
ast::NoReturn(span) => ast::NoReturn(span)
hir::DefaultReturn(span) => hir::DefaultReturn(span),
hir::NoReturn(span) => hir::NoReturn(span)
}
}
fn rebuild_arg_ty_or_output(&self,
ty: &ast::Ty,
lifetime: ast::Lifetime,
ty: &hir::Ty,
lifetime: hir::Lifetime,
anon_nums: &HashSet<u32>,
region_names: &HashSet<ast::Name>)
-> P<ast::Ty> {
-> P<hir::Ty> {
let mut new_ty = P(ty.clone());
let mut ty_queue = vec!(ty);
while !ty_queue.is_empty() {
let cur_ty = ty_queue.remove(0);
match cur_ty.node {
ast::TyRptr(lt_opt, ref mut_ty) => {
hir::TyRptr(lt_opt, ref mut_ty) => {
let rebuild = match lt_opt {
Some(lt) => region_names.contains(&lt.name),
None => {
@ -1332,16 +1333,16 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
}
};
if rebuild {
let to = ast::Ty {
let to = hir::Ty {
id: cur_ty.id,
node: ast::TyRptr(Some(lifetime), mut_ty.clone()),
node: hir::TyRptr(Some(lifetime), mut_ty.clone()),
span: cur_ty.span
};
new_ty = self.rebuild_ty(new_ty, P(to));
}
ty_queue.push(&*mut_ty.ty);
}
ast::TyPath(ref maybe_qself, ref path) => {
hir::TyPath(ref maybe_qself, ref path) => {
let a_def = match self.tcx.def_map.borrow().get(&cur_ty.id) {
None => {
self.tcx
@ -1386,15 +1387,15 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
};
let new_path = self.rebuild_path(rebuild_info, lifetime);
let qself = maybe_qself.as_ref().map(|qself| {
ast::QSelf {
hir::QSelf {
ty: self.rebuild_arg_ty_or_output(&qself.ty, lifetime,
anon_nums, region_names),
position: qself.position
}
});
let to = ast::Ty {
let to = hir::Ty {
id: cur_ty.id,
node: ast::TyPath(qself, new_path),
node: hir::TyPath(qself, new_path),
span: cur_ty.span
};
new_ty = self.rebuild_ty(new_ty, P(to));
@ -1404,14 +1405,14 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
}
ast::TyPtr(ref mut_ty) => {
hir::TyPtr(ref mut_ty) => {
ty_queue.push(&*mut_ty.ty);
}
ast::TyVec(ref ty) |
ast::TyFixedLengthVec(ref ty, _) => {
hir::TyVec(ref ty) |
hir::TyFixedLengthVec(ref ty, _) => {
ty_queue.push(&**ty);
}
ast::TyTup(ref tys) => ty_queue.extend(tys.iter().map(|ty| &**ty)),
hir::TyTup(ref tys) => ty_queue.extend(tys.iter().map(|ty| &**ty)),
_ => {}
}
}
@ -1419,41 +1420,41 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
}
fn rebuild_ty(&self,
from: P<ast::Ty>,
to: P<ast::Ty>)
-> P<ast::Ty> {
from: P<hir::Ty>,
to: P<hir::Ty>)
-> P<hir::Ty> {
fn build_to(from: P<ast::Ty>,
to: &mut Option<P<ast::Ty>>)
-> P<ast::Ty> {
fn build_to(from: P<hir::Ty>,
to: &mut Option<P<hir::Ty>>)
-> P<hir::Ty> {
if Some(from.id) == to.as_ref().map(|ty| ty.id) {
return to.take().expect("`to` type found more than once during rebuild");
}
from.map(|ast::Ty {id, node, span}| {
from.map(|hir::Ty {id, node, span}| {
let new_node = match node {
ast::TyRptr(lifetime, mut_ty) => {
ast::TyRptr(lifetime, ast::MutTy {
hir::TyRptr(lifetime, mut_ty) => {
hir::TyRptr(lifetime, hir::MutTy {
mutbl: mut_ty.mutbl,
ty: build_to(mut_ty.ty, to),
})
}
ast::TyPtr(mut_ty) => {
ast::TyPtr(ast::MutTy {
hir::TyPtr(mut_ty) => {
hir::TyPtr(hir::MutTy {
mutbl: mut_ty.mutbl,
ty: build_to(mut_ty.ty, to),
})
}
ast::TyVec(ty) => ast::TyVec(build_to(ty, to)),
ast::TyFixedLengthVec(ty, e) => {
ast::TyFixedLengthVec(build_to(ty, to), e)
hir::TyVec(ty) => hir::TyVec(build_to(ty, to)),
hir::TyFixedLengthVec(ty, e) => {
hir::TyFixedLengthVec(build_to(ty, to), e)
}
ast::TyTup(tys) => {
ast::TyTup(tys.into_iter().map(|ty| build_to(ty, to)).collect())
hir::TyTup(tys) => {
hir::TyTup(tys.into_iter().map(|ty| build_to(ty, to)).collect())
}
ast::TyParen(typ) => ast::TyParen(build_to(typ, to)),
hir::TyParen(typ) => hir::TyParen(build_to(typ, to)),
other => other
};
ast::Ty { id: id, node: new_node, span: span }
hir::Ty { id: id, node: new_node, span: span }
})
}
@ -1462,8 +1463,8 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
fn rebuild_path(&self,
rebuild_info: RebuildPathInfo,
lifetime: ast::Lifetime)
-> ast::Path
lifetime: hir::Lifetime)
-> hir::Path
{
let RebuildPathInfo {
path,
@ -1475,11 +1476,11 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
let last_seg = path.segments.last().unwrap();
let new_parameters = match last_seg.parameters {
ast::ParenthesizedParameters(..) => {
hir::ParenthesizedParameters(..) => {
last_seg.parameters.clone()
}
ast::AngleBracketedParameters(ref data) => {
hir::AngleBracketedParameters(ref data) => {
let mut new_lts = Vec::new();
if data.lifetimes.is_empty() {
// traverse once to see if there's a need to insert lifetime
@ -1508,7 +1509,7 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
self.rebuild_arg_ty_or_output(&**t, lifetime, anon_nums, region_names)
});
let new_bindings = data.bindings.map(|b| {
P(ast::TypeBinding {
P(hir::TypeBinding {
id: b.id,
ident: b.ident,
ty: self.rebuild_arg_ty_or_output(&*b.ty,
@ -1518,21 +1519,21 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
span: b.span
})
});
ast::AngleBracketedParameters(ast::AngleBracketedParameterData {
hir::AngleBracketedParameters(hir::AngleBracketedParameterData {
lifetimes: new_lts,
types: new_types,
bindings: new_bindings,
})
}
};
let new_seg = ast::PathSegment {
let new_seg = hir::PathSegment {
identifier: last_seg.identifier,
parameters: new_parameters
};
let mut new_segs = Vec::new();
new_segs.push_all(path.segments.split_last().unwrap().1);
new_segs.push(new_seg);
ast::Path {
hir::Path {
span: path.span,
global: path.global,
segments: new_segs
@ -1542,12 +1543,12 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
impl<'a, 'tcx> ErrorReportingHelpers<'tcx> for InferCtxt<'a, 'tcx> {
fn give_expl_lifetime_param(&self,
decl: &ast::FnDecl,
unsafety: ast::Unsafety,
constness: ast::Constness,
decl: &hir::FnDecl,
unsafety: hir::Unsafety,
constness: hir::Constness,
ident: ast::Ident,
opt_explicit_self: Option<&ast::ExplicitSelf_>,
generics: &ast::Generics,
opt_explicit_self: Option<&hir::ExplicitSelf_>,
generics: &hir::Generics,
span: Span) {
let suggested_fn = pprust::fun_to_string(decl, unsafety, constness, ident,
opt_explicit_self, generics);
@ -1832,13 +1833,13 @@ impl<'tcx> Resolvable<'tcx> for ty::PolyTraitRef<'tcx> {
fn lifetimes_in_scope(tcx: &ty::ctxt,
scope_id: ast::NodeId)
-> Vec<ast::LifetimeDef> {
-> Vec<hir::LifetimeDef> {
let mut taken = Vec::new();
let parent = tcx.map.get_parent(scope_id);
let method_id_opt = match tcx.map.find(parent) {
Some(node) => match node {
ast_map::NodeItem(item) => match item.node {
ast::ItemFn(_, _, _, _, ref gen, _) => {
hir::ItemFn(_, _, _, _, ref gen, _) => {
taken.push_all(&gen.lifetimes);
None
},
@ -1846,11 +1847,10 @@ fn lifetimes_in_scope(tcx: &ty::ctxt,
},
ast_map::NodeImplItem(ii) => {
match ii.node {
ast::MethodImplItem(ref sig, _) => {
hir::MethodImplItem(ref sig, _) => {
taken.push_all(&sig.generics.lifetimes);
Some(ii.id)
}
ast::MacImplItem(_) => tcx.sess.bug("unexpanded macro"),
_ => None,
}
}
@ -1864,7 +1864,7 @@ fn lifetimes_in_scope(tcx: &ty::ctxt,
match tcx.map.find(parent) {
Some(node) => match node {
ast_map::NodeItem(item) => match item.node {
ast::ItemImpl(_, _, ref gen, _, _, _) => {
hir::ItemImpl(_, _, ref gen, _, _, _) => {
taken.push_all(&gen.lifetimes);
}
_ => ()
@ -1881,11 +1881,11 @@ fn lifetimes_in_scope(tcx: &ty::ctxt,
struct LifeGiver {
taken: HashSet<String>,
counter: Cell<usize>,
generated: RefCell<Vec<ast::Lifetime>>,
generated: RefCell<Vec<hir::Lifetime>>,
}
impl LifeGiver {
fn with_taken(taken: &[ast::LifetimeDef]) -> LifeGiver {
fn with_taken(taken: &[hir::LifetimeDef]) -> LifeGiver {
let mut taken_ = HashSet::new();
for lt in taken {
let lt_name = lt.lifetime.name.to_string();
@ -1903,7 +1903,7 @@ impl LifeGiver {
self.counter.set(c+1);
}
fn give_lifetime(&self) -> ast::Lifetime {
fn give_lifetime(&self) -> hir::Lifetime {
let lifetime;
loop {
let mut s = String::from("'");
@ -1931,7 +1931,13 @@ impl LifeGiver {
}
}
fn get_generated_lifetimes(&self) -> Vec<ast::Lifetime> {
fn get_generated_lifetimes(&self) -> Vec<hir::Lifetime> {
self.generated.borrow().clone()
}
}
fn name_to_dummy_lifetime(name: ast::Name) -> hir::Lifetime {
hir::Lifetime { id: ast::DUMMY_NODE_ID,
span: codemap::DUMMY_SP,
name: name }
}

View File

@ -20,6 +20,7 @@ pub use self::freshen::TypeFreshener;
pub use self::region_inference::{GenericKind, VerifyBound};
use middle::def_id::DefId;
use rustc_front::hir;
use middle::free_region::FreeRegionMap;
use middle::mem_categorization as mc;
use middle::mem_categorization::McResult;
@ -1147,7 +1148,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
/// Apply `adjustment` to the type of `expr`
pub fn adjust_expr_ty(&self,
expr: &ast::Expr,
expr: &hir::Expr,
adjustment: Option<&ty::AutoAdjustment<'tcx>>)
-> Ty<'tcx>
{
@ -1179,7 +1180,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
}
}
pub fn expr_ty(&self, ex: &ast::Expr) -> Ty<'tcx> {
pub fn expr_ty(&self, ex: &hir::Expr) -> Ty<'tcx> {
match self.tables.borrow().node_types.get(&ex.id) {
Some(&t) => t,
None => {
@ -1446,7 +1447,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
self.resolve_type_vars_or_error(&ty)
}
pub fn expr_ty_adjusted(&self, expr: &ast::Expr) -> McResult<Ty<'tcx>> {
pub fn expr_ty_adjusted(&self, expr: &hir::Expr) -> McResult<Ty<'tcx>> {
let ty = self.adjust_expr_ty(expr, self.tables.borrow().adjustments.get(&expr.id));
self.resolve_type_vars_or_error(&ty)
}

View File

@ -10,7 +10,7 @@
use middle::ty::{self, IntVarValue, Ty};
use rustc_data_structures::unify::UnifyKey;
use syntax::ast;
use rustc_front::hir as ast;
pub trait ToType<'tcx> {
fn to_type(&self, tcx: &ty::ctxt<'tcx>) -> Ty<'tcx>;

View File

@ -19,8 +19,8 @@ use std::fmt;
use syntax::abi::RustIntrinsic;
use syntax::ast;
use syntax::codemap::Span;
use syntax::visit::{FnKind, Visitor};
use syntax::visit;
use rustc_front::visit::{self, Visitor, FnKind};
use rustc_front::hir;
pub fn check_crate(tcx: &ctxt) {
let mut visitor = IntrinsicCheckingVisitor {
@ -216,8 +216,8 @@ impl<'a, 'tcx> IntrinsicCheckingVisitor<'a, 'tcx> {
}
impl<'a, 'tcx, 'v> Visitor<'v> for IntrinsicCheckingVisitor<'a, 'tcx> {
fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v ast::FnDecl,
b: &'v ast::Block, s: Span, id: ast::NodeId) {
fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v hir::FnDecl,
b: &'v hir::Block, s: Span, id: ast::NodeId) {
match fk {
FnKind::ItemFn(..) | FnKind::Method(..) => {
let param_env = ty::ParameterEnvironment::for_item(self.tcx, id);
@ -232,8 +232,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for IntrinsicCheckingVisitor<'a, 'tcx> {
}
fn visit_expr(&mut self, expr: &ast::Expr) {
if let ast::ExprPath(..) = expr.node {
fn visit_expr(&mut self, expr: &hir::Expr) {
if let hir::ExprPath(..) = expr.node {
match self.tcx.resolve_expr(expr) {
DefFn(did, _) if self.def_id_is_transmute(did) => {
let typ = self.tcx.node_id_to_type(expr.id);

View File

@ -28,12 +28,12 @@ use middle::ty;
use middle::weak_lang_items;
use util::nodemap::FnvHashMap;
use syntax::ast;
use syntax::attr::AttrMetaMethods;
use rustc_front::attr::AttrMetaMethods;
use syntax::codemap::{DUMMY_SP, Span};
use syntax::parse::token::InternedString;
use syntax::visit::Visitor;
use syntax::visit;
use rustc_front::visit::Visitor;
use rustc_front::visit;
use rustc_front::hir;
use std::iter::Enumerate;
use std::slice;
@ -152,7 +152,7 @@ struct LanguageItemCollector<'a> {
}
impl<'a, 'v> Visitor<'v> for LanguageItemCollector<'a> {
fn visit_item(&mut self, item: &ast::Item) {
fn visit_item(&mut self, item: &hir::Item) {
if let Some(value) = extract(&item.attrs) {
let item_index = self.item_refs.get(&value[..]).cloned();
@ -195,7 +195,7 @@ impl<'a> LanguageItemCollector<'a> {
self.items.items[item_index] = Some(item_def_id);
}
pub fn collect_local_language_items(&mut self, krate: &ast::Crate) {
pub fn collect_local_language_items(&mut self, krate: &hir::Crate) {
visit::walk_crate(self, krate);
}
@ -210,13 +210,13 @@ impl<'a> LanguageItemCollector<'a> {
})
}
pub fn collect(&mut self, krate: &ast::Crate) {
pub fn collect(&mut self, krate: &hir::Crate) {
self.collect_local_language_items(krate);
self.collect_external_language_items();
}
}
pub fn extract(attrs: &[ast::Attribute]) -> Option<InternedString> {
pub fn extract(attrs: &[hir::Attribute]) -> Option<InternedString> {
for attribute in attrs {
match attribute.value_str() {
Some(ref value) if attribute.check_name("lang") => {
@ -229,7 +229,7 @@ pub fn extract(attrs: &[ast::Attribute]) -> Option<InternedString> {
return None;
}
pub fn collect_language_items(krate: &ast::Crate,
pub fn collect_language_items(krate: &hir::Crate,
session: &Session) -> LanguageItems {
let mut collector = LanguageItemCollector::new(session);
collector.collect(krate);

View File

@ -119,13 +119,15 @@ use std::{fmt, usize};
use std::io::prelude::*;
use std::io;
use std::rc::Rc;
use syntax::ast::{self, NodeId, Expr};
use syntax::ast::{self, NodeId};
use syntax::codemap::{BytePos, original_sp, Span};
use syntax::parse::token::special_idents;
use syntax::print::pprust::{expr_to_string, block_to_string};
use syntax::ptr::P;
use syntax::ast_util;
use syntax::visit::{self, Visitor, FnKind};
use rustc_front::hir::Expr;
use rustc_front::hir;
use rustc_front::print::pprust::{expr_to_string, block_to_string};
use rustc_front::visit::{self, Visitor, FnKind};
/// For use with `propagate_through_loop`.
enum LoopKind<'a> {
@ -180,13 +182,13 @@ fn live_node_kind_to_string(lnk: LiveNodeKind, cx: &ty::ctxt) -> String {
}
impl<'a, 'tcx, 'v> Visitor<'v> for IrMaps<'a, 'tcx> {
fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v ast::FnDecl,
b: &'v ast::Block, s: Span, id: NodeId) {
fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v hir::FnDecl,
b: &'v hir::Block, s: Span, id: NodeId) {
visit_fn(self, fk, fd, b, s, id);
}
fn visit_local(&mut self, l: &ast::Local) { visit_local(self, l); }
fn visit_local(&mut self, l: &hir::Local) { visit_local(self, l); }
fn visit_expr(&mut self, ex: &Expr) { visit_expr(self, ex); }
fn visit_arm(&mut self, a: &ast::Arm) { visit_arm(self, a); }
fn visit_arm(&mut self, a: &hir::Arm) { visit_arm(self, a); }
}
pub fn check_crate(tcx: &ty::ctxt) {
@ -348,25 +350,25 @@ impl<'a, 'tcx> IrMaps<'a, 'tcx> {
}
impl<'a, 'tcx, 'v> Visitor<'v> for Liveness<'a, 'tcx> {
fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v ast::FnDecl,
b: &'v ast::Block, s: Span, n: NodeId) {
fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v hir::FnDecl,
b: &'v hir::Block, s: Span, n: NodeId) {
check_fn(self, fk, fd, b, s, n);
}
fn visit_local(&mut self, l: &ast::Local) {
fn visit_local(&mut self, l: &hir::Local) {
check_local(self, l);
}
fn visit_expr(&mut self, ex: &Expr) {
check_expr(self, ex);
}
fn visit_arm(&mut self, a: &ast::Arm) {
fn visit_arm(&mut self, a: &hir::Arm) {
check_arm(self, a);
}
}
fn visit_fn(ir: &mut IrMaps,
fk: FnKind,
decl: &ast::FnDecl,
body: &ast::Block,
decl: &hir::FnDecl,
body: &hir::Block,
sp: Span,
id: ast::NodeId) {
debug!("visit_fn");
@ -411,7 +413,7 @@ fn visit_fn(ir: &mut IrMaps,
lsets.warn_about_unused_args(decl, entry_ln);
}
fn visit_local(ir: &mut IrMaps, local: &ast::Local) {
fn visit_local(ir: &mut IrMaps, local: &hir::Local) {
pat_util::pat_bindings(&ir.tcx.def_map, &*local.pat, |_, p_id, sp, path1| {
debug!("adding local variable {}", p_id);
let name = path1.node.name;
@ -424,7 +426,7 @@ fn visit_local(ir: &mut IrMaps, local: &ast::Local) {
visit::walk_local(ir, local);
}
fn visit_arm(ir: &mut IrMaps, arm: &ast::Arm) {
fn visit_arm(ir: &mut IrMaps, arm: &hir::Arm) {
for pat in &arm.pats {
pat_util::pat_bindings(&ir.tcx.def_map, &**pat, |bm, p_id, sp, path1| {
debug!("adding local variable {} from match with bm {:?}",
@ -443,7 +445,7 @@ fn visit_arm(ir: &mut IrMaps, arm: &ast::Arm) {
fn visit_expr(ir: &mut IrMaps, expr: &Expr) {
match expr.node {
// live nodes required for uses or definitions of variables:
ast::ExprPath(..) => {
hir::ExprPath(..) => {
let def = ir.tcx.def_map.borrow().get(&expr.id).unwrap().full_def();
debug!("expr {}: path that leads to {:?}", expr.id, def);
if let DefLocal(..) = def {
@ -451,7 +453,7 @@ fn visit_expr(ir: &mut IrMaps, expr: &Expr) {
}
visit::walk_expr(ir, expr);
}
ast::ExprClosure(..) => {
hir::ExprClosure(..) => {
// Interesting control flow (for loops can contain labeled
// breaks or continues)
ir.add_live_node_for_node(expr.id, ExprNode(expr.span));
@ -476,34 +478,25 @@ fn visit_expr(ir: &mut IrMaps, expr: &Expr) {
}
// live nodes required for interesting control flow:
ast::ExprIf(..) | ast::ExprMatch(..) | ast::ExprWhile(..) | ast::ExprLoop(..) => {
hir::ExprIf(..) | hir::ExprMatch(..) | hir::ExprWhile(..) | hir::ExprLoop(..) => {
ir.add_live_node_for_node(expr.id, ExprNode(expr.span));
visit::walk_expr(ir, expr);
}
ast::ExprIfLet(..) => {
ir.tcx.sess.span_bug(expr.span, "non-desugared ExprIfLet");
}
ast::ExprWhileLet(..) => {
ir.tcx.sess.span_bug(expr.span, "non-desugared ExprWhileLet");
}
ast::ExprForLoop(..) => {
ir.tcx.sess.span_bug(expr.span, "non-desugared ExprForLoop");
}
ast::ExprBinary(op, _, _) if ast_util::lazy_binop(op.node) => {
hir::ExprBinary(op, _, _) if ::rustc_front::util::lazy_binop(op.node) => {
ir.add_live_node_for_node(expr.id, ExprNode(expr.span));
visit::walk_expr(ir, expr);
}
// otherwise, live nodes are not required:
ast::ExprIndex(..) | ast::ExprField(..) | ast::ExprTupField(..) |
ast::ExprVec(..) | ast::ExprCall(..) | ast::ExprMethodCall(..) |
ast::ExprTup(..) | ast::ExprBinary(..) | ast::ExprAddrOf(..) |
ast::ExprCast(..) | ast::ExprUnary(..) | ast::ExprBreak(_) |
ast::ExprAgain(_) | ast::ExprLit(_) | ast::ExprRet(..) |
ast::ExprBlock(..) | ast::ExprAssign(..) | ast::ExprAssignOp(..) |
ast::ExprMac(..) | ast::ExprStruct(..) | ast::ExprRepeat(..) |
ast::ExprParen(..) | ast::ExprInlineAsm(..) | ast::ExprBox(..) |
ast::ExprRange(..) => {
hir::ExprIndex(..) | hir::ExprField(..) | hir::ExprTupField(..) |
hir::ExprVec(..) | hir::ExprCall(..) | hir::ExprMethodCall(..) |
hir::ExprTup(..) | hir::ExprBinary(..) | hir::ExprAddrOf(..) |
hir::ExprCast(..) | hir::ExprUnary(..) | hir::ExprBreak(_) |
hir::ExprAgain(_) | hir::ExprLit(_) | hir::ExprRet(..) |
hir::ExprBlock(..) | hir::ExprAssign(..) | hir::ExprAssignOp(..) |
hir::ExprStruct(..) | hir::ExprRepeat(..) |
hir::ExprParen(..) | hir::ExprInlineAsm(..) | hir::ExprBox(..) |
hir::ExprRange(..) => {
visit::walk_expr(ir, expr);
}
}
@ -592,7 +585,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
self.ir.variable(node_id, span)
}
fn pat_bindings<F>(&mut self, pat: &ast::Pat, mut f: F) where
fn pat_bindings<F>(&mut self, pat: &hir::Pat, mut f: F) where
F: FnMut(&mut Liveness<'a, 'tcx>, LiveNode, Variable, Span, NodeId),
{
pat_util::pat_bindings(&self.ir.tcx.def_map, pat, |_bm, p_id, sp, _n| {
@ -602,7 +595,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
})
}
fn arm_pats_bindings<F>(&mut self, pat: Option<&ast::Pat>, f: F) where
fn arm_pats_bindings<F>(&mut self, pat: Option<&hir::Pat>, f: F) where
F: FnMut(&mut Liveness<'a, 'tcx>, LiveNode, Variable, Span, NodeId),
{
match pat {
@ -613,12 +606,12 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
}
}
fn define_bindings_in_pat(&mut self, pat: &ast::Pat, succ: LiveNode)
fn define_bindings_in_pat(&mut self, pat: &hir::Pat, succ: LiveNode)
-> LiveNode {
self.define_bindings_in_arm_pats(Some(pat), succ)
}
fn define_bindings_in_arm_pats(&mut self, pat: Option<&ast::Pat>, succ: LiveNode)
fn define_bindings_in_arm_pats(&mut self, pat: Option<&hir::Pat>, succ: LiveNode)
-> LiveNode {
let mut succ = succ;
self.arm_pats_bindings(pat, |this, ln, var, _sp, _id| {
@ -830,7 +823,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
// _______________________________________________________________________
fn compute(&mut self, decl: &ast::FnDecl, body: &ast::Block) -> LiveNode {
fn compute(&mut self, decl: &hir::FnDecl, body: &hir::Block) -> LiveNode {
// if there is a `break` or `again` at the top level, then it's
// effectively a return---this only occurs in `for` loops,
// where the body is really a closure.
@ -855,7 +848,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
entry_ln
}
fn propagate_through_fn_block(&mut self, _: &ast::FnDecl, blk: &ast::Block)
fn propagate_through_fn_block(&mut self, _: &hir::FnDecl, blk: &hir::Block)
-> LiveNode {
// the fallthrough exit is only for those cases where we do not
// explicitly return:
@ -869,7 +862,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
self.propagate_through_block(blk, s.fallthrough_ln)
}
fn propagate_through_block(&mut self, blk: &ast::Block, succ: LiveNode)
fn propagate_through_block(&mut self, blk: &hir::Block, succ: LiveNode)
-> LiveNode {
let succ = self.propagate_through_opt_expr(blk.expr.as_ref().map(|e| &**e), succ);
blk.stmts.iter().rev().fold(succ, |succ, stmt| {
@ -877,34 +870,30 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
})
}
fn propagate_through_stmt(&mut self, stmt: &ast::Stmt, succ: LiveNode)
fn propagate_through_stmt(&mut self, stmt: &hir::Stmt, succ: LiveNode)
-> LiveNode {
match stmt.node {
ast::StmtDecl(ref decl, _) => {
hir::StmtDecl(ref decl, _) => {
self.propagate_through_decl(&**decl, succ)
}
ast::StmtExpr(ref expr, _) | ast::StmtSemi(ref expr, _) => {
hir::StmtExpr(ref expr, _) | hir::StmtSemi(ref expr, _) => {
self.propagate_through_expr(&**expr, succ)
}
ast::StmtMac(..) => {
self.ir.tcx.sess.span_bug(stmt.span, "unexpanded macro");
}
}
}
fn propagate_through_decl(&mut self, decl: &ast::Decl, succ: LiveNode)
fn propagate_through_decl(&mut self, decl: &hir::Decl, succ: LiveNode)
-> LiveNode {
match decl.node {
ast::DeclLocal(ref local) => {
hir::DeclLocal(ref local) => {
self.propagate_through_local(&**local, succ)
}
ast::DeclItem(_) => succ,
hir::DeclItem(_) => succ,
}
}
fn propagate_through_local(&mut self, local: &ast::Local, succ: LiveNode)
fn propagate_through_local(&mut self, local: &hir::Local, succ: LiveNode)
-> LiveNode {
// Note: we mark the variable as defined regardless of whether
// there is an initializer. Initially I had thought to only mark
@ -945,19 +934,19 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
match expr.node {
// Interesting cases with control flow or which gen/kill
ast::ExprPath(..) => {
hir::ExprPath(..) => {
self.access_path(expr, succ, ACC_READ | ACC_USE)
}
ast::ExprField(ref e, _) => {
hir::ExprField(ref e, _) => {
self.propagate_through_expr(&**e, succ)
}
ast::ExprTupField(ref e, _) => {
hir::ExprTupField(ref e, _) => {
self.propagate_through_expr(&**e, succ)
}
ast::ExprClosure(_, _, ref blk) => {
hir::ExprClosure(_, _, ref blk) => {
debug!("{} is an ExprClosure",
expr_to_string(expr));
@ -985,7 +974,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
})
}
ast::ExprIf(ref cond, ref then, ref els) => {
hir::ExprIf(ref cond, ref then, ref els) => {
//
// (cond)
// |
@ -1007,29 +996,17 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
self.propagate_through_expr(&**cond, ln)
}
ast::ExprIfLet(..) => {
self.ir.tcx.sess.span_bug(expr.span, "non-desugared ExprIfLet");
}
ast::ExprWhile(ref cond, ref blk, _) => {
hir::ExprWhile(ref cond, ref blk, _) => {
self.propagate_through_loop(expr, WhileLoop(&**cond), &**blk, succ)
}
ast::ExprWhileLet(..) => {
self.ir.tcx.sess.span_bug(expr.span, "non-desugared ExprWhileLet");
}
ast::ExprForLoop(..) => {
self.ir.tcx.sess.span_bug(expr.span, "non-desugared ExprForLoop");
}
// Note that labels have been resolved, so we don't need to look
// at the label ident
ast::ExprLoop(ref blk, _) => {
hir::ExprLoop(ref blk, _) => {
self.propagate_through_loop(expr, LoopLoop, &**blk, succ)
}
ast::ExprMatch(ref e, ref arms, _) => {
hir::ExprMatch(ref e, ref arms, _) => {
//
// (e)
// |
@ -1064,13 +1041,13 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
self.propagate_through_expr(&**e, ln)
}
ast::ExprRet(ref o_e) => {
hir::ExprRet(ref o_e) => {
// ignore succ and subst exit_ln:
let exit_ln = self.s.exit_ln;
self.propagate_through_opt_expr(o_e.as_ref().map(|e| &**e), exit_ln)
}
ast::ExprBreak(opt_label) => {
hir::ExprBreak(opt_label) => {
// Find which label this break jumps to
let sc = self.find_loop_scope(opt_label, expr.id, expr.span);
@ -1084,7 +1061,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
}
}
ast::ExprAgain(opt_label) => {
hir::ExprAgain(opt_label) => {
// Find which label this expr continues to
let sc = self.find_loop_scope(opt_label, expr.id, expr.span);
@ -1098,7 +1075,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
}
}
ast::ExprAssign(ref l, ref r) => {
hir::ExprAssign(ref l, ref r) => {
// see comment on lvalues in
// propagate_through_lvalue_components()
let succ = self.write_lvalue(&**l, succ, ACC_WRITE);
@ -1106,7 +1083,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
self.propagate_through_expr(&**r, succ)
}
ast::ExprAssignOp(_, ref l, ref r) => {
hir::ExprAssignOp(_, ref l, ref r) => {
// see comment on lvalues in
// propagate_through_lvalue_components()
let succ = self.write_lvalue(&**l, succ, ACC_WRITE|ACC_READ);
@ -1116,23 +1093,23 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
// Uninteresting cases: just propagate in rev exec order
ast::ExprVec(ref exprs) => {
hir::ExprVec(ref exprs) => {
self.propagate_through_exprs(&exprs[..], succ)
}
ast::ExprRepeat(ref element, ref count) => {
hir::ExprRepeat(ref element, ref count) => {
let succ = self.propagate_through_expr(&**count, succ);
self.propagate_through_expr(&**element, succ)
}
ast::ExprStruct(_, ref fields, ref with_expr) => {
hir::ExprStruct(_, ref fields, ref with_expr) => {
let succ = self.propagate_through_opt_expr(with_expr.as_ref().map(|e| &**e), succ);
fields.iter().rev().fold(succ, |succ, field| {
self.propagate_through_expr(&*field.expr, succ)
})
}
ast::ExprCall(ref f, ref args) => {
hir::ExprCall(ref f, ref args) => {
let diverges = !self.ir.tcx.is_method_call(expr.id) &&
self.ir.tcx.expr_ty_adjusted(&**f).fn_ret().diverges();
let succ = if diverges {
@ -1144,7 +1121,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
self.propagate_through_expr(&**f, succ)
}
ast::ExprMethodCall(_, _, ref args) => {
hir::ExprMethodCall(_, _, ref args) => {
let method_call = ty::MethodCall::expr(expr.id);
let method_ty = self.ir.tcx.tables.borrow().method_map[&method_call].ty;
let succ = if method_ty.fn_ret().diverges() {
@ -1155,11 +1132,11 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
self.propagate_through_exprs(&args[..], succ)
}
ast::ExprTup(ref exprs) => {
hir::ExprTup(ref exprs) => {
self.propagate_through_exprs(&exprs[..], succ)
}
ast::ExprBinary(op, ref l, ref r) if ast_util::lazy_binop(op.node) => {
hir::ExprBinary(op, ref l, ref r) if ::rustc_front::util::lazy_binop(op.node) => {
let r_succ = self.propagate_through_expr(&**r, succ);
let ln = self.live_node(expr.id, expr.span);
@ -1169,27 +1146,27 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
self.propagate_through_expr(&**l, ln)
}
ast::ExprIndex(ref l, ref r) |
ast::ExprBinary(_, ref l, ref r) |
ast::ExprBox(Some(ref l), ref r) => {
hir::ExprIndex(ref l, ref r) |
hir::ExprBinary(_, ref l, ref r) |
hir::ExprBox(Some(ref l), ref r) => {
let r_succ = self.propagate_through_expr(&**r, succ);
self.propagate_through_expr(&**l, r_succ)
}
ast::ExprRange(ref e1, ref e2) => {
hir::ExprRange(ref e1, ref e2) => {
let succ = e2.as_ref().map_or(succ, |e| self.propagate_through_expr(&**e, succ));
e1.as_ref().map_or(succ, |e| self.propagate_through_expr(&**e, succ))
}
ast::ExprBox(None, ref e) |
ast::ExprAddrOf(_, ref e) |
ast::ExprCast(ref e, _) |
ast::ExprUnary(_, ref e) |
ast::ExprParen(ref e) => {
hir::ExprBox(None, ref e) |
hir::ExprAddrOf(_, ref e) |
hir::ExprCast(ref e, _) |
hir::ExprUnary(_, ref e) |
hir::ExprParen(ref e) => {
self.propagate_through_expr(&**e, succ)
}
ast::ExprInlineAsm(ref ia) => {
hir::ExprInlineAsm(ref ia) => {
let succ = ia.outputs.iter().rev().fold(succ, |succ, &(_, ref expr, _)| {
// see comment on lvalues
@ -1203,17 +1180,13 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
})
}
ast::ExprLit(..) => {
hir::ExprLit(..) => {
succ
}
ast::ExprBlock(ref blk) => {
hir::ExprBlock(ref blk) => {
self.propagate_through_block(&**blk, succ)
}
ast::ExprMac(..) => {
self.ir.tcx.sess.span_bug(expr.span, "unexpanded macro");
}
}
}
@ -1271,9 +1244,9 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
// just ignore such cases and treat them as reads.
match expr.node {
ast::ExprPath(..) => succ,
ast::ExprField(ref e, _) => self.propagate_through_expr(&**e, succ),
ast::ExprTupField(ref e, _) => self.propagate_through_expr(&**e, succ),
hir::ExprPath(..) => succ,
hir::ExprField(ref e, _) => self.propagate_through_expr(&**e, succ),
hir::ExprTupField(ref e, _) => self.propagate_through_expr(&**e, succ),
_ => self.propagate_through_expr(expr, succ)
}
}
@ -1282,7 +1255,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
fn write_lvalue(&mut self, expr: &Expr, succ: LiveNode, acc: u32)
-> LiveNode {
match expr.node {
ast::ExprPath(..) => {
hir::ExprPath(..) => {
self.access_path(expr, succ, acc)
}
@ -1313,7 +1286,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
fn propagate_through_loop(&mut self,
expr: &Expr,
kind: LoopKind,
body: &ast::Block,
body: &hir::Block,
succ: LiveNode)
-> LiveNode {
@ -1400,7 +1373,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
// _______________________________________________________________________
// Checking for error conditions
fn check_local(this: &mut Liveness, local: &ast::Local) {
fn check_local(this: &mut Liveness, local: &hir::Local) {
match local.init {
Some(_) => {
this.warn_about_unused_or_dead_vars_in_pat(&*local.pat);
@ -1415,7 +1388,7 @@ fn check_local(this: &mut Liveness, local: &ast::Local) {
visit::walk_local(this, local);
}
fn check_arm(this: &mut Liveness, arm: &ast::Arm) {
fn check_arm(this: &mut Liveness, arm: &hir::Arm) {
// only consider the first pattern; any later patterns must have
// the same bindings, and we also consider the first pattern to be
// the "authoritative" set of ids
@ -1427,20 +1400,20 @@ fn check_arm(this: &mut Liveness, arm: &ast::Arm) {
fn check_expr(this: &mut Liveness, expr: &Expr) {
match expr.node {
ast::ExprAssign(ref l, ref r) => {
hir::ExprAssign(ref l, ref r) => {
this.check_lvalue(&**l);
this.visit_expr(&**r);
visit::walk_expr(this, expr);
}
ast::ExprAssignOp(_, ref l, _) => {
hir::ExprAssignOp(_, ref l, _) => {
this.check_lvalue(&**l);
visit::walk_expr(this, expr);
}
ast::ExprInlineAsm(ref ia) => {
hir::ExprInlineAsm(ref ia) => {
for &(_, ref input) in &ia.inputs {
this.visit_expr(&**input);
}
@ -1455,34 +1428,25 @@ fn check_expr(this: &mut Liveness, expr: &Expr) {
}
// no correctness conditions related to liveness
ast::ExprCall(..) | ast::ExprMethodCall(..) | ast::ExprIf(..) |
ast::ExprMatch(..) | ast::ExprWhile(..) | ast::ExprLoop(..) |
ast::ExprIndex(..) | ast::ExprField(..) | ast::ExprTupField(..) |
ast::ExprVec(..) | ast::ExprTup(..) | ast::ExprBinary(..) |
ast::ExprCast(..) | ast::ExprUnary(..) | ast::ExprRet(..) |
ast::ExprBreak(..) | ast::ExprAgain(..) | ast::ExprLit(_) |
ast::ExprBlock(..) | ast::ExprMac(..) | ast::ExprAddrOf(..) |
ast::ExprStruct(..) | ast::ExprRepeat(..) | ast::ExprParen(..) |
ast::ExprClosure(..) | ast::ExprPath(..) | ast::ExprBox(..) |
ast::ExprRange(..) => {
hir::ExprCall(..) | hir::ExprMethodCall(..) | hir::ExprIf(..) |
hir::ExprMatch(..) | hir::ExprWhile(..) | hir::ExprLoop(..) |
hir::ExprIndex(..) | hir::ExprField(..) | hir::ExprTupField(..) |
hir::ExprVec(..) | hir::ExprTup(..) | hir::ExprBinary(..) |
hir::ExprCast(..) | hir::ExprUnary(..) | hir::ExprRet(..) |
hir::ExprBreak(..) | hir::ExprAgain(..) | hir::ExprLit(_) |
hir::ExprBlock(..) | hir::ExprAddrOf(..) |
hir::ExprStruct(..) | hir::ExprRepeat(..) | hir::ExprParen(..) |
hir::ExprClosure(..) | hir::ExprPath(..) | hir::ExprBox(..) |
hir::ExprRange(..) => {
visit::walk_expr(this, expr);
}
ast::ExprIfLet(..) => {
this.ir.tcx.sess.span_bug(expr.span, "non-desugared ExprIfLet");
}
ast::ExprWhileLet(..) => {
this.ir.tcx.sess.span_bug(expr.span, "non-desugared ExprWhileLet");
}
ast::ExprForLoop(..) => {
this.ir.tcx.sess.span_bug(expr.span, "non-desugared ExprForLoop");
}
}
}
fn check_fn(_v: &Liveness,
_fk: FnKind,
_decl: &ast::FnDecl,
_body: &ast::Block,
_decl: &hir::FnDecl,
_body: &hir::Block,
_sp: Span,
_id: NodeId) {
// do not check contents of nested fns
@ -1503,7 +1467,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
sp: Span,
_fk: FnKind,
entry_ln: LiveNode,
body: &ast::Block)
body: &hir::Block)
{
// within the fn body, late-bound regions are liberated:
let fn_ret =
@ -1521,7 +1485,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
let ends_with_stmt = match body.expr {
None if !body.stmts.is_empty() =>
match body.stmts.first().unwrap().node {
ast::StmtSemi(ref e, _) => {
hir::StmtSemi(ref e, _) => {
self.ir.tcx.expr_ty(&**e) == t_ret
},
_ => false
@ -1555,7 +1519,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
fn check_lvalue(&mut self, expr: &Expr) {
match expr.node {
ast::ExprPath(..) => {
hir::ExprPath(..) => {
if let DefLocal(nid) = self.ir.tcx.def_map.borrow().get(&expr.id)
.unwrap()
.full_def() {
@ -1585,7 +1549,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
}
}
fn warn_about_unused_args(&self, decl: &ast::FnDecl, entry_ln: LiveNode) {
fn warn_about_unused_args(&self, decl: &hir::FnDecl, entry_ln: LiveNode) {
for arg in &decl.inputs {
pat_util::pat_bindings(&self.ir.tcx.def_map,
&*arg.pat,
@ -1600,7 +1564,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
}
}
fn warn_about_unused_or_dead_vars_in_pat(&mut self, pat: &ast::Pat) {
fn warn_about_unused_or_dead_vars_in_pat(&mut self, pat: &hir::Pat) {
self.pat_bindings(pat, |this, ln, var, sp, id| {
if !this.warn_about_unused(sp, id, ln, var) {
this.warn_about_dead_assign(sp, id, ln, var);

View File

@ -72,14 +72,15 @@ pub use self::categorization::*;
use self::Aliasability::*;
use ast_map;
use middle::def_id::DefId;
use front::map as ast_map;
use middle::infer;
use middle::check_const;
use middle::def;
use middle::ty::{self, Ty};
use syntax::ast::{MutImmutable, MutMutable};
use rustc_front::hir::{MutImmutable, MutMutable};
use rustc_front::hir;
use syntax::ast;
use syntax::codemap::Span;
@ -116,7 +117,7 @@ pub enum PointerKind {
BorrowedPtr(ty::BorrowKind, ty::Region),
/// `*T`
UnsafePtr(ast::Mutability),
UnsafePtr(hir::Mutability),
/// Implicit deref of the `&T` that results from an overloaded index `[]`.
Implicit(ty::BorrowKind, ty::Region),
@ -244,12 +245,12 @@ pub trait ast_node {
fn span(&self) -> Span;
}
impl ast_node for ast::Expr {
impl ast_node for hir::Expr {
fn id(&self) -> ast::NodeId { self.id }
fn span(&self) -> Span { self.span }
}
impl ast_node for ast::Pat {
impl ast_node for hir::Pat {
fn id(&self) -> ast::NodeId { self.id }
fn span(&self) -> Span { self.span }
}
@ -262,7 +263,7 @@ pub struct MemCategorizationContext<'t, 'a: 't, 'tcx : 'a> {
pub type McResult<T> = Result<T, ()>;
impl MutabilityCategory {
pub fn from_mutbl(m: ast::Mutability) -> MutabilityCategory {
pub fn from_mutbl(m: hir::Mutability) -> MutabilityCategory {
let ret = match m {
MutImmutable => McImmutable,
MutMutable => McDeclared
@ -304,8 +305,8 @@ impl MutabilityCategory {
fn from_local(tcx: &ty::ctxt, id: ast::NodeId) -> MutabilityCategory {
let ret = match tcx.map.get(id) {
ast_map::NodeLocal(p) | ast_map::NodeArg(p) => match p.node {
ast::PatIdent(bind_mode, _, _) => {
if bind_mode == ast::BindByValue(ast::MutMutable) {
hir::PatIdent(bind_mode, _, _) => {
if bind_mode == hir::BindByValue(hir::MutMutable) {
McDeclared
} else {
McImmutable
@ -366,7 +367,7 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
self.typer.tcx
}
fn expr_ty(&self, expr: &ast::Expr) -> McResult<Ty<'tcx>> {
fn expr_ty(&self, expr: &hir::Expr) -> McResult<Ty<'tcx>> {
match self.typer.node_ty(expr.id) {
Ok(t) => Ok(t),
Err(()) => {
@ -376,7 +377,7 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
}
}
fn expr_ty_adjusted(&self, expr: &ast::Expr) -> McResult<Ty<'tcx>> {
fn expr_ty_adjusted(&self, expr: &hir::Expr) -> McResult<Ty<'tcx>> {
let unadjusted_ty = try!(self.expr_ty(expr));
Ok(unadjusted_ty.adjust(
self.tcx(), expr.span, expr.id,
@ -388,14 +389,14 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
self.typer.node_ty(id)
}
fn pat_ty(&self, pat: &ast::Pat) -> McResult<Ty<'tcx>> {
fn pat_ty(&self, pat: &hir::Pat) -> McResult<Ty<'tcx>> {
let base_ty = try!(self.typer.node_ty(pat.id));
// FIXME (Issue #18207): This code detects whether we are
// looking at a `ref x`, and if so, figures out what the type
// *being borrowed* is. But ideally we would put in a more
// fundamental fix to this conflated use of the node id.
let ret_ty = match pat.node {
ast::PatIdent(ast::BindByRef(_), _, _) => {
hir::PatIdent(hir::BindByRef(_), _, _) => {
// a bind-by-ref means that the base_ty will be the type of the ident itself,
// but what we want here is the type of the underlying value being borrowed.
// So peel off one-level, turning the &T into T.
@ -411,7 +412,7 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
Ok(ret_ty)
}
pub fn cat_expr(&self, expr: &ast::Expr) -> McResult<cmt<'tcx>> {
pub fn cat_expr(&self, expr: &hir::Expr) -> McResult<cmt<'tcx>> {
match self.typer.adjustments().get(&expr.id) {
None => {
// No adjustments.
@ -443,7 +444,7 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
}
pub fn cat_expr_autoderefd(&self,
expr: &ast::Expr,
expr: &hir::Expr,
autoderefs: usize)
-> McResult<cmt<'tcx>> {
let mut cmt = try!(self.cat_expr_unadjusted(expr));
@ -456,17 +457,17 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
return Ok(cmt);
}
pub fn cat_expr_unadjusted(&self, expr: &ast::Expr) -> McResult<cmt<'tcx>> {
pub fn cat_expr_unadjusted(&self, expr: &hir::Expr) -> McResult<cmt<'tcx>> {
debug!("cat_expr: id={} expr={:?}", expr.id, expr);
let expr_ty = try!(self.expr_ty(expr));
match expr.node {
ast::ExprUnary(ast::UnDeref, ref e_base) => {
hir::ExprUnary(hir::UnDeref, ref e_base) => {
let base_cmt = try!(self.cat_expr(&**e_base));
self.cat_deref(expr, base_cmt, 0, None)
}
ast::ExprField(ref base, f_name) => {
hir::ExprField(ref base, f_name) => {
let base_cmt = try!(self.cat_expr(&**base));
debug!("cat_expr(cat_field): id={} expr={:?} base={:?}",
expr.id,
@ -475,12 +476,12 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
Ok(self.cat_field(expr, base_cmt, f_name.node.name, expr_ty))
}
ast::ExprTupField(ref base, idx) => {
hir::ExprTupField(ref base, idx) => {
let base_cmt = try!(self.cat_expr(&**base));
Ok(self.cat_tup_field(expr, base_cmt, idx.node, expr_ty))
}
ast::ExprIndex(ref base, _) => {
hir::ExprIndex(ref base, _) => {
let method_call = ty::MethodCall::expr(expr.id());
let context = InteriorOffsetKind::Index;
match self.typer.node_method_ty(method_call) {
@ -512,38 +513,28 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
}
}
ast::ExprPath(..) => {
hir::ExprPath(..) => {
let def = self.tcx().def_map.borrow().get(&expr.id).unwrap().full_def();
self.cat_def(expr.id, expr.span, expr_ty, def)
}
ast::ExprParen(ref e) => {
hir::ExprParen(ref e) => {
self.cat_expr(&**e)
}
ast::ExprAddrOf(..) | ast::ExprCall(..) |
ast::ExprAssign(..) | ast::ExprAssignOp(..) |
ast::ExprClosure(..) | ast::ExprRet(..) |
ast::ExprUnary(..) | ast::ExprRange(..) |
ast::ExprMethodCall(..) | ast::ExprCast(..) |
ast::ExprVec(..) | ast::ExprTup(..) | ast::ExprIf(..) |
ast::ExprBinary(..) | ast::ExprWhile(..) |
ast::ExprBlock(..) | ast::ExprLoop(..) | ast::ExprMatch(..) |
ast::ExprLit(..) | ast::ExprBreak(..) | ast::ExprMac(..) |
ast::ExprAgain(..) | ast::ExprStruct(..) | ast::ExprRepeat(..) |
ast::ExprInlineAsm(..) | ast::ExprBox(..) => {
hir::ExprAddrOf(..) | hir::ExprCall(..) |
hir::ExprAssign(..) | hir::ExprAssignOp(..) |
hir::ExprClosure(..) | hir::ExprRet(..) |
hir::ExprUnary(..) | hir::ExprRange(..) |
hir::ExprMethodCall(..) | hir::ExprCast(..) |
hir::ExprVec(..) | hir::ExprTup(..) | hir::ExprIf(..) |
hir::ExprBinary(..) | hir::ExprWhile(..) |
hir::ExprBlock(..) | hir::ExprLoop(..) | hir::ExprMatch(..) |
hir::ExprLit(..) | hir::ExprBreak(..) |
hir::ExprAgain(..) | hir::ExprStruct(..) | hir::ExprRepeat(..) |
hir::ExprInlineAsm(..) | hir::ExprBox(..) => {
Ok(self.cat_rvalue_node(expr.id(), expr.span(), expr_ty))
}
ast::ExprIfLet(..) => {
self.tcx().sess.span_bug(expr.span, "non-desugared ExprIfLet");
}
ast::ExprWhileLet(..) => {
self.tcx().sess.span_bug(expr.span, "non-desugared ExprWhileLet");
}
ast::ExprForLoop(..) => {
self.tcx().sess.span_bug(expr.span, "non-desugared ExprForLoop");
}
}
}
@ -738,7 +729,7 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
};
match fn_expr.node {
ast::ExprClosure(_, _, ref body) => body.id,
hir::ExprClosure(_, _, ref body) => body.id,
_ => unreachable!()
}
};
@ -1078,8 +1069,8 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
/// These last two bits of info happen to be things that borrowck needs.
pub fn cat_slice_pattern(&self,
vec_cmt: cmt<'tcx>,
slice_pat: &ast::Pat)
-> McResult<(cmt<'tcx>, ast::Mutability, ty::Region)> {
slice_pat: &hir::Pat)
-> McResult<(cmt<'tcx>, hir::Mutability, ty::Region)> {
let slice_ty = try!(self.node_ty(slice_pat.id));
let (slice_mutbl, slice_r) = vec_slice_info(self.tcx(),
slice_pat,
@ -1093,9 +1084,9 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
/// ..ref c], then the type of `ref c` will be `&&[]`, so to extract the slice details we
/// have to recurse through rptrs.
fn vec_slice_info(tcx: &ty::ctxt,
pat: &ast::Pat,
pat: &hir::Pat,
slice_ty: Ty)
-> (ast::Mutability, ty::Region) {
-> (hir::Mutability, ty::Region) {
match slice_ty.sty {
ty::TyRef(r, ref mt) => match mt.ty.sty {
ty::TySlice(_) => (mt.mutbl, *r),
@ -1146,16 +1137,16 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
ret
}
pub fn cat_pattern<F>(&self, cmt: cmt<'tcx>, pat: &ast::Pat, mut op: F) -> McResult<()>
where F: FnMut(&MemCategorizationContext<'t, 'a, 'tcx>, cmt<'tcx>, &ast::Pat),
pub fn cat_pattern<F>(&self, cmt: cmt<'tcx>, pat: &hir::Pat, mut op: F) -> McResult<()>
where F: FnMut(&MemCategorizationContext<'t, 'a, 'tcx>, cmt<'tcx>, &hir::Pat),
{
self.cat_pattern_(cmt, pat, &mut op)
}
// FIXME(#19596) This is a workaround, but there should be a better way to do this
fn cat_pattern_<F>(&self, cmt: cmt<'tcx>, pat: &ast::Pat, op: &mut F)
fn cat_pattern_<F>(&self, cmt: cmt<'tcx>, pat: &hir::Pat, op: &mut F)
-> McResult<()>
where F : FnMut(&MemCategorizationContext<'t, 'a, 'tcx>, cmt<'tcx>, &ast::Pat),
where F : FnMut(&MemCategorizationContext<'t, 'a, 'tcx>, cmt<'tcx>, &hir::Pat),
{
// Here, `cmt` is the categorization for the value being
// matched and pat is the pattern it is being matched against.
@ -1223,14 +1214,14 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
};
match pat.node {
ast::PatWild(_) => {
hir::PatWild(_) => {
// _
}
ast::PatEnum(_, None) => {
hir::PatEnum(_, None) => {
// variant(..)
}
ast::PatEnum(_, Some(ref subpats)) => {
hir::PatEnum(_, Some(ref subpats)) => {
match opt_def {
Some(def::DefVariant(..)) => {
// variant(x, y, z)
@ -1268,19 +1259,19 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
}
}
ast::PatQPath(..) => {
hir::PatQPath(..) => {
// Lone constant: ignore
}
ast::PatIdent(_, _, Some(ref subpat)) => {
hir::PatIdent(_, _, Some(ref subpat)) => {
try!(self.cat_pattern_(cmt, &**subpat, op));
}
ast::PatIdent(_, _, None) => {
hir::PatIdent(_, _, None) => {
// nullary variant or identifier: ignore
}
ast::PatStruct(_, ref field_pats, _) => {
hir::PatStruct(_, ref field_pats, _) => {
// {f1: p1, ..., fN: pN}
for fp in field_pats {
let field_ty = try!(self.pat_ty(&*fp.node.pat)); // see (*2)
@ -1289,7 +1280,7 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
}
}
ast::PatTup(ref subpats) => {
hir::PatTup(ref subpats) => {
// (p1, ..., pN)
for (i, subpat) in subpats.iter().enumerate() {
let subpat_ty = try!(self.pat_ty(&**subpat)); // see (*2)
@ -1301,7 +1292,7 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
}
}
ast::PatBox(ref subpat) | ast::PatRegion(ref subpat, _) => {
hir::PatBox(ref subpat) | hir::PatRegion(ref subpat, _) => {
// box p1, &p1, &mut p1. we can ignore the mutability of
// PatRegion since that information is already contained
// in the type.
@ -1309,7 +1300,7 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
try!(self.cat_pattern_(subcmt, &**subpat, op));
}
ast::PatVec(ref before, ref slice, ref after) => {
hir::PatVec(ref before, ref slice, ref after) => {
let context = InteriorOffsetKind::Pattern;
let vec_cmt = try!(self.deref_vec(pat, cmt, context));
let elt_cmt = try!(self.cat_index(pat, vec_cmt, context));
@ -1326,13 +1317,9 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
}
}
ast::PatLit(_) | ast::PatRange(_, _) => {
hir::PatLit(_) | hir::PatRange(_, _) => {
/*always ok*/
}
ast::PatMac(_) => {
self.tcx().sess.span_bug(pat.span, "unexpanded macro");
}
}
Ok(())

View File

@ -14,14 +14,15 @@ use middle::ty;
use util::nodemap::FnvHashMap;
use syntax::ast;
use syntax::ast_util::walk_pat;
use rustc_front::hir;
use rustc_front::util::walk_pat;
use syntax::codemap::{Span, DUMMY_SP};
pub type PatIdMap = FnvHashMap<ast::Ident, ast::NodeId>;
// This is used because same-named variables in alternative patterns need to
// use the NodeId of their namesake in the first pattern.
pub fn pat_id_map(dm: &DefMap, pat: &ast::Pat) -> PatIdMap {
pub fn pat_id_map(dm: &DefMap, pat: &hir::Pat) -> PatIdMap {
let mut map = FnvHashMap();
pat_bindings(dm, pat, |_bm, p_id, _s, path1| {
map.insert(path1.node, p_id);
@ -29,27 +30,27 @@ pub fn pat_id_map(dm: &DefMap, pat: &ast::Pat) -> PatIdMap {
map
}
pub fn pat_is_refutable(dm: &DefMap, pat: &ast::Pat) -> bool {
pub fn pat_is_refutable(dm: &DefMap, pat: &hir::Pat) -> bool {
match pat.node {
ast::PatLit(_) | ast::PatRange(_, _) | ast::PatQPath(..) => true,
ast::PatEnum(_, _) |
ast::PatIdent(_, _, None) |
ast::PatStruct(..) => {
hir::PatLit(_) | hir::PatRange(_, _) | hir::PatQPath(..) => true,
hir::PatEnum(_, _) |
hir::PatIdent(_, _, None) |
hir::PatStruct(..) => {
match dm.borrow().get(&pat.id).map(|d| d.full_def()) {
Some(DefVariant(..)) => true,
_ => false
}
}
ast::PatVec(_, _, _) => true,
hir::PatVec(_, _, _) => true,
_ => false
}
}
pub fn pat_is_variant_or_struct(dm: &DefMap, pat: &ast::Pat) -> bool {
pub fn pat_is_variant_or_struct(dm: &DefMap, pat: &hir::Pat) -> bool {
match pat.node {
ast::PatEnum(_, _) |
ast::PatIdent(_, _, None) |
ast::PatStruct(..) => {
hir::PatEnum(_, _) |
hir::PatIdent(_, _, None) |
hir::PatStruct(..) => {
match dm.borrow().get(&pat.id).map(|d| d.full_def()) {
Some(DefVariant(..)) | Some(DefStruct(..)) => true,
_ => false
@ -59,9 +60,9 @@ pub fn pat_is_variant_or_struct(dm: &DefMap, pat: &ast::Pat) -> bool {
}
}
pub fn pat_is_const(dm: &DefMap, pat: &ast::Pat) -> bool {
pub fn pat_is_const(dm: &DefMap, pat: &hir::Pat) -> bool {
match pat.node {
ast::PatIdent(_, _, None) | ast::PatEnum(..) | ast::PatQPath(..) => {
hir::PatIdent(_, _, None) | hir::PatEnum(..) | hir::PatQPath(..) => {
match dm.borrow().get(&pat.id).map(|d| d.full_def()) {
Some(DefConst(..)) | Some(DefAssociatedConst(..)) => true,
_ => false
@ -73,9 +74,9 @@ pub fn pat_is_const(dm: &DefMap, pat: &ast::Pat) -> bool {
// Same as above, except that partially-resolved defs cause `false` to be
// returned instead of a panic.
pub fn pat_is_resolved_const(dm: &DefMap, pat: &ast::Pat) -> bool {
pub fn pat_is_resolved_const(dm: &DefMap, pat: &hir::Pat) -> bool {
match pat.node {
ast::PatIdent(_, _, None) | ast::PatEnum(..) | ast::PatQPath(..) => {
hir::PatIdent(_, _, None) | hir::PatEnum(..) | hir::PatQPath(..) => {
match dm.borrow().get(&pat.id)
.and_then(|d| if d.depth == 0 { Some(d.base_def) }
else { None } ) {
@ -87,9 +88,9 @@ pub fn pat_is_resolved_const(dm: &DefMap, pat: &ast::Pat) -> bool {
}
}
pub fn pat_is_binding(dm: &DefMap, pat: &ast::Pat) -> bool {
pub fn pat_is_binding(dm: &DefMap, pat: &hir::Pat) -> bool {
match pat.node {
ast::PatIdent(..) => {
hir::PatIdent(..) => {
!pat_is_variant_or_struct(dm, pat) &&
!pat_is_const(dm, pat)
}
@ -97,22 +98,22 @@ pub fn pat_is_binding(dm: &DefMap, pat: &ast::Pat) -> bool {
}
}
pub fn pat_is_binding_or_wild(dm: &DefMap, pat: &ast::Pat) -> bool {
pub fn pat_is_binding_or_wild(dm: &DefMap, pat: &hir::Pat) -> bool {
match pat.node {
ast::PatIdent(..) => pat_is_binding(dm, pat),
ast::PatWild(_) => true,
hir::PatIdent(..) => pat_is_binding(dm, pat),
hir::PatWild(_) => true,
_ => false
}
}
/// Call `it` on every "binding" in a pattern, e.g., on `a` in
/// `match foo() { Some(a) => (), None => () }`
pub fn pat_bindings<I>(dm: &DefMap, pat: &ast::Pat, mut it: I) where
I: FnMut(ast::BindingMode, ast::NodeId, Span, &ast::SpannedIdent),
pub fn pat_bindings<I>(dm: &DefMap, pat: &hir::Pat, mut it: I) where
I: FnMut(hir::BindingMode, ast::NodeId, Span, &hir::SpannedIdent),
{
walk_pat(pat, |p| {
match p.node {
ast::PatIdent(binding_mode, ref pth, _) if pat_is_binding(dm, p) => {
hir::PatIdent(binding_mode, ref pth, _) if pat_is_binding(dm, p) => {
it(binding_mode, p.id, p.span, pth);
}
_ => {}
@ -123,7 +124,7 @@ pub fn pat_bindings<I>(dm: &DefMap, pat: &ast::Pat, mut it: I) where
/// Checks if the pattern contains any patterns that bind something to
/// an ident, e.g. `foo`, or `Foo(foo)` or `foo @ Bar(..)`.
pub fn pat_contains_bindings(dm: &DefMap, pat: &ast::Pat) -> bool {
pub fn pat_contains_bindings(dm: &DefMap, pat: &hir::Pat) -> bool {
let mut contains_bindings = false;
walk_pat(pat, |p| {
if pat_is_binding(dm, p) {
@ -138,18 +139,18 @@ pub fn pat_contains_bindings(dm: &DefMap, pat: &ast::Pat) -> bool {
/// Checks if the pattern contains any `ref` or `ref mut` bindings,
/// and if yes wether its containing mutable ones or just immutables ones.
pub fn pat_contains_ref_binding(dm: &DefMap, pat: &ast::Pat) -> Option<ast::Mutability> {
pub fn pat_contains_ref_binding(dm: &DefMap, pat: &hir::Pat) -> Option<hir::Mutability> {
let mut result = None;
pat_bindings(dm, pat, |mode, _, _, _| {
match mode {
ast::BindingMode::BindByRef(m) => {
hir::BindingMode::BindByRef(m) => {
// Pick Mutable as maximum
match result {
None | Some(ast::MutImmutable) => result = Some(m),
None | Some(hir::MutImmutable) => result = Some(m),
_ => (),
}
}
ast::BindingMode::BindByValue(_) => { }
hir::BindingMode::BindByValue(_) => { }
}
});
result
@ -157,18 +158,18 @@ pub fn pat_contains_ref_binding(dm: &DefMap, pat: &ast::Pat) -> Option<ast::Muta
/// Checks if the patterns for this arm contain any `ref` or `ref mut`
/// bindings, and if yes wether its containing mutable ones or just immutables ones.
pub fn arm_contains_ref_binding(dm: &DefMap, arm: &ast::Arm) -> Option<ast::Mutability> {
pub fn arm_contains_ref_binding(dm: &DefMap, arm: &hir::Arm) -> Option<hir::Mutability> {
arm.pats.iter()
.filter_map(|pat| pat_contains_ref_binding(dm, pat))
.max_by(|m| match *m {
ast::MutMutable => 1,
ast::MutImmutable => 0,
hir::MutMutable => 1,
hir::MutImmutable => 0,
})
}
/// Checks if the pattern contains any patterns that bind something to
/// an ident or wildcard, e.g. `foo`, or `Foo(_)`, `foo @ Bar(..)`,
pub fn pat_contains_bindings_or_wild(dm: &DefMap, pat: &ast::Pat) -> bool {
pub fn pat_contains_bindings_or_wild(dm: &DefMap, pat: &hir::Pat) -> bool {
let mut contains_bindings = false;
walk_pat(pat, |p| {
if pat_is_binding_or_wild(dm, p) {
@ -181,9 +182,9 @@ pub fn pat_contains_bindings_or_wild(dm: &DefMap, pat: &ast::Pat) -> bool {
contains_bindings
}
pub fn simple_identifier<'a>(pat: &'a ast::Pat) -> Option<&'a ast::Ident> {
pub fn simple_identifier<'a>(pat: &'a hir::Pat) -> Option<&'a ast::Ident> {
match pat.node {
ast::PatIdent(ast::BindByValue(_), ref path1, None) => {
hir::PatIdent(hir::BindByValue(_), ref path1, None) => {
Some(&path1.node)
}
_ => {
@ -192,25 +193,25 @@ pub fn simple_identifier<'a>(pat: &'a ast::Pat) -> Option<&'a ast::Ident> {
}
}
pub fn def_to_path(tcx: &ty::ctxt, id: DefId) -> ast::Path {
tcx.with_path(id, |path| ast::Path {
pub fn def_to_path(tcx: &ty::ctxt, id: DefId) -> hir::Path {
tcx.with_path(id, |path| hir::Path {
global: false,
segments: path.last().map(|elem| ast::PathSegment {
segments: path.last().map(|elem| hir::PathSegment {
identifier: ast::Ident::new(elem.name()),
parameters: ast::PathParameters::none(),
parameters: hir::PathParameters::none(),
}).into_iter().collect(),
span: DUMMY_SP,
})
}
/// Return variants that are necessary to exist for the pattern to match.
pub fn necessary_variants(dm: &DefMap, pat: &ast::Pat) -> Vec<ast::NodeId> {
pub fn necessary_variants(dm: &DefMap, pat: &hir::Pat) -> Vec<ast::NodeId> {
let mut variants = vec![];
walk_pat(pat, |p| {
match p.node {
ast::PatEnum(_, _) |
ast::PatIdent(_, _, None) |
ast::PatStruct(..) => {
hir::PatEnum(_, _) |
hir::PatIdent(_, _, None) |
hir::PatStruct(..) => {
match dm.borrow().get(&p.id) {
Some(&PathResolution { base_def: DefVariant(_, id, _), .. }) => {
variants.push(id.node);

View File

@ -15,7 +15,7 @@
// makes all other generics or inline functions that it references
// reachable as well.
use ast_map;
use front::map as ast_map;
use middle::def;
use middle::def_id::{DefId, LOCAL_CRATE};
use middle::ty;
@ -26,35 +26,36 @@ use util::nodemap::NodeSet;
use std::collections::HashSet;
use syntax::abi;
use syntax::ast;
use syntax::attr;
use syntax::visit::Visitor;
use syntax::visit;
use rustc_front::hir;
use rustc_front::attr;
use rustc_front::visit::Visitor;
use rustc_front::visit;
// Returns true if the given set of generics implies that the item it's
// associated with must be inlined.
fn generics_require_inlining(generics: &ast::Generics) -> bool {
fn generics_require_inlining(generics: &hir::Generics) -> bool {
!generics.ty_params.is_empty()
}
// Returns true if the given item must be inlined because it may be
// monomorphized or it was marked with `#[inline]`. This will only return
// true for functions.
fn item_might_be_inlined(item: &ast::Item) -> bool {
fn item_might_be_inlined(item: &hir::Item) -> bool {
if attr::requests_inline(&item.attrs) {
return true
}
match item.node {
ast::ItemImpl(_, _, ref generics, _, _, _) |
ast::ItemFn(_, _, _, _, ref generics, _) => {
hir::ItemImpl(_, _, ref generics, _, _, _) |
hir::ItemFn(_, _, _, _, ref generics, _) => {
generics_require_inlining(generics)
}
_ => false,
}
}
fn method_might_be_inlined(tcx: &ty::ctxt, sig: &ast::MethodSig,
impl_item: &ast::ImplItem,
fn method_might_be_inlined(tcx: &ty::ctxt, sig: &hir::MethodSig,
impl_item: &hir::ImplItem,
impl_src: DefId) -> bool {
if attr::requests_inline(&impl_item.attrs) ||
generics_require_inlining(&sig.generics) {
@ -92,10 +93,10 @@ struct ReachableContext<'a, 'tcx: 'a> {
impl<'a, 'tcx, 'v> Visitor<'v> for ReachableContext<'a, 'tcx> {
fn visit_expr(&mut self, expr: &ast::Expr) {
fn visit_expr(&mut self, expr: &hir::Expr) {
match expr.node {
ast::ExprPath(..) => {
hir::ExprPath(..) => {
let def = match self.tcx.def_map.borrow().get(&expr.id) {
Some(d) => d.full_def(),
None => {
@ -126,7 +127,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ReachableContext<'a, 'tcx> {
}
}
}
ast::ExprMethodCall(..) => {
hir::ExprMethodCall(..) => {
let method_call = ty::MethodCall::expr(expr.id);
let def_id = self.tcx.tables.borrow().method_map[&method_call].def_id;
match self.tcx.impl_or_trait_item(def_id).container() {
@ -147,7 +148,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ReachableContext<'a, 'tcx> {
visit::walk_expr(self, expr)
}
fn visit_item(&mut self, _item: &ast::Item) {
fn visit_item(&mut self, _item: &hir::Item) {
// Do not recurse into items. These items will be added to the worklist
// and recursed into manually if necessary.
}
@ -178,21 +179,21 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
match self.tcx.map.find(node_id) {
Some(ast_map::NodeItem(item)) => {
match item.node {
ast::ItemFn(..) => item_might_be_inlined(&*item),
hir::ItemFn(..) => item_might_be_inlined(&*item),
_ => false,
}
}
Some(ast_map::NodeTraitItem(trait_method)) => {
match trait_method.node {
ast::ConstTraitItem(_, ref default) => default.is_some(),
ast::MethodTraitItem(_, ref body) => body.is_some(),
ast::TypeTraitItem(..) => false,
hir::ConstTraitItem(_, ref default) => default.is_some(),
hir::MethodTraitItem(_, ref body) => body.is_some(),
hir::TypeTraitItem(..) => false,
}
}
Some(ast_map::NodeImplItem(impl_item)) => {
match impl_item.node {
ast::ConstImplItem(..) => true,
ast::MethodImplItem(ref sig, _) => {
hir::ConstImplItem(..) => true,
hir::MethodImplItem(ref sig, _) => {
if generics_require_inlining(&sig.generics) ||
attr::requests_inline(&impl_item.attrs) {
true
@ -208,15 +209,14 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
.map
.expect_item(impl_did.node)
.node {
ast::ItemImpl(_, _, ref generics, _, _, _) => {
hir::ItemImpl(_, _, ref generics, _, _, _) => {
generics_require_inlining(generics)
}
_ => false
}
}
}
ast::TypeImplItem(_) => false,
ast::MacImplItem(_) => self.tcx.sess.bug("unexpanded macro")
hir::TypeImplItem(_) => false,
}
}
Some(_) => false,
@ -257,7 +257,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
// but all other rust-only interfaces can be private (they will not
// participate in linkage after this product is produced)
if let ast_map::NodeItem(item) = *node {
if let ast::ItemFn(_, _, _, abi, _, _) = item.node {
if let hir::ItemFn(_, _, _, abi, _, _) = item.node {
if abi != abi::Rust {
self.reachable_symbols.insert(search_item);
}
@ -274,7 +274,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
match *node {
ast_map::NodeItem(item) => {
match item.node {
ast::ItemFn(_, _, _, _, _, ref search_block) => {
hir::ItemFn(_, _, _, _, _, ref search_block) => {
if item_might_be_inlined(&*item) {
visit::walk_block(self, &**search_block)
}
@ -283,55 +283,48 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
// Reachable constants will be inlined into other crates
// unconditionally, so we need to make sure that their
// contents are also reachable.
ast::ItemConst(_, ref init) => {
hir::ItemConst(_, ref init) => {
self.visit_expr(&**init);
}
// These are normal, nothing reachable about these
// inherently and their children are already in the
// worklist, as determined by the privacy pass
ast::ItemExternCrate(_) | ast::ItemUse(_) |
ast::ItemTy(..) | ast::ItemStatic(_, _, _) |
ast::ItemMod(..) | ast::ItemForeignMod(..) |
ast::ItemImpl(..) | ast::ItemTrait(..) |
ast::ItemStruct(..) | ast::ItemEnum(..) |
ast::ItemDefaultImpl(..) => {}
_ => {
self.tcx.sess.span_bug(item.span,
"found non-function item \
in worklist?!")
}
hir::ItemExternCrate(_) | hir::ItemUse(_) |
hir::ItemTy(..) | hir::ItemStatic(_, _, _) |
hir::ItemMod(..) | hir::ItemForeignMod(..) |
hir::ItemImpl(..) | hir::ItemTrait(..) |
hir::ItemStruct(..) | hir::ItemEnum(..) |
hir::ItemDefaultImpl(..) => {}
}
}
ast_map::NodeTraitItem(trait_method) => {
match trait_method.node {
ast::ConstTraitItem(_, None) |
ast::MethodTraitItem(_, None) => {
hir::ConstTraitItem(_, None) |
hir::MethodTraitItem(_, None) => {
// Keep going, nothing to get exported
}
ast::ConstTraitItem(_, Some(ref expr)) => {
hir::ConstTraitItem(_, Some(ref expr)) => {
self.visit_expr(&*expr);
}
ast::MethodTraitItem(_, Some(ref body)) => {
hir::MethodTraitItem(_, Some(ref body)) => {
visit::walk_block(self, body);
}
ast::TypeTraitItem(..) => {}
hir::TypeTraitItem(..) => {}
}
}
ast_map::NodeImplItem(impl_item) => {
match impl_item.node {
ast::ConstImplItem(_, ref expr) => {
hir::ConstImplItem(_, ref expr) => {
self.visit_expr(&*expr);
}
ast::MethodImplItem(ref sig, ref body) => {
hir::MethodImplItem(ref sig, ref body) => {
let did = self.tcx.map.get_parent_did(search_item);
if method_might_be_inlined(self.tcx, sig, impl_item, did) {
visit::walk_block(self, body)
}
}
ast::TypeImplItem(_) => {}
ast::MacImplItem(_) => self.tcx.sess.bug("unexpanded macro")
hir::TypeImplItem(_) => {}
}
}
// Nothing to recurse on for these

View File

@ -16,20 +16,22 @@
//! Most of the documentation on regions can be found in
//! `middle/typeck/infer/region_inference.rs`
use ast_map;
use metadata::inline::InlinedItem;
use middle::ty::{self, Ty};
use front::map as ast_map;
use session::Session;
use util::nodemap::{FnvHashMap, NodeMap, NodeSet};
use middle::ty::{self, Ty};
use std::cell::RefCell;
use std::collections::hash_map::Entry;
use std::mem;
use syntax::codemap::{self, Span};
use syntax::{ast, visit};
use syntax::ast::{Block, Item, FnDecl, NodeId, Arm, Pat, Stmt, Expr, Local};
use syntax::ast_util::stmt_id;
use syntax::visit::{Visitor, FnKind};
use syntax::ast::{self, NodeId};
use rustc_front::hir;
use rustc_front::visit::{self, Visitor, FnKind};
use rustc_front::hir::{Block, Item, FnDecl, Arm, Pat, Stmt, Expr, Local};
use rustc_front::util::stmt_id;
#[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, RustcEncodable,
RustcDecodable, Debug, Copy)]
@ -632,7 +634,7 @@ fn record_var_lifetime(visitor: &mut RegionResolutionVisitor,
}
}
fn resolve_block(visitor: &mut RegionResolutionVisitor, blk: &ast::Block) {
fn resolve_block(visitor: &mut RegionResolutionVisitor, blk: &hir::Block) {
debug!("resolve_block(blk.id={:?})", blk.id);
let prev_cx = visitor.cx;
@ -676,7 +678,7 @@ fn resolve_block(visitor: &mut RegionResolutionVisitor, blk: &ast::Block) {
// index information.)
for (i, statement) in blk.stmts.iter().enumerate() {
if let ast::StmtDecl(..) = statement.node {
if let hir::StmtDecl(..) = statement.node {
// Each StmtDecl introduces a subscope for bindings
// introduced by the declaration; this subscope covers
// a suffix of the block . Each subscope in a block
@ -703,7 +705,7 @@ fn resolve_block(visitor: &mut RegionResolutionVisitor, blk: &ast::Block) {
visitor.cx = prev_cx;
}
fn resolve_arm(visitor: &mut RegionResolutionVisitor, arm: &ast::Arm) {
fn resolve_arm(visitor: &mut RegionResolutionVisitor, arm: &hir::Arm) {
visitor.terminating_scopes.insert(arm.body.id);
if let Some(ref expr) = arm.guard {
@ -713,13 +715,13 @@ fn resolve_arm(visitor: &mut RegionResolutionVisitor, arm: &ast::Arm) {
visit::walk_arm(visitor, arm);
}
fn resolve_pat(visitor: &mut RegionResolutionVisitor, pat: &ast::Pat) {
fn resolve_pat(visitor: &mut RegionResolutionVisitor, pat: &hir::Pat) {
visitor.new_node_extent(pat.id);
// If this is a binding (or maybe a binding, I'm too lazy to check
// the def map) then record the lifetime of that binding.
match pat.node {
ast::PatIdent(..) => {
hir::PatIdent(..) => {
record_var_lifetime(visitor, pat.id, pat.span);
}
_ => { }
@ -728,7 +730,7 @@ fn resolve_pat(visitor: &mut RegionResolutionVisitor, pat: &ast::Pat) {
visit::walk_pat(visitor, pat);
}
fn resolve_stmt(visitor: &mut RegionResolutionVisitor, stmt: &ast::Stmt) {
fn resolve_stmt(visitor: &mut RegionResolutionVisitor, stmt: &hir::Stmt) {
let stmt_id = stmt_id(stmt);
debug!("resolve_stmt(stmt.id={:?})", stmt_id);
@ -746,7 +748,7 @@ fn resolve_stmt(visitor: &mut RegionResolutionVisitor, stmt: &ast::Stmt) {
visitor.cx.parent = prev_parent;
}
fn resolve_expr(visitor: &mut RegionResolutionVisitor, expr: &ast::Expr) {
fn resolve_expr(visitor: &mut RegionResolutionVisitor, expr: &hir::Expr) {
debug!("resolve_expr(expr.id={:?})", expr.id);
let expr_extent = visitor.new_node_extent_with_dtor(expr.id);
@ -763,38 +765,38 @@ fn resolve_expr(visitor: &mut RegionResolutionVisitor, expr: &ast::Expr) {
// scopes, meaning that temporaries cannot outlive them.
// This ensures fixed size stacks.
ast::ExprBinary(codemap::Spanned { node: ast::BiAnd, .. }, _, ref r) |
ast::ExprBinary(codemap::Spanned { node: ast::BiOr, .. }, _, ref r) => {
hir::ExprBinary(codemap::Spanned { node: hir::BiAnd, .. }, _, ref r) |
hir::ExprBinary(codemap::Spanned { node: hir::BiOr, .. }, _, ref r) => {
// For shortcircuiting operators, mark the RHS as a terminating
// scope since it only executes conditionally.
terminating(r.id);
}
ast::ExprIf(_, ref then, Some(ref otherwise)) => {
hir::ExprIf(_, ref then, Some(ref otherwise)) => {
terminating(then.id);
terminating(otherwise.id);
}
ast::ExprIf(ref expr, ref then, None) => {
hir::ExprIf(ref expr, ref then, None) => {
terminating(expr.id);
terminating(then.id);
}
ast::ExprLoop(ref body, _) => {
hir::ExprLoop(ref body, _) => {
terminating(body.id);
}
ast::ExprWhile(ref expr, ref body, _) => {
hir::ExprWhile(ref expr, ref body, _) => {
terminating(expr.id);
terminating(body.id);
}
ast::ExprMatch(..) => {
hir::ExprMatch(..) => {
visitor.cx.var_parent = expr_extent;
}
ast::ExprAssignOp(..) | ast::ExprIndex(..) |
ast::ExprUnary(..) | ast::ExprCall(..) | ast::ExprMethodCall(..) => {
hir::ExprAssignOp(..) | hir::ExprIndex(..) |
hir::ExprUnary(..) | hir::ExprCall(..) | hir::ExprMethodCall(..) => {
// FIXME(#6268) Nested method calls
//
// The lifetimes for a call or method call look as follows:
@ -823,7 +825,7 @@ fn resolve_expr(visitor: &mut RegionResolutionVisitor, expr: &ast::Expr) {
visitor.cx = prev_cx;
}
fn resolve_local(visitor: &mut RegionResolutionVisitor, local: &ast::Local) {
fn resolve_local(visitor: &mut RegionResolutionVisitor, local: &hir::Local) {
debug!("resolve_local(local.id={:?},local.init={:?})",
local.id,local.init.is_some());
@ -920,26 +922,26 @@ fn resolve_local(visitor: &mut RegionResolutionVisitor, local: &ast::Local) {
/// | [ ..., P&, ... ]
/// | ( ..., P&, ... )
/// | box P&
fn is_binding_pat(pat: &ast::Pat) -> bool {
fn is_binding_pat(pat: &hir::Pat) -> bool {
match pat.node {
ast::PatIdent(ast::BindByRef(_), _, _) => true,
hir::PatIdent(hir::BindByRef(_), _, _) => true,
ast::PatStruct(_, ref field_pats, _) => {
hir::PatStruct(_, ref field_pats, _) => {
field_pats.iter().any(|fp| is_binding_pat(&*fp.node.pat))
}
ast::PatVec(ref pats1, ref pats2, ref pats3) => {
hir::PatVec(ref pats1, ref pats2, ref pats3) => {
pats1.iter().any(|p| is_binding_pat(&**p)) ||
pats2.iter().any(|p| is_binding_pat(&**p)) ||
pats3.iter().any(|p| is_binding_pat(&**p))
}
ast::PatEnum(_, Some(ref subpats)) |
ast::PatTup(ref subpats) => {
hir::PatEnum(_, Some(ref subpats)) |
hir::PatTup(ref subpats) => {
subpats.iter().any(|p| is_binding_pat(&**p))
}
ast::PatBox(ref subpat) => {
hir::PatBox(ref subpat) => {
is_binding_pat(&**subpat)
}
@ -948,9 +950,9 @@ fn resolve_local(visitor: &mut RegionResolutionVisitor, local: &ast::Local) {
}
/// True if `ty` is a borrowed pointer type like `&int` or `&[...]`.
fn is_borrowed_ty(ty: &ast::Ty) -> bool {
fn is_borrowed_ty(ty: &hir::Ty) -> bool {
match ty.node {
ast::TyRptr(..) => true,
hir::TyRptr(..) => true,
_ => false
}
}
@ -966,34 +968,34 @@ fn resolve_local(visitor: &mut RegionResolutionVisitor, local: &ast::Local) {
/// | E& as ...
/// | ( E& )
fn record_rvalue_scope_if_borrow_expr(visitor: &mut RegionResolutionVisitor,
expr: &ast::Expr,
expr: &hir::Expr,
blk_id: CodeExtent) {
match expr.node {
ast::ExprAddrOf(_, ref subexpr) => {
hir::ExprAddrOf(_, ref subexpr) => {
record_rvalue_scope_if_borrow_expr(visitor, &**subexpr, blk_id);
record_rvalue_scope(visitor, &**subexpr, blk_id);
}
ast::ExprStruct(_, ref fields, _) => {
hir::ExprStruct(_, ref fields, _) => {
for field in fields {
record_rvalue_scope_if_borrow_expr(
visitor, &*field.expr, blk_id);
}
}
ast::ExprVec(ref subexprs) |
ast::ExprTup(ref subexprs) => {
hir::ExprVec(ref subexprs) |
hir::ExprTup(ref subexprs) => {
for subexpr in subexprs {
record_rvalue_scope_if_borrow_expr(
visitor, &**subexpr, blk_id);
}
}
ast::ExprUnary(ast::UnUniq, ref subexpr) => {
hir::ExprUnary(hir::UnUniq, ref subexpr) => {
record_rvalue_scope_if_borrow_expr(visitor, &**subexpr, blk_id);
}
ast::ExprCast(ref subexpr, _) |
ast::ExprParen(ref subexpr) => {
hir::ExprCast(ref subexpr, _) |
hir::ExprParen(ref subexpr) => {
record_rvalue_scope_if_borrow_expr(visitor, &**subexpr, blk_id)
}
ast::ExprBlock(ref block) => {
hir::ExprBlock(ref block) => {
match block.expr {
Some(ref subexpr) => {
record_rvalue_scope_if_borrow_expr(
@ -1023,7 +1025,7 @@ fn resolve_local(visitor: &mut RegionResolutionVisitor, local: &ast::Local) {
///
/// Note: ET is intended to match "rvalues or lvalues based on rvalues".
fn record_rvalue_scope<'a>(visitor: &mut RegionResolutionVisitor,
expr: &'a ast::Expr,
expr: &'a hir::Expr,
blk_scope: CodeExtent) {
let mut expr = expr;
loop {
@ -1035,12 +1037,12 @@ fn resolve_local(visitor: &mut RegionResolutionVisitor, local: &ast::Local) {
visitor.region_maps.record_rvalue_scope(expr.id, blk_scope);
match expr.node {
ast::ExprAddrOf(_, ref subexpr) |
ast::ExprUnary(ast::UnDeref, ref subexpr) |
ast::ExprField(ref subexpr, _) |
ast::ExprTupField(ref subexpr, _) |
ast::ExprIndex(ref subexpr, _) |
ast::ExprParen(ref subexpr) => {
hir::ExprAddrOf(_, ref subexpr) |
hir::ExprUnary(hir::UnDeref, ref subexpr) |
hir::ExprField(ref subexpr, _) |
hir::ExprTupField(ref subexpr, _) |
hir::ExprIndex(ref subexpr, _) |
hir::ExprParen(ref subexpr) => {
expr = &**subexpr;
}
_ => {
@ -1051,7 +1053,7 @@ fn resolve_local(visitor: &mut RegionResolutionVisitor, local: &ast::Local) {
}
}
fn resolve_item(visitor: &mut RegionResolutionVisitor, item: &ast::Item) {
fn resolve_item(visitor: &mut RegionResolutionVisitor, item: &hir::Item) {
// Items create a new outer block scope as far as we're concerned.
let prev_cx = visitor.cx;
let prev_ts = mem::replace(&mut visitor.terminating_scopes, NodeSet());
@ -1068,8 +1070,8 @@ fn resolve_item(visitor: &mut RegionResolutionVisitor, item: &ast::Item) {
fn resolve_fn(visitor: &mut RegionResolutionVisitor,
_: FnKind,
decl: &ast::FnDecl,
body: &ast::Block,
decl: &hir::FnDecl,
body: &hir::Block,
sp: Span,
id: ast::NodeId) {
debug!("region::resolve_fn(id={:?}, \
@ -1159,12 +1161,12 @@ impl<'a, 'v> Visitor<'v> for RegionResolutionVisitor<'a> {
resolve_item(self, i);
}
fn visit_impl_item(&mut self, ii: &ast::ImplItem) {
fn visit_impl_item(&mut self, ii: &hir::ImplItem) {
visit::walk_impl_item(self, ii);
self.create_item_scope_if_needed(ii.id);
}
fn visit_trait_item(&mut self, ti: &ast::TraitItem) {
fn visit_trait_item(&mut self, ti: &hir::TraitItem) {
visit::walk_trait_item(self, ti);
self.create_item_scope_if_needed(ti.id);
}
@ -1190,7 +1192,7 @@ impl<'a, 'v> Visitor<'v> for RegionResolutionVisitor<'a> {
}
}
pub fn resolve_crate(sess: &Session, krate: &ast::Crate) -> RegionMaps {
pub fn resolve_crate(sess: &Session, krate: &hir::Crate) -> RegionMaps {
let maps = RegionMaps {
code_extents: RefCell::new(vec![]),
code_extent_interner: RefCell::new(FnvHashMap()),

View File

@ -28,11 +28,12 @@ use std::mem::replace;
use syntax::ast;
use syntax::codemap::Span;
use syntax::parse::token::special_idents;
use syntax::print::pprust::lifetime_to_string;
use syntax::visit;
use syntax::visit::{FnKind, Visitor};
use util::nodemap::NodeMap;
use rustc_front::hir;
use rustc_front::print::pprust::lifetime_to_string;
use rustc_front::visit::{self, Visitor, FnKind};
#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug)]
pub enum DefRegion {
DefStaticRegion,
@ -78,10 +79,10 @@ struct LifetimeContext<'a> {
enum ScopeChain<'a> {
/// EarlyScope(i, ['a, 'b, ...], s) extends s with early-bound
/// lifetimes, assigning indexes 'a => i, 'b => i+1, ... etc.
EarlyScope(subst::ParamSpace, &'a Vec<ast::LifetimeDef>, Scope<'a>),
EarlyScope(subst::ParamSpace, &'a Vec<hir::LifetimeDef>, Scope<'a>),
/// LateScope(['a, 'b, ...], s) extends s with late-bound
/// lifetimes introduced by the declaration binder_id.
LateScope(&'a Vec<ast::LifetimeDef>, Scope<'a>),
LateScope(&'a Vec<hir::LifetimeDef>, Scope<'a>),
/// lifetimes introduced by items within a code block are scoped
/// to that block.
BlockScope(region::DestructionScopeData, Scope<'a>),
@ -92,7 +93,7 @@ type Scope<'a> = &'a ScopeChain<'a>;
static ROOT_SCOPE: ScopeChain<'static> = RootScope;
pub fn krate(sess: &Session, krate: &ast::Crate, def_map: &DefMap) -> NamedRegionMap {
pub fn krate(sess: &Session, krate: &hir::Crate, def_map: &DefMap) -> NamedRegionMap {
let mut named_region_map = NodeMap();
visit::walk_crate(&mut LifetimeContext {
sess: sess,
@ -107,7 +108,7 @@ pub fn krate(sess: &Session, krate: &ast::Crate, def_map: &DefMap) -> NamedRegio
}
impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
fn visit_item(&mut self, item: &ast::Item) {
fn visit_item(&mut self, item: &hir::Item) {
// Items save/restore the set of labels. This way inner items
// can freely reuse names, be they loop labels or lifetimes.
let saved = replace(&mut self.labels_in_fn, vec![]);
@ -115,26 +116,25 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
// Items always introduce a new root scope
self.with(RootScope, |_, this| {
match item.node {
ast::ItemFn(..) => {
hir::ItemFn(..) => {
// Fn lifetimes get added in visit_fn below:
visit::walk_item(this, item);
}
ast::ItemExternCrate(_) |
ast::ItemUse(_) |
ast::ItemMod(..) |
ast::ItemMac(..) |
ast::ItemDefaultImpl(..) |
ast::ItemForeignMod(..) |
ast::ItemStatic(..) |
ast::ItemConst(..) => {
hir::ItemExternCrate(_) |
hir::ItemUse(_) |
hir::ItemMod(..) |
hir::ItemDefaultImpl(..) |
hir::ItemForeignMod(..) |
hir::ItemStatic(..) |
hir::ItemConst(..) => {
// These sorts of items have no lifetime parameters at all.
visit::walk_item(this, item);
}
ast::ItemTy(_, ref generics) |
ast::ItemEnum(_, ref generics) |
ast::ItemStruct(_, ref generics) |
ast::ItemTrait(_, ref generics, _, _) |
ast::ItemImpl(_, _, ref generics, _, _, _) => {
hir::ItemTy(_, ref generics) |
hir::ItemEnum(_, ref generics) |
hir::ItemStruct(_, ref generics) |
hir::ItemTrait(_, ref generics, _, _) |
hir::ItemImpl(_, _, ref generics, _, _, _) => {
// These kinds of items have only early bound lifetime parameters.
let lifetimes = &generics.lifetimes;
let early_scope = EarlyScope(subst::TypeSpace, lifetimes, &ROOT_SCOPE);
@ -150,7 +150,7 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
replace(&mut self.labels_in_fn, saved);
}
fn visit_foreign_item(&mut self, item: &ast::ForeignItem) {
fn visit_foreign_item(&mut self, item: &hir::ForeignItem) {
// Items save/restore the set of labels. This way inner items
// can freely reuse names, be they loop labels or lifetimes.
let saved = replace(&mut self.labels_in_fn, vec![]);
@ -158,12 +158,12 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
// Items always introduce a new root scope
self.with(RootScope, |_, this| {
match item.node {
ast::ForeignItemFn(_, ref generics) => {
hir::ForeignItemFn(_, ref generics) => {
this.visit_early_late(subst::FnSpace, generics, |this| {
visit::walk_foreign_item(this, item);
})
}
ast::ForeignItemStatic(..) => {
hir::ForeignItemStatic(..) => {
visit::walk_foreign_item(this, item);
}
}
@ -173,8 +173,8 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
replace(&mut self.labels_in_fn, saved);
}
fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v ast::FnDecl,
b: &'v ast::Block, s: Span, _: ast::NodeId) {
fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v hir::FnDecl,
b: &'v hir::Block, s: Span, _: ast::NodeId) {
match fk {
FnKind::ItemFn(_, generics, _, _, _, _) => {
self.visit_early_late(subst::FnSpace, generics, |this| {
@ -192,9 +192,9 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
}
}
fn visit_ty(&mut self, ty: &ast::Ty) {
fn visit_ty(&mut self, ty: &hir::Ty) {
match ty.node {
ast::TyBareFn(ref c) => {
hir::TyBareFn(ref c) => {
visit::walk_lifetime_decls_helper(self, &c.lifetimes);
self.with(LateScope(&c.lifetimes, self.scope), |old_scope, this| {
// a bare fn has no bounds, so everything
@ -203,7 +203,7 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
visit::walk_ty(this, ty);
});
}
ast::TyPath(None, ref path) => {
hir::TyPath(None, ref path) => {
// if this path references a trait, then this will resolve to
// a trait ref, which introduces a binding scope.
match self.def_map.borrow().get(&ty.id).map(|d| (d.base_def, d.depth)) {
@ -223,12 +223,12 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
}
}
fn visit_trait_item(&mut self, trait_item: &ast::TraitItem) {
fn visit_trait_item(&mut self, trait_item: &hir::TraitItem) {
// We reset the labels on every trait item, so that different
// methods in an impl can reuse label names.
let saved = replace(&mut self.labels_in_fn, vec![]);
if let ast::MethodTraitItem(ref sig, None) = trait_item.node {
if let hir::MethodTraitItem(ref sig, None) = trait_item.node {
self.visit_early_late(
subst::FnSpace, &sig.generics,
|this| visit::walk_trait_item(this, trait_item))
@ -239,13 +239,13 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
replace(&mut self.labels_in_fn, saved);
}
fn visit_block(&mut self, b: &ast::Block) {
fn visit_block(&mut self, b: &hir::Block) {
self.with(BlockScope(region::DestructionScopeData::new(b.id),
self.scope),
|_, this| visit::walk_block(this, b));
}
fn visit_lifetime_ref(&mut self, lifetime_ref: &ast::Lifetime) {
fn visit_lifetime_ref(&mut self, lifetime_ref: &hir::Lifetime) {
if lifetime_ref.name == special_idents::static_lifetime.name {
self.insert_lifetime(lifetime_ref, DefStaticRegion);
return;
@ -253,7 +253,7 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
self.resolve_lifetime_ref(lifetime_ref);
}
fn visit_generics(&mut self, generics: &ast::Generics) {
fn visit_generics(&mut self, generics: &hir::Generics) {
for ty_param in generics.ty_params.iter() {
visit::walk_ty_param_bounds_helper(self, &ty_param.bounds);
match ty_param.default {
@ -263,7 +263,7 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
}
for predicate in &generics.where_clause.predicates {
match predicate {
&ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate{ ref bounded_ty,
&hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate{ ref bounded_ty,
ref bounds,
ref bound_lifetimes,
.. }) => {
@ -282,7 +282,7 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
visit::walk_ty_param_bounds_helper(self, bounds);
}
}
&ast::WherePredicate::RegionPredicate(ast::WhereRegionPredicate{ref lifetime,
&hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate{ref lifetime,
ref bounds,
.. }) => {
@ -291,7 +291,7 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
self.visit_lifetime_ref(bound);
}
}
&ast::WherePredicate::EqPredicate(ast::WhereEqPredicate{ id,
&hir::WherePredicate::EqPredicate(hir::WhereEqPredicate{ id,
ref path,
ref ty,
.. }) => {
@ -303,8 +303,8 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
}
fn visit_poly_trait_ref(&mut self,
trait_ref: &ast::PolyTraitRef,
_modifier: &ast::TraitBoundModifier) {
trait_ref: &hir::PolyTraitRef,
_modifier: &hir::TraitBoundModifier) {
debug!("visit_poly_trait_ref trait_ref={:?}", trait_ref);
if !self.trait_ref_hack || !trait_ref.bound_lifetimes.is_empty() {
@ -337,10 +337,10 @@ fn original_label(span: Span) -> Original {
fn shadower_label(span: Span) -> Shadower {
Shadower { kind: ShadowKind::Label, span: span }
}
fn original_lifetime(l: &ast::Lifetime) -> Original {
fn original_lifetime(l: &hir::Lifetime) -> Original {
Original { kind: ShadowKind::Lifetime, span: l.span }
}
fn shadower_lifetime(l: &ast::Lifetime) -> Shadower {
fn shadower_lifetime(l: &hir::Lifetime) -> Shadower {
Shadower { kind: ShadowKind::Lifetime, span: l.span }
}
@ -376,7 +376,7 @@ fn signal_shadowing_problem(
// Adds all labels in `b` to `ctxt.labels_in_fn`, signalling a warning
// if one of the label shadows a lifetime or another label.
fn extract_labels<'v, 'a>(ctxt: &mut LifetimeContext<'a>, b: &'v ast::Block) {
fn extract_labels<'v, 'a>(ctxt: &mut LifetimeContext<'a>, b: &'v hir::Block) {
struct GatherLabels<'a> {
sess: &'a Session,
@ -393,11 +393,11 @@ fn extract_labels<'v, 'a>(ctxt: &mut LifetimeContext<'a>, b: &'v ast::Block) {
return;
impl<'v, 'a> Visitor<'v> for GatherLabels<'a> {
fn visit_expr(&mut self, ex: &'v ast::Expr) {
fn visit_expr(&mut self, ex: &'v hir::Expr) {
// do not recurse into closures defined in the block
// since they are treated as separate fns from the POV of
// labels_in_fn
if let ast::ExprClosure(..) = ex.node {
if let hir::ExprClosure(..) = ex.node {
return
}
if let Some(label) = expression_label(ex) {
@ -421,17 +421,15 @@ fn extract_labels<'v, 'a>(ctxt: &mut LifetimeContext<'a>, b: &'v ast::Block) {
visit::walk_expr(self, ex)
}
fn visit_item(&mut self, _: &ast::Item) {
fn visit_item(&mut self, _: &hir::Item) {
// do not recurse into items defined in the block
}
}
fn expression_label(ex: &ast::Expr) -> Option<ast::Ident> {
fn expression_label(ex: &hir::Expr) -> Option<ast::Ident> {
match ex.node {
ast::ExprWhile(_, _, Some(label)) |
ast::ExprWhileLet(_, _, _, Some(label)) |
ast::ExprForLoop(_, _, _, Some(label)) |
ast::ExprLoop(_, Some(label)) => Some(label),
hir::ExprWhile(_, _, Some(label)) |
hir::ExprLoop(_, Some(label)) => Some(label),
_ => None,
}
}
@ -471,8 +469,8 @@ impl<'a> LifetimeContext<'a> {
// the function body itself.
fn walk_fn<'b>(&mut self,
fk: FnKind,
fd: &ast::FnDecl,
fb: &'b ast::Block,
fd: &hir::FnDecl,
fb: &'b hir::Block,
_span: Span) {
match fk {
FnKind::ItemFn(_, generics, _, _, _, _) => {
@ -533,7 +531,7 @@ impl<'a> LifetimeContext<'a> {
/// ordering is not important there.
fn visit_early_late<F>(&mut self,
early_space: subst::ParamSpace,
generics: &ast::Generics,
generics: &hir::Generics,
walk: F) where
F: FnOnce(&mut LifetimeContext),
{
@ -553,7 +551,7 @@ impl<'a> LifetimeContext<'a> {
});
}
fn resolve_lifetime_ref(&mut self, lifetime_ref: &ast::Lifetime) {
fn resolve_lifetime_ref(&mut self, lifetime_ref: &hir::Lifetime) {
// Walk up the scope chain, tracking the number of fn scopes
// that we pass through, until we find a lifetime with the
// given name or we run out of scopes. If we encounter a code
@ -610,7 +608,7 @@ impl<'a> LifetimeContext<'a> {
fn resolve_free_lifetime_ref(&mut self,
scope_data: region::DestructionScopeData,
lifetime_ref: &ast::Lifetime,
lifetime_ref: &hir::Lifetime,
scope: Scope) {
debug!("resolve_free_lifetime_ref \
scope_data: {:?} lifetime_ref: {:?} scope: {:?}",
@ -660,13 +658,13 @@ impl<'a> LifetimeContext<'a> {
}
fn unresolved_lifetime_ref(&self, lifetime_ref: &ast::Lifetime) {
fn unresolved_lifetime_ref(&self, lifetime_ref: &hir::Lifetime) {
span_err!(self.sess, lifetime_ref.span, E0261,
"use of undeclared lifetime name `{}`",
lifetime_ref.name);
}
fn check_lifetime_defs(&mut self, old_scope: Scope, lifetimes: &Vec<ast::LifetimeDef>) {
fn check_lifetime_defs(&mut self, old_scope: Scope, lifetimes: &Vec<hir::LifetimeDef>) {
for i in 0..lifetimes.len() {
let lifetime_i = &lifetimes[i];
@ -701,7 +699,7 @@ impl<'a> LifetimeContext<'a> {
fn check_lifetime_def_for_shadowing(&self,
mut old_scope: Scope,
lifetime: &ast::Lifetime)
lifetime: &hir::Lifetime)
{
for &(label, label_span) in &self.labels_in_fn {
// FIXME (#24278): non-hygienic comparison
@ -742,7 +740,7 @@ impl<'a> LifetimeContext<'a> {
}
fn insert_lifetime(&mut self,
lifetime_ref: &ast::Lifetime,
lifetime_ref: &hir::Lifetime,
def: DefRegion) {
if lifetime_ref.id == ast::DUMMY_NODE_ID {
self.sess.span_bug(lifetime_ref.span,
@ -758,9 +756,9 @@ impl<'a> LifetimeContext<'a> {
}
}
fn search_lifetimes<'a>(lifetimes: &'a Vec<ast::LifetimeDef>,
lifetime_ref: &ast::Lifetime)
-> Option<(u32, &'a ast::Lifetime)> {
fn search_lifetimes<'a>(lifetimes: &'a Vec<hir::LifetimeDef>,
lifetime_ref: &hir::Lifetime)
-> Option<(u32, &'a hir::Lifetime)> {
for (i, lifetime_decl) in lifetimes.iter().enumerate() {
if lifetime_decl.lifetime.name == lifetime_ref.name {
return Some((i as u32, &lifetime_decl.lifetime));
@ -771,7 +769,7 @@ fn search_lifetimes<'a>(lifetimes: &'a Vec<ast::LifetimeDef>,
///////////////////////////////////////////////////////////////////////////
pub fn early_bound_lifetimes<'a>(generics: &'a ast::Generics) -> Vec<ast::LifetimeDef> {
pub fn early_bound_lifetimes<'a>(generics: &'a hir::Generics) -> Vec<hir::LifetimeDef> {
let referenced_idents = early_bound_lifetime_names(generics);
if referenced_idents.is_empty() {
return Vec::new();
@ -785,7 +783,7 @@ pub fn early_bound_lifetimes<'a>(generics: &'a ast::Generics) -> Vec<ast::Lifeti
/// Given a set of generic declarations, returns a list of names containing all early bound
/// lifetime names for those generics. (In fact, this list may also contain other names.)
fn early_bound_lifetime_names(generics: &ast::Generics) -> Vec<ast::Name> {
fn early_bound_lifetime_names(generics: &hir::Generics) -> Vec<ast::Name> {
// Create two lists, dividing the lifetimes into early/late bound.
// Initially, all of them are considered late, but we will move
// things from late into early as we go if we find references to
@ -805,13 +803,13 @@ fn early_bound_lifetime_names(generics: &ast::Generics) -> Vec<ast::Name> {
}
for predicate in &generics.where_clause.predicates {
match predicate {
&ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate{ref bounds,
&hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate{ref bounds,
ref bounded_ty,
..}) => {
collector.visit_ty(&**bounded_ty);
visit::walk_ty_param_bounds_helper(&mut collector, bounds);
}
&ast::WherePredicate::RegionPredicate(ast::WhereRegionPredicate{ref lifetime,
&hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate{ref lifetime,
ref bounds,
..}) => {
collector.visit_lifetime_ref(lifetime);
@ -820,7 +818,7 @@ fn early_bound_lifetime_names(generics: &ast::Generics) -> Vec<ast::Name> {
collector.visit_lifetime_ref(bound);
}
}
&ast::WherePredicate::EqPredicate(_) => unimplemented!()
&hir::WherePredicate::EqPredicate(_) => unimplemented!()
}
}
}
@ -845,7 +843,7 @@ fn early_bound_lifetime_names(generics: &ast::Generics) -> Vec<ast::Name> {
}
impl<'a, 'v> Visitor<'v> for FreeLifetimeCollector<'a> {
fn visit_lifetime_ref(&mut self, lifetime_ref: &ast::Lifetime) {
fn visit_lifetime_ref(&mut self, lifetime_ref: &hir::Lifetime) {
shuffle(self.early_bound, self.late_bound,
lifetime_ref.name);
}

View File

@ -20,15 +20,16 @@ use middle::privacy::PublicItems;
use metadata::csearch;
use syntax::parse::token::InternedString;
use syntax::codemap::{Span, DUMMY_SP};
use syntax::{attr, visit};
use syntax::ast;
use syntax::ast::{Attribute, Block, Crate, FnDecl, NodeId, Variant};
use syntax::ast::{Item, Generics, StructField};
use syntax::attr::{Stability, AttrMetaMethods};
use syntax::visit::{FnKind, Visitor};
use syntax::ast::NodeId;
use syntax::feature_gate::emit_feature_err;
use util::nodemap::{DefIdMap, FnvHashSet, FnvHashMap};
use rustc_front::hir;
use rustc_front::hir::{FnDecl, Attribute, Block, Crate, Item, Generics, StructField, Variant};
use rustc_front::attr::{self, Stability, AttrMetaMethods};
use rustc_front::visit::{self, FnKind, Visitor};
use std::mem::replace;
use std::cmp::Ordering;
@ -166,21 +167,21 @@ impl<'a, 'tcx, 'v> Visitor<'v> for Annotator<'a, 'tcx> {
// stability of the trait. This is WRONG, but expedient to get
// libstd stabilized for the 1.0 release.
let use_parent = match i.node {
ast::ItemImpl(_, _, _, Some(_), _, _) => false,
hir::ItemImpl(_, _, _, Some(_), _, _) => false,
_ => true,
};
// In case of a `pub use <mod>;`, we should not error since the stability
// is inherited from the module itself
let required = match i.node {
ast::ItemUse(_) => i.vis != ast::Public,
hir::ItemUse(_) => i.vis != hir::Public,
_ => true
};
self.annotate(i.id, use_parent, &i.attrs, i.span,
|v| visit::walk_item(v, i), required);
if let ast::ItemStruct(ref sd, _) = i.node {
if let hir::ItemStruct(ref sd, _) = i.node {
sd.ctor_id.map(|id| {
self.annotate(id, true, &i.attrs, i.span, |_| {}, true)
});
@ -193,12 +194,12 @@ impl<'a, 'tcx, 'v> Visitor<'v> for Annotator<'a, 'tcx> {
// a stability attribute, so we don't recurse.
}
fn visit_trait_item(&mut self, ti: &ast::TraitItem) {
fn visit_trait_item(&mut self, ti: &hir::TraitItem) {
self.annotate(ti.id, true, &ti.attrs, ti.span,
|v| visit::walk_trait_item(v, ti), true);
}
fn visit_impl_item(&mut self, ii: &ast::ImplItem) {
fn visit_impl_item(&mut self, ii: &hir::ImplItem) {
self.annotate(ii.id, true, &ii.attrs, ii.span,
|v| visit::walk_impl_item(v, ii), true);
}
@ -213,7 +214,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for Annotator<'a, 'tcx> {
|v| visit::walk_struct_field(v, s), true);
}
fn visit_foreign_item(&mut self, i: &ast::ForeignItem) {
fn visit_foreign_item(&mut self, i: &hir::ForeignItem) {
self.annotate(i.id, true, &i.attrs, i.span, |_| {}, true);
}
}
@ -236,7 +237,7 @@ impl<'tcx> Index<'tcx> {
for attr in &krate.attrs {
if &attr.name()[..] == "staged_api" {
match attr.node.value.node {
ast::MetaWord(_) => {
hir::MetaWord(_) => {
attr::mark_used(attr);
is_staged_api = true;
}
@ -335,7 +336,7 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
}
impl<'a, 'v, 'tcx> Visitor<'v> for Checker<'a, 'tcx> {
fn visit_item(&mut self, item: &ast::Item) {
fn visit_item(&mut self, item: &hir::Item) {
// When compiling with --test we don't enforce stability on the
// compiler-generated test module, demarcated with `DUMMY_SP` plus the
// name `__test`
@ -346,19 +347,19 @@ impl<'a, 'v, 'tcx> Visitor<'v> for Checker<'a, 'tcx> {
visit::walk_item(self, item);
}
fn visit_expr(&mut self, ex: &ast::Expr) {
fn visit_expr(&mut self, ex: &hir::Expr) {
check_expr(self.tcx, ex,
&mut |id, sp, stab| self.check(id, sp, stab));
visit::walk_expr(self, ex);
}
fn visit_path(&mut self, path: &ast::Path, id: ast::NodeId) {
fn visit_path(&mut self, path: &hir::Path, id: ast::NodeId) {
check_path(self.tcx, path, id,
&mut |id, sp, stab| self.check(id, sp, stab));
visit::walk_path(self, path)
}
fn visit_pat(&mut self, pat: &ast::Pat) {
fn visit_pat(&mut self, pat: &hir::Pat) {
check_pat(self.tcx, pat,
&mut |id, sp, stab| self.check(id, sp, stab));
visit::walk_pat(self, pat)
@ -366,10 +367,10 @@ impl<'a, 'v, 'tcx> Visitor<'v> for Checker<'a, 'tcx> {
}
/// Helper for discovering nodes to check for stability
pub fn check_item(tcx: &ty::ctxt, item: &ast::Item, warn_about_defns: bool,
pub fn check_item(tcx: &ty::ctxt, item: &hir::Item, warn_about_defns: bool,
cb: &mut FnMut(DefId, Span, &Option<&Stability>)) {
match item.node {
ast::ItemExternCrate(_) => {
hir::ItemExternCrate(_) => {
// compiler-generated `extern crate` items have a dummy span.
if item.span == DUMMY_SP { return }
@ -384,7 +385,7 @@ pub fn check_item(tcx: &ty::ctxt, item: &ast::Item, warn_about_defns: bool,
// For implementations of traits, check the stability of each item
// individually as it's possible to have a stable trait with unstable
// items.
ast::ItemImpl(_, _, _, Some(ref t), _, ref impl_items) => {
hir::ItemImpl(_, _, _, Some(ref t), _, ref impl_items) => {
let trait_did = tcx.def_map.borrow().get(&t.ref_id).unwrap().def_id();
let trait_items = tcx.trait_items(trait_did);
@ -403,16 +404,16 @@ pub fn check_item(tcx: &ty::ctxt, item: &ast::Item, warn_about_defns: bool,
}
/// Helper for discovering nodes to check for stability
pub fn check_expr(tcx: &ty::ctxt, e: &ast::Expr,
pub fn check_expr(tcx: &ty::ctxt, e: &hir::Expr,
cb: &mut FnMut(DefId, Span, &Option<&Stability>)) {
let span;
let id = match e.node {
ast::ExprMethodCall(i, _, _) => {
hir::ExprMethodCall(i, _, _) => {
span = i.span;
let method_call = ty::MethodCall::expr(e.id);
tcx.tables.borrow().method_map[&method_call].def_id
}
ast::ExprField(ref base_e, ref field) => {
hir::ExprField(ref base_e, ref field) => {
span = field.span;
match tcx.expr_ty_adjusted(base_e).sty {
ty::TyStruct(def, _) => def.struct_variant().field_named(field.node.name).did,
@ -420,7 +421,7 @@ pub fn check_expr(tcx: &ty::ctxt, e: &ast::Expr,
"stability::check_expr: named field access on non-struct")
}
}
ast::ExprTupField(ref base_e, ref field) => {
hir::ExprTupField(ref base_e, ref field) => {
span = field.span;
match tcx.expr_ty_adjusted(base_e).sty {
ty::TyStruct(def, _) => def.struct_variant().fields[field.node].did,
@ -430,7 +431,7 @@ pub fn check_expr(tcx: &ty::ctxt, e: &ast::Expr,
something other than a tuple or struct")
}
}
ast::ExprStruct(_, ref expr_fields, _) => {
hir::ExprStruct(_, ref expr_fields, _) => {
let type_ = tcx.expr_ty(e);
match type_.sty {
ty::TyStruct(def, _) => {
@ -464,7 +465,7 @@ pub fn check_expr(tcx: &ty::ctxt, e: &ast::Expr,
maybe_do_stability_check(tcx, id, span, cb);
}
pub fn check_path(tcx: &ty::ctxt, path: &ast::Path, id: ast::NodeId,
pub fn check_path(tcx: &ty::ctxt, path: &hir::Path, id: ast::NodeId,
cb: &mut FnMut(DefId, Span, &Option<&Stability>)) {
match tcx.def_map.borrow().get(&id).map(|d| d.full_def()) {
Some(def::DefPrimTy(..)) => {}
@ -476,7 +477,7 @@ pub fn check_path(tcx: &ty::ctxt, path: &ast::Path, id: ast::NodeId,
}
pub fn check_pat(tcx: &ty::ctxt, pat: &ast::Pat,
pub fn check_pat(tcx: &ty::ctxt, pat: &hir::Pat,
cb: &mut FnMut(DefId, Span, &Option<&Stability>)) {
debug!("check_pat(pat = {:?})", pat);
if is_internal(tcx, pat.span) { return; }
@ -487,18 +488,18 @@ pub fn check_pat(tcx: &ty::ctxt, pat: &ast::Pat,
};
match pat.node {
// Foo(a, b, c)
ast::PatEnum(_, Some(ref pat_fields)) => {
hir::PatEnum(_, Some(ref pat_fields)) => {
for (field, struct_field) in pat_fields.iter().zip(&v.fields) {
// a .. pattern is fine, but anything positional is
// not.
if let ast::PatWild(ast::PatWildMulti) = field.node {
if let hir::PatWild(hir::PatWildMulti) = field.node {
continue
}
maybe_do_stability_check(tcx, struct_field.did, field.span, cb)
}
}
// Foo { a, b, c }
ast::PatStruct(_, ref pat_fields, _) => {
hir::PatStruct(_, ref pat_fields, _) => {
for field in pat_fields {
let did = v.field_named(field.node.ident.name).did;
maybe_do_stability_check(tcx, did, field.span, cb);

View File

@ -31,7 +31,7 @@ use middle::ty_fold::TypeFoldable;
use std::collections::HashMap;
use std::fmt;
use syntax::codemap::Span;
use syntax::attr::{AttributeMethods, AttrMetaMethods};
use rustc_front::attr::{AttributeMethods, AttrMetaMethods};
pub fn report_fulfillment_errors<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
errors: &Vec<FulfillmentError<'tcx>>) {

View File

@ -51,7 +51,8 @@ use middle::wf;
use std::cell::RefCell;
use std::fmt;
use std::rc::Rc;
use syntax::{abi, ast};
use syntax::abi;
use rustc_front::hir;
use util::common::ErrorReported;
use util::nodemap::FnvHashMap;
@ -793,7 +794,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
match candidate {
ImplCandidate(def_id) => {
match self.tcx().trait_impl_polarity(def_id) {
Some(ast::ImplPolarity::Negative) => return Err(Unimplemented),
Some(hir::ImplPolarity::Negative) => return Err(Unimplemented),
_ => {}
}
}
@ -1217,7 +1218,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// provide an impl, but only for suitable `fn` pointers
ty::TyBareFn(_, &ty::BareFnTy {
unsafety: ast::Unsafety::Normal,
unsafety: hir::Unsafety::Normal,
abi: abi::Rust,
sig: ty::Binder(ty::FnSig {
inputs: _,
@ -1676,10 +1677,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
ty::BoundCopy => {
match mutbl {
// &mut T is affine and hence never `Copy`
ast::MutMutable => Err(Unimplemented),
hir::MutMutable => Err(Unimplemented),
// &T is always copyable
ast::MutImmutable => ok_if(Vec::new()),
hir::MutImmutable => ok_if(Vec::new()),
}
}

File diff suppressed because it is too large Load Diff

View File

@ -42,7 +42,7 @@ use middle::traits;
use std::fmt;
use std::rc::Rc;
use syntax::abi;
use syntax::ast;
use rustc_front::hir;
use syntax::owned_slice::OwnedSlice;
use util::nodemap::{FnvHashMap, FnvHashSet};
@ -165,7 +165,7 @@ macro_rules! CopyImpls {
}
}
CopyImpls! { (), ast::Unsafety, abi::Abi }
CopyImpls! { (), hir::Unsafety, abi::Abi }
impl<'tcx, T:TypeFoldable<'tcx>, U:TypeFoldable<'tcx>> TypeFoldable<'tcx> for (T, U) {
fn fold_with<F:TypeFolder<'tcx>>(&self, folder: &mut F) -> (T, U) {

View File

@ -19,7 +19,7 @@ use middle::ty::{self, HasTypeFlags, Ty, TypeError};
use middle::ty_fold::TypeFoldable;
use std::rc::Rc;
use syntax::abi;
use syntax::ast;
use rustc_front::hir as ast;
pub type RelateResult<'tcx, T> = Result<T, ty::TypeError<'tcx>>;

View File

@ -15,11 +15,11 @@ use session::Session;
use metadata::csearch;
use middle::lang_items;
use syntax::ast;
use syntax::codemap::Span;
use syntax::parse::token::InternedString;
use syntax::visit::Visitor;
use syntax::visit;
use rustc_front::visit::Visitor;
use rustc_front::visit;
use rustc_front::hir;
use std::collections::HashSet;
@ -33,7 +33,7 @@ struct Context<'a> {
/// Checks the crate for usage of weak lang items, returning a vector of all the
/// language items required by this crate, but not defined yet.
pub fn check_crate(krate: &ast::Crate,
pub fn check_crate(krate: &hir::Crate,
sess: &Session,
items: &mut lang_items::LanguageItems) {
// These are never called by user code, they're generated by the compiler.
@ -54,7 +54,7 @@ pub fn check_crate(krate: &ast::Crate,
verify(sess, items);
}
pub fn link_name(attrs: &[ast::Attribute]) -> Option<InternedString> {
pub fn link_name(attrs: &[hir::Attribute]) -> Option<InternedString> {
lang_items::extract(attrs).and_then(|name| {
$(if &name[..] == stringify!($name) {
Some(InternedString::new(stringify!($sym)))
@ -108,7 +108,7 @@ impl<'a> Context<'a> {
}
impl<'a, 'v> Visitor<'v> for Context<'a> {
fn visit_foreign_item(&mut self, i: &ast::ForeignItem) {
fn visit_foreign_item(&mut self, i: &hir::ForeignItem) {
match lang_items::extract(&i.attrs) {
None => {}
Some(lang_item) => self.register(&lang_item, i.span),

View File

@ -11,19 +11,20 @@
//! Used by `rustc` when compiling a plugin crate.
use syntax::ast;
use syntax::attr;
use syntax::codemap::Span;
use syntax::diagnostic;
use syntax::visit;
use syntax::visit::Visitor;
use rustc_front::visit;
use rustc_front::visit::Visitor;
use rustc_front::hir;
use rustc_front::attr;
struct RegistrarFinder {
registrars: Vec<(ast::NodeId, Span)> ,
}
impl<'v> Visitor<'v> for RegistrarFinder {
fn visit_item(&mut self, item: &ast::Item) {
if let ast::ItemFn(..) = item.node {
fn visit_item(&mut self, item: &hir::Item) {
if let hir::ItemFn(..) = item.node {
if attr::contains_name(&item.attrs,
"plugin_registrar") {
self.registrars.push((item.id, item.span));
@ -36,7 +37,8 @@ impl<'v> Visitor<'v> for RegistrarFinder {
/// Find the function marked with `#[plugin_registrar]`, if any.
pub fn find_plugin_registrar(diagnostic: &diagnostic::SpanHandler,
krate: &ast::Crate) -> Option<ast::NodeId> {
krate: &hir::Crate)
-> Option<ast::NodeId> {
let mut finder = RegistrarFinder { registrars: Vec::new() };
visit::walk_crate(&mut finder, krate);

View File

@ -26,9 +26,10 @@ use lint;
use metadata::cstore;
use syntax::ast;
use syntax::ast::{IntTy, UintTy};
use rustc_front::hir::{IntTy, UintTy};
use syntax::attr;
use syntax::attr::AttrMetaMethods;
use rustc_front::hir;
use syntax::diagnostic::{ColorConfig, Auto, Always, Never, SpanHandler};
use syntax::parse;
use syntax::parse::token::InternedString;
@ -664,8 +665,8 @@ pub fn build_target_config(opts: &Options, sp: &SpanHandler) -> Config {
};
let (int_type, uint_type) = match &target.target_pointer_width[..] {
"32" => (ast::TyI32, ast::TyU32),
"64" => (ast::TyI64, ast::TyU64),
"32" => (hir::TyI32, hir::TyU32),
"64" => (hir::TyI64, hir::TyU64),
w => sp.handler().fatal(&format!("target specification was invalid: unrecognized \
target-pointer-width {}", w))
};
@ -824,15 +825,16 @@ pub fn rustc_optgroups() -> Vec<RustcOptGroup> {
opt::flagopt_u("", "pretty",
"Pretty-print the input instead of compiling;
valid types are: `normal` (un-annotated source),
`expanded` (crates expanded),
`typed` (crates expanded, with type annotations), or
`expanded` (crates expanded), or
`expanded,identified` (fully parenthesized, AST nodes with IDs).",
"TYPE"),
opt::flagopt_u("", "unpretty",
"Present the input source, unstable (and less-pretty) variants;
valid types are any of the types for `--pretty`, as well as:
`flowgraph=<nodeid>` (graphviz formatted flowgraph for node), or
`everybody_loops` (all function bodies replaced with `loop {}`).",
`flowgraph=<nodeid>` (graphviz formatted flowgraph for node),
`everybody_loops` (all function bodies replaced with `loop {}`),
`hir` (the HIR), `hir,identified`, or
`hir,typed` (HIR with types for each node).",
"TYPE"),
opt::opt_u("", "show-span", "Show spans for compiler debugging", "expr|pat|ty"),
]);

View File

@ -20,9 +20,9 @@ use std::iter::repeat;
use std::path::Path;
use std::time::Duration;
use syntax::ast;
use syntax::visit;
use syntax::visit::Visitor;
use rustc_front::hir;
use rustc_front::visit;
use rustc_front::visit::Visitor;
// The name of the associated type for `Fn` return types
pub const FN_OUTPUT_NAME: &'static str = "Output";
@ -152,18 +152,18 @@ pub fn indenter() -> Indenter {
Indenter { _cannot_construct_outside_of_this_module: () }
}
struct LoopQueryVisitor<P> where P: FnMut(&ast::Expr_) -> bool {
struct LoopQueryVisitor<P> where P: FnMut(&hir::Expr_) -> bool {
p: P,
flag: bool,
}
impl<'v, P> Visitor<'v> for LoopQueryVisitor<P> where P: FnMut(&ast::Expr_) -> bool {
fn visit_expr(&mut self, e: &ast::Expr) {
impl<'v, P> Visitor<'v> for LoopQueryVisitor<P> where P: FnMut(&hir::Expr_) -> bool {
fn visit_expr(&mut self, e: &hir::Expr) {
self.flag |= (self.p)(&e.node);
match e.node {
// Skip inner loops, since a break in the inner loop isn't a
// break inside the outer loop
ast::ExprLoop(..) | ast::ExprWhile(..) => {}
hir::ExprLoop(..) | hir::ExprWhile(..) => {}
_ => visit::walk_expr(self, e)
}
}
@ -171,7 +171,7 @@ impl<'v, P> Visitor<'v> for LoopQueryVisitor<P> where P: FnMut(&ast::Expr_) -> b
// Takes a predicate p, returns true iff p is true for any subexpressions
// of b -- skipping any inner loops (loop, while, loop_body)
pub fn loop_query<P>(b: &ast::Block, p: P) -> bool where P: FnMut(&ast::Expr_) -> bool {
pub fn loop_query<P>(b: &hir::Block, p: P) -> bool where P: FnMut(&hir::Expr_) -> bool {
let mut v = LoopQueryVisitor {
p: p,
flag: false,
@ -180,13 +180,13 @@ pub fn loop_query<P>(b: &ast::Block, p: P) -> bool where P: FnMut(&ast::Expr_) -
return v.flag;
}
struct BlockQueryVisitor<P> where P: FnMut(&ast::Expr) -> bool {
struct BlockQueryVisitor<P> where P: FnMut(&hir::Expr) -> bool {
p: P,
flag: bool,
}
impl<'v, P> Visitor<'v> for BlockQueryVisitor<P> where P: FnMut(&ast::Expr) -> bool {
fn visit_expr(&mut self, e: &ast::Expr) {
impl<'v, P> Visitor<'v> for BlockQueryVisitor<P> where P: FnMut(&hir::Expr) -> bool {
fn visit_expr(&mut self, e: &hir::Expr) {
self.flag |= (self.p)(e);
visit::walk_expr(self, e)
}
@ -194,7 +194,7 @@ impl<'v, P> Visitor<'v> for BlockQueryVisitor<P> where P: FnMut(&ast::Expr) -> b
// Takes a predicate p, returns true iff p is true for any subexpressions
// of b -- skipping any inner loops (loop, while, loop_body)
pub fn block_query<P>(b: &ast::Block, p: P) -> bool where P: FnMut(&ast::Expr) -> bool {
pub fn block_query<P>(b: &hir::Block, p: P) -> bool where P: FnMut(&hir::Expr) -> bool {
let mut v = BlockQueryVisitor {
p: p,
flag: false,

View File

@ -26,7 +26,8 @@ use middle::ty_fold::{self, TypeFoldable};
use std::fmt;
use syntax::abi;
use syntax::parse::token;
use syntax::{ast, ast_util};
use syntax::ast::DUMMY_NODE_ID;
use rustc_front::hir as ast;
pub fn verbose() -> bool {
ty::tls::with(|tcx| tcx.sess.verbose())
@ -230,7 +231,7 @@ fn in_binder<'tcx, T, U>(f: &mut fmt::Formatter,
ty::BrEnv => {
let name = token::intern("'r");
let _ = write!(f, "{}", name);
ty::BrNamed(DefId::local(ast::DUMMY_NODE_ID), name)
ty::BrNamed(DefId::local(DUMMY_NODE_ID), name)
}
})
}).0;
@ -623,14 +624,55 @@ impl<'tcx> fmt::Display for ty::TraitRef<'tcx> {
}
}
pub fn int_ty_to_string(t: ast::IntTy, val: Option<i64>) -> String {
let s = match t {
ast::TyIs => "isize",
ast::TyI8 => "i8",
ast::TyI16 => "i16",
ast::TyI32 => "i32",
ast::TyI64 => "i64"
};
match val {
// cast to a u64 so we can correctly print INT64_MIN. All integral types
// are parsed as u64, so we wouldn't want to print an extra negative
// sign.
Some(n) => format!("{}{}", n as u64, s),
None => s.to_string()
}
}
pub fn uint_ty_to_string(t: ast::UintTy, val: Option<u64>) -> String {
let s = match t {
ast::TyUs => "usize",
ast::TyU8 => "u8",
ast::TyU16 => "u16",
ast::TyU32 => "u32",
ast::TyU64 => "u64"
};
match val {
Some(n) => format!("{}{}", n, s),
None => s.to_string()
}
}
pub fn float_ty_to_string(t: ast::FloatTy) -> String {
match t {
ast::TyF32 => "f32".to_string(),
ast::TyF64 => "f64".to_string(),
}
}
impl<'tcx> fmt::Display for ty::TypeVariants<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
TyBool => write!(f, "bool"),
TyChar => write!(f, "char"),
TyInt(t) => write!(f, "{}", ast_util::int_ty_to_string(t, None)),
TyUint(t) => write!(f, "{}", ast_util::uint_ty_to_string(t, None)),
TyFloat(t) => write!(f, "{}", ast_util::float_ty_to_string(t)),
TyInt(t) => write!(f, "{}", int_ty_to_string(t, None)),
TyUint(t) => write!(f, "{}", uint_ty_to_string(t, None)),
TyFloat(t) => write!(f, "{}", float_ty_to_string(t)),
TyBox(typ) => write!(f, "Box<{}>", typ),
TyRawPtr(ref tm) => {
write!(f, "*{} {}", match tm.mutbl {

View File

@ -48,6 +48,7 @@ extern crate syntax;
extern crate libc;
extern crate serialize;
extern crate rustc_llvm;
extern crate rustc_front;
#[macro_use] extern crate log;
pub mod abi;

View File

@ -48,8 +48,8 @@
use std::fmt;
use std::hash::{Hash, SipHasher, Hasher};
use syntax::ast;
use syntax::visit;
use rustc_front::hir;
use rustc_front::visit;
#[derive(Clone, PartialEq, Debug)]
pub struct Svh {
@ -66,7 +66,7 @@ impl Svh {
&self.hash
}
pub fn calculate(metadata: &Vec<String>, krate: &ast::Crate) -> Svh {
pub fn calculate(metadata: &Vec<String>, krate: &hir::Crate) -> Svh {
// FIXME (#14132): This is better than it used to be, but it still not
// ideal. We now attempt to hash only the relevant portions of the
// Crate AST as well as the top-level crate attributes. (However,
@ -131,13 +131,13 @@ mod svh_visitor {
pub use self::SawExprComponent::*;
pub use self::SawStmtComponent::*;
use self::SawAbiComponent::*;
use syntax::ast;
use syntax::ast::*;
use syntax::ast::{self, NodeId, Ident};
use syntax::codemap::Span;
use syntax::parse::token;
use syntax::print::pprust;
use syntax::visit;
use syntax::visit::{Visitor, FnKind};
use rustc_front::visit;
use rustc_front::visit::{Visitor, FnKind};
use rustc_front::hir::*;
use rustc_front::hir;
use std::hash::{Hash, SipHasher};
@ -230,9 +230,9 @@ mod svh_visitor {
SawExprCall,
SawExprMethodCall,
SawExprTup,
SawExprBinary(ast::BinOp_),
SawExprUnary(ast::UnOp),
SawExprLit(ast::Lit_),
SawExprBinary(hir::BinOp_),
SawExprUnary(hir::UnOp),
SawExprLit(hir::Lit_),
SawExprCast,
SawExprIf,
SawExprWhile,
@ -240,13 +240,13 @@ mod svh_visitor {
SawExprClosure,
SawExprBlock,
SawExprAssign,
SawExprAssignOp(ast::BinOp_),
SawExprAssignOp(hir::BinOp_),
SawExprIndex,
SawExprRange,
SawExprPath(Option<usize>),
SawExprAddrOf(ast::Mutability),
SawExprAddrOf(hir::Mutability),
SawExprRet,
SawExprInlineAsm(&'a ast::InlineAsm),
SawExprInlineAsm(&'a hir::InlineAsm),
SawExprStruct,
SawExprRepeat,
SawExprParen,
@ -284,12 +284,6 @@ mod svh_visitor {
ExprStruct(..) => SawExprStruct,
ExprRepeat(..) => SawExprRepeat,
ExprParen(..) => SawExprParen,
// just syntactic artifacts, expanded away by time of SVH.
ExprForLoop(..) => unreachable!(),
ExprIfLet(..) => unreachable!(),
ExprWhileLet(..) => unreachable!(),
ExprMac(..) => unreachable!(),
}
}
@ -306,51 +300,10 @@ mod svh_visitor {
StmtDecl(..) => SawStmtDecl,
StmtExpr(..) => SawStmtExpr,
StmtSemi(..) => SawStmtSemi,
StmtMac(..) => unreachable!(),
}
}
impl<'a, 'v> Visitor<'v> for StrictVersionHashVisitor<'a> {
fn visit_mac(&mut self, mac: &Mac) {
// macro invocations, namely macro_rules definitions,
// *can* appear as items, even in the expanded crate AST.
if &macro_name(mac)[..] == "macro_rules" {
// Pretty-printing definition to a string strips out
// surface artifacts (currently), such as the span
// information, yielding a content-based hash.
// FIXME (#14132): building temporary string is
// expensive; a direct content-based hash on token
// trees might be faster. Implementing this is far
// easier in short term.
let macro_defn_as_string = pprust::to_string(|pp_state| {
pp_state.print_mac(mac, token::Paren)
});
macro_defn_as_string.hash(self.st);
} else {
// It is not possible to observe any kind of macro
// invocation at this stage except `macro_rules!`.
panic!("reached macro somehow: {}",
pprust::to_string(|pp_state| {
pp_state.print_mac(mac, token::Paren)
}));
}
visit::walk_mac(self, mac);
fn macro_name(mac: &Mac) -> token::InternedString {
match &mac.node {
&MacInvocTT(ref path, ref _tts, ref _stx_ctxt) => {
let s = &path.segments;
assert_eq!(s.len(), 1);
s[0].identifier.name.as_str()
}
}
}
}
fn visit_struct_def(&mut self, s: &StructDef, ident: Ident,
g: &Generics, _: NodeId) {
SawStructDef(ident.name.as_str()).hash(self.st);

View File

@ -27,6 +27,7 @@ use rustc::middle::region;
use rustc::middle::ty;
use syntax::ast;
use syntax::codemap::Span;
use rustc_front::hir;
use std::rc::Rc;
@ -104,12 +105,12 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for CheckLoanCtxt<'a, 'tcx> {
}
fn matched_pat(&mut self,
_matched_pat: &ast::Pat,
_matched_pat: &hir::Pat,
_cmt: mc::cmt,
_mode: euv::MatchMode) { }
fn consume_pat(&mut self,
consume_pat: &ast::Pat,
consume_pat: &hir::Pat,
cmt: mc::cmt<'tcx>,
mode: euv::ConsumeMode) {
debug!("consume_pat(consume_pat={:?}, cmt={:?}, mode={:?})",
@ -194,8 +195,8 @@ pub fn check_loans<'a, 'b, 'c, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
move_data: &move_data::FlowedMoveData<'c, 'tcx>,
all_loans: &[Loan<'tcx>],
fn_id: ast::NodeId,
decl: &ast::FnDecl,
body: &ast::Block) {
decl: &hir::FnDecl,
body: &hir::Block) {
debug!("check_loans(body id={})", body.id);
let param_env = ty::ParameterEnvironment::for_item(bccx.tcx, fn_id);

View File

@ -27,8 +27,8 @@ use rustc::middle::mem_categorization as mc;
use std::mem;
use std::rc::Rc;
use syntax::ast;
use syntax::attr::AttrMetaMethods;
use syntax::codemap::Span;
use rustc_front::attr::AttrMetaMethods;
#[derive(PartialEq, Eq, PartialOrd, Ord)]
enum Fragment {

View File

@ -22,6 +22,7 @@ use rustc::middle::ty;
use std::rc::Rc;
use syntax::ast;
use syntax::codemap::Span;
use rustc_front::hir;
struct GatherMoveInfo<'tcx> {
id: ast::NodeId,
@ -62,7 +63,7 @@ pub fn gather_move_from_expr<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
pub fn gather_match_variant<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
move_data: &MoveData<'tcx>,
_move_error_collector: &MoveErrorCollector<'tcx>,
move_pat: &ast::Pat,
move_pat: &hir::Pat,
cmt: mc::cmt<'tcx>,
mode: euv::MatchMode) {
let tcx = bccx.tcx;
@ -93,10 +94,10 @@ pub fn gather_match_variant<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
pub fn gather_move_from_pat<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
move_data: &MoveData<'tcx>,
move_error_collector: &MoveErrorCollector<'tcx>,
move_pat: &ast::Pat,
move_pat: &hir::Pat,
cmt: mc::cmt<'tcx>) {
let pat_span_path_opt = match move_pat.node {
ast::PatIdent(_, ref path1, _) => {
hir::PatIdent(_, ref path1, _) => {
Some(MoveSpanAndPath{span: move_pat.span,
ident: path1.node})
},

View File

@ -26,9 +26,11 @@ use rustc::middle::ty;
use syntax::ast;
use syntax::codemap::Span;
use syntax::visit;
use syntax::visit::Visitor;
use syntax::ast::{Expr, FnDecl, Block, NodeId, Pat};
use syntax::ast::NodeId;
use rustc_front::hir;
use rustc_front::hir::{Expr, FnDecl, Block, Pat};
use rustc_front::visit;
use rustc_front::visit::Visitor;
mod lifetime;
mod restrictions;
@ -37,8 +39,8 @@ mod move_error;
pub fn gather_loans_in_fn<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
fn_id: NodeId,
decl: &ast::FnDecl,
body: &ast::Block)
decl: &hir::FnDecl,
body: &hir::Block)
-> (Vec<Loan<'tcx>>,
move_data::MoveData<'tcx>) {
let mut glcx = GatherLoanCtxt {
@ -91,7 +93,7 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for GatherLoanCtxt<'a, 'tcx> {
}
fn matched_pat(&mut self,
matched_pat: &ast::Pat,
matched_pat: &hir::Pat,
cmt: mc::cmt<'tcx>,
mode: euv::MatchMode) {
debug!("matched_pat(matched_pat={:?}, cmt={:?}, mode={:?})",
@ -107,7 +109,7 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for GatherLoanCtxt<'a, 'tcx> {
}
fn consume_pat(&mut self,
consume_pat: &ast::Pat,
consume_pat: &hir::Pat,
cmt: mc::cmt<'tcx>,
mode: euv::ConsumeMode) {
debug!("consume_pat(consume_pat={:?}, cmt={:?}, mode={:?})",
@ -527,7 +529,7 @@ struct StaticInitializerCtxt<'a, 'tcx: 'a> {
impl<'a, 'tcx, 'v> Visitor<'v> for StaticInitializerCtxt<'a, 'tcx> {
fn visit_expr(&mut self, ex: &Expr) {
if let ast::ExprAddrOf(mutbl, ref base) = ex.node {
if let hir::ExprAddrOf(mutbl, ref base) = ex.node {
let infcx = infer::new_infer_ctxt(self.bccx.tcx, &self.bccx.tcx.tables, None, false);
let mc = mc::MemCategorizationContext::new(&infcx);
let base_cmt = mc.cat_expr(&**base).unwrap();
@ -544,7 +546,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for StaticInitializerCtxt<'a, 'tcx> {
}
}
pub fn gather_loans_in_static_initializer(bccx: &mut BorrowckCtxt, expr: &ast::Expr) {
pub fn gather_loans_in_static_initializer(bccx: &mut BorrowckCtxt, expr: &hir::Expr) {
debug!("gather_loans_in_static_initializer(expr={:?})", expr);

View File

@ -15,7 +15,8 @@ use rustc::middle::ty;
use std::cell::RefCell;
use syntax::ast;
use syntax::codemap;
use syntax::print::pprust;
use rustc_front::print::pprust;
use rustc_front::hir;
pub struct MoveErrorCollector<'tcx> {
errors: RefCell<Vec<MoveError<'tcx>>>
@ -125,7 +126,7 @@ fn report_cannot_move_out_of<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
mc::cat_interior(ref b, mc::InteriorElement(Kind::Index, _)) => {
let expr = bccx.tcx.map.expect_expr(move_from.id);
if let ast::ExprIndex(..) = expr.node {
if let hir::ExprIndex(..) = expr.node {
bccx.span_err(move_from.span,
&format!("cannot move out of type `{}`, \
a non-copy fixed-size array",

View File

@ -20,8 +20,8 @@ pub use self::MovedValueUseKind::*;
use self::InteriorKind::*;
use rustc::ast_map;
use rustc::ast_map::blocks::{FnLikeNode, FnParts};
use rustc::front::map as hir_map;
use rustc::front::map::blocks::{FnLikeNode, FnParts};
use rustc::middle::cfg;
use rustc::middle::dataflow::DataFlowContext;
use rustc::middle::dataflow::BitwiseOperator;
@ -37,12 +37,14 @@ use rustc::middle::ty::{self, Ty};
use std::fmt;
use std::mem;
use std::rc::Rc;
use syntax::ast;
use syntax::ast_util;
use syntax::ast::{self, NodeId};
use syntax::codemap::Span;
use syntax::visit;
use syntax::visit::{Visitor, FnKind};
use syntax::ast::{FnDecl, Block, NodeId};
use rustc_front::hir;
use rustc_front::hir::{FnDecl, Block};
use rustc_front::visit;
use rustc_front::visit::{Visitor, FnKind};
use rustc_front::util as hir_util;
pub mod check_loans;
@ -74,19 +76,19 @@ impl<'a, 'tcx, 'v> Visitor<'v> for BorrowckCtxt<'a, 'tcx> {
}
}
fn visit_item(&mut self, item: &ast::Item) {
fn visit_item(&mut self, item: &hir::Item) {
borrowck_item(self, item);
}
fn visit_trait_item(&mut self, ti: &ast::TraitItem) {
if let ast::ConstTraitItem(_, Some(ref expr)) = ti.node {
fn visit_trait_item(&mut self, ti: &hir::TraitItem) {
if let hir::ConstTraitItem(_, Some(ref expr)) = ti.node {
gather_loans::gather_loans_in_static_initializer(self, &*expr);
}
visit::walk_trait_item(self, ti);
}
fn visit_impl_item(&mut self, ii: &ast::ImplItem) {
if let ast::ConstImplItem(_, ref expr) = ii.node {
fn visit_impl_item(&mut self, ii: &hir::ImplItem) {
if let hir::ConstImplItem(_, ref expr) = ii.node {
gather_loans::gather_loans_in_static_initializer(self, &*expr);
}
visit::walk_impl_item(self, ii);
@ -126,14 +128,14 @@ pub fn check_crate(tcx: &ty::ctxt) {
}
}
fn borrowck_item(this: &mut BorrowckCtxt, item: &ast::Item) {
fn borrowck_item(this: &mut BorrowckCtxt, item: &hir::Item) {
// Gather loans for items. Note that we don't need
// to check loans for single expressions. The check
// loan step is intended for things that have a data
// flow dependent conditions.
match item.node {
ast::ItemStatic(_, _, ref ex) |
ast::ItemConst(_, ref ex) => {
hir::ItemStatic(_, _, ref ex) |
hir::ItemConst(_, ref ex) => {
gather_loans::gather_loans_in_static_initializer(this, &**ex);
}
_ => { }
@ -151,8 +153,8 @@ pub struct AnalysisData<'a, 'tcx: 'a> {
fn borrowck_fn(this: &mut BorrowckCtxt,
fk: FnKind,
decl: &ast::FnDecl,
body: &ast::Block,
decl: &hir::FnDecl,
body: &hir::Block,
sp: Span,
id: ast::NodeId) {
debug!("borrowck_fn(id={})", id);
@ -183,16 +185,16 @@ fn borrowck_fn(this: &mut BorrowckCtxt,
fn build_borrowck_dataflow_data<'a, 'tcx>(this: &mut BorrowckCtxt<'a, 'tcx>,
fk: FnKind,
decl: &ast::FnDecl,
decl: &hir::FnDecl,
cfg: &cfg::CFG,
body: &ast::Block,
body: &hir::Block,
sp: Span,
id: ast::NodeId)
-> AnalysisData<'a, 'tcx>
{
// Check the body of fn items.
let tcx = this.tcx;
let id_range = ast_util::compute_id_range_for_fn_body(fk, decl, body, sp, id);
let id_range = hir_util::compute_id_range_for_fn_body(fk, decl, body, sp, id);
let (all_loans, move_data) =
gather_loans::gather_loans_in_fn(this, id, decl, body);
@ -398,8 +400,8 @@ pub enum LoanPathElem {
pub fn closure_to_block(closure_id: ast::NodeId,
tcx: &ty::ctxt) -> ast::NodeId {
match tcx.map.get(closure_id) {
ast_map::NodeExpr(expr) => match expr.node {
ast::ExprClosure(_, _, ref block) => {
hir_map::NodeExpr(expr) => match expr.node {
hir::ExprClosure(_, _, ref block) => {
block.id
}
_ => {
@ -667,7 +669,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
let (expr_ty, expr_span) = match self.tcx
.map
.find(the_move.id) {
Some(ast_map::NodeExpr(expr)) => {
Some(hir_map::NodeExpr(expr)) => {
(self.tcx.expr_ty_adjusted(&*expr), expr.span)
}
r => {
@ -729,7 +731,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
let (expr_ty, expr_span) = match self.tcx
.map
.find(the_move.id) {
Some(ast_map::NodeExpr(expr)) => {
Some(hir_map::NodeExpr(expr)) => {
(self.tcx.expr_ty_adjusted(&*expr), expr.span)
}
r => {
@ -1138,7 +1140,7 @@ fn statement_scope_span(tcx: &ty::ctxt, region: ty::Region) -> Option<Span> {
match region {
ty::ReScope(scope) => {
match tcx.map.find(scope.node_id(&tcx.region_maps)) {
Some(ast_map::NodeStmt(stmt)) => Some(stmt.span),
Some(hir_map::NodeStmt(stmt)) => Some(stmt.span),
_ => None
}
}

View File

@ -29,6 +29,7 @@ use std::usize;
use syntax::ast;
use syntax::ast_util;
use syntax::codemap::Span;
use rustc_front::hir;
#[path="fragments.rs"]
pub mod fragments;
@ -601,8 +602,8 @@ impl<'a, 'tcx> FlowedMoveData<'a, 'tcx> {
tcx: &'a ty::ctxt<'tcx>,
cfg: &cfg::CFG,
id_range: ast_util::IdRange,
decl: &ast::FnDecl,
body: &ast::Block)
decl: &hir::FnDecl,
body: &hir::Block)
-> FlowedMoveData<'a, 'tcx> {
let mut dfcx_moves =
DataFlowContext::new(tcx,

View File

@ -34,6 +34,7 @@
// refers to the borrowck-specific graphviz adapter traits.
extern crate graphviz as dot;
extern crate rustc;
extern crate rustc_front;
pub use borrowck::check_crate;
pub use borrowck::build_borrowck_dataflow_data_for_fn;

View File

@ -8,10 +8,11 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use rustc::front;
use rustc::front::map as hir_map;
use rustc::session::Session;
use rustc::session::config::{self, Input, OutputFilenames};
use rustc::session::search_paths::PathKind;
use rustc::ast_map;
use rustc::lint;
use rustc::metadata;
use rustc::metadata::creader::LocalCrateReader;
@ -28,6 +29,8 @@ use rustc_trans::back::write;
use rustc_trans::trans;
use rustc_typeck as typeck;
use rustc_privacy;
use rustc_front::hir;
use rustc_front::lowering::lower_crate;
use super::Compilation;
use serialize::json;
@ -41,6 +44,7 @@ use syntax::ast;
use syntax::attr;
use syntax::attr::AttrMetaMethods;
use syntax::diagnostics;
use syntax::fold::Folder;
use syntax::parse;
use syntax::parse::token;
use syntax;
@ -104,9 +108,13 @@ pub fn compile_input(sess: Session,
&expanded_crate,
&id[..]));
let mut forest = ast_map::Forest::new(expanded_crate);
let expanded_crate = assign_node_ids(&sess, expanded_crate);
// Lower ast -> hir.
let mut hir_forest = time(sess.time_passes(),
"lowering ast -> hir",
|| hir_map::Forest::new(lower_crate(&expanded_crate)));
let arenas = ty::CtxtArenas::new();
let ast_map = assign_node_ids_and_map(&sess, &mut forest);
let ast_map = make_map(&sess, &mut hir_forest);
write_out_deps(&sess, input, &outputs, &id[..]);
@ -116,11 +124,14 @@ pub fn compile_input(sess: Session,
&sess,
outdir,
&ast_map,
&expanded_crate,
&ast_map.krate(),
&id[..]));
phase_3_run_analysis_passes(sess,
ast_map,
&expanded_crate,
&arenas,
id,
control.make_glob_map,
@ -130,6 +141,7 @@ pub fn compile_input(sess: Session,
let state = CompileState::state_after_analysis(input,
&tcx.sess,
outdir,
&expanded_crate,
tcx.map.krate(),
&analysis,
tcx);
@ -254,7 +266,8 @@ pub struct CompileState<'a, 'ast: 'a, 'tcx: 'a> {
pub output_filenames: Option<&'a OutputFilenames>,
pub out_dir: Option<&'a Path>,
pub expanded_crate: Option<&'a ast::Crate>,
pub ast_map: Option<&'a ast_map::Map<'ast>>,
pub hir_crate: Option<&'a hir::Crate>,
pub ast_map: Option<&'a hir_map::Map<'ast>>,
pub analysis: Option<&'a ty::CrateAnalysis>,
pub tcx: Option<&'a ty::ctxt<'tcx>>,
pub trans: Option<&'a trans::CrateTranslation>,
@ -274,6 +287,7 @@ impl<'a, 'ast, 'tcx> CompileState<'a, 'ast, 'tcx> {
crate_name: None,
output_filenames: None,
expanded_crate: None,
hir_crate: None,
ast_map: None,
analysis: None,
tcx: None,
@ -308,14 +322,16 @@ impl<'a, 'ast, 'tcx> CompileState<'a, 'ast, 'tcx> {
fn state_after_write_deps(input: &'a Input,
session: &'a Session,
out_dir: &'a Option<PathBuf>,
ast_map: &'a ast_map::Map<'ast>,
expanded_crate: &'a ast::Crate,
ast_map: &'a hir_map::Map<'ast>,
krate: &'a ast::Crate,
hir_crate: &'a hir::Crate,
crate_name: &'a str)
-> CompileState<'a, 'ast, 'tcx> {
CompileState {
crate_name: Some(crate_name),
ast_map: Some(ast_map),
expanded_crate: Some(expanded_crate),
krate: Some(krate),
hir_crate: Some(hir_crate),
.. CompileState::empty(input, session, out_dir)
}
}
@ -323,14 +339,16 @@ impl<'a, 'ast, 'tcx> CompileState<'a, 'ast, 'tcx> {
fn state_after_analysis(input: &'a Input,
session: &'a Session,
out_dir: &'a Option<PathBuf>,
expanded_crate: &'a ast::Crate,
krate: &'a ast::Crate,
hir_crate: &'a hir::Crate,
analysis: &'a ty::CrateAnalysis,
tcx: &'a ty::ctxt<'tcx>)
-> CompileState<'a, 'ast, 'tcx> {
CompileState {
analysis: Some(analysis),
tcx: Some(tcx),
expanded_crate: Some(expanded_crate),
krate: Some(krate),
hir_crate: Some(hir_crate),
.. CompileState::empty(input, session, out_dir)
}
}
@ -582,27 +600,38 @@ pub fn phase_2_configure_and_expand(sess: &Session,
Some(krate)
}
pub fn assign_node_ids_and_map<'ast>(sess: &Session,
forest: &'ast mut ast_map::Forest)
-> ast_map::Map<'ast> {
pub fn assign_node_ids(sess: &Session,
krate: ast::Crate) -> ast::Crate {
struct NodeIdAssigner<'a> {
sess: &'a Session
}
impl<'a> ast_map::FoldOps for NodeIdAssigner<'a> {
fn new_id(&self, old_id: ast::NodeId) -> ast::NodeId {
impl<'a> Folder for NodeIdAssigner<'a> {
fn new_id(&mut self, old_id: ast::NodeId) -> ast::NodeId {
assert_eq!(old_id, ast::DUMMY_NODE_ID);
self.sess.next_node_id()
}
}
let map = time(sess.time_passes(), "assigning node ids and indexing ast", move ||
ast_map::map_crate(forest, NodeIdAssigner { sess: sess }));
let krate = time(sess.time_passes(),
"assigning node ids",
|| NodeIdAssigner { sess: sess }.fold_crate(krate));
if sess.opts.debugging_opts.ast_json {
println!("{}", json::as_json(map.krate()));
println!("{}", json::as_json(&krate));
}
krate
}
pub fn make_map<'ast>(sess: &Session,
forest: &'ast mut front::map::Forest)
-> front::map::Map<'ast> {
// Construct the 'ast'-map
let map = time(sess.time_passes(),
"indexing hir",
move || front::map::map_crate(forest));
map
}
@ -610,14 +639,15 @@ pub fn assign_node_ids_and_map<'ast>(sess: &Session,
/// miscellaneous analysis passes on the crate. Return various
/// structures carrying the results of the analysis.
pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: Session,
ast_map: ast_map::Map<'tcx>,
ast_map: front::map::Map<'tcx>,
ast_crate: &ast::Crate,
arenas: &'tcx ty::CtxtArenas<'tcx>,
name: String,
make_glob_map: resolve::MakeGlobMap,
f: F)
-> (Session, R)
where F: for<'a> FnOnce(&'a ty::ctxt<'tcx>,
ty::CrateAnalysis) -> R
ty::CrateAnalysis) -> R
{
let time_passes = sess.time_passes();
let krate = ast_map.krate();
@ -731,7 +761,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: Session,
&tcx.sess, lib_features_used));
time(time_passes, "lint checking", ||
lint::check_crate(tcx, &exported_items));
lint::check_crate(tcx, ast_crate, &exported_items));
// The above three passes generate errors w/o aborting
tcx.sess.abort_if_errors();

View File

@ -42,6 +42,7 @@ extern crate libc;
extern crate rustc;
extern crate rustc_back;
extern crate rustc_borrowck;
extern crate rustc_front;
extern crate rustc_lint;
extern crate rustc_privacy;
extern crate rustc_resolve;
@ -389,6 +390,7 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls {
time(state.session.time_passes(),
"save analysis",
|| save::process_crate(state.tcx.unwrap(),
state.krate.unwrap(),
state.analysis.unwrap(),
state.out_dir));
};

View File

@ -19,7 +19,6 @@ use rustc_trans::back::link;
use driver;
use rustc::ast_map::{self, blocks, NodePrinter};
use rustc::middle::ty;
use rustc::middle::cfg;
use rustc::middle::cfg::graphviz::LabelledCFG;
@ -44,18 +43,23 @@ use std::option;
use std::path::PathBuf;
use std::str::FromStr;
use rustc::front::map as hir_map;
use rustc::front::map::{blocks, NodePrinter};
use rustc_front::hir;
use rustc_front::lowering::lower_crate;
use rustc_front::print::pprust as pprust_hir;
#[derive(Copy, Clone, PartialEq, Debug)]
pub enum PpSourceMode {
PpmNormal,
PpmEveryBodyLoops,
PpmExpanded,
PpmTyped,
PpmIdentified,
PpmExpandedIdentified,
PpmExpandedHygiene,
PpmTyped,
}
#[derive(Copy, Clone, PartialEq, Debug)]
pub enum PpFlowGraphMode {
Default,
@ -68,6 +72,7 @@ pub enum PpFlowGraphMode {
#[derive(Copy, Clone, PartialEq, Debug)]
pub enum PpMode {
PpmSource(PpSourceMode),
PpmHir(PpSourceMode),
PpmFlowGraph(PpFlowGraphMode),
}
@ -79,25 +84,27 @@ pub fn parse_pretty(sess: &Session,
let opt_second = split.next();
let first = match (first, extended) {
("normal", _) => PpmSource(PpmNormal),
("identified", _) => PpmSource(PpmIdentified),
("everybody_loops", true) => PpmSource(PpmEveryBodyLoops),
("expanded", _) => PpmSource(PpmExpanded),
("typed", _) => PpmSource(PpmTyped),
("expanded,identified", _) => PpmSource(PpmExpandedIdentified),
("expanded,hygiene", _) => PpmSource(PpmExpandedHygiene),
("identified", _) => PpmSource(PpmIdentified),
("hir", true) => PpmHir(PpmNormal),
("hir,identified", true) => PpmHir(PpmExpandedIdentified),
("hir,typed", true) => PpmHir(PpmTyped),
("flowgraph", true) => PpmFlowGraph(PpFlowGraphMode::Default),
("flowgraph,unlabelled", true) => PpmFlowGraph(PpFlowGraphMode::UnlabelledEdges),
_ => {
if extended {
sess.fatal(&format!(
"argument to `unpretty` must be one of `normal`, \
`expanded`, `flowgraph[,unlabelled]=<nodeid>`, `typed`, `identified`, \
`expanded,identified`, or `everybody_loops`; got {}", name));
`expanded`, `flowgraph[,unlabelled]=<nodeid>`, `identified`, \
`expanded,identified`, `everybody_loops`, `hir`, \
`hir,identified`, or `hir,typed`; got {}", name));
} else {
sess.fatal(&format!(
"argument to `pretty` must be one of `normal`, \
`expanded`, `typed`, `identified`, \
or `expanded,identified`; got {}", name));
"argument to `pretty` must be one of `normal`, `expanded`, \
`identified`, or `expanded,identified`; got {}", name));
}
}
};
@ -124,9 +131,7 @@ impl PpSourceMode {
/// Constructs a `PrinterSupport` object and passes it to `f`.
fn call_with_pp_support<'tcx, A, B, F>(&self,
sess: Session,
ast_map: Option<ast_map::Map<'tcx>>,
arenas: &'tcx ty::CtxtArenas<'tcx>,
id: String,
ast_map: Option<hir_map::Map<'tcx>>,
payload: B,
f: F) -> A where
F: FnOnce(&PrinterSupport, B) -> A,
@ -145,18 +150,45 @@ impl PpSourceMode {
let annotation = HygieneAnnotation { sess: sess, ast_map: ast_map };
f(&annotation, payload)
}
_ => panic!("Should use call_with_pp_support_hir"),
}
}
fn call_with_pp_support_hir<'tcx, A, B, F>(&self,
sess: Session,
ast_map: &hir_map::Map<'tcx>,
ast_crate: &ast::Crate,
arenas: &'tcx ty::CtxtArenas<'tcx>,
id: String,
payload: B,
f: F) -> A where
F: FnOnce(&HirPrinterSupport, B, &hir::Crate) -> A,
{
match *self {
PpmNormal => {
let annotation = NoAnn { sess: sess, ast_map: Some(ast_map.clone()) };
f(&annotation, payload, &ast_map.forest.krate)
}
PpmIdentified => {
let annotation = IdentifiedAnnotation {
sess: sess,
ast_map: Some(ast_map.clone())
};
f(&annotation, payload, &ast_map.forest.krate)
}
PpmTyped => {
let ast_map = ast_map.expect("--pretty=typed missing ast_map");
driver::phase_3_run_analysis_passes(sess,
ast_map,
ast_map.clone(),
ast_crate,
arenas,
id,
resolve::MakeGlobMap::No,
|tcx, _| {
let annotation = TypedAnnotation { tcx: tcx };
f(&annotation, payload)
f(&annotation, payload, &ast_map.forest.krate)
}).1
}
_ => panic!("Should use call_with_pp_support"),
}
}
}
@ -167,8 +199,8 @@ trait PrinterSupport<'ast>: pprust::PpAnn {
fn sess<'a>(&'a self) -> &'a Session;
/// Provides a uniform interface for re-extracting a reference to an
/// `ast_map::Map` from a value that now owns it.
fn ast_map<'a>(&'a self) -> Option<&'a ast_map::Map<'ast>>;
/// `hir_map::Map` from a value that now owns it.
fn ast_map<'a>(&'a self) -> Option<&'a hir_map::Map<'ast>>;
/// Produces the pretty-print annotation object.
///
@ -177,32 +209,59 @@ trait PrinterSupport<'ast>: pprust::PpAnn {
fn pp_ann<'a>(&'a self) -> &'a pprust::PpAnn;
}
trait HirPrinterSupport<'ast>: pprust_hir::PpAnn {
/// Provides a uniform interface for re-extracting a reference to a
/// `Session` from a value that now owns it.
fn sess<'a>(&'a self) -> &'a Session;
/// Provides a uniform interface for re-extracting a reference to an
/// `hir_map::Map` from a value that now owns it.
fn ast_map<'a>(&'a self) -> Option<&'a hir_map::Map<'ast>>;
/// Produces the pretty-print annotation object.
///
/// (Rust does not yet support upcasting from a trait object to
/// an object for one of its super-traits.)
fn pp_ann<'a>(&'a self) -> &'a pprust_hir::PpAnn;
}
struct NoAnn<'ast> {
sess: Session,
ast_map: Option<ast_map::Map<'ast>>
ast_map: Option<hir_map::Map<'ast>>
}
impl<'ast> PrinterSupport<'ast> for NoAnn<'ast> {
fn sess<'a>(&'a self) -> &'a Session { &self.sess }
fn ast_map<'a>(&'a self) -> Option<&'a ast_map::Map<'ast>> {
fn ast_map<'a>(&'a self) -> Option<&'a hir_map::Map<'ast>> {
self.ast_map.as_ref()
}
fn pp_ann<'a>(&'a self) -> &'a pprust::PpAnn { self }
}
impl<'ast> HirPrinterSupport<'ast> for NoAnn<'ast> {
fn sess<'a>(&'a self) -> &'a Session { &self.sess }
fn ast_map<'a>(&'a self) -> Option<&'a hir_map::Map<'ast>> {
self.ast_map.as_ref()
}
fn pp_ann<'a>(&'a self) -> &'a pprust_hir::PpAnn { self }
}
impl<'ast> pprust::PpAnn for NoAnn<'ast> {}
impl<'ast> pprust_hir::PpAnn for NoAnn<'ast> {}
struct IdentifiedAnnotation<'ast> {
sess: Session,
ast_map: Option<ast_map::Map<'ast>>,
ast_map: Option<hir_map::Map<'ast>>,
}
impl<'ast> PrinterSupport<'ast> for IdentifiedAnnotation<'ast> {
fn sess<'a>(&'a self) -> &'a Session { &self.sess }
fn ast_map<'a>(&'a self) -> Option<&'a ast_map::Map<'ast>> {
fn ast_map<'a>(&'a self) -> Option<&'a hir_map::Map<'ast>> {
self.ast_map.as_ref()
}
@ -249,15 +308,65 @@ impl<'ast> pprust::PpAnn for IdentifiedAnnotation<'ast> {
}
}
impl<'ast> HirPrinterSupport<'ast> for IdentifiedAnnotation<'ast> {
fn sess<'a>(&'a self) -> &'a Session { &self.sess }
fn ast_map<'a>(&'a self) -> Option<&'a hir_map::Map<'ast>> {
self.ast_map.as_ref()
}
fn pp_ann<'a>(&'a self) -> &'a pprust_hir::PpAnn { self }
}
impl<'ast> pprust_hir::PpAnn for IdentifiedAnnotation<'ast> {
fn pre(&self,
s: &mut pprust_hir::State,
node: pprust_hir::AnnNode) -> io::Result<()> {
match node {
pprust_hir::NodeExpr(_) => s.popen(),
_ => Ok(())
}
}
fn post(&self,
s: &mut pprust_hir::State,
node: pprust_hir::AnnNode) -> io::Result<()> {
match node {
pprust_hir::NodeIdent(_) | pprust_hir::NodeName(_) => Ok(()),
pprust_hir::NodeItem(item) => {
try!(pp::space(&mut s.s));
s.synth_comment(item.id.to_string())
}
pprust_hir::NodeSubItem(id) => {
try!(pp::space(&mut s.s));
s.synth_comment(id.to_string())
}
pprust_hir::NodeBlock(blk) => {
try!(pp::space(&mut s.s));
s.synth_comment(format!("block {}", blk.id))
}
pprust_hir::NodeExpr(expr) => {
try!(pp::space(&mut s.s));
try!(s.synth_comment(expr.id.to_string()));
s.pclose()
}
pprust_hir::NodePat(pat) => {
try!(pp::space(&mut s.s));
s.synth_comment(format!("pat {}", pat.id))
}
}
}
}
struct HygieneAnnotation<'ast> {
sess: Session,
ast_map: Option<ast_map::Map<'ast>>,
ast_map: Option<hir_map::Map<'ast>>,
}
impl<'ast> PrinterSupport<'ast> for HygieneAnnotation<'ast> {
fn sess<'a>(&'a self) -> &'a Session { &self.sess }
fn ast_map<'a>(&'a self) -> Option<&'a ast_map::Map<'ast>> {
fn ast_map<'a>(&'a self) -> Option<&'a hir_map::Map<'ast>> {
self.ast_map.as_ref()
}
@ -289,30 +398,30 @@ struct TypedAnnotation<'a, 'tcx: 'a> {
tcx: &'a ty::ctxt<'tcx>,
}
impl<'b, 'tcx> PrinterSupport<'tcx> for TypedAnnotation<'b, 'tcx> {
impl<'b, 'tcx> HirPrinterSupport<'tcx> for TypedAnnotation<'b, 'tcx> {
fn sess<'a>(&'a self) -> &'a Session { &self.tcx.sess }
fn ast_map<'a>(&'a self) -> Option<&'a ast_map::Map<'tcx>> {
fn ast_map<'a>(&'a self) -> Option<&'a hir_map::Map<'tcx>> {
Some(&self.tcx.map)
}
fn pp_ann<'a>(&'a self) -> &'a pprust::PpAnn { self }
fn pp_ann<'a>(&'a self) -> &'a pprust_hir::PpAnn { self }
}
impl<'a, 'tcx> pprust::PpAnn for TypedAnnotation<'a, 'tcx> {
impl<'a, 'tcx> pprust_hir::PpAnn for TypedAnnotation<'a, 'tcx> {
fn pre(&self,
s: &mut pprust::State,
node: pprust::AnnNode) -> io::Result<()> {
s: &mut pprust_hir::State,
node: pprust_hir::AnnNode) -> io::Result<()> {
match node {
pprust::NodeExpr(_) => s.popen(),
pprust_hir::NodeExpr(_) => s.popen(),
_ => Ok(())
}
}
fn post(&self,
s: &mut pprust::State,
node: pprust::AnnNode) -> io::Result<()> {
s: &mut pprust_hir::State,
node: pprust_hir::AnnNode) -> io::Result<()> {
match node {
pprust::NodeExpr(expr) => {
pprust_hir::NodeExpr(expr) => {
try!(pp::space(&mut s.s));
try!(pp::word(&mut s.s, "as"));
try!(pp::space(&mut s.s));
@ -360,7 +469,7 @@ impl FromStr for UserIdentifiedItem {
enum NodesMatchingUII<'a, 'ast: 'a> {
NodesMatchingDirect(option::IntoIter<ast::NodeId>),
NodesMatchingSuffix(ast_map::NodesMatchingSuffix<'a, 'ast>),
NodesMatchingSuffix(hir_map::NodesMatchingSuffix<'a, 'ast>),
}
impl<'a, 'ast> Iterator for NodesMatchingUII<'a, 'ast> {
@ -382,7 +491,7 @@ impl UserIdentifiedItem {
}
}
fn all_matching_node_ids<'a, 'ast>(&'a self, map: &'a ast_map::Map<'ast>)
fn all_matching_node_ids<'a, 'ast>(&'a self, map: &'a hir_map::Map<'ast>)
-> NodesMatchingUII<'a, 'ast> {
match *self {
ItemViaNode(node_id) =>
@ -392,7 +501,7 @@ impl UserIdentifiedItem {
}
}
fn to_one_node_id(self, user_option: &str, sess: &Session, map: &ast_map::Map) -> ast::NodeId {
fn to_one_node_id(self, user_option: &str, sess: &Session, map: &hir_map::Map) -> ast::NodeId {
let fail_because = |is_wrong_because| -> ast::NodeId {
let message =
format!("{} needs NodeId (int) or unique \
@ -430,8 +539,9 @@ fn needs_ast_map(ppm: &PpMode, opt_uii: &Option<UserIdentifiedItem>) -> bool {
PpmSource(PpmExpanded) |
PpmSource(PpmExpandedIdentified) |
PpmSource(PpmExpandedHygiene) |
PpmSource(PpmTyped) |
PpmFlowGraph(_) => true
PpmHir(_) |
PpmFlowGraph(_) => true,
PpmSource(PpmTyped) => panic!("invalid state"),
}
}
@ -444,8 +554,9 @@ fn needs_expansion(ppm: &PpMode) -> bool {
PpmSource(PpmExpanded) |
PpmSource(PpmExpandedIdentified) |
PpmSource(PpmExpandedHygiene) |
PpmSource(PpmTyped) |
PpmFlowGraph(_) => true
PpmHir(_) |
PpmFlowGraph(_) => true,
PpmSource(PpmTyped) => panic!("invalid state"),
}
}
@ -552,20 +663,22 @@ pub fn pretty_print_input(sess: Session,
let krate = if compute_ast_map {
match driver::phase_2_configure_and_expand(&sess, krate, &id[..], None) {
None => return,
Some(k) => k
Some(k) => driver::assign_node_ids(&sess, k)
}
} else {
krate
};
let mut forest = ast_map::Forest::new(krate);
// There is some twisted, god-forsaken tangle of lifetimes here which makes
// the ordering of stuff super-finicky.
let mut hir_forest;
let arenas = ty::CtxtArenas::new();
let (krate, ast_map) = if compute_ast_map {
let map = driver::assign_node_ids_and_map(&sess, &mut forest);
(map.krate(), Some(map))
let ast_map = if compute_ast_map {
hir_forest = hir_map::Forest::new(lower_crate(&krate));
let map = driver::make_map(&sess, &mut hir_forest);
Some(map)
} else {
(forest.krate(), None)
None
};
let src_name = driver::source_name(input);
@ -580,15 +693,16 @@ pub fn pretty_print_input(sess: Session,
let mut out = Vec::new();
match (ppm, opt_uii) {
(PpmSource(s), None) => {
(PpmSource(s), _) => {
// Silently ignores an identified node.
let out: &mut Write = &mut out;
s.call_with_pp_support(
sess, ast_map, &arenas, id, box out, |annotation, out| {
sess, ast_map, box out, |annotation, out| {
debug!("pretty printing source code {:?}", s);
let sess = annotation.sess();
pprust::print_crate(sess.codemap(),
sess.diagnostic(),
krate,
&krate,
src_name.to_string(),
&mut rdr,
out,
@ -597,31 +711,52 @@ pub fn pretty_print_input(sess: Session,
})
}
(PpmSource(s), Some(uii)) => {
(PpmHir(s), None) => {
let out: &mut Write = &mut out;
s.call_with_pp_support(
sess, ast_map, &arenas, id, (out,uii), |annotation, (out,uii)| {
s.call_with_pp_support_hir(
sess, &ast_map.unwrap(), &krate, &arenas, id, box out, |annotation, out, krate| {
debug!("pretty printing source code {:?}", s);
let sess = annotation.sess();
let ast_map = annotation.ast_map()
.expect("--pretty missing ast_map");
let mut pp_state =
pprust::State::new_from_input(sess.codemap(),
pprust_hir::print_crate(sess.codemap(),
sess.diagnostic(),
krate,
src_name.to_string(),
&mut rdr,
out,
annotation.pp_ann(),
is_expanded)
})
}
(PpmHir(s), Some(uii)) => {
let out: &mut Write = &mut out;
s.call_with_pp_support_hir(sess,
&ast_map.unwrap(),
&krate,
&arenas,
id,
(out,uii),
|annotation, (out,uii), _| {
debug!("pretty printing source code {:?}", s);
let sess = annotation.sess();
let ast_map = annotation.ast_map().expect("--pretty missing ast_map");
let mut pp_state =
pprust_hir::State::new_from_input(sess.codemap(),
sess.diagnostic(),
src_name.to_string(),
&mut rdr,
box out,
annotation.pp_ann(),
is_expanded);
for node_id in uii.all_matching_node_ids(ast_map) {
let node = ast_map.get(node_id);
try!(pp_state.print_node(&node));
try!(pp::space(&mut pp_state.s));
try!(pp_state.synth_comment(ast_map.path_to_string(node_id)));
try!(pp::hardbreak(&mut pp_state.s));
}
pp::eof(&mut pp_state.s)
})
true);
for node_id in uii.all_matching_node_ids(ast_map) {
let node = ast_map.get(node_id);
try!(pp_state.print_node(&node));
try!(pp::space(&mut pp_state.s));
try!(pp_state.synth_comment(ast_map.path_to_string(node_id)));
try!(pp::hardbreak(&mut pp_state.s));
}
pp::eof(&mut pp_state.s)
})
}
(PpmFlowGraph(mode), opt_uii) => {
@ -646,6 +781,7 @@ pub fn pretty_print_input(sess: Session,
let variants = gather_flowgraph_variants(&sess);
driver::phase_3_run_analysis_passes(sess,
ast_map,
&krate,
&arenas,
id,
resolve::MakeGlobMap::No,

View File

@ -29,7 +29,7 @@ use rustc_typeck::middle::infer;
use rustc_typeck::middle::infer::lub::Lub;
use rustc_typeck::middle::infer::glb::Glb;
use rustc_typeck::middle::infer::sub::Sub;
use rustc::ast_map;
use rustc::front::map as hir_map;
use rustc::session::{self,config};
use syntax::{abi, ast};
use syntax::codemap;
@ -38,6 +38,9 @@ use syntax::diagnostic::{Level, RenderSpan, Bug, Fatal, Error, Warning, Note, He
use syntax::parse::token;
use syntax::feature_gate::UnstableFeatures;
use rustc_front::lowering::lower_crate;
use rustc_front::hir;
struct Env<'a, 'tcx: 'a> {
infcx: &'a infer::InferCtxt<'a, 'tcx>,
}
@ -120,9 +123,10 @@ fn test_env<F>(source_string: &str,
let krate = driver::phase_2_configure_and_expand(&sess, krate, "test", None)
.expect("phase 2 aborted");
let mut forest = ast_map::Forest::new(krate);
let krate = driver::assign_node_ids(&sess, krate);
let mut hir_forest = hir_map::Forest::new(lower_crate(&krate));
let arenas = ty::CtxtArenas::new();
let ast_map = driver::assign_node_ids_and_map(&sess, &mut forest);
let ast_map = driver::make_map(&sess, &mut hir_forest);
let krate = ast_map.krate();
// run just enough stuff to build a tcx:
@ -185,7 +189,7 @@ impl<'a, 'tcx> Env<'a, 'tcx> {
};
fn search_mod(this: &Env,
m: &ast::Mod,
m: &hir::Mod,
idx: usize,
names: &[String])
-> Option<ast::NodeId> {
@ -199,7 +203,7 @@ impl<'a, 'tcx> Env<'a, 'tcx> {
}
fn search(this: &Env,
it: &ast::Item,
it: &hir::Item,
idx: usize,
names: &[String])
-> Option<ast::NodeId> {
@ -208,19 +212,19 @@ impl<'a, 'tcx> Env<'a, 'tcx> {
}
return match it.node {
ast::ItemUse(..) | ast::ItemExternCrate(..) |
ast::ItemConst(..) | ast::ItemStatic(..) | ast::ItemFn(..) |
ast::ItemForeignMod(..) | ast::ItemTy(..) => {
hir::ItemUse(..) | hir::ItemExternCrate(..) |
hir::ItemConst(..) | hir::ItemStatic(..) | hir::ItemFn(..) |
hir::ItemForeignMod(..) | hir::ItemTy(..) => {
None
}
ast::ItemEnum(..) | ast::ItemStruct(..) |
ast::ItemTrait(..) | ast::ItemImpl(..) |
ast::ItemMac(..) | ast::ItemDefaultImpl(..) => {
hir::ItemEnum(..) | hir::ItemStruct(..) |
hir::ItemTrait(..) | hir::ItemImpl(..) |
hir::ItemDefaultImpl(..) => {
None
}
ast::ItemMod(ref m) => {
hir::ItemMod(ref m) => {
search_mod(this, m, idx, names)
}
};
@ -260,7 +264,7 @@ impl<'a, 'tcx> Env<'a, 'tcx> {
let input_args = input_tys.iter().cloned().collect();
self.infcx.tcx.mk_fn(None,
self.infcx.tcx.mk_bare_fn(ty::BareFnTy {
unsafety: ast::Unsafety::Normal,
unsafety: hir::Unsafety::Normal,
abi: abi::Rust,
sig: ty::Binder(ty::FnSig {
inputs: input_args,

628
src/librustc_front/attr.rs Normal file
View File

@ -0,0 +1,628 @@
// Copyright 2012-2015 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.
// Functions dealing with attributes and meta items
pub use self::StabilityLevel::*;
pub use self::ReprAttr::*;
pub use self::IntType::*;
use hir;
use hir::{AttrId, Attribute, Attribute_, MetaItem, MetaWord, MetaNameValue, MetaList};
use lowering::{lower_attr_style, unlower_attribute};
use syntax::codemap::{Span, Spanned, spanned, dummy_spanned};
use syntax::codemap::BytePos;
use syntax::diagnostic::SpanHandler;
use syntax::attr as syntax_attr;
use syntax::parse::lexer::comments::{doc_comment_style, strip_doc_comment_decoration};
use syntax::parse::token::{InternedString, intern_and_get_ident};
use syntax::parse::token;
use syntax::ptr::P;
use std::cell::Cell;
use std::collections::HashSet;
use std::fmt;
pub fn mark_used(attr: &Attribute) {
syntax_attr::mark_used(&unlower_attribute(attr))
}
pub trait AttrMetaMethods {
fn check_name(&self, name: &str) -> bool {
name == &self.name()[..]
}
/// Retrieve the name of the meta item, e.g. `foo` in `#[foo]`,
/// `#[foo="bar"]` and `#[foo(bar)]`
fn name(&self) -> InternedString;
/// Gets the string value if self is a MetaNameValue variant
/// containing a string, otherwise None.
fn value_str(&self) -> Option<InternedString>;
/// Gets a list of inner meta items from a list MetaItem type.
fn meta_item_list<'a>(&'a self) -> Option<&'a [P<MetaItem>]>;
fn span(&self) -> Span;
}
impl AttrMetaMethods for Attribute {
fn check_name(&self, name: &str) -> bool {
let matches = name == &self.name()[..];
if matches {
syntax_attr::mark_used(&unlower_attribute(self));
}
matches
}
fn name(&self) -> InternedString { self.meta().name() }
fn value_str(&self) -> Option<InternedString> {
self.meta().value_str()
}
fn meta_item_list<'a>(&'a self) -> Option<&'a [P<MetaItem>]> {
self.node.value.meta_item_list()
}
fn span(&self) -> Span { self.meta().span }
}
impl AttrMetaMethods for MetaItem {
fn name(&self) -> InternedString {
match self.node {
MetaWord(ref n) => (*n).clone(),
MetaNameValue(ref n, _) => (*n).clone(),
MetaList(ref n, _) => (*n).clone(),
}
}
fn value_str(&self) -> Option<InternedString> {
match self.node {
MetaNameValue(_, ref v) => {
match v.node {
hir::LitStr(ref s, _) => Some((*s).clone()),
_ => None,
}
},
_ => None
}
}
fn meta_item_list<'a>(&'a self) -> Option<&'a [P<MetaItem>]> {
match self.node {
MetaList(_, ref l) => Some(&l[..]),
_ => None
}
}
fn span(&self) -> Span { self.span }
}
// Annoying, but required to get test_cfg to work
impl AttrMetaMethods for P<MetaItem> {
fn name(&self) -> InternedString { (**self).name() }
fn value_str(&self) -> Option<InternedString> { (**self).value_str() }
fn meta_item_list<'a>(&'a self) -> Option<&'a [P<MetaItem>]> {
(**self).meta_item_list()
}
fn span(&self) -> Span { (**self).span() }
}
pub trait AttributeMethods {
fn meta<'a>(&'a self) -> &'a MetaItem;
fn with_desugared_doc<T, F>(&self, f: F) -> T where
F: FnOnce(&Attribute) -> T;
}
impl AttributeMethods for Attribute {
/// Extract the MetaItem from inside this Attribute.
fn meta<'a>(&'a self) -> &'a MetaItem {
&*self.node.value
}
/// Convert self to a normal #[doc="foo"] comment, if it is a
/// comment like `///` or `/** */`. (Returns self unchanged for
/// non-sugared doc attributes.)
fn with_desugared_doc<T, F>(&self, f: F) -> T where
F: FnOnce(&Attribute) -> T,
{
if self.node.is_sugared_doc {
let comment = self.value_str().unwrap();
let meta = mk_name_value_item_str(
InternedString::new("doc"),
token::intern_and_get_ident(&strip_doc_comment_decoration(
&comment)));
if self.node.style == hir::AttrOuter {
f(&mk_attr_outer(self.node.id, meta))
} else {
f(&mk_attr_inner(self.node.id, meta))
}
} else {
f(self)
}
}
}
/* Constructors */
pub fn mk_name_value_item_str(name: InternedString, value: InternedString)
-> P<MetaItem> {
let value_lit = dummy_spanned(hir::LitStr(value, hir::CookedStr));
mk_name_value_item(name, value_lit)
}
pub fn mk_name_value_item(name: InternedString, value: hir::Lit)
-> P<MetaItem> {
P(dummy_spanned(MetaNameValue(name, value)))
}
pub fn mk_list_item(name: InternedString, items: Vec<P<MetaItem>>) -> P<MetaItem> {
P(dummy_spanned(MetaList(name, items)))
}
pub fn mk_word_item(name: InternedString) -> P<MetaItem> {
P(dummy_spanned(MetaWord(name)))
}
thread_local! { static NEXT_ATTR_ID: Cell<usize> = Cell::new(0) }
pub fn mk_attr_id() -> AttrId {
let id = NEXT_ATTR_ID.with(|slot| {
let r = slot.get();
slot.set(r + 1);
r
});
AttrId(id)
}
/// Returns an inner attribute with the given value.
pub fn mk_attr_inner(id: AttrId, item: P<MetaItem>) -> Attribute {
dummy_spanned(Attribute_ {
id: id,
style: hir::AttrInner,
value: item,
is_sugared_doc: false,
})
}
/// Returns an outer attribute with the given value.
pub fn mk_attr_outer(id: AttrId, item: P<MetaItem>) -> Attribute {
dummy_spanned(Attribute_ {
id: id,
style: hir::AttrOuter,
value: item,
is_sugared_doc: false,
})
}
pub fn mk_sugared_doc_attr(id: AttrId, text: InternedString, lo: BytePos,
hi: BytePos)
-> Attribute {
let style = lower_attr_style(doc_comment_style(&text));
let lit = spanned(lo, hi, hir::LitStr(text, hir::CookedStr));
let attr = Attribute_ {
id: id,
style: style,
value: P(spanned(lo, hi, MetaNameValue(InternedString::new("doc"),
lit))),
is_sugared_doc: true
};
spanned(lo, hi, attr)
}
/* Searching */
/// Check if `needle` occurs in `haystack` by a structural
/// comparison. This is slightly subtle, and relies on ignoring the
/// span included in the `==` comparison a plain MetaItem.
pub fn contains(haystack: &[P<MetaItem>], needle: &MetaItem) -> bool {
debug!("attr::contains (name={})", needle.name());
haystack.iter().any(|item| {
debug!(" testing: {}", item.name());
item.node == needle.node
})
}
pub fn contains_name<AM: AttrMetaMethods>(metas: &[AM], name: &str) -> bool {
debug!("attr::contains_name (name={})", name);
metas.iter().any(|item| {
debug!(" testing: {}", item.name());
item.check_name(name)
})
}
pub fn first_attr_value_str_by_name(attrs: &[Attribute], name: &str)
-> Option<InternedString> {
attrs.iter()
.find(|at| at.check_name(name))
.and_then(|at| at.value_str())
}
pub fn last_meta_item_value_str_by_name(items: &[P<MetaItem>], name: &str)
-> Option<InternedString> {
items.iter()
.rev()
.find(|mi| mi.check_name(name))
.and_then(|i| i.value_str())
}
/* Higher-level applications */
pub fn sort_meta_items(items: Vec<P<MetaItem>>) -> Vec<P<MetaItem>> {
// This is sort of stupid here, but we need to sort by
// human-readable strings.
let mut v = items.into_iter()
.map(|mi| (mi.name(), mi))
.collect::<Vec<(InternedString, P<MetaItem>)>>();
v.sort_by(|&(ref a, _), &(ref b, _)| a.cmp(b));
// There doesn't seem to be a more optimal way to do this
v.into_iter().map(|(_, m)| m.map(|Spanned {node, span}| {
Spanned {
node: match node {
MetaList(n, mis) => MetaList(n, sort_meta_items(mis)),
_ => node
},
span: span
}
})).collect()
}
pub fn find_crate_name(attrs: &[Attribute]) -> Option<InternedString> {
first_attr_value_str_by_name(attrs, "crate_name")
}
/// Find the value of #[export_name=*] attribute and check its validity.
pub fn find_export_name_attr(diag: &SpanHandler, attrs: &[Attribute]) -> Option<InternedString> {
attrs.iter().fold(None, |ia,attr| {
if attr.check_name("export_name") {
if let s@Some(_) = attr.value_str() {
s
} else {
diag.span_err(attr.span, "export_name attribute has invalid format");
diag.handler.help("use #[export_name=\"*\"]");
None
}
} else {
ia
}
})
}
#[derive(Copy, Clone, PartialEq)]
pub enum InlineAttr {
None,
Hint,
Always,
Never,
}
/// Determine what `#[inline]` attribute is present in `attrs`, if any.
pub fn find_inline_attr(diagnostic: Option<&SpanHandler>, attrs: &[Attribute]) -> InlineAttr {
// FIXME (#2809)---validate the usage of #[inline] and #[inline]
attrs.iter().fold(InlineAttr::None, |ia,attr| {
match attr.node.value.node {
MetaWord(ref n) if *n == "inline" => {
syntax_attr::mark_used(&unlower_attribute(attr));
InlineAttr::Hint
}
MetaList(ref n, ref items) if *n == "inline" => {
syntax_attr::mark_used(&unlower_attribute(attr));
if items.len() != 1 {
diagnostic.map(|d|{ d.span_err(attr.span, "expected one argument"); });
InlineAttr::None
} else if contains_name(&items[..], "always") {
InlineAttr::Always
} else if contains_name(&items[..], "never") {
InlineAttr::Never
} else {
diagnostic.map(|d|{ d.span_err((*items[0]).span, "invalid argument"); });
InlineAttr::None
}
}
_ => ia
}
})
}
/// True if `#[inline]` or `#[inline(always)]` is present in `attrs`.
pub fn requests_inline(attrs: &[Attribute]) -> bool {
match find_inline_attr(None, attrs) {
InlineAttr::Hint | InlineAttr::Always => true,
InlineAttr::None | InlineAttr::Never => false,
}
}
/// Represents the #[deprecated] and friends attributes.
#[derive(RustcEncodable, RustcDecodable, Clone, Debug, PartialEq, Eq, Hash)]
pub struct Stability {
pub level: StabilityLevel,
pub feature: InternedString,
pub since: Option<InternedString>,
pub deprecated_since: Option<InternedString>,
// The reason for the current stability level. If deprecated, the
// reason for deprecation.
pub reason: Option<InternedString>,
// The relevant rust-lang issue
pub issue: Option<u32>
}
/// The available stability levels.
#[derive(RustcEncodable, RustcDecodable, PartialEq, PartialOrd, Clone, Debug, Copy, Eq, Hash)]
pub enum StabilityLevel {
Unstable,
Stable,
}
impl fmt::Display for StabilityLevel {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Debug::fmt(self, f)
}
}
fn find_stability_generic<'a,
AM: AttrMetaMethods,
I: Iterator<Item=&'a AM>>
(diagnostic: &SpanHandler, attrs: I, item_sp: Span)
-> (Option<Stability>, Vec<&'a AM>) {
let mut stab: Option<Stability> = None;
let mut deprecated: Option<(Option<InternedString>, Option<InternedString>)> = None;
let mut used_attrs: Vec<&'a AM> = vec![];
'outer: for attr in attrs {
let tag = attr.name();
let tag = &tag[..];
if tag != "deprecated" && tag != "unstable" && tag != "stable" {
continue // not a stability level
}
used_attrs.push(attr);
let (feature, since, reason, issue) = match attr.meta_item_list() {
Some(metas) => {
let mut feature = None;
let mut since = None;
let mut reason = None;
let mut issue = None;
for meta in metas {
match &*meta.name() {
"feature" => {
match meta.value_str() {
Some(v) => feature = Some(v),
None => {
diagnostic.span_err(meta.span, "incorrect meta item");
continue 'outer;
}
}
}
"since" => {
match meta.value_str() {
Some(v) => since = Some(v),
None => {
diagnostic.span_err(meta.span, "incorrect meta item");
continue 'outer;
}
}
}
"reason" => {
match meta.value_str() {
Some(v) => reason = Some(v),
None => {
diagnostic.span_err(meta.span, "incorrect meta item");
continue 'outer;
}
}
}
"issue" => {
match meta.value_str().and_then(|s| s.parse().ok()) {
Some(v) => issue = Some(v),
None => {
diagnostic.span_err(meta.span, "incorrect meta item");
continue 'outer;
}
}
}
_ => {}
}
}
(feature, since, reason, issue)
}
None => {
diagnostic.span_err(attr.span(), "incorrect stability attribute type");
continue
}
};
// Deprecated tags don't require feature names
if feature == None && tag != "deprecated" {
diagnostic.span_err(attr.span(), "missing 'feature'");
}
// Unstable tags don't require a version
if since == None && tag != "unstable" {
diagnostic.span_err(attr.span(), "missing 'since'");
}
if tag == "unstable" || tag == "stable" {
if stab.is_some() {
diagnostic.span_err(item_sp, "multiple stability levels");
}
let level = match tag {
"unstable" => Unstable,
"stable" => Stable,
_ => unreachable!()
};
stab = Some(Stability {
level: level,
feature: feature.unwrap_or(intern_and_get_ident("bogus")),
since: since,
deprecated_since: None,
reason: reason,
issue: issue,
});
} else { // "deprecated"
if deprecated.is_some() {
diagnostic.span_err(item_sp, "multiple deprecated attributes");
}
deprecated = Some((since, reason));
}
}
// Merge the deprecation info into the stability info
if deprecated.is_some() {
match stab {
Some(ref mut s) => {
let (since, reason) = deprecated.unwrap();
s.deprecated_since = since;
s.reason = reason;
}
None => {
diagnostic.span_err(item_sp, "deprecated attribute must be paired with \
either stable or unstable attribute");
}
}
} else if stab.as_ref().map_or(false, |s| s.level == Unstable && s.issue.is_none()) {
// non-deprecated unstable items need to point to issues.
diagnostic.span_err(item_sp,
"non-deprecated unstable items need to point \
to an issue with `issue = \"NNN\"`");
}
(stab, used_attrs)
}
/// Find the first stability attribute. `None` if none exists.
pub fn find_stability(diagnostic: &SpanHandler, attrs: &[Attribute],
item_sp: Span) -> Option<Stability> {
let (s, used) = find_stability_generic(diagnostic, attrs.iter(), item_sp);
for used in used { syntax_attr::mark_used(&unlower_attribute(used)) }
return s;
}
pub fn require_unique_names(diagnostic: &SpanHandler, metas: &[P<MetaItem>]) {
let mut set = HashSet::new();
for meta in metas {
let name = meta.name();
if !set.insert(name.clone()) {
panic!(diagnostic.span_fatal(meta.span,
&format!("duplicate meta item `{}`", name)));
}
}
}
/// Parse #[repr(...)] forms.
///
/// Valid repr contents: any of the primitive integral type names (see
/// `int_type_of_word`, below) to specify enum discriminant type; `C`, to use
/// the same discriminant size that the corresponding C enum would or C
/// structure layout, and `packed` to remove padding.
pub fn find_repr_attrs(diagnostic: &SpanHandler, attr: &Attribute) -> Vec<ReprAttr> {
let mut acc = Vec::new();
match attr.node.value.node {
hir::MetaList(ref s, ref items) if *s == "repr" => {
syntax_attr::mark_used(&unlower_attribute(attr));
for item in items {
match item.node {
hir::MetaWord(ref word) => {
let hint = match &word[..] {
// Can't use "extern" because it's not a lexical identifier.
"C" => Some(ReprExtern),
"packed" => Some(ReprPacked),
"simd" => Some(ReprSimd),
_ => match int_type_of_word(&word) {
Some(ity) => Some(ReprInt(item.span, ity)),
None => {
// Not a word we recognize
diagnostic.span_err(item.span,
"unrecognized representation hint");
None
}
}
};
match hint {
Some(h) => acc.push(h),
None => { }
}
}
// Not a word:
_ => diagnostic.span_err(item.span, "unrecognized enum representation hint")
}
}
}
// Not a "repr" hint: ignore.
_ => { }
}
acc
}
fn int_type_of_word(s: &str) -> Option<IntType> {
match s {
"i8" => Some(SignedInt(hir::TyI8)),
"u8" => Some(UnsignedInt(hir::TyU8)),
"i16" => Some(SignedInt(hir::TyI16)),
"u16" => Some(UnsignedInt(hir::TyU16)),
"i32" => Some(SignedInt(hir::TyI32)),
"u32" => Some(UnsignedInt(hir::TyU32)),
"i64" => Some(SignedInt(hir::TyI64)),
"u64" => Some(UnsignedInt(hir::TyU64)),
"isize" => Some(SignedInt(hir::TyIs)),
"usize" => Some(UnsignedInt(hir::TyUs)),
_ => None
}
}
#[derive(PartialEq, Debug, RustcEncodable, RustcDecodable, Copy, Clone)]
pub enum ReprAttr {
ReprAny,
ReprInt(Span, IntType),
ReprExtern,
ReprPacked,
ReprSimd,
}
impl ReprAttr {
pub fn is_ffi_safe(&self) -> bool {
match *self {
ReprAny => false,
ReprInt(_sp, ity) => ity.is_ffi_safe(),
ReprExtern => true,
ReprPacked => false,
ReprSimd => true,
}
}
}
#[derive(Eq, Hash, PartialEq, Debug, RustcEncodable, RustcDecodable, Copy, Clone)]
pub enum IntType {
SignedInt(hir::IntTy),
UnsignedInt(hir::UintTy)
}
impl IntType {
#[inline]
pub fn is_signed(self) -> bool {
match self {
SignedInt(..) => true,
UnsignedInt(..) => false
}
}
fn is_ffi_safe(self) -> bool {
match self {
SignedInt(hir::TyI8) | UnsignedInt(hir::TyU8) |
SignedInt(hir::TyI16) | UnsignedInt(hir::TyU16) |
SignedInt(hir::TyI32) | UnsignedInt(hir::TyU32) |
SignedInt(hir::TyI64) | UnsignedInt(hir::TyU64) => true,
SignedInt(hir::TyIs) | UnsignedInt(hir::TyUs) => false
}
}
}

1192
src/librustc_front/fold.rs Normal file

File diff suppressed because it is too large Load Diff

1533
src/librustc_front/hir.rs Normal file

File diff suppressed because it is too large Load Diff

58
src/librustc_front/lib.rs Normal file
View File

@ -0,0 +1,58 @@
// Copyright 2015 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.
//! The Rust compiler.
//!
//! # Note
//!
//! This API is completely unstable and subject to change.
// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
#![cfg_attr(stage0, feature(custom_attribute))]
#![crate_name = "rustc_front"]
#![unstable(feature = "rustc_private", issue = "27812")]
#![staged_api]
#![crate_type = "dylib"]
#![crate_type = "rlib"]
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
html_root_url = "http://doc.rust-lang.org/nightly/")]
#![feature(associated_consts)]
#![feature(box_patterns)]
#![feature(box_syntax)]
#![feature(const_fn)]
#![feature(quote)]
#![feature(rustc_diagnostic_macros)]
#![feature(rustc_private)]
#![feature(slice_patterns)]
#![feature(staged_api)]
#![feature(str_char)]
#![feature(filling_drop)]
#![feature(str_escape)]
#![cfg_attr(test, feature(test))]
extern crate serialize;
#[macro_use] extern crate log;
#[macro_use] extern crate syntax;
#[macro_use] #[no_link] extern crate rustc_bitflags;
extern crate serialize as rustc_serialize; // used by deriving
pub mod hir;
pub mod lowering;
pub mod fold;
pub mod visit;
pub mod attr;
pub mod util;
pub mod print {
pub mod pprust;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,686 @@
// Copyright 2012 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.
//! This pretty-printer is a direct reimplementation of Philip Karlton's
//! Mesa pretty-printer, as described in appendix A of
//!
//! STAN-CS-79-770: "Pretty Printing", by Derek C. Oppen.
//! Stanford Department of Computer Science, 1979.
//!
//! The algorithm's aim is to break a stream into as few lines as possible
//! while respecting the indentation-consistency requirements of the enclosing
//! block, and avoiding breaking at silly places on block boundaries, for
//! example, between "x" and ")" in "x)".
//!
//! I am implementing this algorithm because it comes with 20 pages of
//! documentation explaining its theory, and because it addresses the set of
//! concerns I've seen other pretty-printers fall down on. Weirdly. Even though
//! it's 32 years old. What can I say?
//!
//! Despite some redundancies and quirks in the way it's implemented in that
//! paper, I've opted to keep the implementation here as similar as I can,
//! changing only what was blatantly wrong, a typo, or sufficiently
//! non-idiomatic rust that it really stuck out.
//!
//! In particular you'll see a certain amount of churn related to INTEGER vs.
//! CARDINAL in the Mesa implementation. Mesa apparently interconverts the two
//! somewhat readily? In any case, I've used usize for indices-in-buffers and
//! ints for character-sizes-and-indentation-offsets. This respects the need
//! for ints to "go negative" while carrying a pending-calculation balance, and
//! helps differentiate all the numbers flying around internally (slightly).
//!
//! I also inverted the indentation arithmetic used in the print stack, since
//! the Mesa implementation (somewhat randomly) stores the offset on the print
//! stack in terms of margin-col rather than col itself. I store col.
//!
//! I also implemented a small change in the String token, in that I store an
//! explicit length for the string. For most tokens this is just the length of
//! the accompanying string. But it's necessary to permit it to differ, for
//! encoding things that are supposed to "go on their own line" -- certain
//! classes of comment and blank-line -- where relying on adjacent
//! hardbreak-like Break tokens with long blankness indication doesn't actually
//! work. To see why, consider when there is a "thing that should be on its own
//! line" between two long blocks, say functions. If you put a hardbreak after
//! each function (or before each) and the breaking algorithm decides to break
//! there anyways (because the functions themselves are long) you wind up with
//! extra blank lines. If you don't put hardbreaks you can wind up with the
//! "thing which should be on its own line" not getting its own line in the
//! rare case of "really small functions" or such. This re-occurs with comments
//! and explicit blank lines. So in those cases we use a string with a payload
//! we want isolated to a line and an explicit length that's huge, surrounded
//! by two zero-length breaks. The algorithm will try its best to fit it on a
//! line (which it can't) and so naturally place the content on its own line to
//! avoid combining it with other lines and making matters even worse.
use std::io;
use std::string;
#[derive(Clone, Copy, PartialEq)]
pub enum Breaks {
Consistent,
Inconsistent,
}
#[derive(Clone, Copy)]
pub struct BreakToken {
offset: isize,
blank_space: isize
}
#[derive(Clone, Copy)]
pub struct BeginToken {
offset: isize,
breaks: Breaks
}
#[derive(Clone)]
pub enum Token {
String(String, isize),
Break(BreakToken),
Begin(BeginToken),
End,
Eof,
}
impl Token {
pub fn is_eof(&self) -> bool {
match *self {
Token::Eof => true,
_ => false,
}
}
pub fn is_hardbreak_tok(&self) -> bool {
match *self {
Token::Break(BreakToken {
offset: 0,
blank_space: bs
}) if bs == SIZE_INFINITY =>
true,
_ =>
false
}
}
}
pub fn tok_str(token: &Token) -> String {
match *token {
Token::String(ref s, len) => format!("STR({},{})", s, len),
Token::Break(_) => "BREAK".to_string(),
Token::Begin(_) => "BEGIN".to_string(),
Token::End => "END".to_string(),
Token::Eof => "EOF".to_string()
}
}
pub fn buf_str(toks: &[Token],
szs: &[isize],
left: usize,
right: usize,
lim: usize)
-> String {
let n = toks.len();
assert_eq!(n, szs.len());
let mut i = left;
let mut l = lim;
let mut s = string::String::from("[");
while i != right && l != 0 {
l -= 1;
if i != left {
s.push_str(", ");
}
s.push_str(&format!("{}={}",
szs[i],
tok_str(&toks[i])));
i += 1;
i %= n;
}
s.push(']');
s
}
#[derive(Copy, Clone)]
pub enum PrintStackBreak {
Fits,
Broken(Breaks),
}
#[derive(Copy, Clone)]
pub struct PrintStackElem {
offset: isize,
pbreak: PrintStackBreak
}
const SIZE_INFINITY: isize = 0xffff;
pub fn mk_printer<'a>(out: Box<io::Write+'a>, linewidth: usize) -> Printer<'a> {
// Yes 3, it makes the ring buffers big enough to never
// fall behind.
let n: usize = 3 * linewidth;
debug!("mk_printer {}", linewidth);
let token = vec![Token::Eof; n];
let size = vec![0_isize; n];
let scan_stack = vec![0_usize; n];
Printer {
out: out,
buf_len: n,
margin: linewidth as isize,
space: linewidth as isize,
left: 0,
right: 0,
token: token,
size: size,
left_total: 0,
right_total: 0,
scan_stack: scan_stack,
scan_stack_empty: true,
top: 0,
bottom: 0,
print_stack: Vec::new(),
pending_indentation: 0
}
}
/// In case you do not have the paper, here is an explanation of what's going
/// on.
///
/// There is a stream of input tokens flowing through this printer.
///
/// The printer buffers up to 3N tokens inside itself, where N is linewidth.
/// Yes, linewidth is chars and tokens are multi-char, but in the worst
/// case every token worth buffering is 1 char long, so it's ok.
///
/// Tokens are String, Break, and Begin/End to delimit blocks.
///
/// Begin tokens can carry an offset, saying "how far to indent when you break
/// inside here", as well as a flag indicating "consistent" or "inconsistent"
/// breaking. Consistent breaking means that after the first break, no attempt
/// will be made to flow subsequent breaks together onto lines. Inconsistent
/// is the opposite. Inconsistent breaking example would be, say:
///
/// foo(hello, there, good, friends)
///
/// breaking inconsistently to become
///
/// foo(hello, there
/// good, friends);
///
/// whereas a consistent breaking would yield:
///
/// foo(hello,
/// there
/// good,
/// friends);
///
/// That is, in the consistent-break blocks we value vertical alignment
/// more than the ability to cram stuff onto a line. But in all cases if it
/// can make a block a one-liner, it'll do so.
///
/// Carrying on with high-level logic:
///
/// The buffered tokens go through a ring-buffer, 'tokens'. The 'left' and
/// 'right' indices denote the active portion of the ring buffer as well as
/// describing hypothetical points-in-the-infinite-stream at most 3N tokens
/// apart (i.e. "not wrapped to ring-buffer boundaries"). The paper will switch
/// between using 'left' and 'right' terms to denote the wrapped-to-ring-buffer
/// and point-in-infinite-stream senses freely.
///
/// There is a parallel ring buffer, 'size', that holds the calculated size of
/// each token. Why calculated? Because for Begin/End pairs, the "size"
/// includes everything between the pair. That is, the "size" of Begin is
/// actually the sum of the sizes of everything between Begin and the paired
/// End that follows. Since that is arbitrarily far in the future, 'size' is
/// being rewritten regularly while the printer runs; in fact most of the
/// machinery is here to work out 'size' entries on the fly (and give up when
/// they're so obviously over-long that "infinity" is a good enough
/// approximation for purposes of line breaking).
///
/// The "input side" of the printer is managed as an abstract process called
/// SCAN, which uses 'scan_stack', 'scan_stack_empty', 'top' and 'bottom', to
/// manage calculating 'size'. SCAN is, in other words, the process of
/// calculating 'size' entries.
///
/// The "output side" of the printer is managed by an abstract process called
/// PRINT, which uses 'print_stack', 'margin' and 'space' to figure out what to
/// do with each token/size pair it consumes as it goes. It's trying to consume
/// the entire buffered window, but can't output anything until the size is >=
/// 0 (sizes are set to negative while they're pending calculation).
///
/// So SCAN takes input and buffers tokens and pending calculations, while
/// PRINT gobbles up completed calculations and tokens from the buffer. The
/// theory is that the two can never get more than 3N tokens apart, because
/// once there's "obviously" too much data to fit on a line, in a size
/// calculation, SCAN will write "infinity" to the size and let PRINT consume
/// it.
///
/// In this implementation (following the paper, again) the SCAN process is
/// the method called 'pretty_print', and the 'PRINT' process is the method
/// called 'print'.
pub struct Printer<'a> {
pub out: Box<io::Write+'a>,
buf_len: usize,
/// Width of lines we're constrained to
margin: isize,
/// Number of spaces left on line
space: isize,
/// Index of left side of input stream
left: usize,
/// Index of right side of input stream
right: usize,
/// Ring-buffer stream goes through
token: Vec<Token> ,
/// Ring-buffer of calculated sizes
size: Vec<isize> ,
/// Running size of stream "...left"
left_total: isize,
/// Running size of stream "...right"
right_total: isize,
/// Pseudo-stack, really a ring too. Holds the
/// primary-ring-buffers index of the Begin that started the
/// current block, possibly with the most recent Break after that
/// Begin (if there is any) on top of it. Stuff is flushed off the
/// bottom as it becomes irrelevant due to the primary ring-buffer
/// advancing.
scan_stack: Vec<usize> ,
/// Top==bottom disambiguator
scan_stack_empty: bool,
/// Index of top of scan_stack
top: usize,
/// Index of bottom of scan_stack
bottom: usize,
/// Stack of blocks-in-progress being flushed by print
print_stack: Vec<PrintStackElem> ,
/// Buffered indentation to avoid writing trailing whitespace
pending_indentation: isize,
}
impl<'a> Printer<'a> {
pub fn last_token(&mut self) -> Token {
self.token[self.right].clone()
}
// be very careful with this!
pub fn replace_last_token(&mut self, t: Token) {
self.token[self.right] = t;
}
pub fn pretty_print(&mut self, token: Token) -> io::Result<()> {
debug!("pp Vec<{},{}>", self.left, self.right);
match token {
Token::Eof => {
if !self.scan_stack_empty {
self.check_stack(0);
try!(self.advance_left());
}
self.indent(0);
Ok(())
}
Token::Begin(b) => {
if self.scan_stack_empty {
self.left_total = 1;
self.right_total = 1;
self.left = 0;
self.right = 0;
} else { self.advance_right(); }
debug!("pp Begin({})/buffer Vec<{},{}>",
b.offset, self.left, self.right);
self.token[self.right] = token;
self.size[self.right] = -self.right_total;
let right = self.right;
self.scan_push(right);
Ok(())
}
Token::End => {
if self.scan_stack_empty {
debug!("pp End/print Vec<{},{}>", self.left, self.right);
self.print(token, 0)
} else {
debug!("pp End/buffer Vec<{},{}>", self.left, self.right);
self.advance_right();
self.token[self.right] = token;
self.size[self.right] = -1;
let right = self.right;
self.scan_push(right);
Ok(())
}
}
Token::Break(b) => {
if self.scan_stack_empty {
self.left_total = 1;
self.right_total = 1;
self.left = 0;
self.right = 0;
} else { self.advance_right(); }
debug!("pp Break({})/buffer Vec<{},{}>",
b.offset, self.left, self.right);
self.check_stack(0);
let right = self.right;
self.scan_push(right);
self.token[self.right] = token;
self.size[self.right] = -self.right_total;
self.right_total += b.blank_space;
Ok(())
}
Token::String(s, len) => {
if self.scan_stack_empty {
debug!("pp String('{}')/print Vec<{},{}>",
s, self.left, self.right);
self.print(Token::String(s, len), len)
} else {
debug!("pp String('{}')/buffer Vec<{},{}>",
s, self.left, self.right);
self.advance_right();
self.token[self.right] = Token::String(s, len);
self.size[self.right] = len;
self.right_total += len;
self.check_stream()
}
}
}
}
pub fn check_stream(&mut self) -> io::Result<()> {
debug!("check_stream Vec<{}, {}> with left_total={}, right_total={}",
self.left, self.right, self.left_total, self.right_total);
if self.right_total - self.left_total > self.space {
debug!("scan window is {}, longer than space on line ({})",
self.right_total - self.left_total, self.space);
if !self.scan_stack_empty {
if self.left == self.scan_stack[self.bottom] {
debug!("setting {} to infinity and popping", self.left);
let scanned = self.scan_pop_bottom();
self.size[scanned] = SIZE_INFINITY;
}
}
try!(self.advance_left());
if self.left != self.right {
try!(self.check_stream());
}
}
Ok(())
}
pub fn scan_push(&mut self, x: usize) {
debug!("scan_push {}", x);
if self.scan_stack_empty {
self.scan_stack_empty = false;
} else {
self.top += 1;
self.top %= self.buf_len;
assert!((self.top != self.bottom));
}
self.scan_stack[self.top] = x;
}
pub fn scan_pop(&mut self) -> usize {
assert!((!self.scan_stack_empty));
let x = self.scan_stack[self.top];
if self.top == self.bottom {
self.scan_stack_empty = true;
} else {
self.top += self.buf_len - 1; self.top %= self.buf_len;
}
return x;
}
pub fn scan_top(&mut self) -> usize {
assert!((!self.scan_stack_empty));
return self.scan_stack[self.top];
}
pub fn scan_pop_bottom(&mut self) -> usize {
assert!((!self.scan_stack_empty));
let x = self.scan_stack[self.bottom];
if self.top == self.bottom {
self.scan_stack_empty = true;
} else {
self.bottom += 1; self.bottom %= self.buf_len;
}
return x;
}
pub fn advance_right(&mut self) {
self.right += 1;
self.right %= self.buf_len;
assert!((self.right != self.left));
}
pub fn advance_left(&mut self) -> io::Result<()> {
debug!("advance_left Vec<{},{}>, sizeof({})={}", self.left, self.right,
self.left, self.size[self.left]);
let mut left_size = self.size[self.left];
while left_size >= 0 {
let left = self.token[self.left].clone();
let len = match left {
Token::Break(b) => b.blank_space,
Token::String(_, len) => {
assert_eq!(len, left_size);
len
}
_ => 0
};
try!(self.print(left, left_size));
self.left_total += len;
if self.left == self.right {
break;
}
self.left += 1;
self.left %= self.buf_len;
left_size = self.size[self.left];
}
Ok(())
}
pub fn check_stack(&mut self, k: isize) {
if !self.scan_stack_empty {
let x = self.scan_top();
match self.token[x] {
Token::Begin(_) => {
if k > 0 {
let popped = self.scan_pop();
self.size[popped] = self.size[x] + self.right_total;
self.check_stack(k - 1);
}
}
Token::End => {
// paper says + not =, but that makes no sense.
let popped = self.scan_pop();
self.size[popped] = 1;
self.check_stack(k + 1);
}
_ => {
let popped = self.scan_pop();
self.size[popped] = self.size[x] + self.right_total;
if k > 0 {
self.check_stack(k);
}
}
}
}
}
pub fn print_newline(&mut self, amount: isize) -> io::Result<()> {
debug!("NEWLINE {}", amount);
let ret = write!(self.out, "\n");
self.pending_indentation = 0;
self.indent(amount);
return ret;
}
pub fn indent(&mut self, amount: isize) {
debug!("INDENT {}", amount);
self.pending_indentation += amount;
}
pub fn get_top(&mut self) -> PrintStackElem {
let print_stack = &mut self.print_stack;
let n = print_stack.len();
if n != 0 {
(*print_stack)[n - 1]
} else {
PrintStackElem {
offset: 0,
pbreak: PrintStackBreak::Broken(Breaks::Inconsistent)
}
}
}
pub fn print_str(&mut self, s: &str) -> io::Result<()> {
while self.pending_indentation > 0 {
try!(write!(self.out, " "));
self.pending_indentation -= 1;
}
write!(self.out, "{}", s)
}
pub fn print(&mut self, token: Token, l: isize) -> io::Result<()> {
debug!("print {} {} (remaining line space={})", tok_str(&token), l,
self.space);
debug!("{}", buf_str(&self.token,
&self.size,
self.left,
self.right,
6));
match token {
Token::Begin(b) => {
if l > self.space {
let col = self.margin - self.space + b.offset;
debug!("print Begin -> push broken block at col {}", col);
self.print_stack.push(PrintStackElem {
offset: col,
pbreak: PrintStackBreak::Broken(b.breaks)
});
} else {
debug!("print Begin -> push fitting block");
self.print_stack.push(PrintStackElem {
offset: 0,
pbreak: PrintStackBreak::Fits
});
}
Ok(())
}
Token::End => {
debug!("print End -> pop End");
let print_stack = &mut self.print_stack;
assert!((!print_stack.is_empty()));
print_stack.pop().unwrap();
Ok(())
}
Token::Break(b) => {
let top = self.get_top();
match top.pbreak {
PrintStackBreak::Fits => {
debug!("print Break({}) in fitting block", b.blank_space);
self.space -= b.blank_space;
self.indent(b.blank_space);
Ok(())
}
PrintStackBreak::Broken(Breaks::Consistent) => {
debug!("print Break({}+{}) in consistent block",
top.offset, b.offset);
let ret = self.print_newline(top.offset + b.offset);
self.space = self.margin - (top.offset + b.offset);
ret
}
PrintStackBreak::Broken(Breaks::Inconsistent) => {
if l > self.space {
debug!("print Break({}+{}) w/ newline in inconsistent",
top.offset, b.offset);
let ret = self.print_newline(top.offset + b.offset);
self.space = self.margin - (top.offset + b.offset);
ret
} else {
debug!("print Break({}) w/o newline in inconsistent",
b.blank_space);
self.indent(b.blank_space);
self.space -= b.blank_space;
Ok(())
}
}
}
}
Token::String(s, len) => {
debug!("print String({})", s);
assert_eq!(l, len);
// assert!(l <= space);
self.space -= len;
self.print_str(&s[..])
}
Token::Eof => {
// Eof should never get here.
panic!();
}
}
}
}
// Convenience functions to talk to the printer.
//
// "raw box"
pub fn rbox(p: &mut Printer, indent: usize, b: Breaks) -> io::Result<()> {
p.pretty_print(Token::Begin(BeginToken {
offset: indent as isize,
breaks: b
}))
}
pub fn ibox(p: &mut Printer, indent: usize) -> io::Result<()> {
rbox(p, indent, Breaks::Inconsistent)
}
pub fn cbox(p: &mut Printer, indent: usize) -> io::Result<()> {
rbox(p, indent, Breaks::Consistent)
}
pub fn break_offset(p: &mut Printer, n: usize, off: isize) -> io::Result<()> {
p.pretty_print(Token::Break(BreakToken {
offset: off,
blank_space: n as isize
}))
}
pub fn end(p: &mut Printer) -> io::Result<()> {
p.pretty_print(Token::End)
}
pub fn eof(p: &mut Printer) -> io::Result<()> {
p.pretty_print(Token::Eof)
}
pub fn word(p: &mut Printer, wrd: &str) -> io::Result<()> {
p.pretty_print(Token::String(/* bad */ wrd.to_string(), wrd.len() as isize))
}
pub fn huge_word(p: &mut Printer, wrd: &str) -> io::Result<()> {
p.pretty_print(Token::String(/* bad */ wrd.to_string(), SIZE_INFINITY))
}
pub fn zero_word(p: &mut Printer, wrd: &str) -> io::Result<()> {
p.pretty_print(Token::String(/* bad */ wrd.to_string(), 0))
}
pub fn spaces(p: &mut Printer, n: usize) -> io::Result<()> {
break_offset(p, n, 0)
}
pub fn zerobreak(p: &mut Printer) -> io::Result<()> {
spaces(p, 0)
}
pub fn space(p: &mut Printer) -> io::Result<()> {
spaces(p, 1)
}
pub fn hardbreak(p: &mut Printer) -> io::Result<()> {
spaces(p, SIZE_INFINITY as usize)
}
pub fn hardbreak_tok_offset(off: isize) -> Token {
Token::Break(BreakToken {offset: off, blank_space: SIZE_INFINITY})
}
pub fn hardbreak_tok() -> Token {
hardbreak_tok_offset(0)
}

File diff suppressed because it is too large Load Diff

427
src/librustc_front/util.rs Normal file
View File

@ -0,0 +1,427 @@
// Copyright 2015 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 hir;
use hir::*;
use visit::{self, Visitor, FnKind};
use syntax::ast_util;
use syntax::ast::{Ident, NodeId, DUMMY_NODE_ID};
use syntax::codemap::Span;
use syntax::ptr::P;
use syntax::owned_slice::OwnedSlice;
pub fn walk_pat<F>(pat: &Pat, mut it: F) -> bool where F: FnMut(&Pat) -> bool {
// FIXME(#19596) this is a workaround, but there should be a better way
fn walk_pat_<G>(pat: &Pat, it: &mut G) -> bool where G: FnMut(&Pat) -> bool {
if !(*it)(pat) {
return false;
}
match pat.node {
PatIdent(_, _, Some(ref p)) => walk_pat_(&**p, it),
PatStruct(_, ref fields, _) => {
fields.iter().all(|field| walk_pat_(&*field.node.pat, it))
}
PatEnum(_, Some(ref s)) | PatTup(ref s) => {
s.iter().all(|p| walk_pat_(&**p, it))
}
PatBox(ref s) | PatRegion(ref s, _) => {
walk_pat_(&**s, it)
}
PatVec(ref before, ref slice, ref after) => {
before.iter().all(|p| walk_pat_(&**p, it)) &&
slice.iter().all(|p| walk_pat_(&**p, it)) &&
after.iter().all(|p| walk_pat_(&**p, it))
}
PatWild(_) | PatLit(_) | PatRange(_, _) | PatIdent(_, _, _) |
PatEnum(_, _) | PatQPath(_, _) => {
true
}
}
}
walk_pat_(pat, &mut it)
}
pub fn binop_to_string(op: BinOp_) -> &'static str {
match op {
BiAdd => "+",
BiSub => "-",
BiMul => "*",
BiDiv => "/",
BiRem => "%",
BiAnd => "&&",
BiOr => "||",
BiBitXor => "^",
BiBitAnd => "&",
BiBitOr => "|",
BiShl => "<<",
BiShr => ">>",
BiEq => "==",
BiLt => "<",
BiLe => "<=",
BiNe => "!=",
BiGe => ">=",
BiGt => ">"
}
}
/// Returns true if the given struct def is tuple-like; i.e. that its fields
/// are unnamed.
pub fn struct_def_is_tuple_like(struct_def: &hir::StructDef) -> bool {
struct_def.ctor_id.is_some()
}
pub fn stmt_id(s: &Stmt) -> NodeId {
match s.node {
StmtDecl(_, id) => id,
StmtExpr(_, id) => id,
StmtSemi(_, id) => id,
}
}
pub fn lazy_binop(b: BinOp_) -> bool {
match b {
BiAnd => true,
BiOr => true,
_ => false
}
}
pub fn is_shift_binop(b: BinOp_) -> bool {
match b {
BiShl => true,
BiShr => true,
_ => false
}
}
pub fn is_comparison_binop(b: BinOp_) -> bool {
match b {
BiEq | BiLt | BiLe | BiNe | BiGt | BiGe =>
true,
BiAnd | BiOr | BiAdd | BiSub | BiMul | BiDiv | BiRem |
BiBitXor | BiBitAnd | BiBitOr | BiShl | BiShr =>
false,
}
}
/// Returns `true` if the binary operator takes its arguments by value
pub fn is_by_value_binop(b: BinOp_) -> bool {
!is_comparison_binop(b)
}
/// Returns `true` if the unary operator takes its argument by value
pub fn is_by_value_unop(u: UnOp) -> bool {
match u {
UnNeg | UnNot => true,
_ => false,
}
}
pub fn unop_to_string(op: UnOp) -> &'static str {
match op {
UnUniq => "box() ",
UnDeref => "*",
UnNot => "!",
UnNeg => "-",
}
}
pub struct IdVisitor<'a, O:'a> {
pub operation: &'a mut O,
pub pass_through_items: bool,
pub visited_outermost: bool,
}
impl<'a, O: ast_util::IdVisitingOperation> IdVisitor<'a, O> {
fn visit_generics_helper(&mut self, generics: &Generics) {
for type_parameter in generics.ty_params.iter() {
self.operation.visit_id(type_parameter.id)
}
for lifetime in &generics.lifetimes {
self.operation.visit_id(lifetime.lifetime.id)
}
}
}
impl<'a, 'v, O: ast_util::IdVisitingOperation> Visitor<'v> for IdVisitor<'a, O> {
fn visit_mod(&mut self,
module: &Mod,
_: Span,
node_id: NodeId) {
self.operation.visit_id(node_id);
visit::walk_mod(self, module)
}
fn visit_foreign_item(&mut self, foreign_item: &ForeignItem) {
self.operation.visit_id(foreign_item.id);
visit::walk_foreign_item(self, foreign_item)
}
fn visit_item(&mut self, item: &Item) {
if !self.pass_through_items {
if self.visited_outermost {
return
} else {
self.visited_outermost = true
}
}
self.operation.visit_id(item.id);
match item.node {
ItemUse(ref view_path) => {
match view_path.node {
ViewPathSimple(_, _) |
ViewPathGlob(_) => {}
ViewPathList(_, ref paths) => {
for path in paths {
self.operation.visit_id(path.node.id())
}
}
}
}
ItemEnum(ref enum_definition, _) => {
for variant in &enum_definition.variants {
self.operation.visit_id(variant.node.id)
}
}
_ => {}
}
visit::walk_item(self, item);
self.visited_outermost = false
}
fn visit_local(&mut self, local: &Local) {
self.operation.visit_id(local.id);
visit::walk_local(self, local)
}
fn visit_block(&mut self, block: &Block) {
self.operation.visit_id(block.id);
visit::walk_block(self, block)
}
fn visit_stmt(&mut self, statement: &Stmt) {
self.operation.visit_id(stmt_id(statement));
visit::walk_stmt(self, statement)
}
fn visit_pat(&mut self, pattern: &Pat) {
self.operation.visit_id(pattern.id);
visit::walk_pat(self, pattern)
}
fn visit_expr(&mut self, expression: &Expr) {
self.operation.visit_id(expression.id);
visit::walk_expr(self, expression)
}
fn visit_ty(&mut self, typ: &Ty) {
self.operation.visit_id(typ.id);
visit::walk_ty(self, typ)
}
fn visit_generics(&mut self, generics: &Generics) {
self.visit_generics_helper(generics);
visit::walk_generics(self, generics)
}
fn visit_fn(&mut self,
function_kind: FnKind<'v>,
function_declaration: &'v FnDecl,
block: &'v Block,
span: Span,
node_id: NodeId) {
if !self.pass_through_items {
match function_kind {
FnKind::Method(..) if self.visited_outermost => return,
FnKind::Method(..) => self.visited_outermost = true,
_ => {}
}
}
self.operation.visit_id(node_id);
match function_kind {
FnKind::ItemFn(_, generics, _, _, _, _) => {
self.visit_generics_helper(generics)
}
FnKind::Method(_, sig, _) => {
self.visit_generics_helper(&sig.generics)
}
FnKind::Closure => {}
}
for argument in &function_declaration.inputs {
self.operation.visit_id(argument.id)
}
visit::walk_fn(self,
function_kind,
function_declaration,
block,
span);
if !self.pass_through_items {
if let FnKind::Method(..) = function_kind {
self.visited_outermost = false;
}
}
}
fn visit_struct_field(&mut self, struct_field: &StructField) {
self.operation.visit_id(struct_field.node.id);
visit::walk_struct_field(self, struct_field)
}
fn visit_struct_def(&mut self,
struct_def: &StructDef,
_: Ident,
_: &hir::Generics,
id: NodeId) {
self.operation.visit_id(id);
struct_def.ctor_id.map(|ctor_id| self.operation.visit_id(ctor_id));
visit::walk_struct_def(self, struct_def);
}
fn visit_trait_item(&mut self, ti: &hir::TraitItem) {
self.operation.visit_id(ti.id);
visit::walk_trait_item(self, ti);
}
fn visit_impl_item(&mut self, ii: &hir::ImplItem) {
self.operation.visit_id(ii.id);
visit::walk_impl_item(self, ii);
}
fn visit_lifetime_ref(&mut self, lifetime: &Lifetime) {
self.operation.visit_id(lifetime.id);
}
fn visit_lifetime_def(&mut self, def: &LifetimeDef) {
self.visit_lifetime_ref(&def.lifetime);
}
fn visit_trait_ref(&mut self, trait_ref: &TraitRef) {
self.operation.visit_id(trait_ref.ref_id);
visit::walk_trait_ref(self, trait_ref);
}
}
/// Computes the id range for a single fn body, ignoring nested items.
pub fn compute_id_range_for_fn_body(fk: FnKind,
decl: &FnDecl,
body: &Block,
sp: Span,
id: NodeId)
-> ast_util::IdRange
{
let mut visitor = ast_util::IdRangeComputingVisitor {
result: ast_util::IdRange::max()
};
let mut id_visitor = IdVisitor {
operation: &mut visitor,
pass_through_items: false,
visited_outermost: false,
};
id_visitor.visit_fn(fk, decl, body, sp, id);
id_visitor.operation.result
}
/// Returns true if this literal is a string and false otherwise.
pub fn lit_is_str(lit: &Lit) -> bool {
match lit.node {
LitStr(..) => true,
_ => false,
}
}
pub fn is_path(e: P<Expr>) -> bool {
match e.node { ExprPath(..) => true, _ => false }
}
/// Get a string representation of a signed int type, with its value.
/// We want to avoid "45int" and "-3int" in favor of "45" and "-3"
pub fn int_ty_to_string(t: IntTy, val: Option<i64>) -> String {
let s = match t {
TyIs => "isize",
TyI8 => "i8",
TyI16 => "i16",
TyI32 => "i32",
TyI64 => "i64"
};
match val {
// cast to a u64 so we can correctly print INT64_MIN. All integral types
// are parsed as u64, so we wouldn't want to print an extra negative
// sign.
Some(n) => format!("{}{}", n as u64, s),
None => s.to_string()
}
}
/// Get a string representation of an unsigned int type, with its value.
/// We want to avoid "42u" in favor of "42us". "42uint" is right out.
pub fn uint_ty_to_string(t: UintTy, val: Option<u64>) -> String {
let s = match t {
TyUs => "usize",
TyU8 => "u8",
TyU16 => "u16",
TyU32 => "u32",
TyU64 => "u64"
};
match val {
Some(n) => format!("{}{}", n, s),
None => s.to_string()
}
}
pub fn float_ty_to_string(t: FloatTy) -> String {
match t {
TyF32 => "f32".to_string(),
TyF64 => "f64".to_string(),
}
}
pub fn empty_generics() -> Generics {
Generics {
lifetimes: Vec::new(),
ty_params: OwnedSlice::empty(),
where_clause: WhereClause {
id: DUMMY_NODE_ID,
predicates: Vec::new(),
}
}
}
// convert a span and an identifier to the corresponding
// 1-segment path
pub fn ident_to_path(s: Span, identifier: Ident) -> Path {
hir::Path {
span: s,
global: false,
segments: vec!(
hir::PathSegment {
identifier: identifier,
parameters: hir::AngleBracketedParameters(hir::AngleBracketedParameterData {
lifetimes: Vec::new(),
types: OwnedSlice::empty(),
bindings: OwnedSlice::empty(),
})
}
),
}
}

841
src/librustc_front/visit.rs Normal file
View File

@ -0,0 +1,841 @@
// Copyright 2012-2015 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.
//! HIR walker. Each overridden visit method has full control over what
//! happens with its node, it can do its own traversal of the node's children,
//! call `visit::walk_*` to apply the default traversal algorithm, or prevent
//! deeper traversal by doing nothing.
//!
//! Note: it is an important invariant that the default visitor walks the body
//! of a function in "execution order" (more concretely, reverse post-order
//! with respect to the CFG implied by the AST), meaning that if AST node A may
//! execute before AST node B, then A is visited first. The borrow checker in
//! particular relies on this property.
//!
//! Note: walking an AST before macro expansion is probably a bad idea. For
//! instance, a walker looking for item names in a module will miss all of
//! those that are created by the expansion of a macro.
use syntax::abi::Abi;
use syntax::ast::{Ident, NodeId, CRATE_NODE_ID, Name};
use hir::*;
use hir;
use syntax::codemap::Span;
use syntax::ptr::P;
use syntax::owned_slice::OwnedSlice;
#[derive(Copy, Clone, PartialEq, Eq)]
pub enum FnKind<'a> {
/// fn foo() or extern "Abi" fn foo()
ItemFn(Ident, &'a Generics, Unsafety, Constness, Abi, Visibility),
/// fn foo(&self)
Method(Ident, &'a MethodSig, Option<Visibility>),
/// |x, y| ...
/// proc(x, y) ...
Closure,
}
/// Each method of the Visitor trait is a hook to be potentially
/// overridden. Each method's default implementation recursively visits
/// the substructure of the input via the corresponding `walk` method;
/// e.g. the `visit_mod` method by default calls `visit::walk_mod`.
///
/// If you want to ensure that your code handles every variant
/// explicitly, you need to override each method. (And you also need
/// to monitor future changes to `Visitor` in case a new method with a
/// new default implementation gets introduced.)
pub trait Visitor<'v> : Sized {
fn visit_name(&mut self, _span: Span, _name: Name) {
// Nothing to do.
}
fn visit_ident(&mut self, span: Span, ident: Ident) {
self.visit_name(span, ident.name);
}
fn visit_mod(&mut self, m: &'v Mod, _s: Span, _n: NodeId) { walk_mod(self, m) }
fn visit_foreign_item(&mut self, i: &'v ForeignItem) { walk_foreign_item(self, i) }
fn visit_item(&mut self, i: &'v Item) { walk_item(self, i) }
fn visit_local(&mut self, l: &'v Local) { walk_local(self, l) }
fn visit_block(&mut self, b: &'v Block) { walk_block(self, b) }
fn visit_stmt(&mut self, s: &'v Stmt) { walk_stmt(self, s) }
fn visit_arm(&mut self, a: &'v Arm) { walk_arm(self, a) }
fn visit_pat(&mut self, p: &'v Pat) { walk_pat(self, p) }
fn visit_decl(&mut self, d: &'v Decl) { walk_decl(self, d) }
fn visit_expr(&mut self, ex: &'v Expr) { walk_expr(self, ex) }
fn visit_expr_post(&mut self, _ex: &'v Expr) { }
fn visit_ty(&mut self, t: &'v Ty) { walk_ty(self, t) }
fn visit_generics(&mut self, g: &'v Generics) { walk_generics(self, g) }
fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v FnDecl, b: &'v Block, s: Span, _: NodeId) {
walk_fn(self, fk, fd, b, s)
}
fn visit_trait_item(&mut self, ti: &'v TraitItem) { walk_trait_item(self, ti) }
fn visit_impl_item(&mut self, ii: &'v ImplItem) { walk_impl_item(self, ii) }
fn visit_trait_ref(&mut self, t: &'v TraitRef) { walk_trait_ref(self, t) }
fn visit_ty_param_bound(&mut self, bounds: &'v TyParamBound) {
walk_ty_param_bound(self, bounds)
}
fn visit_poly_trait_ref(&mut self, t: &'v PolyTraitRef, m: &'v TraitBoundModifier) {
walk_poly_trait_ref(self, t, m)
}
fn visit_struct_def(&mut self, s: &'v StructDef, _: Ident, _: &'v Generics, _: NodeId) {
walk_struct_def(self, s)
}
fn visit_struct_field(&mut self, s: &'v StructField) { walk_struct_field(self, s) }
fn visit_enum_def(&mut self, enum_definition: &'v EnumDef,
generics: &'v Generics) {
walk_enum_def(self, enum_definition, generics)
}
fn visit_variant(&mut self, v: &'v Variant, g: &'v Generics) { walk_variant(self, v, g) }
/// Visits an optional reference to a lifetime. The `span` is the span of some surrounding
/// reference should opt_lifetime be None.
fn visit_opt_lifetime_ref(&mut self,
_span: Span,
opt_lifetime: &'v Option<Lifetime>) {
match *opt_lifetime {
Some(ref l) => self.visit_lifetime_ref(l),
None => ()
}
}
fn visit_lifetime_bound(&mut self, lifetime: &'v Lifetime) {
walk_lifetime_bound(self, lifetime)
}
fn visit_lifetime_ref(&mut self, lifetime: &'v Lifetime) {
walk_lifetime_ref(self, lifetime)
}
fn visit_lifetime_def(&mut self, lifetime: &'v LifetimeDef) {
walk_lifetime_def(self, lifetime)
}
fn visit_explicit_self(&mut self, es: &'v ExplicitSelf) {
walk_explicit_self(self, es)
}
fn visit_path(&mut self, path: &'v Path, _id: NodeId) {
walk_path(self, path)
}
fn visit_path_segment(&mut self, path_span: Span, path_segment: &'v PathSegment) {
walk_path_segment(self, path_span, path_segment)
}
fn visit_path_parameters(&mut self, path_span: Span, path_parameters: &'v PathParameters) {
walk_path_parameters(self, path_span, path_parameters)
}
fn visit_assoc_type_binding(&mut self, type_binding: &'v TypeBinding) {
walk_assoc_type_binding(self, type_binding)
}
fn visit_attribute(&mut self, _attr: &'v Attribute) {}
}
pub fn walk_crate<'v, V: Visitor<'v>>(visitor: &mut V, krate: &'v Crate) {
visitor.visit_mod(&krate.module, krate.span, CRATE_NODE_ID);
for attr in &krate.attrs {
visitor.visit_attribute(attr);
}
}
pub fn walk_mod<'v, V: Visitor<'v>>(visitor: &mut V, module: &'v Mod) {
for item in &module.items {
visitor.visit_item(&**item)
}
}
pub fn walk_local<'v, V: Visitor<'v>>(visitor: &mut V, local: &'v Local) {
visitor.visit_pat(&*local.pat);
walk_ty_opt(visitor, &local.ty);
walk_expr_opt(visitor, &local.init);
}
pub fn walk_lifetime_def<'v, V: Visitor<'v>>(visitor: &mut V,
lifetime_def: &'v LifetimeDef) {
visitor.visit_name(lifetime_def.lifetime.span, lifetime_def.lifetime.name);
for bound in &lifetime_def.bounds {
visitor.visit_lifetime_bound(bound);
}
}
pub fn walk_lifetime_bound<'v, V: Visitor<'v>>(visitor: &mut V,
lifetime_ref: &'v Lifetime) {
visitor.visit_lifetime_ref(lifetime_ref)
}
pub fn walk_lifetime_ref<'v, V: Visitor<'v>>(visitor: &mut V,
lifetime_ref: &'v Lifetime) {
visitor.visit_name(lifetime_ref.span, lifetime_ref.name)
}
pub fn walk_explicit_self<'v, V: Visitor<'v>>(visitor: &mut V,
explicit_self: &'v ExplicitSelf) {
match explicit_self.node {
SelfStatic | SelfValue(_) => {},
SelfRegion(ref lifetime, _, _) => {
visitor.visit_opt_lifetime_ref(explicit_self.span, lifetime)
}
SelfExplicit(ref typ, _) => visitor.visit_ty(&**typ),
}
}
pub fn walk_poly_trait_ref<'v, V>(visitor: &mut V,
trait_ref: &'v PolyTraitRef,
_modifier: &'v TraitBoundModifier)
where V: Visitor<'v>
{
walk_lifetime_decls_helper(visitor, &trait_ref.bound_lifetimes);
visitor.visit_trait_ref(&trait_ref.trait_ref);
}
pub fn walk_trait_ref<'v,V>(visitor: &mut V,
trait_ref: &'v TraitRef)
where V: Visitor<'v>
{
visitor.visit_path(&trait_ref.path, trait_ref.ref_id)
}
pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
visitor.visit_ident(item.span, item.ident);
match item.node {
ItemExternCrate(..) => {}
ItemUse(ref vp) => {
match vp.node {
ViewPathSimple(ident, ref path) => {
visitor.visit_ident(vp.span, ident);
visitor.visit_path(path, item.id);
}
ViewPathGlob(ref path) => {
visitor.visit_path(path, item.id);
}
ViewPathList(ref prefix, ref list) => {
for id in list {
match id.node {
PathListIdent { name, .. } => {
visitor.visit_ident(id.span, name);
}
PathListMod { .. } => ()
}
}
// Note that the `prefix` here is not a complete
// path, so we don't use `visit_path`.
walk_path(visitor, prefix);
}
}
}
ItemStatic(ref typ, _, ref expr) |
ItemConst(ref typ, ref expr) => {
visitor.visit_ty(&**typ);
visitor.visit_expr(&**expr);
}
ItemFn(ref declaration, unsafety, constness, abi, ref generics, ref body) => {
visitor.visit_fn(FnKind::ItemFn(item.ident, generics, unsafety,
constness, abi, item.vis),
&**declaration,
&**body,
item.span,
item.id)
}
ItemMod(ref module) => {
visitor.visit_mod(module, item.span, item.id)
}
ItemForeignMod(ref foreign_module) => {
for foreign_item in &foreign_module.items {
visitor.visit_foreign_item(&**foreign_item)
}
}
ItemTy(ref typ, ref type_parameters) => {
visitor.visit_ty(&**typ);
visitor.visit_generics(type_parameters)
}
ItemEnum(ref enum_definition, ref type_parameters) => {
visitor.visit_generics(type_parameters);
visitor.visit_enum_def(enum_definition, type_parameters)
}
ItemDefaultImpl(_, ref trait_ref) => {
visitor.visit_trait_ref(trait_ref)
}
ItemImpl(_, _,
ref type_parameters,
ref trait_reference,
ref typ,
ref impl_items) => {
visitor.visit_generics(type_parameters);
match *trait_reference {
Some(ref trait_reference) => visitor.visit_trait_ref(trait_reference),
None => ()
}
visitor.visit_ty(&**typ);
for impl_item in impl_items {
visitor.visit_impl_item(impl_item);
}
}
ItemStruct(ref struct_definition, ref generics) => {
visitor.visit_generics(generics);
visitor.visit_struct_def(&**struct_definition,
item.ident,
generics,
item.id)
}
ItemTrait(_, ref generics, ref bounds, ref methods) => {
visitor.visit_generics(generics);
walk_ty_param_bounds_helper(visitor, bounds);
for method in methods {
visitor.visit_trait_item(method)
}
}
}
for attr in &item.attrs {
visitor.visit_attribute(attr);
}
}
pub fn walk_enum_def<'v, V: Visitor<'v>>(visitor: &mut V,
enum_definition: &'v EnumDef,
generics: &'v Generics) {
for variant in &enum_definition.variants {
visitor.visit_variant(&**variant, generics);
}
}
pub fn walk_variant<'v, V: Visitor<'v>>(visitor: &mut V,
variant: &'v Variant,
generics: &'v Generics) {
visitor.visit_ident(variant.span, variant.node.name);
match variant.node.kind {
TupleVariantKind(ref variant_arguments) => {
for variant_argument in variant_arguments {
visitor.visit_ty(&*variant_argument.ty)
}
}
StructVariantKind(ref struct_definition) => {
visitor.visit_struct_def(&**struct_definition,
variant.node.name,
generics,
variant.node.id)
}
}
match variant.node.disr_expr {
Some(ref expr) => visitor.visit_expr(&**expr),
None => ()
}
for attr in &variant.node.attrs {
visitor.visit_attribute(attr);
}
}
pub fn skip_ty<'v, V: Visitor<'v>>(_: &mut V, _: &'v Ty) {
// Empty!
}
pub fn walk_ty_opt<'v, V: Visitor<'v>>(visitor: &mut V, optional_type: &'v Option<P<Ty>>) {
match *optional_type {
Some(ref ty) => visitor.visit_ty(&**ty),
None => ()
}
}
pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) {
match typ.node {
TyVec(ref ty) | TyParen(ref ty) => {
visitor.visit_ty(&**ty)
}
TyPtr(ref mutable_type) => {
visitor.visit_ty(&*mutable_type.ty)
}
TyRptr(ref lifetime, ref mutable_type) => {
visitor.visit_opt_lifetime_ref(typ.span, lifetime);
visitor.visit_ty(&*mutable_type.ty)
}
TyTup(ref tuple_element_types) => {
for tuple_element_type in tuple_element_types {
visitor.visit_ty(&**tuple_element_type)
}
}
TyBareFn(ref function_declaration) => {
for argument in &function_declaration.decl.inputs {
visitor.visit_ty(&*argument.ty)
}
walk_fn_ret_ty(visitor, &function_declaration.decl.output);
walk_lifetime_decls_helper(visitor, &function_declaration.lifetimes);
}
TyPath(ref maybe_qself, ref path) => {
if let Some(ref qself) = *maybe_qself {
visitor.visit_ty(&qself.ty);
}
visitor.visit_path(path, typ.id);
}
TyObjectSum(ref ty, ref bounds) => {
visitor.visit_ty(&**ty);
walk_ty_param_bounds_helper(visitor, bounds);
}
TyFixedLengthVec(ref ty, ref expression) => {
visitor.visit_ty(&**ty);
visitor.visit_expr(&**expression)
}
TyPolyTraitRef(ref bounds) => {
walk_ty_param_bounds_helper(visitor, bounds)
}
TyTypeof(ref expression) => {
visitor.visit_expr(&**expression)
}
TyInfer => {}
}
}
pub fn walk_lifetime_decls_helper<'v, V: Visitor<'v>>(visitor: &mut V,
lifetimes: &'v Vec<LifetimeDef>) {
for l in lifetimes {
visitor.visit_lifetime_def(l);
}
}
pub fn walk_path<'v, V: Visitor<'v>>(visitor: &mut V, path: &'v Path) {
for segment in &path.segments {
visitor.visit_path_segment(path.span, segment);
}
}
pub fn walk_path_segment<'v, V: Visitor<'v>>(visitor: &mut V,
path_span: Span,
segment: &'v PathSegment) {
visitor.visit_ident(path_span, segment.identifier);
visitor.visit_path_parameters(path_span, &segment.parameters);
}
pub fn walk_path_parameters<'v, V: Visitor<'v>>(visitor: &mut V,
_path_span: Span,
path_parameters: &'v PathParameters) {
match *path_parameters {
hir::AngleBracketedParameters(ref data) => {
for typ in data.types.iter() {
visitor.visit_ty(&**typ);
}
for lifetime in &data.lifetimes {
visitor.visit_lifetime_ref(lifetime);
}
for binding in data.bindings.iter() {
visitor.visit_assoc_type_binding(&**binding);
}
}
hir::ParenthesizedParameters(ref data) => {
for typ in &data.inputs {
visitor.visit_ty(&**typ);
}
if let Some(ref typ) = data.output {
visitor.visit_ty(&**typ);
}
}
}
}
pub fn walk_assoc_type_binding<'v, V: Visitor<'v>>(visitor: &mut V,
type_binding: &'v TypeBinding) {
visitor.visit_ident(type_binding.span, type_binding.ident);
visitor.visit_ty(&*type_binding.ty);
}
pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat) {
match pattern.node {
PatEnum(ref path, ref children) => {
visitor.visit_path(path, pattern.id);
if let Some(ref children) = *children {
for child in children {
visitor.visit_pat(&*child)
}
}
}
PatQPath(ref qself, ref path) => {
visitor.visit_ty(&qself.ty);
visitor.visit_path(path, pattern.id)
}
PatStruct(ref path, ref fields, _) => {
visitor.visit_path(path, pattern.id);
for field in fields {
visitor.visit_pat(&*field.node.pat)
}
}
PatTup(ref tuple_elements) => {
for tuple_element in tuple_elements {
visitor.visit_pat(&**tuple_element)
}
}
PatBox(ref subpattern) |
PatRegion(ref subpattern, _) => {
visitor.visit_pat(&**subpattern)
}
PatIdent(_, ref pth1, ref optional_subpattern) => {
visitor.visit_ident(pth1.span, pth1.node);
match *optional_subpattern {
None => {}
Some(ref subpattern) => visitor.visit_pat(&**subpattern),
}
}
PatLit(ref expression) => visitor.visit_expr(&**expression),
PatRange(ref lower_bound, ref upper_bound) => {
visitor.visit_expr(&**lower_bound);
visitor.visit_expr(&**upper_bound)
}
PatWild(_) => (),
PatVec(ref prepattern, ref slice_pattern, ref postpatterns) => {
for prepattern in prepattern {
visitor.visit_pat(&**prepattern)
}
if let Some(ref slice_pattern) = *slice_pattern {
visitor.visit_pat(&**slice_pattern)
}
for postpattern in postpatterns {
visitor.visit_pat(&**postpattern)
}
}
}
}
pub fn walk_foreign_item<'v, V: Visitor<'v>>(visitor: &mut V,
foreign_item: &'v ForeignItem) {
visitor.visit_ident(foreign_item.span, foreign_item.ident);
match foreign_item.node {
ForeignItemFn(ref function_declaration, ref generics) => {
walk_fn_decl(visitor, &**function_declaration);
visitor.visit_generics(generics)
}
ForeignItemStatic(ref typ, _) => visitor.visit_ty(&**typ),
}
for attr in &foreign_item.attrs {
visitor.visit_attribute(attr);
}
}
pub fn walk_ty_param_bounds_helper<'v, V: Visitor<'v>>(visitor: &mut V,
bounds: &'v OwnedSlice<TyParamBound>) {
for bound in bounds.iter() {
visitor.visit_ty_param_bound(bound)
}
}
pub fn walk_ty_param_bound<'v, V: Visitor<'v>>(visitor: &mut V,
bound: &'v TyParamBound) {
match *bound {
TraitTyParamBound(ref typ, ref modifier) => {
visitor.visit_poly_trait_ref(typ, modifier);
}
RegionTyParamBound(ref lifetime) => {
visitor.visit_lifetime_bound(lifetime);
}
}
}
pub fn walk_generics<'v, V: Visitor<'v>>(visitor: &mut V, generics: &'v Generics) {
for param in generics.ty_params.iter() {
visitor.visit_ident(param.span, param.ident);
walk_ty_param_bounds_helper(visitor, &param.bounds);
walk_ty_opt(visitor, &param.default);
}
walk_lifetime_decls_helper(visitor, &generics.lifetimes);
for predicate in &generics.where_clause.predicates {
match predicate {
&hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate{ref bounded_ty,
ref bounds,
..}) => {
visitor.visit_ty(&**bounded_ty);
walk_ty_param_bounds_helper(visitor, bounds);
}
&hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate{ref lifetime,
ref bounds,
..}) => {
visitor.visit_lifetime_ref(lifetime);
for bound in bounds {
visitor.visit_lifetime_ref(bound);
}
}
&hir::WherePredicate::EqPredicate(hir::WhereEqPredicate{id,
ref path,
ref ty,
..}) => {
visitor.visit_path(path, id);
visitor.visit_ty(&**ty);
}
}
}
}
pub fn walk_fn_ret_ty<'v, V: Visitor<'v>>(visitor: &mut V, ret_ty: &'v FunctionRetTy) {
if let Return(ref output_ty) = *ret_ty {
visitor.visit_ty(&**output_ty)
}
}
pub fn walk_fn_decl<'v, V: Visitor<'v>>(visitor: &mut V, function_declaration: &'v FnDecl) {
for argument in &function_declaration.inputs {
visitor.visit_pat(&*argument.pat);
visitor.visit_ty(&*argument.ty)
}
walk_fn_ret_ty(visitor, &function_declaration.output)
}
pub fn walk_fn<'v, V: Visitor<'v>>(visitor: &mut V,
function_kind: FnKind<'v>,
function_declaration: &'v FnDecl,
function_body: &'v Block,
_span: Span) {
walk_fn_decl(visitor, function_declaration);
match function_kind {
FnKind::ItemFn(_, generics, _, _, _, _) => {
visitor.visit_generics(generics);
}
FnKind::Method(_, sig, _) => {
visitor.visit_generics(&sig.generics);
visitor.visit_explicit_self(&sig.explicit_self);
}
FnKind::Closure(..) => {}
}
visitor.visit_block(function_body)
}
pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_item: &'v TraitItem) {
visitor.visit_ident(trait_item.span, trait_item.ident);
for attr in &trait_item.attrs {
visitor.visit_attribute(attr);
}
match trait_item.node {
ConstTraitItem(ref ty, ref default) => {
visitor.visit_ty(ty);
if let Some(ref expr) = *default {
visitor.visit_expr(expr);
}
}
MethodTraitItem(ref sig, None) => {
visitor.visit_explicit_self(&sig.explicit_self);
visitor.visit_generics(&sig.generics);
walk_fn_decl(visitor, &sig.decl);
}
MethodTraitItem(ref sig, Some(ref body)) => {
visitor.visit_fn(FnKind::Method(trait_item.ident, sig, None), &sig.decl,
body, trait_item.span, trait_item.id);
}
TypeTraitItem(ref bounds, ref default) => {
walk_ty_param_bounds_helper(visitor, bounds);
walk_ty_opt(visitor, default);
}
}
}
pub fn walk_impl_item<'v, V: Visitor<'v>>(visitor: &mut V, impl_item: &'v ImplItem) {
visitor.visit_ident(impl_item.span, impl_item.ident);
for attr in &impl_item.attrs {
visitor.visit_attribute(attr);
}
match impl_item.node {
ConstImplItem(ref ty, ref expr) => {
visitor.visit_ty(ty);
visitor.visit_expr(expr);
}
MethodImplItem(ref sig, ref body) => {
visitor.visit_fn(FnKind::Method(impl_item.ident, sig, Some(impl_item.vis)), &sig.decl,
body, impl_item.span, impl_item.id);
}
TypeImplItem(ref ty) => {
visitor.visit_ty(ty);
}
}
}
pub fn walk_struct_def<'v, V: Visitor<'v>>(visitor: &mut V,
struct_definition: &'v StructDef) {
for field in &struct_definition.fields {
visitor.visit_struct_field(field)
}
}
pub fn walk_struct_field<'v, V: Visitor<'v>>(visitor: &mut V,
struct_field: &'v StructField) {
if let NamedField(name, _) = struct_field.node.kind {
visitor.visit_ident(struct_field.span, name);
}
visitor.visit_ty(&*struct_field.node.ty);
for attr in &struct_field.node.attrs {
visitor.visit_attribute(attr);
}
}
pub fn walk_block<'v, V: Visitor<'v>>(visitor: &mut V, block: &'v Block) {
for statement in &block.stmts {
visitor.visit_stmt(&**statement)
}
walk_expr_opt(visitor, &block.expr)
}
pub fn walk_stmt<'v, V: Visitor<'v>>(visitor: &mut V, statement: &'v Stmt) {
match statement.node {
StmtDecl(ref declaration, _) => visitor.visit_decl(&**declaration),
StmtExpr(ref expression, _) | StmtSemi(ref expression, _) => {
visitor.visit_expr(&**expression)
}
}
}
pub fn walk_decl<'v, V: Visitor<'v>>(visitor: &mut V, declaration: &'v Decl) {
match declaration.node {
DeclLocal(ref local) => visitor.visit_local(&**local),
DeclItem(ref item) => visitor.visit_item(&**item),
}
}
pub fn walk_expr_opt<'v, V: Visitor<'v>>(visitor: &mut V,
optional_expression: &'v Option<P<Expr>>) {
match *optional_expression {
None => {}
Some(ref expression) => visitor.visit_expr(&**expression),
}
}
pub fn walk_exprs<'v, V: Visitor<'v>>(visitor: &mut V, expressions: &'v [P<Expr>]) {
for expression in expressions {
visitor.visit_expr(&**expression)
}
}
pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
match expression.node {
ExprBox(ref place, ref subexpression) => {
place.as_ref().map(|e|visitor.visit_expr(&**e));
visitor.visit_expr(&**subexpression)
}
ExprVec(ref subexpressions) => {
walk_exprs(visitor, subexpressions)
}
ExprRepeat(ref element, ref count) => {
visitor.visit_expr(&**element);
visitor.visit_expr(&**count)
}
ExprStruct(ref path, ref fields, ref optional_base) => {
visitor.visit_path(path, expression.id);
for field in fields {
visitor.visit_expr(&*field.expr)
}
walk_expr_opt(visitor, optional_base)
}
ExprTup(ref subexpressions) => {
for subexpression in subexpressions {
visitor.visit_expr(&**subexpression)
}
}
ExprCall(ref callee_expression, ref arguments) => {
for argument in arguments {
visitor.visit_expr(&**argument)
}
visitor.visit_expr(&**callee_expression)
}
ExprMethodCall(_, ref types, ref arguments) => {
walk_exprs(visitor, arguments);
for typ in types {
visitor.visit_ty(&**typ)
}
}
ExprBinary(_, ref left_expression, ref right_expression) => {
visitor.visit_expr(&**left_expression);
visitor.visit_expr(&**right_expression)
}
ExprAddrOf(_, ref subexpression) | ExprUnary(_, ref subexpression) => {
visitor.visit_expr(&**subexpression)
}
ExprLit(_) => {}
ExprCast(ref subexpression, ref typ) => {
visitor.visit_expr(&**subexpression);
visitor.visit_ty(&**typ)
}
ExprIf(ref head_expression, ref if_block, ref optional_else) => {
visitor.visit_expr(&**head_expression);
visitor.visit_block(&**if_block);
walk_expr_opt(visitor, optional_else)
}
ExprWhile(ref subexpression, ref block, _) => {
visitor.visit_expr(&**subexpression);
visitor.visit_block(&**block)
}
ExprLoop(ref block, _) => visitor.visit_block(&**block),
ExprMatch(ref subexpression, ref arms, _) => {
visitor.visit_expr(&**subexpression);
for arm in arms {
visitor.visit_arm(arm)
}
}
ExprClosure(_, ref function_declaration, ref body) => {
visitor.visit_fn(FnKind::Closure,
&**function_declaration,
&**body,
expression.span,
expression.id)
}
ExprBlock(ref block) => visitor.visit_block(&**block),
ExprAssign(ref left_hand_expression, ref right_hand_expression) => {
visitor.visit_expr(&**right_hand_expression);
visitor.visit_expr(&**left_hand_expression)
}
ExprAssignOp(_, ref left_expression, ref right_expression) => {
visitor.visit_expr(&**right_expression);
visitor.visit_expr(&**left_expression)
}
ExprField(ref subexpression, _) => {
visitor.visit_expr(&**subexpression);
}
ExprTupField(ref subexpression, _) => {
visitor.visit_expr(&**subexpression);
}
ExprIndex(ref main_expression, ref index_expression) => {
visitor.visit_expr(&**main_expression);
visitor.visit_expr(&**index_expression)
}
ExprRange(ref start, ref end) => {
walk_expr_opt(visitor, start);
walk_expr_opt(visitor, end)
}
ExprPath(ref maybe_qself, ref path) => {
if let Some(ref qself) = *maybe_qself {
visitor.visit_ty(&qself.ty);
}
visitor.visit_path(path, expression.id)
}
ExprBreak(_) | ExprAgain(_) => {}
ExprRet(ref optional_expression) => {
walk_expr_opt(visitor, optional_expression)
}
ExprParen(ref subexpression) => {
visitor.visit_expr(&**subexpression)
}
ExprInlineAsm(ref ia) => {
for input in &ia.inputs {
let (_, ref input) = *input;
visitor.visit_expr(&**input)
}
for output in &ia.outputs {
let (_, ref output, _) = *output;
visitor.visit_expr(&**output)
}
}
}
visitor.visit_expr_post(expression)
}
pub fn walk_arm<'v, V: Visitor<'v>>(visitor: &mut V, arm: &'v Arm) {
for pattern in &arm.pats {
visitor.visit_pat(&**pattern)
}
walk_expr_opt(visitor, &arm.guard);
visitor.visit_expr(&*arm.body);
for attr in &arm.attrs {
visitor.visit_attribute(attr);
}
}

View File

@ -35,7 +35,7 @@ use middle::subst::Substs;
use middle::ty::{self, Ty};
use middle::const_eval::{eval_const_expr_partial, ConstVal};
use middle::const_eval::EvalHint::ExprTypeChecked;
use rustc::ast_map;
use rustc::front::map as hir_map;
use util::nodemap::{FnvHashMap, FnvHashSet, NodeSet};
use lint::{Level, Context, LintPass, LintArray, Lint};
@ -53,6 +53,14 @@ use syntax::ast::{TyIs, TyUs, TyI8, TyU8, TyI16, TyU16, TyI32, TyU32, TyI64, TyU
use syntax::ptr::P;
use syntax::visit::{self, FnKind, Visitor};
use rustc_front::lowering::{lower_expr, lower_block, lower_item, lower_path, lower_pat,
lower_trait_ref};
use rustc_front::hir;
use rustc_front::attr as front_attr;
use rustc_front::attr::AttrMetaMethods as FrontAttrMetaMethods;
use rustc_front::visit::Visitor as HirVisitor;
use rustc_front::visit as hir_visit;
// hardwired lints from librustc
pub use lint::builtin::*;
@ -129,7 +137,7 @@ impl LintPass for TypeLimits {
check_unsigned_negation_feature(cx, e.span);
},
ast::LitInt(_, ast::UnsuffixedIntLit(_)) => {
if let ty::TyUint(_) = cx.tcx.expr_ty(e).sty {
if let ty::TyUint(_) = cx.tcx.node_id_to_type(e.id).sty {
check_unsigned_negation_feature(cx, e.span);
}
},
@ -137,7 +145,7 @@ impl LintPass for TypeLimits {
}
},
_ => {
let t = cx.tcx.expr_ty(&**expr);
let t = cx.tcx.node_id_to_type(expr.id);
match t.sty {
ty::TyUint(_) => {
check_unsigned_negation_feature(cx, e.span);
@ -161,7 +169,7 @@ impl LintPass for TypeLimits {
}
if is_shift_binop(binop.node) {
let opt_ty_bits = match cx.tcx.expr_ty(&**l).sty {
let opt_ty_bits = match cx.tcx.node_id_to_type(l.id).sty {
ty::TyInt(t) => Some(int_ty_bits(t, cx.sess().target.int_type)),
ty::TyUint(t) => Some(uint_ty_bits(t, cx.sess().target.uint_type)),
_ => None
@ -172,7 +180,8 @@ impl LintPass for TypeLimits {
if let ast::LitInt(shift, _) = lit.node { shift >= bits }
else { false }
} else {
match eval_const_expr_partial(cx.tcx, &**r, ExprTypeChecked) {
let r = lower_expr(r);
match eval_const_expr_partial(cx.tcx, &r, ExprTypeChecked) {
Ok(ConstVal::Int(shift)) => { shift as u64 >= bits },
Ok(ConstVal::Uint(shift)) => { shift >= bits },
_ => { false }
@ -186,12 +195,12 @@ impl LintPass for TypeLimits {
}
},
ast::ExprLit(ref lit) => {
match cx.tcx.expr_ty(e).sty {
match cx.tcx.node_id_to_type(e.id).sty {
ty::TyInt(t) => {
match lit.node {
ast::LitInt(v, ast::SignedIntLit(_, ast::Plus)) |
ast::LitInt(v, ast::UnsuffixedIntLit(ast::Plus)) => {
let int_type = if let ast::TyIs = t {
let int_type = if let hir::TyIs = t {
cx.sess().target.int_type
} else {
t
@ -212,7 +221,7 @@ impl LintPass for TypeLimits {
};
},
ty::TyUint(t) => {
let uint_type = if let ast::TyUs = t {
let uint_type = if let hir::TyUs = t {
cx.sess().target.uint_type
} else {
t
@ -275,50 +284,50 @@ impl LintPass for TypeLimits {
// for isize & usize, be conservative with the warnings, so that the
// warnings are consistent between 32- and 64-bit platforms
fn int_ty_range(int_ty: ast::IntTy) -> (i64, i64) {
fn int_ty_range(int_ty: hir::IntTy) -> (i64, i64) {
match int_ty {
ast::TyIs => (i64::MIN, i64::MAX),
ast::TyI8 => (i8::MIN as i64, i8::MAX as i64),
ast::TyI16 => (i16::MIN as i64, i16::MAX as i64),
ast::TyI32 => (i32::MIN as i64, i32::MAX as i64),
ast::TyI64 => (i64::MIN, i64::MAX)
hir::TyIs => (i64::MIN, i64::MAX),
hir::TyI8 => (i8::MIN as i64, i8::MAX as i64),
hir::TyI16 => (i16::MIN as i64, i16::MAX as i64),
hir::TyI32 => (i32::MIN as i64, i32::MAX as i64),
hir::TyI64 => (i64::MIN, i64::MAX)
}
}
fn uint_ty_range(uint_ty: ast::UintTy) -> (u64, u64) {
fn uint_ty_range(uint_ty: hir::UintTy) -> (u64, u64) {
match uint_ty {
ast::TyUs => (u64::MIN, u64::MAX),
ast::TyU8 => (u8::MIN as u64, u8::MAX as u64),
ast::TyU16 => (u16::MIN as u64, u16::MAX as u64),
ast::TyU32 => (u32::MIN as u64, u32::MAX as u64),
ast::TyU64 => (u64::MIN, u64::MAX)
hir::TyUs => (u64::MIN, u64::MAX),
hir::TyU8 => (u8::MIN as u64, u8::MAX as u64),
hir::TyU16 => (u16::MIN as u64, u16::MAX as u64),
hir::TyU32 => (u32::MIN as u64, u32::MAX as u64),
hir::TyU64 => (u64::MIN, u64::MAX)
}
}
fn float_ty_range(float_ty: ast::FloatTy) -> (f64, f64) {
fn float_ty_range(float_ty: hir::FloatTy) -> (f64, f64) {
match float_ty {
ast::TyF32 => (f32::MIN as f64, f32::MAX as f64),
ast::TyF64 => (f64::MIN, f64::MAX)
hir::TyF32 => (f32::MIN as f64, f32::MAX as f64),
hir::TyF64 => (f64::MIN, f64::MAX)
}
}
fn int_ty_bits(int_ty: ast::IntTy, target_int_ty: ast::IntTy) -> u64 {
fn int_ty_bits(int_ty: hir::IntTy, target_int_ty: hir::IntTy) -> u64 {
match int_ty {
ast::TyIs => int_ty_bits(target_int_ty, target_int_ty),
ast::TyI8 => i8::BITS as u64,
ast::TyI16 => i16::BITS as u64,
ast::TyI32 => i32::BITS as u64,
ast::TyI64 => i64::BITS as u64
hir::TyIs => int_ty_bits(target_int_ty, target_int_ty),
hir::TyI8 => i8::BITS as u64,
hir::TyI16 => i16::BITS as u64,
hir::TyI32 => i32::BITS as u64,
hir::TyI64 => i64::BITS as u64
}
}
fn uint_ty_bits(uint_ty: ast::UintTy, target_uint_ty: ast::UintTy) -> u64 {
fn uint_ty_bits(uint_ty: hir::UintTy, target_uint_ty: hir::UintTy) -> u64 {
match uint_ty {
ast::TyUs => uint_ty_bits(target_uint_ty, target_uint_ty),
ast::TyU8 => u8::BITS as u64,
ast::TyU16 => u16::BITS as u64,
ast::TyU32 => u32::BITS as u64,
ast::TyU64 => u64::BITS as u64
hir::TyUs => uint_ty_bits(target_uint_ty, target_uint_ty),
hir::TyU8 => u8::BITS as u64,
hir::TyU16 => u16::BITS as u64,
hir::TyU32 => u32::BITS as u64,
hir::TyU64 => u64::BITS as u64
}
}
@ -336,7 +345,7 @@ impl LintPass for TypeLimits {
} else {
binop
};
match tcx.expr_ty(expr).sty {
match tcx.node_id_to_type(expr.id).sty {
ty::TyInt(int_ty) => {
let (min, max) = int_ty_range(int_ty);
let lit_val: i64 = match lit.node {
@ -466,7 +475,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
match ty.sty {
ty::TyStruct(def, substs) => {
if !cx.lookup_repr_hints(def.did).contains(&attr::ReprExtern) {
if !cx.lookup_repr_hints(def.did).contains(&front_attr::ReprExtern) {
return FfiUnsafe(
"found struct without foreign-function-safe \
representation annotation in foreign module, \
@ -550,11 +559,11 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
FfiSafe
}
ty::TyInt(ast::TyIs) => {
ty::TyInt(hir::TyIs) => {
FfiUnsafe("found Rust type `isize` in foreign module, while \
`libc::c_int` or `libc::c_long` should be used")
}
ty::TyUint(ast::TyUs) => {
ty::TyUint(hir::TyUs) => {
FfiUnsafe("found Rust type `usize` in foreign module, while \
`libc::c_uint` or `libc::c_ulong` should be used")
}
@ -784,7 +793,7 @@ impl LintPass for BoxPointers {
}
fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
let ty = cx.tcx.expr_ty(e);
let ty = cx.tcx.node_id_to_type(e.id);
self.check_heap_type(cx, e.span, ty);
}
}
@ -799,17 +808,17 @@ struct RawPtrDeriveVisitor<'a, 'tcx: 'a> {
cx: &'a Context<'a, 'tcx>
}
impl<'a, 'tcx, 'v> Visitor<'v> for RawPtrDeriveVisitor<'a, 'tcx> {
fn visit_ty(&mut self, ty: &ast::Ty) {
impl<'a, 'tcx, 'v> HirVisitor<'v> for RawPtrDeriveVisitor<'a, 'tcx> {
fn visit_ty(&mut self, ty: &hir::Ty) {
const MSG: &'static str = "use of `#[derive]` with a raw pointer";
if let ast::TyPtr(..) = ty.node {
if let hir::TyPtr(..) = ty.node {
self.cx.span_lint(RAW_POINTER_DERIVE, ty.span, MSG);
}
visit::walk_ty(self, ty);
hir_visit::walk_ty(self, ty);
}
// explicit override to a no-op to reduce code bloat
fn visit_expr(&mut self, _: &ast::Expr) {}
fn visit_block(&mut self, _: &ast::Block) {}
fn visit_expr(&mut self, _: &hir::Expr) {}
fn visit_block(&mut self, _: &hir::Block) {}
}
pub struct RawPointerDerive {
@ -833,8 +842,9 @@ impl LintPass for RawPointerDerive {
if !attr::contains_name(&item.attrs, "automatically_derived") {
return;
}
let item = lower_item(item);
let did = match item.node {
ast::ItemImpl(_, _, _, ref t_ref_opt, _, _) => {
hir::ItemImpl(_, _, _, ref t_ref_opt, _, _) => {
// Deriving the Copy trait does not cause a warning
if let &Some(ref trait_ref) = t_ref_opt {
let def_id = cx.tcx.trait_ref_to_def_id(trait_ref);
@ -855,16 +865,16 @@ impl LintPass for RawPointerDerive {
return;
}
let item = match cx.tcx.map.find(did.node) {
Some(ast_map::NodeItem(item)) => item,
Some(hir_map::NodeItem(item)) => item,
_ => return,
};
if !self.checked_raw_pointers.insert(item.id) {
return;
}
match item.node {
ast::ItemStruct(..) | ast::ItemEnum(..) => {
hir::ItemStruct(..) | hir::ItemEnum(..) => {
let mut visitor = RawPtrDeriveVisitor { cx: cx };
visit::walk_item(&mut visitor, &*item);
hir_visit::walk_item(&mut visitor, &item);
}
_ => {}
}
@ -989,14 +999,15 @@ impl LintPass for UnusedResults {
return;
}
let t = cx.tcx.expr_ty(expr);
let expr = lower_expr(expr);
let t = cx.tcx.expr_ty(&expr);
let warned = match t.sty {
ty::TyTuple(ref tys) if tys.is_empty() => return,
ty::TyBool => return,
ty::TyStruct(def, _) |
ty::TyEnum(def, _) => {
if def.did.is_local() {
if let ast_map::NodeItem(it) = cx.tcx.map.get(def.did.node) {
if let hir_map::NodeItem(it) = cx.tcx.map.get(def.did.node) {
check_must_use(cx, &it.attrs, s.span)
} else {
false
@ -1012,7 +1023,7 @@ impl LintPass for UnusedResults {
cx.span_lint(UNUSED_RESULTS, s.span, "unused result");
}
fn check_must_use(cx: &Context, attrs: &[ast::Attribute], sp: Span) -> bool {
fn check_must_use(cx: &Context, attrs: &[hir::Attribute], sp: Span) -> bool {
for attr in attrs {
if attr.check_name("must_use") {
let mut msg = "unused result which must be used".to_string();
@ -1642,9 +1653,9 @@ impl UnusedMut {
let mut mutables = FnvHashMap();
for p in pats {
pat_util::pat_bindings(&cx.tcx.def_map, &**p, |mode, id, _, path1| {
pat_util::pat_bindings(&cx.tcx.def_map, &lower_pat(p), |mode, id, _, path1| {
let ident = path1.node;
if let ast::BindByValue(ast::MutMutable) = mode {
if let hir::BindByValue(hir::MutMutable) = mode {
if !ident.name.as_str().starts_with("_") {
match mutables.entry(ident.name.usize()) {
Vacant(entry) => { entry.insert(vec![id]); },
@ -1718,11 +1729,11 @@ impl LintPass for UnusedAllocation {
if let Some(adjustment) = cx.tcx.tables.borrow().adjustments.get(&e.id) {
if let ty::AdjustDerefRef(ty::AutoDerefRef { ref autoref, .. }) = *adjustment {
match autoref {
&Some(ty::AutoPtr(_, ast::MutImmutable)) => {
&Some(ty::AutoPtr(_, hir::MutImmutable)) => {
cx.span_lint(UNUSED_ALLOCATION, e.span,
"unnecessary allocation, use & instead");
}
&Some(ty::AutoPtr(_, ast::MutMutable)) => {
&Some(ty::AutoPtr(_, hir::MutMutable)) => {
cx.span_lint(UNUSED_ALLOCATION, e.span,
"unnecessary allocation, use &mut instead");
}
@ -1862,9 +1873,9 @@ impl LintPass for MissingDoc {
ast::ItemImpl(_, _, _, Some(ref trait_ref), _, ref impl_items) => {
// If the trait is private, add the impl items to private_traits so they don't get
// reported for missing docs.
let real_trait = cx.tcx.trait_ref_to_def_id(trait_ref);
let real_trait = cx.tcx.trait_ref_to_def_id(&lower_trait_ref(trait_ref));
match cx.tcx.map.find(real_trait.node) {
Some(ast_map::NodeItem(item)) => if item.vis == ast::Visibility::Inherited {
Some(hir_map::NodeItem(item)) => if item.vis == hir::Visibility::Inherited {
for itm in impl_items {
self.private_traits.insert(itm.id);
}
@ -2087,29 +2098,51 @@ impl Stability {
}
}
fn hir_to_ast_stability(stab: &front_attr::Stability) -> attr::Stability {
attr::Stability {
level: match stab.level {
front_attr::Unstable => attr::Unstable,
front_attr::Stable => attr::Stable,
},
feature: stab.feature.clone(),
since: stab.since.clone(),
deprecated_since: stab.deprecated_since.clone(),
reason: stab.reason.clone(),
issue: stab.issue,
}
}
impl LintPass for Stability {
fn get_lints(&self) -> LintArray {
lint_array!(DEPRECATED)
}
fn check_item(&mut self, cx: &Context, item: &ast::Item) {
stability::check_item(cx.tcx, item, false,
&mut |id, sp, stab| self.lint(cx, id, sp, stab));
stability::check_item(cx.tcx, &lower_item(item), false,
&mut |id, sp, stab|
self.lint(cx, id, sp,
&stab.map(|s| hir_to_ast_stability(s)).as_ref()));
}
fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
stability::check_expr(cx.tcx, e,
&mut |id, sp, stab| self.lint(cx, id, sp, stab));
stability::check_expr(cx.tcx, &lower_expr(e),
&mut |id, sp, stab|
self.lint(cx, id, sp,
&stab.map(|s| hir_to_ast_stability(s)).as_ref()));
}
fn check_path(&mut self, cx: &Context, path: &ast::Path, id: ast::NodeId) {
stability::check_path(cx.tcx, path, id,
&mut |id, sp, stab| self.lint(cx, id, sp, stab));
stability::check_path(cx.tcx, &lower_path(path), id,
&mut |id, sp, stab|
self.lint(cx, id, sp,
&stab.map(|s| hir_to_ast_stability(s)).as_ref()));
}
fn check_pat(&mut self, cx: &Context, pat: &ast::Pat) {
stability::check_pat(cx.tcx, pat,
&mut |id, sp, stab| self.lint(cx, id, sp, stab))
stability::check_pat(cx.tcx, &lower_pat(pat),
&mut |id, sp, stab|
self.lint(cx, id, sp,
&stab.map(|s| hir_to_ast_stability(s)).as_ref()));
}
}
@ -2168,7 +2201,7 @@ impl LintPass for UnconditionalRecursion {
// to have behaviour like the above, rather than
// e.g. accidentally recurring after an assert.
let cfg = cfg::CFG::new(cx.tcx, blk);
let cfg = cfg::CFG::new(cx.tcx, &lower_block(blk));
let mut work_queue = vec![cfg.entry];
let mut reached_exit_without_self_call = false;
@ -2248,7 +2281,7 @@ impl LintPass for UnconditionalRecursion {
fn_id: ast::NodeId,
id: ast::NodeId) -> bool {
match tcx.map.get(id) {
ast_map::NodeExpr(&ast::Expr { node: ast::ExprCall(ref callee, _), .. }) => {
hir_map::NodeExpr(&hir::Expr { node: hir::ExprCall(ref callee, _), .. }) => {
tcx.def_map.borrow().get(&callee.id)
.map_or(false, |def| def.def_id() == DefId::local(fn_id))
}
@ -2283,7 +2316,7 @@ impl LintPass for UnconditionalRecursion {
// Check for calls to methods via explicit paths (e.g. `T::method()`).
match tcx.map.get(id) {
ast_map::NodeExpr(&ast::Expr { node: ast::ExprCall(ref callee, _), .. }) => {
hir_map::NodeExpr(&hir::Expr { node: hir::ExprCall(ref callee, _), .. }) => {
match tcx.def_map.borrow().get(&callee.id).map(|d| d.full_def()) {
Some(def::DefMethod(def_id)) => {
let no_substs = &ty::ItemSubsts::empty();
@ -2479,12 +2512,13 @@ impl LintPass for MutableTransmutes {
fn check_expr(&mut self, cx: &Context, expr: &ast::Expr) {
use syntax::abi::RustIntrinsic;
let msg = "mutating transmuted &mut T from &T may cause undefined behavior,\
consider instead using an UnsafeCell";
match get_transmute_from_to(cx, expr) {
Some((&ty::TyRef(_, from_mt), &ty::TyRef(_, to_mt))) => {
if to_mt.mutbl == ast::Mutability::MutMutable
&& from_mt.mutbl == ast::Mutability::MutImmutable {
if to_mt.mutbl == hir::Mutability::MutMutable
&& from_mt.mutbl == hir::Mutability::MutImmutable {
cx.span_lint(MUTABLE_TRANSMUTES, expr.span, msg);
}
}
@ -2497,7 +2531,7 @@ impl LintPass for MutableTransmutes {
ast::ExprPath(..) => (),
_ => return None
}
if let def::DefFn(did, _) = cx.tcx.resolve_expr(expr) {
if let def::DefFn(did, _) = cx.tcx.resolve_expr(&lower_expr(expr)) {
if !def_id_is_transmute(cx, did) {
return None;
}
@ -2584,7 +2618,7 @@ impl LintPass for DropWithReprExtern {
ty::TyStruct(self_type_def, _) => {
let self_type_did = self_type_def.did;
let hints = ctx.tcx.lookup_repr_hints(self_type_did);
if hints.iter().any(|attr| *attr == attr::ReprExtern) &&
if hints.iter().any(|attr| *attr == front_attr::ReprExtern) &&
self_type_def.dtor_kind().has_drop_flag() {
let drop_impl_span = ctx.tcx.map.def_id_span(drop_impl_did,
codemap::DUMMY_SP);

View File

@ -47,6 +47,7 @@ extern crate syntax;
extern crate rustc;
#[macro_use]
extern crate log;
extern crate rustc_front;
pub use rustc::lint as lint;
pub use rustc::metadata as metadata;

View File

@ -27,13 +27,16 @@
#[macro_use] extern crate syntax;
extern crate rustc;
extern crate rustc_front;
use self::PrivacyResult::*;
use self::FieldName::*;
use std::mem::replace;
use rustc::ast_map;
use rustc_front::hir;
use rustc_front::visit::{self, Visitor};
use rustc::middle::def;
use rustc::middle::def_id::DefId;
use rustc::middle::privacy::ImportUse::*;
@ -42,10 +45,10 @@ use rustc::middle::privacy::PrivateDep::*;
use rustc::middle::privacy::{ExternalExports, ExportedItems, PublicItems};
use rustc::middle::ty::{self, Ty};
use rustc::util::nodemap::{NodeMap, NodeSet};
use rustc::front::map as ast_map;
use syntax::ast;
use syntax::codemap::Span;
use syntax::visit::{self, Visitor};
type Context<'a, 'tcx> = (&'a ty::MethodMap<'tcx>, &'a def::ExportMap);
@ -64,15 +67,15 @@ struct ParentVisitor {
}
impl<'v> Visitor<'v> for ParentVisitor {
fn visit_item(&mut self, item: &ast::Item) {
fn visit_item(&mut self, item: &hir::Item) {
self.parents.insert(item.id, self.curparent);
let prev = self.curparent;
match item.node {
ast::ItemMod(..) => { self.curparent = item.id; }
hir::ItemMod(..) => { self.curparent = item.id; }
// Enum variants are parented to the enum definition itself because
// they inherit privacy
ast::ItemEnum(ref def, _) => {
hir::ItemEnum(ref def, _) => {
for variant in &def.variants {
// The parent is considered the enclosing enum because the
// enum will dictate the privacy visibility of this variant
@ -86,7 +89,7 @@ impl<'v> Visitor<'v> for ParentVisitor {
// method to the root. In this case, if the trait is private, then
// parent all the methods to the trait to indicate that they're
// private.
ast::ItemTrait(_, _, _, ref trait_items) if item.vis != ast::Public => {
hir::ItemTrait(_, _, _, ref trait_items) if item.vis != hir::Public => {
for trait_item in trait_items {
self.parents.insert(trait_item.id, item.id);
}
@ -98,13 +101,13 @@ impl<'v> Visitor<'v> for ParentVisitor {
self.curparent = prev;
}
fn visit_foreign_item(&mut self, a: &ast::ForeignItem) {
fn visit_foreign_item(&mut self, a: &hir::ForeignItem) {
self.parents.insert(a.id, self.curparent);
visit::walk_foreign_item(self, a);
}
fn visit_fn(&mut self, a: visit::FnKind<'v>, b: &'v ast::FnDecl,
c: &'v ast::Block, d: Span, id: ast::NodeId) {
fn visit_fn(&mut self, a: visit::FnKind<'v>, b: &'v hir::FnDecl,
c: &'v hir::Block, d: Span, id: ast::NodeId) {
// We already took care of some trait methods above, otherwise things
// like impl methods and pub trait methods are parented to the
// containing module, not the containing trait.
@ -114,7 +117,7 @@ impl<'v> Visitor<'v> for ParentVisitor {
visit::walk_fn(self, a, b, c, d);
}
fn visit_impl_item(&mut self, ii: &'v ast::ImplItem) {
fn visit_impl_item(&mut self, ii: &'v hir::ImplItem) {
// visit_fn handles methods, but associated consts have to be handled
// here.
if !self.parents.contains_key(&ii.id) {
@ -123,8 +126,8 @@ impl<'v> Visitor<'v> for ParentVisitor {
visit::walk_impl_item(self, ii);
}
fn visit_struct_def(&mut self, s: &ast::StructDef, _: ast::Ident,
_: &'v ast::Generics, n: ast::NodeId) {
fn visit_struct_def(&mut self, s: &hir::StructDef, _: ast::Ident,
_: &'v hir::Generics, n: ast::NodeId) {
// Struct constructors are parented to their struct definitions because
// they essentially are the struct definitions.
match s.ctor_id {
@ -193,9 +196,9 @@ impl<'a, 'tcx> EmbargoVisitor<'a, 'tcx> {
}
impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> {
fn visit_item(&mut self, item: &ast::Item) {
fn visit_item(&mut self, item: &hir::Item) {
let orig_all_pub = self.prev_public;
self.prev_public = orig_all_pub && item.vis == ast::Public;
self.prev_public = orig_all_pub && item.vis == hir::Public;
if self.prev_public {
self.public_items.insert(item.id);
}
@ -204,11 +207,11 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> {
match item.node {
// impls/extern blocks do not break the "public chain" because they
// cannot have visibility qualifiers on them anyway
ast::ItemImpl(..) | ast::ItemDefaultImpl(..) | ast::ItemForeignMod(..) => {}
hir::ItemImpl(..) | hir::ItemDefaultImpl(..) | hir::ItemForeignMod(..) => {}
// Traits are a little special in that even if they themselves are
// not public they may still be exported.
ast::ItemTrait(..) => {
hir::ItemTrait(..) => {
self.prev_exported = self.exported_trait(item.id);
}
@ -216,7 +219,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> {
// `pub` is explicitly listed.
_ => {
self.prev_exported =
(orig_all_exported && item.vis == ast::Public) ||
(orig_all_exported && item.vis == hir::Public) ||
self.reexports.contains(&item.id);
}
}
@ -227,7 +230,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> {
match item.node {
// Enum variants inherit from their parent, so if the enum is
// public all variants are public unless they're explicitly priv
ast::ItemEnum(ref def, _) if public_first => {
hir::ItemEnum(ref def, _) if public_first => {
for variant in &def.variants {
self.exported_items.insert(variant.node.id);
self.public_items.insert(variant.node.id);
@ -253,9 +256,9 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> {
// undefined symbols at linkage time if this case is not handled.
//
// * Private trait impls for private types can be completely ignored
ast::ItemImpl(_, _, _, _, ref ty, ref impl_items) => {
hir::ItemImpl(_, _, _, _, ref ty, ref impl_items) => {
let public_ty = match ty.node {
ast::TyPath(..) => {
hir::TyPath(..) => {
match self.tcx.def_map.borrow().get(&ty.id).unwrap().full_def() {
def::DefPrimTy(..) => true,
def => {
@ -276,23 +279,22 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> {
if public_ty || public_trait {
for impl_item in impl_items {
match impl_item.node {
ast::ConstImplItem(..) => {
if (public_ty && impl_item.vis == ast::Public)
hir::ConstImplItem(..) => {
if (public_ty && impl_item.vis == hir::Public)
|| tr.is_some() {
self.exported_items.insert(impl_item.id);
}
}
ast::MethodImplItem(ref sig, _) => {
hir::MethodImplItem(ref sig, _) => {
let meth_public = match sig.explicit_self.node {
ast::SelfStatic => public_ty,
hir::SelfStatic => public_ty,
_ => true,
} && impl_item.vis == ast::Public;
} && impl_item.vis == hir::Public;
if meth_public || tr.is_some() {
self.exported_items.insert(impl_item.id);
}
}
ast::TypeImplItem(_) |
ast::MacImplItem(_) => {}
hir::TypeImplItem(_) => {}
}
}
}
@ -300,7 +302,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> {
// Default methods on traits are all public so long as the trait
// is public
ast::ItemTrait(_, _, _, ref trait_items) if public_first => {
hir::ItemTrait(_, _, _, ref trait_items) if public_first => {
for trait_item in trait_items {
debug!("trait item {}", trait_item.id);
self.exported_items.insert(trait_item.id);
@ -308,7 +310,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> {
}
// Struct constructors are public if the struct is all public.
ast::ItemStruct(ref def, _) if public_first => {
hir::ItemStruct(ref def, _) if public_first => {
match def.ctor_id {
Some(id) => { self.exported_items.insert(id); }
None => {}
@ -316,16 +318,16 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> {
// fields can be public or private, so lets check
for field in &def.fields {
let vis = match field.node.kind {
ast::NamedField(_, vis) | ast::UnnamedField(vis) => vis
hir::NamedField(_, vis) | hir::UnnamedField(vis) => vis
};
if vis == ast::Public {
if vis == hir::Public {
self.public_items.insert(field.node.id);
}
}
}
ast::ItemTy(ref ty, _) if public_first => {
if let ast::TyPath(..) = ty.node {
hir::ItemTy(ref ty, _) if public_first => {
if let hir::TyPath(..) = ty.node {
match self.tcx.def_map.borrow().get(&ty.id).unwrap().full_def() {
def::DefPrimTy(..) | def::DefTyParam(..) => {},
def => {
@ -347,13 +349,13 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> {
self.prev_public = orig_all_pub;
}
fn visit_foreign_item(&mut self, a: &ast::ForeignItem) {
if (self.prev_exported && a.vis == ast::Public) || self.reexports.contains(&a.id) {
fn visit_foreign_item(&mut self, a: &hir::ForeignItem) {
if (self.prev_exported && a.vis == hir::Public) || self.reexports.contains(&a.id) {
self.exported_items.insert(a.id);
}
}
fn visit_mod(&mut self, m: &ast::Mod, _sp: Span, id: ast::NodeId) {
fn visit_mod(&mut self, m: &hir::Mod, _sp: Span, id: ast::NodeId) {
// This code is here instead of in visit_item so that the
// crate module gets processed as well.
if self.prev_exported {
@ -426,7 +428,7 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
debug!("privacy - found inherent \
associated constant {:?}",
ac.vis);
if ac.vis == ast::Public {
if ac.vis == hir::Public {
Allowable
} else {
ExternallyDenied
@ -453,7 +455,7 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
None => {
debug!("privacy - found a method {:?}",
meth.vis);
if meth.vis == ast::Public {
if meth.vis == hir::Public {
Allowable
} else {
ExternallyDenied
@ -478,7 +480,7 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
None => {
debug!("privacy - found a typedef {:?}",
typedef.vis);
if typedef.vis == ast::Public {
if typedef.vis == hir::Public {
Allowable
} else {
ExternallyDenied
@ -527,20 +529,19 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
// where the method was defined?
Some(ast_map::NodeImplItem(ii)) => {
match ii.node {
ast::ConstImplItem(..) |
ast::MethodImplItem(..) => {
hir::ConstImplItem(..) |
hir::MethodImplItem(..) => {
let imp = self.tcx.map
.get_parent_did(closest_private_id);
match self.tcx.impl_trait_ref(imp) {
Some(..) => return Allowable,
_ if ii.vis == ast::Public => {
_ if ii.vis == hir::Public => {
return Allowable
}
_ => ii.vis
}
}
ast::TypeImplItem(_) |
ast::MacImplItem(_) => return Allowable,
hir::TypeImplItem(_) => return Allowable,
}
}
Some(ast_map::NodeTraitItem(_)) => {
@ -554,11 +555,11 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
self.tcx.map.get_foreign_vis(closest_private_id)
}
Some(ast_map::NodeVariant(..)) => {
ast::Public // need to move up a level (to the enum)
hir::Public // need to move up a level (to the enum)
}
_ => ast::Public,
_ => hir::Public,
};
if vis != ast::Public { break }
if vis != hir::Public { break }
// if we've reached the root, then everything was allowable and this
// access is public.
if closest_private_id == ast::CRATE_NODE_ID { return Allowable }
@ -654,9 +655,9 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
// invoked, and the struct/enum itself is private. Crawl
// back up the chains to find the relevant struct/enum that
// was private.
ast::ItemImpl(_, _, _, _, ref ty, _) => {
hir::ItemImpl(_, _, _, _, ref ty, _) => {
match ty.node {
ast::TyPath(..) => {}
hir::TyPath(..) => {}
_ => return Some((err_span, err_msg, None)),
};
let def = self.tcx.def_map.borrow().get(&ty.id).unwrap().full_def();
@ -674,10 +675,10 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
Some(..) | None => return Some((err_span, err_msg, None)),
};
let desc = match item.node {
ast::ItemMod(..) => "module",
ast::ItemTrait(..) => "trait",
ast::ItemStruct(..) => "struct",
ast::ItemEnum(..) => "enum",
hir::ItemMod(..) => "module",
hir::ItemTrait(..) => "trait",
hir::ItemStruct(..) => "struct",
hir::ItemEnum(..) => "enum",
_ => return Some((err_span, err_msg, None))
};
let msg = format!("{} `{}` is private", desc, item.ident);
@ -697,7 +698,7 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
}
UnnamedField(idx) => &v.fields[idx]
};
if field.vis == ast::Public ||
if field.vis == hir::Public ||
(field.did.is_local() && self.private_accessible(field.did.node)) {
return
}
@ -854,16 +855,16 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
}
impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
fn visit_item(&mut self, item: &ast::Item) {
if let ast::ItemUse(ref vpath) = item.node {
if let ast::ViewPathList(ref prefix, ref list) = vpath.node {
fn visit_item(&mut self, item: &hir::Item) {
if let hir::ItemUse(ref vpath) = item.node {
if let hir::ViewPathList(ref prefix, ref list) = vpath.node {
for pid in list {
match pid.node {
ast::PathListIdent { id, name, .. } => {
hir::PathListIdent { id, name, .. } => {
debug!("privacy - ident item {}", id);
self.check_path(pid.span, id, name.name);
}
ast::PathListMod { id, .. } => {
hir::PathListMod { id, .. } => {
debug!("privacy - mod item {}", id);
let name = prefix.segments.last().unwrap().identifier.name;
self.check_path(pid.span, id, name);
@ -877,9 +878,9 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
self.curitem = orig_curitem;
}
fn visit_expr(&mut self, expr: &ast::Expr) {
fn visit_expr(&mut self, expr: &hir::Expr) {
match expr.node {
ast::ExprField(ref base, ident) => {
hir::ExprField(ref base, ident) => {
if let ty::TyStruct(def, _) = self.tcx.expr_ty_adjusted(&**base).sty {
self.check_field(expr.span,
def,
@ -887,7 +888,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
NamedField(ident.node.name));
}
}
ast::ExprTupField(ref base, idx) => {
hir::ExprTupField(ref base, idx) => {
if let ty::TyStruct(def, _) = self.tcx.expr_ty_adjusted(&**base).sty {
self.check_field(expr.span,
def,
@ -895,13 +896,13 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
UnnamedField(idx.node));
}
}
ast::ExprMethodCall(ident, _, _) => {
hir::ExprMethodCall(ident, _, _) => {
let method_call = ty::MethodCall::expr(expr.id);
let method = self.tcx.tables.borrow().method_map[&method_call];
debug!("(privacy checking) checking impl method");
self.check_method(expr.span, method.def_id, ident.node.name);
}
ast::ExprStruct(..) => {
hir::ExprStruct(..) => {
let adt = self.tcx.expr_ty(expr).ty_adt_def().unwrap();
let variant = adt.variant_of_def(self.tcx.resolve_expr(expr));
// RFC 736: ensure all unmentioned fields are visible.
@ -911,7 +912,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
self.check_field(expr.span, adt, variant, NamedField(field.name));
}
}
ast::ExprPath(..) => {
hir::ExprPath(..) => {
if let def::DefStruct(_) = self.tcx.resolve_expr(expr) {
let expr_ty = self.tcx.expr_ty(expr);
@ -922,10 +923,11 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
_ => expr_ty
}.ty_adt_def().unwrap();
let any_priv = def.struct_variant().fields.iter().any(|f| {
f.vis != ast::Public && (
f.vis != hir::Public && (
!f.did.is_local() ||
!self.private_accessible(f.did.node))
});
if any_priv {
self.tcx.sess.span_err(expr.span,
"cannot invoke tuple struct constructor \
@ -939,7 +941,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
visit::walk_expr(self, expr);
}
fn visit_pat(&mut self, pattern: &ast::Pat) {
fn visit_pat(&mut self, pattern: &hir::Pat) {
// Foreign functions do not have their patterns mapped in the def_map,
// and there's nothing really relevant there anyway, so don't bother
// checking privacy. If you can name the type then you can pass it to an
@ -947,7 +949,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
if self.in_foreign { return }
match pattern.node {
ast::PatStruct(_, ref fields, _) => {
hir::PatStruct(_, ref fields, _) => {
let adt = self.tcx.pat_ty(pattern).ty_adt_def().unwrap();
let def = self.tcx.def_map.borrow().get(&pattern.id).unwrap().full_def();
let variant = adt.variant_of_def(def);
@ -959,11 +961,11 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
// Patterns which bind no fields are allowable (the path is check
// elsewhere).
ast::PatEnum(_, Some(ref fields)) => {
hir::PatEnum(_, Some(ref fields)) => {
match self.tcx.pat_ty(pattern).sty {
ty::TyStruct(def, _) => {
for (i, field) in fields.iter().enumerate() {
if let ast::PatWild(..) = field.node {
if let hir::PatWild(..) = field.node {
continue
}
self.check_field(field.span,
@ -985,13 +987,13 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
visit::walk_pat(self, pattern);
}
fn visit_foreign_item(&mut self, fi: &ast::ForeignItem) {
fn visit_foreign_item(&mut self, fi: &hir::ForeignItem) {
self.in_foreign = true;
visit::walk_foreign_item(self, fi);
self.in_foreign = false;
}
fn visit_path(&mut self, path: &ast::Path, id: ast::NodeId) {
fn visit_path(&mut self, path: &hir::Path, id: ast::NodeId) {
self.check_path(path.span, id, path.segments.last().unwrap().identifier.name);
visit::walk_path(self, path);
}
@ -1007,7 +1009,7 @@ struct SanePrivacyVisitor<'a, 'tcx: 'a> {
}
impl<'a, 'tcx, 'v> Visitor<'v> for SanePrivacyVisitor<'a, 'tcx> {
fn visit_item(&mut self, item: &ast::Item) {
fn visit_item(&mut self, item: &hir::Item) {
if self.in_fn {
self.check_all_inherited(item);
} else {
@ -1016,15 +1018,15 @@ impl<'a, 'tcx, 'v> Visitor<'v> for SanePrivacyVisitor<'a, 'tcx> {
let in_fn = self.in_fn;
let orig_in_fn = replace(&mut self.in_fn, match item.node {
ast::ItemMod(..) => false, // modules turn privacy back on
hir::ItemMod(..) => false, // modules turn privacy back on
_ => in_fn, // otherwise we inherit
});
visit::walk_item(self, item);
self.in_fn = orig_in_fn;
}
fn visit_fn(&mut self, fk: visit::FnKind<'v>, fd: &'v ast::FnDecl,
b: &'v ast::Block, s: Span, _: ast::NodeId) {
fn visit_fn(&mut self, fk: visit::FnKind<'v>, fd: &'v hir::FnDecl,
b: &'v hir::Block, s: Span, _: ast::NodeId) {
// This catches both functions and methods
let orig_in_fn = replace(&mut self.in_fn, true);
visit::walk_fn(self, fk, fd, b, s);
@ -1037,10 +1039,10 @@ impl<'a, 'tcx> SanePrivacyVisitor<'a, 'tcx> {
/// ensures that there are no extraneous qualifiers that don't actually do
/// anything. In theory these qualifiers wouldn't parse, but that may happen
/// later on down the road...
fn check_sane_privacy(&self, item: &ast::Item) {
fn check_sane_privacy(&self, item: &hir::Item) {
let tcx = self.tcx;
let check_inherited = |sp: Span, vis: ast::Visibility, note: &str| {
if vis != ast::Inherited {
let check_inherited = |sp: Span, vis: hir::Visibility, note: &str| {
if vis != hir::Inherited {
tcx.sess.span_err(sp, "unnecessary visibility qualifier");
if !note.is_empty() {
tcx.sess.span_note(sp, note);
@ -1050,7 +1052,7 @@ impl<'a, 'tcx> SanePrivacyVisitor<'a, 'tcx> {
match item.node {
// implementations of traits don't need visibility qualifiers because
// that's controlled by having the trait in scope.
ast::ItemImpl(_, _, _, Some(..), _, ref impl_items) => {
hir::ItemImpl(_, _, _, Some(..), _, ref impl_items) => {
check_inherited(item.span, item.vis,
"visibility qualifiers have no effect on trait \
impls");
@ -1059,84 +1061,83 @@ impl<'a, 'tcx> SanePrivacyVisitor<'a, 'tcx> {
}
}
ast::ItemImpl(..) => {
hir::ItemImpl(..) => {
check_inherited(item.span, item.vis,
"place qualifiers on individual methods instead");
}
ast::ItemForeignMod(..) => {
hir::ItemForeignMod(..) => {
check_inherited(item.span, item.vis,
"place qualifiers on individual functions \
instead");
}
ast::ItemEnum(ref def, _) => {
hir::ItemEnum(ref def, _) => {
for v in &def.variants {
match v.node.vis {
ast::Public => {
if item.vis == ast::Public {
hir::Public => {
if item.vis == hir::Public {
tcx.sess.span_err(v.span, "unnecessary `pub` \
visibility");
}
}
ast::Inherited => {}
hir::Inherited => {}
}
}
}
ast::ItemTrait(..) | ast::ItemDefaultImpl(..) |
ast::ItemConst(..) | ast::ItemStatic(..) | ast::ItemStruct(..) |
ast::ItemFn(..) | ast::ItemMod(..) | ast::ItemTy(..) |
ast::ItemExternCrate(_) | ast::ItemUse(_) | ast::ItemMac(..) => {}
hir::ItemTrait(..) | hir::ItemDefaultImpl(..) |
hir::ItemConst(..) | hir::ItemStatic(..) | hir::ItemStruct(..) |
hir::ItemFn(..) | hir::ItemMod(..) | hir::ItemTy(..) |
hir::ItemExternCrate(_) | hir::ItemUse(_) => {}
}
}
/// When inside of something like a function or a method, visibility has no
/// control over anything so this forbids any mention of any visibility
fn check_all_inherited(&self, item: &ast::Item) {
fn check_all_inherited(&self, item: &hir::Item) {
let tcx = self.tcx;
fn check_inherited(tcx: &ty::ctxt, sp: Span, vis: ast::Visibility) {
if vis != ast::Inherited {
fn check_inherited(tcx: &ty::ctxt, sp: Span, vis: hir::Visibility) {
if vis != hir::Inherited {
tcx.sess.span_err(sp, "visibility has no effect inside functions");
}
}
let check_struct = |def: &ast::StructDef| {
let check_struct = |def: &hir::StructDef| {
for f in &def.fields {
match f.node.kind {
ast::NamedField(_, p) => check_inherited(tcx, f.span, p),
ast::UnnamedField(..) => {}
hir::NamedField(_, p) => check_inherited(tcx, f.span, p),
hir::UnnamedField(..) => {}
}
}
};
check_inherited(tcx, item.span, item.vis);
match item.node {
ast::ItemImpl(_, _, _, _, _, ref impl_items) => {
hir::ItemImpl(_, _, _, _, _, ref impl_items) => {
for impl_item in impl_items {
match impl_item.node {
ast::MethodImplItem(..) => {
hir::MethodImplItem(..) => {
check_inherited(tcx, impl_item.span, impl_item.vis);
}
_ => {}
}
}
}
ast::ItemForeignMod(ref fm) => {
hir::ItemForeignMod(ref fm) => {
for i in &fm.items {
check_inherited(tcx, i.span, i.vis);
}
}
ast::ItemEnum(ref def, _) => {
hir::ItemEnum(ref def, _) => {
for v in &def.variants {
check_inherited(tcx, v.span, v.node.vis);
}
}
ast::ItemStruct(ref def, _) => check_struct(&**def),
hir::ItemStruct(ref def, _) => check_struct(&**def),
ast::ItemExternCrate(_) | ast::ItemUse(_) |
ast::ItemTrait(..) | ast::ItemDefaultImpl(..) |
ast::ItemStatic(..) | ast::ItemConst(..) |
ast::ItemFn(..) | ast::ItemMod(..) | ast::ItemTy(..) |
ast::ItemMac(..) => {}
hir::ItemExternCrate(_) | hir::ItemUse(_) |
hir::ItemTrait(..) | hir::ItemDefaultImpl(..) |
hir::ItemStatic(..) | hir::ItemConst(..) |
hir::ItemFn(..) | hir::ItemMod(..) | hir::ItemTy(..) => {}
}
}
}
@ -1175,7 +1176,7 @@ impl<'a, 'tcx> VisiblePrivateTypesVisitor<'a, 'tcx> {
// .. and it corresponds to a private type in the AST (this returns
// None for type parameters)
match self.tcx.map.find(did.node) {
Some(ast_map::NodeItem(ref item)) => item.vis != ast::Public,
Some(ast_map::NodeItem(ref item)) => item.vis != hir::Public,
Some(_) | None => false,
}
}
@ -1187,8 +1188,8 @@ impl<'a, 'tcx> VisiblePrivateTypesVisitor<'a, 'tcx> {
}
fn check_ty_param_bound(&self,
ty_param_bound: &ast::TyParamBound) {
if let ast::TraitTyParamBound(ref trait_ref, _) = *ty_param_bound {
ty_param_bound: &hir::TyParamBound) {
if let hir::TraitTyParamBound(ref trait_ref, _) = *ty_param_bound {
if !self.tcx.sess.features.borrow().visible_private_types &&
self.path_is_private_type(trait_ref.trait_ref.ref_id) {
let span = trait_ref.trait_ref.path.span;
@ -1198,14 +1199,14 @@ impl<'a, 'tcx> VisiblePrivateTypesVisitor<'a, 'tcx> {
}
}
fn item_is_public(&self, id: &ast::NodeId, vis: ast::Visibility) -> bool {
self.exported_items.contains(id) || vis == ast::Public
fn item_is_public(&self, id: &ast::NodeId, vis: hir::Visibility) -> bool {
self.exported_items.contains(id) || vis == hir::Public
}
}
impl<'a, 'b, 'tcx, 'v> Visitor<'v> for CheckTypeForPrivatenessVisitor<'a, 'b, 'tcx> {
fn visit_ty(&mut self, ty: &ast::Ty) {
if let ast::TyPath(..) = ty.node {
fn visit_ty(&mut self, ty: &hir::Ty) {
if let hir::TyPath(..) = ty.node {
if self.inner.path_is_private_type(ty.id) {
self.contains_private = true;
// found what we're looking for so let's stop
@ -1220,21 +1221,21 @@ impl<'a, 'b, 'tcx, 'v> Visitor<'v> for CheckTypeForPrivatenessVisitor<'a, 'b, 't
}
// don't want to recurse into [, .. expr]
fn visit_expr(&mut self, _: &ast::Expr) {}
fn visit_expr(&mut self, _: &hir::Expr) {}
}
impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> {
fn visit_item(&mut self, item: &ast::Item) {
fn visit_item(&mut self, item: &hir::Item) {
match item.node {
// contents of a private mod can be reexported, so we need
// to check internals.
ast::ItemMod(_) => {}
hir::ItemMod(_) => {}
// An `extern {}` doesn't introduce a new privacy
// namespace (the contents have their own privacies).
ast::ItemForeignMod(_) => {}
hir::ItemForeignMod(_) => {}
ast::ItemTrait(_, _, ref bounds, _) => {
hir::ItemTrait(_, _, ref bounds, _) => {
if !self.trait_is_public(item.id) {
return
}
@ -1249,7 +1250,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> {
// (i.e. we could just return here to not check them at
// all, or some worse estimation of whether an impl is
// publicly visible).
ast::ItemImpl(_, _, ref g, ref trait_ref, ref self_, ref impl_items) => {
hir::ItemImpl(_, _, ref g, ref trait_ref, ref self_, ref impl_items) => {
// `impl [... for] Private` is never visible.
let self_contains_private;
// impl [... for] Public<...>, but not `impl [... for]
@ -1293,12 +1294,11 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> {
impl_items.iter()
.any(|impl_item| {
match impl_item.node {
ast::ConstImplItem(..) |
ast::MethodImplItem(..) => {
hir::ConstImplItem(..) |
hir::MethodImplItem(..) => {
self.exported_items.contains(&impl_item.id)
}
ast::TypeImplItem(_) |
ast::MacImplItem(_) => false,
hir::TypeImplItem(_) => false,
}
});
@ -1317,13 +1317,13 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> {
// don't erroneously report errors for private
// types in private items.
match impl_item.node {
ast::ConstImplItem(..) |
ast::MethodImplItem(..)
hir::ConstImplItem(..) |
hir::MethodImplItem(..)
if self.item_is_public(&impl_item.id, impl_item.vis) =>
{
visit::walk_impl_item(self, impl_item)
}
ast::TypeImplItem(..) => {
hir::TypeImplItem(..) => {
visit::walk_impl_item(self, impl_item)
}
_ => {}
@ -1348,7 +1348,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> {
// Those in 3. are warned with this call.
for impl_item in impl_items {
if let ast::TypeImplItem(ref ty) = impl_item.node {
if let hir::TypeImplItem(ref ty) = impl_item.node {
self.visit_ty(ty);
}
}
@ -1360,14 +1360,14 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> {
let mut found_pub_static = false;
for impl_item in impl_items {
match impl_item.node {
ast::ConstImplItem(..) => {
hir::ConstImplItem(..) => {
if self.item_is_public(&impl_item.id, impl_item.vis) {
found_pub_static = true;
visit::walk_impl_item(self, impl_item);
}
}
ast::MethodImplItem(ref sig, _) => {
if sig.explicit_self.node == ast::SelfStatic &&
hir::MethodImplItem(ref sig, _) => {
if sig.explicit_self.node == hir::SelfStatic &&
self.item_is_public(&impl_item.id, impl_item.vis) {
found_pub_static = true;
visit::walk_impl_item(self, impl_item);
@ -1385,7 +1385,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> {
// `type ... = ...;` can contain private types, because
// we're introducing a new name.
ast::ItemTy(..) => return,
hir::ItemTy(..) => return,
// not at all public, so we don't care
_ if !self.item_is_public(&item.id, item.vis) => {
@ -1403,7 +1403,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> {
visit::walk_item(self, item);
}
fn visit_generics(&mut self, generics: &ast::Generics) {
fn visit_generics(&mut self, generics: &hir::Generics) {
for ty_param in generics.ty_params.iter() {
for bound in ty_param.bounds.iter() {
self.check_ty_param_bound(bound)
@ -1411,28 +1411,28 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> {
}
for predicate in &generics.where_clause.predicates {
match predicate {
&ast::WherePredicate::BoundPredicate(ref bound_pred) => {
&hir::WherePredicate::BoundPredicate(ref bound_pred) => {
for bound in bound_pred.bounds.iter() {
self.check_ty_param_bound(bound)
}
}
&ast::WherePredicate::RegionPredicate(_) => {}
&ast::WherePredicate::EqPredicate(ref eq_pred) => {
&hir::WherePredicate::RegionPredicate(_) => {}
&hir::WherePredicate::EqPredicate(ref eq_pred) => {
self.visit_ty(&*eq_pred.ty);
}
}
}
}
fn visit_foreign_item(&mut self, item: &ast::ForeignItem) {
fn visit_foreign_item(&mut self, item: &hir::ForeignItem) {
if self.exported_items.contains(&item.id) {
visit::walk_foreign_item(self, item)
}
}
fn visit_ty(&mut self, t: &ast::Ty) {
fn visit_ty(&mut self, t: &hir::Ty) {
debug!("VisiblePrivateTypesVisitor checking ty {:?}", t);
if let ast::TyPath(_, ref p) = t.node {
if let hir::TyPath(_, ref p) = t.node {
if !self.tcx.sess.features.borrow().visible_private_types &&
self.path_is_private_type(t.id) {
self.tcx.sess.span_err(p.span, "private type in exported type signature");
@ -1441,7 +1441,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> {
visit::walk_ty(self, t)
}
fn visit_variant(&mut self, v: &ast::Variant, g: &ast::Generics) {
fn visit_variant(&mut self, v: &hir::Variant, g: &hir::Generics) {
if self.exported_items.contains(&v.node.id) {
self.in_variant = true;
visit::walk_variant(self, v, g);
@ -1449,9 +1449,9 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> {
}
}
fn visit_struct_field(&mut self, s: &ast::StructField) {
fn visit_struct_field(&mut self, s: &hir::StructField) {
match s.node.kind {
ast::NamedField(_, vis) if vis == ast::Public || self.in_variant => {
hir::NamedField(_, vis) if vis == hir::Public || self.in_variant => {
visit::walk_struct_field(self, s);
}
_ => {}
@ -1463,8 +1463,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> {
// expression/block context can't possibly contain exported things.
// (Making them no-ops stops us from traversing the whole AST without
// having to be super careful about our `walk_...` calls above.)
fn visit_block(&mut self, _: &ast::Block) {}
fn visit_expr(&mut self, _: &ast::Expr) {}
fn visit_block(&mut self, _: &hir::Block) {}
fn visit_expr(&mut self, _: &hir::Expr) {}
}
pub fn check_crate(tcx: &ty::ctxt,

View File

@ -36,25 +36,25 @@ use rustc::metadata::decoder::{DefLike, DlDef, DlField, DlImpl};
use rustc::middle::def::*;
use rustc::middle::def_id::DefId;
use syntax::ast::{Block, Crate};
use syntax::ast::{DeclItem};
use syntax::ast::{ForeignItem, ForeignItemFn, ForeignItemStatic};
use syntax::ast::{Item, ItemConst, ItemEnum, ItemExternCrate, ItemFn};
use syntax::ast::{ItemForeignMod, ItemImpl, ItemMac, ItemMod, ItemStatic, ItemDefaultImpl};
use syntax::ast::{ItemStruct, ItemTrait, ItemTy, ItemUse};
use syntax::ast::{Name, NamedField, NodeId};
use syntax::ast::{PathListIdent, PathListMod, Public};
use syntax::ast::StmtDecl;
use syntax::ast::StructVariantKind;
use syntax::ast::TupleVariantKind;
use syntax::ast::UnnamedField;
use syntax::ast::{Variant, ViewPathGlob, ViewPathList, ViewPathSimple};
use syntax::ast::Visibility;
use syntax::ast;
use syntax::attr::AttrMetaMethods;
use syntax::ast::{Name, NodeId};
use syntax::parse::token::special_idents;
use syntax::codemap::{Span, DUMMY_SP};
use syntax::visit::{self, Visitor};
use rustc_front::hir;
use rustc_front::hir::{Block, Crate, DeclItem};
use rustc_front::hir::{ForeignItem, ForeignItemFn, ForeignItemStatic};
use rustc_front::hir::{Item, ItemConst, ItemEnum, ItemExternCrate, ItemFn};
use rustc_front::hir::{ItemForeignMod, ItemImpl, ItemMod, ItemStatic, ItemDefaultImpl};
use rustc_front::hir::{ItemStruct, ItemTrait, ItemTy, ItemUse};
use rustc_front::hir::{NamedField, PathListIdent, PathListMod, Public};
use rustc_front::hir::StmtDecl;
use rustc_front::hir::StructVariantKind;
use rustc_front::hir::TupleVariantKind;
use rustc_front::hir::UnnamedField;
use rustc_front::hir::{Variant, ViewPathGlob, ViewPathList, ViewPathSimple};
use rustc_front::hir::Visibility;
use rustc_front::attr::AttrMetaMethods;
use rustc_front::visit::{self, Visitor};
use std::mem::replace;
use std::ops::{Deref, DerefMut};
@ -107,7 +107,7 @@ impl<'a, 'b:'a, 'tcx:'b> DerefMut for GraphBuilder<'a, 'b, 'tcx> {
impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
/// Constructs the reduced graph for the entire crate.
fn build_reduced_graph(self, krate: &ast::Crate) {
fn build_reduced_graph(self, krate: &hir::Crate) {
let parent = self.graph_root.get_module();
let mut visitor = BuildReducedGraphVisitor {
builder: self,
@ -265,7 +265,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
fn build_reduced_graph_for_item(&mut self, item: &Item, parent: &Rc<Module>) -> Rc<Module> {
let name = item.ident.name;
let sp = item.span;
let is_public = item.vis == ast::Public;
let is_public = item.vis == hir::Public;
let modifiers = if is_public {
DefModifiers::PUBLIC
} else {
@ -426,7 +426,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
// These items live in the value namespace.
ItemStatic(_, m, _) => {
let name_bindings = self.add_child(name, parent, ForbidDuplicateValues, sp);
let mutbl = m == ast::MutMutable;
let mutbl = m == hir::MutMutable;
name_bindings.define_value(DefStatic(DefId::local(item.id), mutbl), sp, modifiers);
parent.clone()
@ -545,17 +545,17 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
trait_item.span);
match trait_item.node {
ast::ConstTraitItem(..) => {
hir::ConstTraitItem(..) => {
let def = DefAssociatedConst(DefId::local(trait_item.id));
// NB: not DefModifiers::IMPORTABLE
name_bindings.define_value(def, trait_item.span, DefModifiers::PUBLIC);
}
ast::MethodTraitItem(..) => {
hir::MethodTraitItem(..) => {
let def = DefMethod(DefId::local(trait_item.id));
// NB: not DefModifiers::IMPORTABLE
name_bindings.define_value(def, trait_item.span, DefModifiers::PUBLIC);
}
ast::TypeTraitItem(..) => {
hir::TypeTraitItem(..) => {
let def = DefAssociatedTy(DefId::local(item.id),
DefId::local(trait_item.id));
// NB: not DefModifiers::IMPORTABLE
@ -570,7 +570,6 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
name_bindings.define_type(DefTrait(def_id), sp, modifiers);
parent.clone()
}
ItemMac(..) => parent.clone()
}
}
@ -608,7 +607,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
foreign_item: &ForeignItem,
parent: &Rc<Module>) {
let name = foreign_item.ident.name;
let is_public = foreign_item.vis == ast::Public;
let is_public = foreign_item.vis == hir::Public;
let modifiers = if is_public {
DefModifiers::PUBLIC
} else {
@ -660,7 +659,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
debug!("(building reduced graph for \
external crate) building external def {}, priv {:?}",
final_ident, vis);
let is_public = vis == ast::Public;
let is_public = vis == hir::Public;
let modifiers = if is_public {
DefModifiers::PUBLIC
} else {
@ -1001,7 +1000,7 @@ impl<'a, 'b, 'v, 'tcx> Visitor<'v> for BuildReducedGraphVisitor<'a, 'b, 'tcx> {
}
}
pub fn build_reduced_graph(resolver: &mut Resolver, krate: &ast::Crate) {
pub fn build_reduced_graph(resolver: &mut Resolver, krate: &hir::Crate) {
GraphBuilder {
resolver: resolver
}.build_reduced_graph(krate);

View File

@ -25,9 +25,11 @@ use Namespace::{TypeNS, ValueNS};
use rustc::lint;
use rustc::middle::privacy::{DependsOn, LastImport, Used, Unused};
use syntax::ast;
use syntax::ast::{ViewPathGlob, ViewPathList, ViewPathSimple};
use syntax::codemap::{Span, DUMMY_SP};
use syntax::visit::{self, Visitor};
use rustc_front::hir;
use rustc_front::hir::{ViewPathGlob, ViewPathList, ViewPathSimple};
use rustc_front::visit::{self, Visitor};
struct UnusedImportCheckVisitor<'a, 'b:'a, 'tcx:'b> {
resolver: &'a mut Resolver<'b, 'tcx>
@ -110,18 +112,18 @@ impl<'a, 'b, 'tcx> UnusedImportCheckVisitor<'a, 'b, 'tcx> {
}
impl<'a, 'b, 'v, 'tcx> Visitor<'v> for UnusedImportCheckVisitor<'a, 'b, 'tcx> {
fn visit_item(&mut self, item: &ast::Item) {
fn visit_item(&mut self, item: &hir::Item) {
// Ignore is_public import statements because there's no way to be sure
// whether they're used or not. Also ignore imports with a dummy span
// because this means that they were generated in some fashion by the
// compiler and we don't need to consider them.
if item.vis == ast::Public || item.span == DUMMY_SP {
if item.vis == hir::Public || item.span == DUMMY_SP {
visit::walk_item(self, item);
return;
}
match item.node {
ast::ItemExternCrate(_) => {
hir::ItemExternCrate(_) => {
if let Some(crate_num) = self.session.cstore.find_extern_mod_stmt_cnum(item.id) {
if !self.used_crates.contains(&crate_num) {
self.session.add_lint(lint::builtin::UNUSED_EXTERN_CRATES,
@ -131,7 +133,7 @@ impl<'a, 'b, 'v, 'tcx> Visitor<'v> for UnusedImportCheckVisitor<'a, 'b, 'tcx> {
}
}
},
ast::ItemUse(ref p) => {
hir::ItemUse(ref p) => {
match p.node {
ViewPathSimple(_, _) => {
self.finalize_import(item.id, p.span)
@ -161,7 +163,7 @@ impl<'a, 'b, 'v, 'tcx> Visitor<'v> for UnusedImportCheckVisitor<'a, 'b, 'tcx> {
}
}
pub fn check_crate(resolver: &mut Resolver, krate: &ast::Crate) {
pub fn check_crate(resolver: &mut Resolver, krate: &hir::Crate) {
let mut visitor = UnusedImportCheckVisitor { resolver: resolver };
visit::walk_crate(&mut visitor, krate);
}

View File

@ -30,6 +30,7 @@
#[macro_use] extern crate log;
#[macro_use] extern crate syntax;
#[macro_use] #[no_link] extern crate rustc_bitflags;
extern crate rustc_front;
extern crate rustc;
@ -50,7 +51,7 @@ use self::ParentLink::*;
use self::ModuleKind::*;
use self::FallbackChecks::*;
use rustc::ast_map;
use rustc::front::map as hir_map;
use rustc::session::Session;
use rustc::lint;
use rustc::metadata::csearch;
@ -64,31 +65,34 @@ use rustc::middle::ty::{Freevar, FreevarMap, TraitMap, GlobMap};
use rustc::util::nodemap::{NodeMap, NodeSet, DefIdSet, FnvHashMap};
use rustc::util::lev_distance::lev_distance;
use syntax::ast::{Arm, BindByRef, BindByValue, BindingMode, Block};
use syntax::ast::{ConstImplItem, Crate, CrateNum};
use syntax::ast::{Expr, ExprAgain, ExprBreak, ExprField};
use syntax::ast::{ExprLoop, ExprWhile, ExprMethodCall};
use syntax::ast::{ExprPath, ExprStruct, FnDecl};
use syntax::ast::{ForeignItemFn, ForeignItemStatic, Generics};
use syntax::ast::{Ident, ImplItem, Item, ItemConst, ItemEnum, ItemExternCrate};
use syntax::ast::{ItemFn, ItemForeignMod, ItemImpl, ItemMac, ItemMod, ItemStatic, ItemDefaultImpl};
use syntax::ast::{ItemStruct, ItemTrait, ItemTy, ItemUse};
use syntax::ast::{Local, MethodImplItem, Name, NodeId};
use syntax::ast::{Pat, PatEnum, PatIdent, PatLit, PatQPath};
use syntax::ast::{PatRange, PatStruct, Path, PrimTy};
use syntax::ast::{TraitRef, Ty, TyBool, TyChar, TyF32};
use syntax::ast::{TyF64, TyFloat, TyIs, TyI8, TyI16, TyI32, TyI64, TyInt};
use syntax::ast::{TyPath, TyPtr};
use syntax::ast::{TyRptr, TyStr, TyUs, TyU8, TyU16, TyU32, TyU64, TyUint};
use syntax::ast::TypeImplItem;
use syntax::ast;
use syntax::ast_util::{walk_pat};
use syntax::ast::{Ident, Name, NodeId, CrateNum};
use syntax::attr::AttrMetaMethods;
use syntax::ext::mtwt;
use syntax::parse::token::{self, special_names, special_idents};
use syntax::ptr::P;
use syntax::codemap::{self, Span, Pos};
use syntax::visit::{self, FnKind, Visitor};
use rustc_front::visit::{self, FnKind, Visitor};
use rustc_front::hir;
use rustc_front::hir::{Arm, BindByRef, BindByValue, BindingMode, Block};
use rustc_front::hir::{ConstImplItem, Crate};
use rustc_front::hir::{Expr, ExprAgain, ExprBreak, ExprField};
use rustc_front::hir::{ExprLoop, ExprWhile, ExprMethodCall};
use rustc_front::hir::{ExprPath, ExprStruct, FnDecl};
use rustc_front::hir::{ForeignItemFn, ForeignItemStatic, Generics};
use rustc_front::hir::{ImplItem, Item, ItemConst, ItemEnum, ItemExternCrate};
use rustc_front::hir::{ItemFn, ItemForeignMod, ItemImpl, ItemMod, ItemStatic, ItemDefaultImpl};
use rustc_front::hir::{ItemStruct, ItemTrait, ItemTy, ItemUse};
use rustc_front::hir::{Local, MethodImplItem};
use rustc_front::hir::{Pat, PatEnum, PatIdent, PatLit, PatQPath};
use rustc_front::hir::{PatRange, PatStruct, Path, PrimTy};
use rustc_front::hir::{TraitRef, Ty, TyBool, TyChar, TyF32};
use rustc_front::hir::{TyF64, TyFloat, TyIs, TyI8, TyI16, TyI32, TyI64, TyInt};
use rustc_front::hir::{TyPath, TyPtr};
use rustc_front::hir::{TyRptr, TyStr, TyUs, TyU8, TyU16, TyU32, TyU64, TyUint};
use rustc_front::hir::TypeImplItem;
use rustc_front::util::walk_pat;
use std::collections::{HashMap, HashSet};
use std::collections::hash_map::Entry::{Occupied, Vacant};
@ -457,22 +461,22 @@ enum NameDefinition {
impl<'a, 'v, 'tcx> Visitor<'v> for Resolver<'a, 'tcx> {
fn visit_item(&mut self, item: &Item) {
execute_callback!(ast_map::Node::NodeItem(item), self);
execute_callback!(hir_map::Node::NodeItem(item), self);
self.resolve_item(item);
}
fn visit_arm(&mut self, arm: &Arm) {
self.resolve_arm(arm);
}
fn visit_block(&mut self, block: &Block) {
execute_callback!(ast_map::Node::NodeBlock(block), self);
execute_callback!(hir_map::Node::NodeBlock(block), self);
self.resolve_block(block);
}
fn visit_expr(&mut self, expr: &Expr) {
execute_callback!(ast_map::Node::NodeExpr(expr), self);
execute_callback!(hir_map::Node::NodeExpr(expr), self);
self.resolve_expr(expr);
}
fn visit_local(&mut self, local: &Local) {
execute_callback!(ast_map::Node::NodeLocal(&*local.pat), self);
execute_callback!(hir_map::Node::NodeLocal(&*local.pat), self);
self.resolve_local(local);
}
fn visit_ty(&mut self, ty: &Ty) {
@ -482,16 +486,16 @@ impl<'a, 'v, 'tcx> Visitor<'v> for Resolver<'a, 'tcx> {
self.resolve_generics(generics);
}
fn visit_poly_trait_ref(&mut self,
tref: &ast::PolyTraitRef,
m: &ast::TraitBoundModifier) {
tref: &hir::PolyTraitRef,
m: &hir::TraitBoundModifier) {
match self.resolve_trait_reference(tref.trait_ref.ref_id, &tref.trait_ref.path, 0) {
Ok(def) => self.record_def(tref.trait_ref.ref_id, def),
Err(_) => { /* error already reported */ }
}
visit::walk_poly_trait_ref(self, tref, m);
}
fn visit_variant(&mut self, variant: &ast::Variant, generics: &Generics) {
execute_callback!(ast_map::Node::NodeVariant(variant), self);
fn visit_variant(&mut self, variant: &hir::Variant, generics: &Generics) {
execute_callback!(hir_map::Node::NodeVariant(variant), self);
if let Some(ref dis_expr) = variant.node.disr_expr {
// resolve the discriminator expr as a constant
self.with_constant_rib(|this| {
@ -501,12 +505,12 @@ impl<'a, 'v, 'tcx> Visitor<'v> for Resolver<'a, 'tcx> {
// `visit::walk_variant` without the discriminant expression.
match variant.node.kind {
ast::TupleVariantKind(ref variant_arguments) => {
hir::TupleVariantKind(ref variant_arguments) => {
for variant_argument in variant_arguments {
self.visit_ty(&*variant_argument.ty);
}
}
ast::StructVariantKind(ref struct_definition) => {
hir::StructVariantKind(ref struct_definition) => {
self.visit_struct_def(&**struct_definition,
variant.node.name,
generics,
@ -514,8 +518,8 @@ impl<'a, 'v, 'tcx> Visitor<'v> for Resolver<'a, 'tcx> {
}
}
}
fn visit_foreign_item(&mut self, foreign_item: &ast::ForeignItem) {
execute_callback!(ast_map::Node::NodeForeignItem(foreign_item), self);
fn visit_foreign_item(&mut self, foreign_item: &hir::ForeignItem) {
execute_callback!(hir_map::Node::NodeForeignItem(foreign_item), self);
let type_parameters = match foreign_item.node {
ForeignItemFn(_, ref generics) => {
HasTypeParameters(generics, FnSpace, ItemRibKind)
@ -1113,7 +1117,7 @@ impl PrimitiveTypeTable {
pub struct Resolver<'a, 'tcx:'a> {
session: &'a Session,
ast_map: &'a ast_map::Map<'tcx>,
ast_map: &'a hir_map::Map<'tcx>,
graph_root: NameBindings,
@ -1167,7 +1171,7 @@ pub struct Resolver<'a, 'tcx:'a> {
used_crates: HashSet<CrateNum>,
// Callback function for intercepting walks
callback: Option<Box<Fn(ast_map::Node, &mut bool) -> bool>>,
callback: Option<Box<Fn(hir_map::Node, &mut bool) -> bool>>,
// The intention is that the callback modifies this flag.
// Once set, the resolver falls out of the walk, preserving the ribs.
resolved: bool,
@ -1182,7 +1186,7 @@ enum FallbackChecks {
impl<'a, 'tcx> Resolver<'a, 'tcx> {
fn new(session: &'a Session,
ast_map: &'a ast_map::Map<'tcx>,
ast_map: &'a hir_map::Map<'tcx>,
crate_span: Span,
make_glob_map: MakeGlobMap) -> Resolver<'a, 'tcx> {
let graph_root = NameBindings::new();
@ -2094,7 +2098,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
None
}
fn resolve_crate(&mut self, krate: &ast::Crate) {
fn resolve_crate(&mut self, krate: &hir::Crate) {
debug!("(resolving crate) starting");
visit::walk_crate(self, krate);
@ -2161,7 +2165,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
for trait_item in trait_items {
match trait_item.node {
ast::ConstTraitItem(_, ref default) => {
hir::ConstTraitItem(_, ref default) => {
// Only impose the restrictions of
// ConstRibKind if there's an actual constant
// expression in a provided default.
@ -2173,7 +2177,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
visit::walk_trait_item(this, trait_item)
}
}
ast::MethodTraitItem(ref sig, _) => {
hir::MethodTraitItem(ref sig, _) => {
let type_parameters =
HasTypeParameters(&sig.generics,
FnSpace,
@ -2182,7 +2186,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
visit::walk_trait_item(this, trait_item)
});
}
ast::TypeTraitItem(..) => {
hir::TypeTraitItem(..) => {
this.check_if_primitive_type_name(trait_item.ident.name,
trait_item.span);
this.with_type_parameter_rib(NoTypeParameters, |this| {
@ -2209,7 +2213,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
ItemUse(ref view_path) => {
// check for imports shadowing primitive types
if let ast::ViewPathSimple(ident, _) = view_path.node {
if let hir::ViewPathSimple(ident, _) = view_path.node {
match self.def_map.borrow().get(&item.id).map(|d| d.full_def()) {
Some(DefTy(..)) | Some(DefStruct(..)) | Some(DefTrait(..)) | None => {
self.check_if_primitive_type_name(ident.name, item.span);
@ -2219,7 +2223,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
}
}
ItemExternCrate(_) | ItemMac(..) => {
ItemExternCrate(_) => {
// do nothing, these are just around to be encoded
}
}
@ -2363,9 +2367,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
}
for predicate in &generics.where_clause.predicates {
match predicate {
&ast::WherePredicate::BoundPredicate(_) |
&ast::WherePredicate::RegionPredicate(_) => {}
&ast::WherePredicate::EqPredicate(ref eq_pred) => {
&hir::WherePredicate::BoundPredicate(_) |
&hir::WherePredicate::RegionPredicate(_) => {}
&hir::WherePredicate::EqPredicate(ref eq_pred) => {
let path_res = self.resolve_path(eq_pred.id, &eq_pred.path, 0, TypeNS, true);
if let Some(PathResolution { base_def: DefTyParam(..), .. }) = path_res {
self.record_def(eq_pred.id, path_res.unwrap());
@ -2488,7 +2492,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
this.visit_ty(ty);
}
ast::MacImplItem(_) => {}
}
}
});
@ -2618,8 +2621,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
// Check for imports appearing after non-item statements.
let mut found_non_item = false;
for statement in &block.stmts {
if let ast::StmtDecl(ref declaration, _) = statement.node {
if let ast::DeclItem(ref i) = declaration.node {
if let hir::StmtDecl(ref declaration, _) = statement.node {
if let hir::DeclItem(ref i) = declaration.node {
match i.node {
ItemExternCrate(_) | ItemUse(_) if found_non_item => {
span_err!(self.session, i.span, E0154,
@ -3039,7 +3042,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
/// Handles paths that may refer to associated items
fn resolve_possibly_assoc_item(&mut self,
id: NodeId,
maybe_qself: Option<&ast::QSelf>,
maybe_qself: Option<&hir::QSelf>,
path: &Path,
namespace: Namespace,
check_ribs: bool)
@ -3228,7 +3231,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
// resolve a "module-relative" path, e.g. a::b::c
fn resolve_module_relative_path(&mut self,
span: Span,
segments: &[ast::PathSegment],
segments: &[hir::PathSegment],
namespace: Namespace)
-> Option<(Def, LastPrivate)> {
let module_path = segments.split_last().unwrap().1.iter()
@ -3285,7 +3288,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
/// import resolution.
fn resolve_crate_relative_path(&mut self,
span: Span,
segments: &[ast::PathSegment],
segments: &[hir::PathSegment],
namespace: Namespace)
-> Option<(Def, LastPrivate)> {
let module_path = segments.split_last().unwrap().1.iter()
@ -3469,17 +3472,17 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
fn is_static_method(this: &Resolver, did: DefId) -> bool {
if did.is_local() {
let sig = match this.ast_map.get(did.node) {
ast_map::NodeTraitItem(trait_item) => match trait_item.node {
ast::MethodTraitItem(ref sig, _) => sig,
hir_map::NodeTraitItem(trait_item) => match trait_item.node {
hir::MethodTraitItem(ref sig, _) => sig,
_ => return false
},
ast_map::NodeImplItem(impl_item) => match impl_item.node {
ast::MethodImplItem(ref sig, _) => sig,
hir_map::NodeImplItem(impl_item) => match impl_item.node {
hir::MethodImplItem(ref sig, _) => sig,
_ => return false
},
_ => return false
};
sig.explicit_self.node == ast::SelfStatic
sig.explicit_self.node == hir::SelfStatic
} else {
csearch::is_static_method(&this.session.cstore, did)
}
@ -4024,7 +4027,7 @@ pub enum MakeGlobMap {
/// Entry point to crate resolution.
pub fn resolve_crate<'a, 'tcx>(session: &'a Session,
ast_map: &'a ast_map::Map<'tcx>,
ast_map: &'a hir_map::Map<'tcx>,
make_glob_map: MakeGlobMap)
-> CrateMap {
let krate = ast_map.krate();
@ -4058,10 +4061,10 @@ pub fn resolve_crate<'a, 'tcx>(session: &'a Session,
/// calls to be made with the correct scope info. The node in the
/// callback corresponds to the current node in the walk.
pub fn create_resolver<'a, 'tcx>(session: &'a Session,
ast_map: &'a ast_map::Map<'tcx>,
ast_map: &'a hir_map::Map<'tcx>,
krate: &'a Crate,
make_glob_map: MakeGlobMap,
callback: Option<Box<Fn(ast_map::Node, &mut bool) -> bool>>)
callback: Option<Box<Fn(hir_map::Node, &mut bool) -> bool>>)
-> Resolver<'a, 'tcx> {
let mut resolver = Resolver::new(session, ast_map, krate.span, make_glob_map);

View File

@ -25,7 +25,7 @@ use metadata::loader::METADATA_FILENAME;
use metadata::{encoder, cstore, filesearch, csearch, creader};
use middle::dependency_format::Linkage;
use middle::ty::{self, Ty};
use rustc::ast_map::{PathElem, PathElems, PathName};
use rustc::front::map::{PathElem, PathElems, PathName};
use trans::{CrateContext, CrateTranslation, gensym_name};
use util::common::time;
use util::sha2::{Digest, Sha256};
@ -43,9 +43,12 @@ use std::str;
use flate;
use serialize::hex::ToHex;
use syntax::ast;
use syntax::attr::AttrMetaMethods;
use syntax::codemap::Span;
use syntax::parse::token;
use syntax::attr::AttrMetaMethods;
use rustc_front::attr::AttrMetaMethods as FrontAttrMetaMethods;
use rustc_front::hir;
// RLIB LLVM-BYTECODE OBJECT LAYOUT
// Version 1
@ -178,7 +181,7 @@ pub fn find_crate_name(sess: Option<&Session>,
"rust_out".to_string()
}
pub fn build_link_meta(sess: &Session, krate: &ast::Crate,
pub fn build_link_meta(sess: &Session, krate: &hir::Crate,
name: String) -> LinkMeta {
let r = LinkMeta {
crate_name: name,

View File

@ -53,6 +53,7 @@ extern crate graphviz;
extern crate libc;
extern crate rustc;
extern crate rustc_back;
extern crate rustc_front;
extern crate rustc_llvm as llvm;
extern crate rustc_platform_intrinsics as intrinsics;
extern crate serialize;

View File

@ -47,6 +47,8 @@ use syntax::visit::{self, Visitor};
use syntax::print::pprust::{path_to_string, ty_to_string};
use syntax::ptr::P;
use rustc_front::lowering::lower_expr;
use super::span_utils::SpanUtils;
use super::recorder::{Recorder, FmtStrs};
@ -1074,8 +1076,9 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DumpCsvVisitor<'l, 'tcx> {
visit::walk_expr(self, ex);
}
ast::ExprStruct(ref path, ref fields, ref base) => {
let adt = self.tcx.expr_ty(ex).ty_adt_def().unwrap();
let def = self.tcx.resolve_expr(ex);
let hir_expr = lower_expr(ex);
let adt = self.tcx.expr_ty(&hir_expr).ty_adt_def().unwrap();
let def = self.tcx.resolve_expr(&hir_expr);
self.process_struct_lit(ex,
path,
fields,
@ -1106,7 +1109,8 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DumpCsvVisitor<'l, 'tcx> {
self.visit_expr(&**sub_ex);
let ty = &self.tcx.expr_ty_adjusted(&**sub_ex).sty;
let hir_node = self.tcx.map.expect_expr(sub_ex.id);
let ty = &self.tcx.expr_ty_adjusted(&hir_node).sty;
match *ty {
ty::TyStruct(def, _) => {
let sub_span = self.span.sub_span_after_token(ex.span, token::Dot);

View File

@ -16,9 +16,11 @@ use std::env;
use std::fs::{self, File};
use std::path::{Path, PathBuf};
use rustc::ast_map::NodeItem;
use rustc_front;
use rustc::front::map::NodeItem;
use rustc_front::hir;
use syntax::{attr};
use syntax::attr;
use syntax::ast::{self, NodeId};
use syntax::ast_util;
use syntax::codemap::*;
@ -356,9 +358,9 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
Some(impl_id) => match self.tcx.map.get(impl_id.node) {
NodeItem(item) => {
match item.node {
ast::ItemImpl(_, _, _, _, ref ty, _) => {
hir::ItemImpl(_, _, _, _, ref ty, _) => {
let mut result = String::from("<");
result.push_str(&ty_to_string(&**ty));
result.push_str(&rustc_front::print::pprust::ty_to_string(&**ty));
match self.tcx.trait_of_item(DefId::local(id)) {
Some(def_id) => {
@ -446,7 +448,8 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
pub fn get_expr_data(&self, expr: &ast::Expr) -> Option<Data> {
match expr.node {
ast::ExprField(ref sub_ex, ident) => {
let ty = &self.tcx.expr_ty_adjusted(&sub_ex).sty;
let hir_node = self.tcx.map.expect_expr(sub_ex.id);
let ty = &self.tcx.expr_ty_adjusted(&hir_node).sty;
match *ty {
ty::TyStruct(def, _) => {
let f = def.struct_variant().field_named(ident.node.name);
@ -465,7 +468,8 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
}
}
ast::ExprStruct(ref path, _, _) => {
let ty = &self.tcx.expr_ty_adjusted(expr).sty;
let hir_node = self.tcx.map.expect_expr(expr.id);
let ty = &self.tcx.expr_ty_adjusted(hir_node).sty;
match *ty {
ty::TyStruct(def, _) => {
let sub_span = self.span_utils.span_for_last_ident(path.span);
@ -605,7 +609,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
}
let trait_item = self.tcx.map.expect_trait_item(def_id.node);
if let ast::TraitItem_::MethodTraitItem(_, Some(_)) = trait_item.node {
if let hir::TraitItem_::MethodTraitItem(_, Some(_)) = trait_item.node {
true
} else {
false
@ -705,9 +709,9 @@ impl<'v> Visitor<'v> for PathCollector {
}
pub fn process_crate(tcx: &ty::ctxt,
krate: &ast::Crate,
analysis: &ty::CrateAnalysis,
odir: Option<&Path>) {
let krate = tcx.map.krate();
if generated_code(krate.span) {
return;
}

View File

@ -224,14 +224,14 @@ use std;
use std::cmp::Ordering;
use std::fmt;
use std::rc::Rc;
use syntax::ast;
use syntax::ast::{DUMMY_NODE_ID, NodeId};
use rustc_front::hir;
use syntax::ast::{self, DUMMY_NODE_ID, NodeId};
use syntax::codemap::Span;
use syntax::fold::Folder;
use rustc_front::fold::Folder;
use syntax::ptr::P;
#[derive(Copy, Clone, Debug)]
struct ConstantExpr<'a>(&'a ast::Expr);
struct ConstantExpr<'a>(&'a hir::Expr);
impl<'a> ConstantExpr<'a> {
fn eq(self, other: ConstantExpr<'a>, tcx: &ty::ctxt) -> bool {
@ -379,7 +379,7 @@ type BindingsMap<'tcx> = FnvHashMap<ast::Ident, BindingInfo<'tcx>>;
struct ArmData<'p, 'blk, 'tcx: 'blk> {
bodycx: Block<'blk, 'tcx>,
arm: &'p ast::Arm,
arm: &'p hir::Arm,
bindings_map: BindingsMap<'tcx>
}
@ -388,7 +388,7 @@ struct ArmData<'p, 'blk, 'tcx: 'blk> {
/// As we proceed `bound_ptrs` are filled with pointers to values to be bound,
/// these pointers are stored in llmatch variables just before executing `data` arm.
struct Match<'a, 'p: 'a, 'blk: 'a, 'tcx: 'blk> {
pats: Vec<&'p ast::Pat>,
pats: Vec<&'p hir::Pat>,
data: &'a ArmData<'p, 'blk, 'tcx>,
bound_ptrs: Vec<(ast::Ident, ValueRef)>,
// Thread along renamings done by the check_match::StaticInliner, so we can
@ -410,7 +410,7 @@ impl<'a, 'p, 'blk, 'tcx> fmt::Debug for Match<'a, 'p, 'blk, 'tcx> {
fn has_nested_bindings(m: &[Match], col: usize) -> bool {
for br in m {
match br.pats[col].node {
ast::PatIdent(_, _, Some(_)) => return true,
hir::PatIdent(_, _, Some(_)) => return true,
_ => ()
}
}
@ -463,7 +463,7 @@ fn expand_nested_bindings<'a, 'p, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
let mut pat = br.pats[col];
loop {
pat = match pat.node {
ast::PatIdent(_, ref path, Some(ref inner)) => {
hir::PatIdent(_, ref path, Some(ref inner)) => {
bound_ptrs.push((path.node, val.val));
&**inner
},
@ -489,7 +489,7 @@ fn enter_match<'a, 'b, 'p, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
val: MatchInput,
mut e: F)
-> Vec<Match<'a, 'p, 'blk, 'tcx>> where
F: FnMut(&[&'p ast::Pat]) -> Option<Vec<&'p ast::Pat>>,
F: FnMut(&[&'p hir::Pat]) -> Option<Vec<&'p hir::Pat>>,
{
debug!("enter_match(bcx={}, m={:?}, col={}, val={})",
bcx.to_str(),
@ -503,13 +503,13 @@ fn enter_match<'a, 'b, 'p, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
let this = br.pats[col];
let mut bound_ptrs = br.bound_ptrs.clone();
match this.node {
ast::PatIdent(_, ref path, None) => {
hir::PatIdent(_, ref path, None) => {
if pat_is_binding(dm, &*this) {
bound_ptrs.push((path.node, val.val));
}
}
ast::PatVec(ref before, Some(ref slice), ref after) => {
if let ast::PatIdent(_, ref path, None) = slice.node {
hir::PatVec(ref before, Some(ref slice), ref after) => {
if let hir::PatIdent(_, ref path, None) = slice.node {
let subslice_val = bind_subslice_pat(
bcx, this.id, val,
before.len(), after.len());
@ -648,10 +648,10 @@ fn get_branches<'a, 'p, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
};
let opt = match cur.node {
ast::PatLit(ref l) => {
hir::PatLit(ref l) => {
ConstantValue(ConstantExpr(&**l), debug_loc)
}
ast::PatIdent(..) | ast::PatEnum(..) | ast::PatStruct(..) => {
hir::PatIdent(..) | hir::PatEnum(..) | hir::PatStruct(..) => {
// This is either an enum variant or a variable binding.
let opt_def = tcx.def_map.borrow().get(&cur.id).map(|d| d.full_def());
match opt_def {
@ -665,13 +665,13 @@ fn get_branches<'a, 'p, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
_ => continue
}
}
ast::PatRange(ref l1, ref l2) => {
hir::PatRange(ref l1, ref l2) => {
ConstantRange(ConstantExpr(&**l1), ConstantExpr(&**l2), debug_loc)
}
ast::PatVec(ref before, None, ref after) => {
hir::PatVec(ref before, None, ref after) => {
SliceLengthEqual(before.len() + after.len(), debug_loc)
}
ast::PatVec(ref before, Some(_), ref after) => {
hir::PatVec(ref before, Some(_), ref after) => {
SliceLengthGreaterOrEqual(before.len(), after.len(), debug_loc)
}
_ => continue
@ -770,25 +770,25 @@ macro_rules! any_pat {
}
fn any_uniq_pat(m: &[Match], col: usize) -> bool {
any_pat!(m, col, ast::PatBox(_))
any_pat!(m, col, hir::PatBox(_))
}
fn any_region_pat(m: &[Match], col: usize) -> bool {
any_pat!(m, col, ast::PatRegion(..))
any_pat!(m, col, hir::PatRegion(..))
}
fn any_irrefutable_adt_pat(tcx: &ty::ctxt, m: &[Match], col: usize) -> bool {
m.iter().any(|br| {
let pat = br.pats[col];
match pat.node {
ast::PatTup(_) => true,
ast::PatStruct(..) => {
hir::PatTup(_) => true,
hir::PatStruct(..) => {
match tcx.def_map.borrow().get(&pat.id).map(|d| d.full_def()) {
Some(def::DefVariant(..)) => false,
_ => true,
}
}
ast::PatEnum(..) | ast::PatIdent(_, _, None) => {
hir::PatEnum(..) | hir::PatIdent(_, _, None) => {
match tcx.def_map.borrow().get(&pat.id).map(|d| d.full_def()) {
Some(def::DefStruct(..)) => true,
_ => false
@ -831,9 +831,9 @@ impl FailureHandler {
}
fn pick_column_to_specialize(def_map: &DefMap, m: &[Match]) -> Option<usize> {
fn pat_score(def_map: &DefMap, pat: &ast::Pat) -> usize {
fn pat_score(def_map: &DefMap, pat: &hir::Pat) -> usize {
match pat.node {
ast::PatIdent(_, _, Some(ref inner)) => pat_score(def_map, &**inner),
hir::PatIdent(_, _, Some(ref inner)) => pat_score(def_map, &**inner),
_ if pat_is_refutable(def_map, pat) => 1,
_ => 0
}
@ -855,7 +855,7 @@ fn pick_column_to_specialize(def_map: &DefMap, m: &[Match]) -> Option<usize> {
let column_contains_any_nonwild_patterns = |&col: &usize| -> bool {
m.iter().any(|row| match row.pats[col].node {
ast::PatWild(_) => false,
hir::PatWild(_) => false,
_ => true
})
};
@ -891,7 +891,7 @@ fn compare_values<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
let _icx = push_ctxt("compare_values");
if rhs_t.is_scalar() {
let cmp = compare_scalar_types(cx, lhs, rhs, rhs_t, ast::BiEq, debug_loc);
let cmp = compare_scalar_types(cx, lhs, rhs, rhs_t, hir::BiEq, debug_loc);
return Result::new(cx, cmp);
}
@ -905,7 +905,7 @@ fn compare_values<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
compare_str(cx, lhs_data, lhs_len, rhs_data, rhs_len, rhs_t, debug_loc)
}
ty::TyArray(ty, _) | ty::TySlice(ty) => match ty.sty {
ty::TyUint(ast::TyU8) => {
ty::TyUint(hir::TyU8) => {
// NOTE: cast &[u8] and &[u8; N] to &str and abuse the str_eq lang item,
// which calls memcmp().
let pat_len = val_ty(rhs).element_type().array_length();
@ -1027,7 +1027,7 @@ fn insert_lllocals<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
}
fn compile_guard<'a, 'p, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
guard_expr: &ast::Expr,
guard_expr: &hir::Expr,
data: &ArmData<'p, 'blk, 'tcx>,
m: &[Match<'a, 'p, 'blk, 'tcx>],
vals: &[MatchInput],
@ -1324,14 +1324,14 @@ fn compile_submatch_continue<'a, 'p, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
RangeResult(Result { val: vbegin, .. },
Result { bcx, val: vend }) => {
let llge = compare_scalar_types(bcx, test_val, vbegin,
t, ast::BiGe, debug_loc);
t, hir::BiGe, debug_loc);
let llle = compare_scalar_types(bcx, test_val, vend,
t, ast::BiLe, debug_loc);
t, hir::BiLe, debug_loc);
Result::new(bcx, And(bcx, llge, llle, DebugLoc::None))
}
LowerBound(Result { bcx, val }) => {
Result::new(bcx, compare_scalar_types(bcx, test_val,
val, t, ast::BiGe,
val, t, hir::BiGe,
debug_loc))
}
}
@ -1415,9 +1415,9 @@ fn compile_submatch_continue<'a, 'p, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
}
pub fn trans_match<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
match_expr: &ast::Expr,
discr_expr: &ast::Expr,
arms: &[ast::Arm],
match_expr: &hir::Expr,
discr_expr: &hir::Expr,
arms: &[hir::Arm],
dest: Dest)
-> Block<'blk, 'tcx> {
let _icx = push_ctxt("match::trans_match");
@ -1425,20 +1425,20 @@ pub fn trans_match<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
}
/// Checks whether the binding in `discr` is assigned to anywhere in the expression `body`
fn is_discr_reassigned(bcx: Block, discr: &ast::Expr, body: &ast::Expr) -> bool {
fn is_discr_reassigned(bcx: Block, discr: &hir::Expr, body: &hir::Expr) -> bool {
let (vid, field) = match discr.node {
ast::ExprPath(..) => match bcx.def(discr.id) {
hir::ExprPath(..) => match bcx.def(discr.id) {
def::DefLocal(vid) | def::DefUpvar(vid, _) => (vid, None),
_ => return false
},
ast::ExprField(ref base, field) => {
hir::ExprField(ref base, field) => {
let vid = match bcx.tcx().def_map.borrow().get(&base.id).map(|d| d.full_def()) {
Some(def::DefLocal(vid)) | Some(def::DefUpvar(vid, _)) => vid,
_ => return false
};
(vid, Some(mc::NamedField(field.node.name)))
},
ast::ExprTupField(ref base, field) => {
hir::ExprTupField(ref base, field) => {
let vid = match bcx.tcx().def_map.borrow().get(&base.id).map(|d| d.full_def()) {
Some(def::DefLocal(vid)) | Some(def::DefUpvar(vid, _)) => vid,
_ => return false
@ -1473,8 +1473,8 @@ struct ReassignmentChecker {
// for cases where the matched value is moved.
impl<'tcx> euv::Delegate<'tcx> for ReassignmentChecker {
fn consume(&mut self, _: ast::NodeId, _: Span, _: mc::cmt, _: euv::ConsumeMode) {}
fn matched_pat(&mut self, _: &ast::Pat, _: mc::cmt, _: euv::MatchMode) {}
fn consume_pat(&mut self, _: &ast::Pat, _: mc::cmt, _: euv::ConsumeMode) {}
fn matched_pat(&mut self, _: &hir::Pat, _: mc::cmt, _: euv::MatchMode) {}
fn consume_pat(&mut self, _: &hir::Pat, _: mc::cmt, _: euv::ConsumeMode) {}
fn borrow(&mut self, _: ast::NodeId, _: Span, _: mc::cmt, _: ty::Region,
_: ty::BorrowKind, _: euv::LoanCause) {}
fn decl_without_init(&mut self, _: ast::NodeId, _: Span) {}
@ -1498,8 +1498,8 @@ impl<'tcx> euv::Delegate<'tcx> for ReassignmentChecker {
}
}
fn create_bindings_map<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, pat: &ast::Pat,
discr: &ast::Expr, body: &ast::Expr)
fn create_bindings_map<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, pat: &hir::Pat,
discr: &hir::Expr, body: &hir::Expr)
-> BindingsMap<'tcx> {
// Create the bindings map, which is a mapping from each binding name
// to an alloca() that will be the value for that local variable.
@ -1521,7 +1521,7 @@ fn create_bindings_map<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, pat: &ast::Pat,
let trmode;
let moves_by_default = variable_ty.moves_by_default(&param_env, span);
match bm {
ast::BindByValue(_) if !moves_by_default || reassigned =>
hir::BindByValue(_) if !moves_by_default || reassigned =>
{
llmatch = alloca(bcx, llvariable_ty.ptr_to(), "__llmatch");
let llcopy = alloca(bcx, llvariable_ty, &bcx.name(name));
@ -1531,14 +1531,14 @@ fn create_bindings_map<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, pat: &ast::Pat,
TrByCopy(llcopy)
};
}
ast::BindByValue(_) => {
hir::BindByValue(_) => {
// in this case, the final type of the variable will be T,
// but during matching we need to store a *T as explained
// above
llmatch = alloca(bcx, llvariable_ty.ptr_to(), &bcx.name(name));
trmode = TrByMoveRef;
}
ast::BindByRef(_) => {
hir::BindByRef(_) => {
llmatch = alloca(bcx, llvariable_ty, &bcx.name(name));
trmode = TrByRef;
}
@ -1556,8 +1556,8 @@ fn create_bindings_map<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, pat: &ast::Pat,
fn trans_match_inner<'blk, 'tcx>(scope_cx: Block<'blk, 'tcx>,
match_id: ast::NodeId,
discr_expr: &ast::Expr,
arms: &[ast::Arm],
discr_expr: &hir::Expr,
arms: &[hir::Arm],
dest: Dest) -> Block<'blk, 'tcx> {
let _icx = push_ctxt("match::trans_match_inner");
let fcx = scope_cx.fcx;
@ -1589,7 +1589,7 @@ fn trans_match_inner<'blk, 'tcx>(scope_cx: Block<'blk, 'tcx>,
None
};
let arm_pats: Vec<Vec<P<ast::Pat>>> = {
let arm_pats: Vec<Vec<P<hir::Pat>>> = {
let mut static_inliner = StaticInliner::new(scope_cx.tcx(),
pat_renaming_map.as_mut());
arm_datas.iter().map(|arm_data| {
@ -1615,7 +1615,7 @@ fn trans_match_inner<'blk, 'tcx>(scope_cx: Block<'blk, 'tcx>,
// to the default arm.
let has_default = arms.last().map_or(false, |arm| {
arm.pats.len() == 1
&& arm.pats.last().unwrap().node == ast::PatWild(ast::PatWildSingle)
&& arm.pats.last().unwrap().node == hir::PatWild(hir::PatWildSingle)
});
compile_submatch(bcx, &matches[..], &[discr_datum.match_input()], &chk, has_default);
@ -1639,7 +1639,7 @@ fn trans_match_inner<'blk, 'tcx>(scope_cx: Block<'blk, 'tcx>,
/// Generates code for a local variable declaration like `let <pat>;` or `let <pat> =
/// <opt_init_expr>`.
pub fn store_local<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
local: &ast::Local)
local: &hir::Local)
-> Block<'blk, 'tcx> {
let _icx = push_ctxt("match::store_local");
let mut bcx = bcx;
@ -1647,7 +1647,7 @@ pub fn store_local<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
let pat = &*local.pat;
fn create_dummy_locals<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
pat: &ast::Pat)
pat: &hir::Pat)
-> Block<'blk, 'tcx> {
let _icx = push_ctxt("create_dummy_locals");
// create dummy memory for the variables if we have no
@ -1764,7 +1764,7 @@ fn mk_binding_alloca<'blk, 'tcx, A, F>(bcx: Block<'blk, 'tcx>,
/// - pat: the irrefutable pattern being matched.
/// - val: the value being matched -- must be an lvalue (by ref, with cleanup)
pub fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
pat: &ast::Pat,
pat: &hir::Pat,
val: MatchInput,
cleanup_scope: cleanup::ScopeId)
-> Block<'blk, 'tcx> {
@ -1784,7 +1784,7 @@ pub fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
let tcx = bcx.tcx();
let ccx = bcx.ccx();
match pat.node {
ast::PatIdent(pat_binding_mode, ref path1, ref inner) => {
hir::PatIdent(pat_binding_mode, ref path1, ref inner) => {
if pat_is_binding(&tcx.def_map, &*pat) {
// Allocate the stack slot where the value of this
// binding will live and place it into the appropriate
@ -1794,14 +1794,14 @@ pub fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
"_match::bind_irrefutable_pat",
|(), bcx, Datum { val: llval, ty, kind: _ }| {
match pat_binding_mode {
ast::BindByValue(_) => {
hir::BindByValue(_) => {
// By value binding: move the value that `val`
// points at into the binding's stack slot.
let d = val.to_datum(ty);
d.store_to(bcx, llval)
}
ast::BindByRef(_) => {
hir::BindByRef(_) => {
// By ref binding: the value of the variable
// is the pointer `val` itself or fat pointer referenced by `val`
if type_is_fat_ptr(bcx.tcx(), ty) {
@ -1821,7 +1821,7 @@ pub fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
bcx = bind_irrefutable_pat(bcx, &**inner_pat, val, cleanup_scope);
}
}
ast::PatEnum(_, ref sub_pats) => {
hir::PatEnum(_, ref sub_pats) => {
let opt_def = bcx.tcx().def_map.borrow().get(&pat.id).map(|d| d.full_def());
match opt_def {
Some(def::DefVariant(enum_id, var_id, _)) => {
@ -1866,7 +1866,7 @@ pub fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
}
}
}
ast::PatStruct(_, ref fields, _) => {
hir::PatStruct(_, ref fields, _) => {
let tcx = bcx.tcx();
let pat_ty = node_id_type(bcx, pat.id);
let pat_repr = adt::represent_type(bcx.ccx(), pat_ty);
@ -1885,7 +1885,7 @@ pub fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
cleanup_scope);
}
}
ast::PatTup(ref elems) => {
hir::PatTup(ref elems) => {
let repr = adt::represent_node(bcx, pat.id);
for (i, elem) in elems.iter().enumerate() {
let fldptr = adt::trans_field_ptr(bcx, &*repr, val.val, 0, i);
@ -1896,12 +1896,12 @@ pub fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
cleanup_scope);
}
}
ast::PatBox(ref inner) => {
hir::PatBox(ref inner) => {
let llbox = Load(bcx, val.val);
bcx = bind_irrefutable_pat(
bcx, &**inner, MatchInput::from_val(llbox), cleanup_scope);
}
ast::PatRegion(ref inner, _) => {
hir::PatRegion(ref inner, _) => {
let loaded_val = Load(bcx, val.val);
bcx = bind_irrefutable_pat(
bcx,
@ -1909,7 +1909,7 @@ pub fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
MatchInput::from_val(loaded_val),
cleanup_scope);
}
ast::PatVec(ref before, ref slice, ref after) => {
hir::PatVec(ref before, ref slice, ref after) => {
let pat_ty = node_id_type(bcx, pat.id);
let mut extracted = extract_vec_elems(bcx, pat_ty, before.len(), after.len(), val);
match slice {
@ -1934,11 +1934,8 @@ pub fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
cleanup_scope)
});
}
ast::PatMac(..) => {
bcx.sess().span_bug(pat.span, "unexpanded macro");
}
ast::PatQPath(..) | ast::PatWild(_) | ast::PatLit(_) |
ast::PatRange(_, _) => ()
hir::PatQPath(..) | hir::PatWild(_) | hir::PatLit(_) |
hir::PatRange(_, _) => ()
}
return bcx;
}

View File

@ -51,8 +51,9 @@ use middle::subst;
use middle::ty::{self, Ty};
use middle::ty::Disr;
use syntax::ast;
use syntax::attr;
use syntax::attr::IntType;
use rustc_front::attr;
use rustc_front::attr::IntType;
use rustc_front::hir;
use trans::_match;
use trans::build::*;
use trans::cleanup;
@ -386,11 +387,11 @@ fn represent_type_uncached<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
let ity = if use_align {
// Use the overall alignment
match align {
1 => attr::UnsignedInt(ast::TyU8),
2 => attr::UnsignedInt(ast::TyU16),
4 => attr::UnsignedInt(ast::TyU32),
1 => attr::UnsignedInt(hir::TyU8),
2 => attr::UnsignedInt(hir::TyU16),
4 => attr::UnsignedInt(hir::TyU32),
8 if machine::llalign_of_min(cx, Type::i64(cx)) == 8 =>
attr::UnsignedInt(ast::TyU64),
attr::UnsignedInt(hir::TyU64),
_ => min_ity // use min_ity as a fallback
}
} else {
@ -582,12 +583,12 @@ fn range_to_inttype(cx: &CrateContext, hint: Hint, bounds: &IntBounds) -> IntTyp
// Lists of sizes to try. u64 is always allowed as a fallback.
#[allow(non_upper_case_globals)]
const choose_shortest: &'static [IntType] = &[
attr::UnsignedInt(ast::TyU8), attr::SignedInt(ast::TyI8),
attr::UnsignedInt(ast::TyU16), attr::SignedInt(ast::TyI16),
attr::UnsignedInt(ast::TyU32), attr::SignedInt(ast::TyI32)];
attr::UnsignedInt(hir::TyU8), attr::SignedInt(hir::TyI8),
attr::UnsignedInt(hir::TyU16), attr::SignedInt(hir::TyI16),
attr::UnsignedInt(hir::TyU32), attr::SignedInt(hir::TyI32)];
#[allow(non_upper_case_globals)]
const at_least_32: &'static [IntType] = &[
attr::UnsignedInt(ast::TyU32), attr::SignedInt(ast::TyI32)];
attr::UnsignedInt(hir::TyU32), attr::SignedInt(hir::TyI32)];
let attempts;
match hint {
@ -621,7 +622,7 @@ fn range_to_inttype(cx: &CrateContext, hint: Hint, bounds: &IntBounds) -> IntTyp
return ity;
}
}
return attr::UnsignedInt(ast::TyU64);
return attr::UnsignedInt(hir::TyU64);
}
pub fn ll_inttype(cx: &CrateContext, ity: IntType) -> Type {

View File

@ -20,7 +20,7 @@ use trans::expr;
use trans::type_of;
use trans::type_::Type;
use syntax::ast;
use rustc_front::hir as ast;
use std::ffi::CString;
use libc::{c_uint, c_char};

View File

@ -15,8 +15,8 @@ use middle::ty;
use middle::infer;
use session::config::NoDebugInfo;
use syntax::abi;
use syntax::ast;
pub use syntax::attr::InlineAttr;
use rustc_front::hir;
pub use rustc_front::attr::InlineAttr;
use trans::base;
use trans::common;
use trans::context::CrateContext;
@ -91,8 +91,8 @@ pub fn set_optimize_for_size(val: ValueRef, optimize: bool) {
/// Composite function which sets LLVM attributes for function depending on its AST (#[attribute])
/// attributes.
pub fn from_fn_attrs(ccx: &CrateContext, attrs: &[ast::Attribute], llfn: ValueRef) {
use syntax::attr::*;
pub fn from_fn_attrs(ccx: &CrateContext, attrs: &[hir::Attribute], llfn: ValueRef) {
use rustc_front::attr::*;
inline(llfn, find_inline_attr(Some(ccx.sess().diagnostic()), attrs));
// FIXME: #11906: Omitting frame pointers breaks retrieving the value of a
@ -262,11 +262,11 @@ pub fn from_fn_type<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_type: ty::Ty<'tcx
// on memory dependencies rather than pointer equality
let interior_unsafe = mt.ty.type_contents(ccx.tcx()).interior_unsafe();
if mt.mutbl == ast::MutMutable || !interior_unsafe {
if mt.mutbl == hir::MutMutable || !interior_unsafe {
attrs.arg(idx, llvm::Attribute::NoAlias);
}
if mt.mutbl == ast::MutImmutable && !interior_unsafe {
if mt.mutbl == hir::MutImmutable && !interior_unsafe {
attrs.arg(idx, llvm::Attribute::ReadOnly);
}

View File

@ -43,7 +43,7 @@ use middle::weak_lang_items;
use middle::pat_util::simple_identifier;
use middle::subst::Substs;
use middle::ty::{self, Ty, HasTypeFlags};
use rustc::ast_map;
use rustc::front::map as hir_map;
use session::config::{self, NoDebugInfo, FullDebugInfo};
use session::Session;
use trans::_match;
@ -93,13 +93,15 @@ use std::mem;
use std::str;
use std::{i8, i16, i32, i64};
use syntax::abi::{Rust, RustCall, RustIntrinsic, PlatformIntrinsic, Abi};
use syntax::attr::AttrMetaMethods;
use syntax::attr;
use syntax::codemap::Span;
use syntax::parse::token::InternedString;
use syntax::visit::Visitor;
use syntax::visit;
use syntax::{ast, ast_util};
use rustc_front;
use rustc_front::attr::AttrMetaMethods;
use rustc_front::attr;
use rustc_front::visit::Visitor;
use rustc_front::visit;
use rustc_front::hir;
use syntax::ast;
thread_local! {
static TASK_LOCAL_INSN_KEY: RefCell<Option<Vec<&'static str>>> = {
@ -277,15 +279,15 @@ pub fn malloc_raw_dyn<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
}
pub fn bin_op_to_icmp_predicate(ccx: &CrateContext, op: ast::BinOp_, signed: bool)
pub fn bin_op_to_icmp_predicate(ccx: &CrateContext, op: hir::BinOp_, signed: bool)
-> llvm::IntPredicate {
match op {
ast::BiEq => llvm::IntEQ,
ast::BiNe => llvm::IntNE,
ast::BiLt => if signed { llvm::IntSLT } else { llvm::IntULT },
ast::BiLe => if signed { llvm::IntSLE } else { llvm::IntULE },
ast::BiGt => if signed { llvm::IntSGT } else { llvm::IntUGT },
ast::BiGe => if signed { llvm::IntSGE } else { llvm::IntUGE },
hir::BiEq => llvm::IntEQ,
hir::BiNe => llvm::IntNE,
hir::BiLt => if signed { llvm::IntSLT } else { llvm::IntULT },
hir::BiLe => if signed { llvm::IntSLE } else { llvm::IntULE },
hir::BiGt => if signed { llvm::IntSGT } else { llvm::IntUGT },
hir::BiGe => if signed { llvm::IntSGE } else { llvm::IntUGE },
op => {
ccx.sess().bug(&format!("comparison_op_to_icmp_predicate: expected \
comparison operator, found {:?}", op));
@ -293,15 +295,15 @@ pub fn bin_op_to_icmp_predicate(ccx: &CrateContext, op: ast::BinOp_, signed: boo
}
}
pub fn bin_op_to_fcmp_predicate(ccx: &CrateContext, op: ast::BinOp_)
pub fn bin_op_to_fcmp_predicate(ccx: &CrateContext, op: hir::BinOp_)
-> llvm::RealPredicate {
match op {
ast::BiEq => llvm::RealOEQ,
ast::BiNe => llvm::RealUNE,
ast::BiLt => llvm::RealOLT,
ast::BiLe => llvm::RealOLE,
ast::BiGt => llvm::RealOGT,
ast::BiGe => llvm::RealOGE,
hir::BiEq => llvm::RealOEQ,
hir::BiNe => llvm::RealUNE,
hir::BiLt => llvm::RealOLT,
hir::BiLe => llvm::RealOLE,
hir::BiGt => llvm::RealOGT,
hir::BiGe => llvm::RealOGE,
op => {
ccx.sess().bug(&format!("comparison_op_to_fcmp_predicate: expected \
comparison operator, found {:?}", op));
@ -313,7 +315,7 @@ pub fn compare_scalar_types<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
lhs: ValueRef,
rhs: ValueRef,
t: Ty<'tcx>,
op: ast::BinOp_,
op: hir::BinOp_,
debug_loc: DebugLoc)
-> ValueRef {
match t.sty {
@ -321,8 +323,8 @@ pub fn compare_scalar_types<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
// We don't need to do actual comparisons for nil.
// () == () holds but () < () does not.
match op {
ast::BiEq | ast::BiLe | ast::BiGe => return C_bool(bcx.ccx(), true),
ast::BiNe | ast::BiLt | ast::BiGt => return C_bool(bcx.ccx(), false),
hir::BiEq | hir::BiLe | hir::BiGe => return C_bool(bcx.ccx(), true),
hir::BiNe | hir::BiLt | hir::BiGt => return C_bool(bcx.ccx(), false),
// refinements would be nice
_ => bcx.sess().bug("compare_scalar_types: must be a comparison operator")
}
@ -349,7 +351,7 @@ pub fn compare_simd_types<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
rhs: ValueRef,
t: Ty<'tcx>,
ret_ty: Type,
op: ast::BinOp_,
op: hir::BinOp_,
debug_loc: DebugLoc)
-> ValueRef {
let signed = match t.sty {
@ -526,7 +528,7 @@ pub fn iter_structural_ty<'blk, 'tcx, F>(cx: Block<'blk, 'tcx>,
}
pub fn cast_shift_expr_rhs(cx: Block,
op: ast::BinOp_,
op: hir::BinOp_,
lhs: ValueRef,
rhs: ValueRef)
-> ValueRef {
@ -535,14 +537,14 @@ pub fn cast_shift_expr_rhs(cx: Block,
|a,b| ZExt(cx, a, b))
}
pub fn cast_shift_const_rhs(op: ast::BinOp_,
pub fn cast_shift_const_rhs(op: hir::BinOp_,
lhs: ValueRef, rhs: ValueRef) -> ValueRef {
cast_shift_rhs(op, lhs, rhs,
|a, b| unsafe { llvm::LLVMConstTrunc(a, b.to_ref()) },
|a, b| unsafe { llvm::LLVMConstZExt(a, b.to_ref()) })
}
fn cast_shift_rhs<F, G>(op: ast::BinOp_,
fn cast_shift_rhs<F, G>(op: hir::BinOp_,
lhs: ValueRef,
rhs: ValueRef,
trunc: F,
@ -552,7 +554,7 @@ fn cast_shift_rhs<F, G>(op: ast::BinOp_,
G: FnOnce(ValueRef, Type) -> ValueRef,
{
// Shifts may have any size int on the rhs
if ast_util::is_shift_binop(op) {
if rustc_front::util::is_shift_binop(op) {
let mut rhs_llty = val_ty(rhs);
let mut lhs_llty = val_ty(lhs);
if rhs_llty.kind() == Vector { rhs_llty = rhs_llty.element_type() }
@ -579,12 +581,12 @@ pub fn llty_and_min_for_signed_ty<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
ty::TyInt(t) => {
let llty = Type::int_from_ty(cx.ccx(), t);
let min = match t {
ast::TyIs if llty == Type::i32(cx.ccx()) => i32::MIN as u64,
ast::TyIs => i64::MIN as u64,
ast::TyI8 => i8::MIN as u64,
ast::TyI16 => i16::MIN as u64,
ast::TyI32 => i32::MIN as u64,
ast::TyI64 => i64::MIN as u64,
hir::TyIs if llty == Type::i32(cx.ccx()) => i32::MIN as u64,
hir::TyIs => i64::MIN as u64,
hir::TyI8 => i8::MIN as u64,
hir::TyI16 => i16::MIN as u64,
hir::TyI32 => i32::MIN as u64,
hir::TyI64 => i64::MIN as u64,
};
(llty, min)
}
@ -595,12 +597,12 @@ pub fn llty_and_min_for_signed_ty<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
pub fn fail_if_zero_or_overflows<'blk, 'tcx>(
cx: Block<'blk, 'tcx>,
call_info: NodeIdAndSpan,
divrem: ast::BinOp,
divrem: hir::BinOp,
lhs: ValueRef,
rhs: ValueRef,
rhs_t: Ty<'tcx>)
-> Block<'blk, 'tcx> {
let (zero_text, overflow_text) = if divrem.node == ast::BiDiv {
let (zero_text, overflow_text) = if divrem.node == hir::BiDiv {
("attempted to divide by zero",
"attempted to divide with overflow")
} else {
@ -871,7 +873,7 @@ pub fn to_arg_ty_ptr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, ptr: ValueRef, ty: Ty<'
}
}
pub fn init_local<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, local: &ast::Local)
pub fn init_local<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, local: &hir::Local)
-> Block<'blk, 'tcx> {
debug!("init_local(bcx={}, local.id={})", bcx.to_str(), local.id);
let _indenter = indenter();
@ -1086,9 +1088,9 @@ impl FindNestedReturn {
}
impl<'v> Visitor<'v> for FindNestedReturn {
fn visit_expr(&mut self, e: &ast::Expr) {
fn visit_expr(&mut self, e: &hir::Expr) {
match e.node {
ast::ExprRet(..) => {
hir::ExprRet(..) => {
self.found = true;
}
_ => visit::walk_expr(self, e)
@ -1098,40 +1100,40 @@ impl<'v> Visitor<'v> for FindNestedReturn {
fn build_cfg(tcx: &ty::ctxt, id: ast::NodeId) -> (ast::NodeId, Option<cfg::CFG>) {
let blk = match tcx.map.find(id) {
Some(ast_map::NodeItem(i)) => {
Some(hir_map::NodeItem(i)) => {
match i.node {
ast::ItemFn(_, _, _, _, _, ref blk) => {
hir::ItemFn(_, _, _, _, _, ref blk) => {
blk
}
_ => tcx.sess.bug("unexpected item variant in has_nested_returns")
}
}
Some(ast_map::NodeTraitItem(trait_item)) => {
Some(hir_map::NodeTraitItem(trait_item)) => {
match trait_item.node {
ast::MethodTraitItem(_, Some(ref body)) => body,
hir::MethodTraitItem(_, Some(ref body)) => body,
_ => {
tcx.sess.bug("unexpected variant: trait item other than a \
provided method in has_nested_returns")
}
}
}
Some(ast_map::NodeImplItem(impl_item)) => {
Some(hir_map::NodeImplItem(impl_item)) => {
match impl_item.node {
ast::MethodImplItem(_, ref body) => body,
hir::MethodImplItem(_, ref body) => body,
_ => {
tcx.sess.bug("unexpected variant: non-method impl item in \
has_nested_returns")
}
}
}
Some(ast_map::NodeExpr(e)) => {
Some(hir_map::NodeExpr(e)) => {
match e.node {
ast::ExprClosure(_, _, ref blk) => blk,
hir::ExprClosure(_, _, ref blk) => blk,
_ => tcx.sess.bug("unexpected expr variant in has_nested_returns")
}
}
Some(ast_map::NodeVariant(..)) |
Some(ast_map::NodeStructCtor(..)) => return (ast::DUMMY_NODE_ID, None),
Some(hir_map::NodeVariant(..)) |
Some(hir_map::NodeStructCtor(..)) => return (ast::DUMMY_NODE_ID, None),
// glue, shims, etc
None if id == ast::DUMMY_NODE_ID => return (ast::DUMMY_NODE_ID, None),
@ -1157,8 +1159,8 @@ fn has_nested_returns(tcx: &ty::ctxt, cfg: &cfg::CFG, blk_id: ast::NodeId) -> bo
for index in cfg.graph.depth_traverse(cfg.entry) {
let n = cfg.graph.node_data(index);
match tcx.map.find(n.id()) {
Some(ast_map::NodeExpr(ex)) => {
if let ast::ExprRet(Some(ref ret_expr)) = ex.node {
Some(hir_map::NodeExpr(ex)) => {
if let hir::ExprRet(Some(ref ret_expr)) = ex.node {
let mut visitor = FindNestedReturn::new();
visit::walk_expr(&mut visitor, &**ret_expr);
if visitor.found {
@ -1166,7 +1168,7 @@ fn has_nested_returns(tcx: &ty::ctxt, cfg: &cfg::CFG, blk_id: ast::NodeId) -> bo
}
}
}
Some(ast_map::NodeBlock(blk)) if blk.id == blk_id => {
Some(hir_map::NodeBlock(blk)) if blk.id == blk_id => {
let mut visitor = FindNestedReturn::new();
visit::walk_expr_opt(&mut visitor, &blk.expr);
if visitor.found {
@ -1354,7 +1356,7 @@ pub fn arg_kind<'a, 'tcx>(cx: &FunctionContext<'a, 'tcx>, t: Ty<'tcx>)
// create_datums_for_fn_args: creates lvalue datums for each of the
// incoming function arguments.
pub fn create_datums_for_fn_args<'a, 'tcx>(mut bcx: Block<'a, 'tcx>,
args: &[ast::Arg],
args: &[hir::Arg],
arg_tys: &[Ty<'tcx>],
has_tupled_arg: bool,
arg_scope: cleanup::CustomScopeIndex)
@ -1559,12 +1561,12 @@ pub fn build_return_block<'blk, 'tcx>(fcx: &FunctionContext<'blk, 'tcx>,
///
/// If the function closes over its environment a closure will be returned.
pub fn trans_closure<'a, 'b, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
decl: &ast::FnDecl,
body: &ast::Block,
decl: &hir::FnDecl,
body: &hir::Block,
llfndecl: ValueRef,
param_substs: &'tcx Substs<'tcx>,
fn_ast_id: ast::NodeId,
_attributes: &[ast::Attribute],
_attributes: &[hir::Attribute],
output_type: ty::FnOutput<'tcx>,
abi: Abi,
closure_env: closure::ClosureEnv<'b>) {
@ -1678,12 +1680,12 @@ pub fn trans_closure<'a, 'b, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
/// Creates an LLVM function corresponding to a source language function.
pub fn trans_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
decl: &ast::FnDecl,
body: &ast::Block,
decl: &hir::FnDecl,
body: &hir::Block,
llfndecl: ValueRef,
param_substs: &'tcx Substs<'tcx>,
id: ast::NodeId,
attrs: &[ast::Attribute]) {
attrs: &[hir::Attribute]) {
let _s = StatRecorder::new(ccx, ccx.tcx().map.path_to_string(id).to_string());
debug!("trans_fn(param_substs={:?})", param_substs);
let _icx = push_ctxt("trans_fn");
@ -1860,7 +1862,7 @@ fn trans_enum_variant_or_tuple_like_struct<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx
finish_fn(&fcx, bcx, result_ty, DebugLoc::None);
}
fn enum_variant_size_lint(ccx: &CrateContext, enum_def: &ast::EnumDef, sp: Span, id: ast::NodeId) {
fn enum_variant_size_lint(ccx: &CrateContext, enum_def: &hir::EnumDef, sp: Span, id: ast::NodeId) {
let mut sizes = Vec::new(); // does no allocation if no pushes, thankfully
let print_info = ccx.sess().print_enum_sizes();
@ -1939,7 +1941,7 @@ pub struct TransItemVisitor<'a, 'tcx: 'a> {
}
impl<'a, 'tcx, 'v> Visitor<'v> for TransItemVisitor<'a, 'tcx> {
fn visit_item(&mut self, i: &ast::Item) {
fn visit_item(&mut self, i: &hir::Item) {
trans_item(self.ccx, i);
}
}
@ -2010,7 +2012,7 @@ pub fn update_linkage(ccx: &CrateContext,
if let Some(id) = id {
let item = ccx.tcx().map.get(id);
if let ast_map::NodeItem(i) = item {
if let hir_map::NodeItem(i) = item {
if let Some(name) = attr::first_attr_value_str_by_name(&i.attrs, "linkage") {
if let Some(linkage) = llvm_linkage_by_name(&name) {
llvm::SetLinkage(llval, linkage);
@ -2037,7 +2039,7 @@ pub fn update_linkage(ccx: &CrateContext,
}
}
fn set_global_section(ccx: &CrateContext, llval: ValueRef, i: &ast::Item) {
fn set_global_section(ccx: &CrateContext, llval: ValueRef, i: &hir::Item) {
match attr::first_attr_value_str_by_name(&i.attrs,
"link_section") {
Some(sect) => {
@ -2054,13 +2056,13 @@ fn set_global_section(ccx: &CrateContext, llval: ValueRef, i: &ast::Item) {
}
}
pub fn trans_item(ccx: &CrateContext, item: &ast::Item) {
pub fn trans_item(ccx: &CrateContext, item: &hir::Item) {
let _icx = push_ctxt("trans_item");
let from_external = ccx.external_srcs().borrow().contains_key(&item.id);
match item.node {
ast::ItemFn(ref decl, _, _, abi, ref generics, ref body) => {
hir::ItemFn(ref decl, _, _, abi, ref generics, ref body) => {
if !generics.is_type_parameterized() {
let trans_everywhere = attr::requests_inline(&item.attrs);
// Ignore `trans_everywhere` for cross-crate inlined items
@ -2098,29 +2100,29 @@ pub fn trans_item(ccx: &CrateContext, item: &ast::Item) {
let mut v = TransItemVisitor{ ccx: ccx };
v.visit_block(&**body);
}
ast::ItemImpl(_, _, ref generics, _, _, ref impl_items) => {
hir::ItemImpl(_, _, ref generics, _, _, ref impl_items) => {
meth::trans_impl(ccx,
item.ident,
&impl_items[..],
generics,
item.id);
}
ast::ItemMod(ref m) => {
hir::ItemMod(ref m) => {
trans_mod(&ccx.rotate(), m);
}
ast::ItemEnum(ref enum_definition, ref gens) => {
hir::ItemEnum(ref enum_definition, ref gens) => {
if gens.ty_params.is_empty() {
// sizes only make sense for non-generic types
enum_variant_size_lint(ccx, enum_definition, item.span, item.id);
}
}
ast::ItemConst(_, ref expr) => {
hir::ItemConst(_, ref expr) => {
// Recurse on the expression to catch items in blocks
let mut v = TransItemVisitor{ ccx: ccx };
v.visit_expr(&**expr);
}
ast::ItemStatic(_, m, ref expr) => {
hir::ItemStatic(_, m, ref expr) => {
// Recurse on the expression to catch items in blocks
let mut v = TransItemVisitor{ ccx: ccx };
v.visit_expr(&**expr);
@ -2129,10 +2131,10 @@ pub fn trans_item(ccx: &CrateContext, item: &ast::Item) {
set_global_section(ccx, g, item);
update_linkage(ccx, g, Some(item.id), OriginalTranslation);
},
ast::ItemForeignMod(ref foreign_mod) => {
hir::ItemForeignMod(ref foreign_mod) => {
foreign::trans_foreign_mod(ccx, foreign_mod);
}
ast::ItemTrait(..) => {
hir::ItemTrait(..) => {
// Inside of this trait definition, we won't be actually translating any
// functions, but the trait still needs to be walked. Otherwise default
// methods with items will not get translated and will cause ICE's when
@ -2149,7 +2151,7 @@ pub fn trans_item(ccx: &CrateContext, item: &ast::Item) {
// separate modules in the compiled program. That's because modules exist
// only as a convenience for humans working with the code, to organize names
// and control visibility.
pub fn trans_mod(ccx: &CrateContext, m: &ast::Mod) {
pub fn trans_mod(ccx: &CrateContext, m: &hir::Mod) {
let _icx = push_ctxt("trans_mod");
for item in &m.items {
trans_item(ccx, &**item);
@ -2295,7 +2297,7 @@ pub fn create_entry_wrapper(ccx: &CrateContext,
}
fn exported_name<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, id: ast::NodeId,
ty: Ty<'tcx>, attrs: &[ast::Attribute]) -> String {
ty: Ty<'tcx>, attrs: &[hir::Attribute]) -> String {
match ccx.external_srcs().borrow().get(&id) {
Some(&did) => {
let sym = csearch::get_symbol(&ccx.sess().cstore, did);
@ -2340,12 +2342,12 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
let item = ccx.tcx().map.get(id);
debug!("get_item_val: id={} item={:?}", id, item);
let val = match item {
ast_map::NodeItem(i) => {
hir_map::NodeItem(i) => {
let ty = ccx.tcx().node_id_to_type(i.id);
let sym = || exported_name(ccx, id, ty, &i.attrs);
let v = match i.node {
ast::ItemStatic(..) => {
hir::ItemStatic(..) => {
// If this static came from an external crate, then
// we need to get the symbol from csearch instead of
// using the current crate's name/version
@ -2366,7 +2368,7 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
g
}
ast::ItemFn(_, _, _, abi, _, _) => {
hir::ItemFn(_, _, _, abi, _, _) => {
let sym = sym();
let llfn = if abi == Rust {
register_fn(ccx, i.span, sym, i.id, ty)
@ -2383,10 +2385,10 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
v
}
ast_map::NodeTraitItem(trait_item) => {
hir_map::NodeTraitItem(trait_item) => {
debug!("get_item_val(): processing a NodeTraitItem");
match trait_item.node {
ast::MethodTraitItem(_, Some(_)) => {
hir::MethodTraitItem(_, Some(_)) => {
register_method(ccx, id, &trait_item.attrs, trait_item.span)
}
_ => {
@ -2397,9 +2399,9 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
}
}
ast_map::NodeImplItem(impl_item) => {
hir_map::NodeImplItem(impl_item) => {
match impl_item.node {
ast::MethodImplItem(..) => {
hir::MethodImplItem(..) => {
register_method(ccx, id, &impl_item.attrs, impl_item.span)
}
_ => {
@ -2410,9 +2412,9 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
}
}
ast_map::NodeForeignItem(ni) => {
hir_map::NodeForeignItem(ni) => {
match ni.node {
ast::ForeignItemFn(..) => {
hir::ForeignItemFn(..) => {
let abi = ccx.tcx().map.get_foreign_abi(id);
let ty = ccx.tcx().node_id_to_type(ni.id);
let name = foreign::link_name(&*ni);
@ -2420,17 +2422,17 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
attributes::from_fn_attrs(ccx, &ni.attrs, llfn);
llfn
}
ast::ForeignItemStatic(..) => {
hir::ForeignItemStatic(..) => {
foreign::register_static(ccx, &*ni)
}
}
}
ast_map::NodeVariant(ref v) => {
hir_map::NodeVariant(ref v) => {
let llfn;
let args = match v.node.kind {
ast::TupleVariantKind(ref args) => args,
ast::StructVariantKind(_) => {
hir::TupleVariantKind(ref args) => args,
hir::StructVariantKind(_) => {
ccx.sess().bug("struct variant kind unexpected in get_item_val")
}
};
@ -2444,7 +2446,7 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
&enm.attrs);
llfn = match enm.node {
ast::ItemEnum(_, _) => {
hir::ItemEnum(_, _) => {
register_fn(ccx, (*v).span, sym, id, ty)
}
_ => ccx.sess().bug("NodeVariant, shouldn't happen")
@ -2453,7 +2455,7 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
llfn
}
ast_map::NodeStructCtor(struct_def) => {
hir_map::NodeStructCtor(struct_def) => {
// Only register the constructor if this is a tuple-like struct.
let ctor_id = match struct_def.ctor_id {
None => {
@ -2495,7 +2497,7 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
}
fn register_method(ccx: &CrateContext, id: ast::NodeId,
attrs: &[ast::Attribute], span: Span) -> ValueRef {
attrs: &[hir::Attribute], span: Span) -> ValueRef {
let mty = ccx.tcx().node_id_to_type(id);
let sym = exported_name(ccx, id, mty, &attrs);
@ -2529,7 +2531,7 @@ pub fn crate_ctxt_to_encode_parms<'a, 'tcx>(cx: &'a SharedCrateContext<'a, 'tcx>
}
}
pub fn write_metadata(cx: &SharedCrateContext, krate: &ast::Crate,
pub fn write_metadata(cx: &SharedCrateContext, krate: &hir::Crate,
reachable: &NodeSet) -> Vec<u8> {
use flate;
@ -2679,7 +2681,7 @@ pub fn filter_reachable_ids(ccx: &SharedCrateContext) -> NodeSet {
// As a result, if this id is an FFI item (foreign item) then we only
// let it through if it's included statically.
match ccx.tcx().map.get(id) {
ast_map::NodeForeignItem(..) => {
hir_map::NodeForeignItem(..) => {
ccx.sess().cstore.is_statically_included_foreign_item(id)
}
_ => true,

View File

@ -26,6 +26,7 @@ use middle::def;
use middle::def_id::{DefId, LOCAL_CRATE};
use middle::subst;
use middle::subst::{Subst, Substs};
use rustc::front::map as hir_map;
use trans::adt;
use trans::base;
use trans::base::*;
@ -50,7 +51,7 @@ use trans::type_::Type;
use trans::type_of;
use middle::ty::{self, Ty, HasTypeFlags, RegionEscape};
use middle::ty::MethodCall;
use rustc::ast_map;
use rustc_front::hir;
use syntax::abi as synabi;
use syntax::ast;
@ -83,14 +84,14 @@ pub struct Callee<'blk, 'tcx: 'blk> {
pub ty: Ty<'tcx>
}
fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, expr: &ast::Expr)
fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, expr: &hir::Expr)
-> Callee<'blk, 'tcx> {
let _icx = push_ctxt("trans_callee");
debug!("callee::trans(expr={:?})", expr);
// pick out special kinds of expressions that can be called:
match expr.node {
ast::ExprPath(..) => {
hir::ExprPath(..) => {
return trans_def(bcx, bcx.def(expr.id), expr);
}
_ => {}
@ -99,7 +100,7 @@ fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, expr: &ast::Expr)
// any other expressions are closures:
return datum_callee(bcx, expr);
fn datum_callee<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, expr: &ast::Expr)
fn datum_callee<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, expr: &hir::Expr)
-> Callee<'blk, 'tcx> {
let DatumBlock { bcx, datum, .. } = expr::trans(bcx, expr);
match datum.ty.sty {
@ -130,7 +131,7 @@ fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, expr: &ast::Expr)
fn trans_def<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
def: def::Def,
ref_expr: &ast::Expr)
ref_expr: &hir::Expr)
-> Callee<'blk, 'tcx> {
debug!("trans_def(def={:?}, ref_expr={:?})", def, ref_expr);
let expr_ty = common::node_id_type(bcx, ref_expr.id);
@ -140,7 +141,7 @@ fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, expr: &ast::Expr)
let maybe_ast_node = maybe_def_id.and_then(|def_id| bcx.tcx().map
.find(def_id.node));
match maybe_ast_node {
Some(ast_map::NodeStructCtor(_)) => true,
Some(hir_map::NodeStructCtor(_)) => true,
_ => false
}
} => {
@ -286,7 +287,7 @@ pub fn trans_fn_pointer_shim<'a, 'tcx>(
let (opt_def_id, sig) =
match bare_fn_ty.sty {
ty::TyBareFn(opt_def_id,
&ty::BareFnTy { unsafety: ast::Unsafety::Normal,
&ty::BareFnTy { unsafety: hir::Unsafety::Normal,
abi: synabi::Rust,
ref sig }) => {
(opt_def_id, sig)
@ -301,7 +302,7 @@ pub fn trans_fn_pointer_shim<'a, 'tcx>(
let tuple_input_ty = tcx.mk_tup(sig.inputs.to_vec());
let tuple_fn_ty = tcx.mk_fn(opt_def_id,
tcx.mk_bare_fn(ty::BareFnTy {
unsafety: ast::Unsafety::Normal,
unsafety: hir::Unsafety::Normal,
abi: synabi::RustCall,
sig: ty::Binder(ty::FnSig {
inputs: vec![bare_fn_ty_maybe_ref,
@ -471,11 +472,11 @@ pub fn trans_fn_ref_with_substs<'a, 'tcx>(
|| "local item should be in ast map".to_string());
match map_node {
ast_map::NodeVariant(v) => match v.node.kind {
ast::TupleVariantKind(ref args) => !args.is_empty(),
hir_map::NodeVariant(v) => match v.node.kind {
hir::TupleVariantKind(ref args) => !args.is_empty(),
_ => false
},
ast_map::NodeStructCtor(_) => true,
hir_map::NodeStructCtor(_) => true,
_ => false
}
} else {
@ -572,8 +573,8 @@ pub fn trans_fn_ref_with_substs<'a, 'tcx>(
// Translating calls
pub fn trans_call<'a, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
call_expr: &ast::Expr,
f: &ast::Expr,
call_expr: &hir::Expr,
f: &hir::Expr,
args: CallArgs<'a, 'tcx>,
dest: expr::Dest)
-> Block<'blk, 'tcx> {
@ -586,8 +587,8 @@ pub fn trans_call<'a, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
}
pub fn trans_method_call<'a, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
call_expr: &ast::Expr,
rcvr: &ast::Expr,
call_expr: &hir::Expr,
rcvr: &hir::Expr,
args: CallArgs<'a, 'tcx>,
dest: expr::Dest)
-> Block<'blk, 'tcx> {
@ -853,7 +854,7 @@ pub fn trans_call_inner<'a, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
pub enum CallArgs<'a, 'tcx> {
// Supply value of arguments as a list of expressions that must be
// translated. This is used in the common case of `foo(bar, qux)`.
ArgExprs(&'a [P<ast::Expr>]),
ArgExprs(&'a [P<hir::Expr>]),
// Supply value of arguments as a list of LLVM value refs; frequently
// used with lang items and so forth, when the argument is an internal
@ -868,12 +869,12 @@ pub enum CallArgs<'a, 'tcx> {
// Supply value of arguments as a list of expressions that must be
// translated, for overloaded call operators.
ArgOverloadedCall(Vec<&'a ast::Expr>),
ArgOverloadedCall(Vec<&'a hir::Expr>),
}
fn trans_args_under_call_abi<'blk, 'tcx>(
mut bcx: Block<'blk, 'tcx>,
arg_exprs: &[P<ast::Expr>],
arg_exprs: &[P<hir::Expr>],
fn_ty: Ty<'tcx>,
llargs: &mut Vec<ValueRef>,
arg_cleanup_scope: cleanup::ScopeId,
@ -934,7 +935,7 @@ fn trans_args_under_call_abi<'blk, 'tcx>(
fn trans_overloaded_call_args<'blk, 'tcx>(
mut bcx: Block<'blk, 'tcx>,
arg_exprs: Vec<&ast::Expr>,
arg_exprs: Vec<&hir::Expr>,
fn_ty: Ty<'tcx>,
llargs: &mut Vec<ValueRef>,
arg_cleanup_scope: cleanup::ScopeId,

View File

@ -32,6 +32,8 @@ use session::config::FullDebugInfo;
use syntax::abi::RustCall;
use syntax::ast;
use rustc_front::hir;
fn load_closure_environment<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
arg_scope_id: ScopeId,
@ -171,8 +173,8 @@ pub enum Dest<'a, 'tcx: 'a> {
}
pub fn trans_closure_expr<'a, 'tcx>(dest: Dest<'a, 'tcx>,
decl: &ast::FnDecl,
body: &ast::Block,
decl: &hir::FnDecl,
body: &hir::Block,
id: ast::NodeId,
closure_substs: &'tcx ty::ClosureSubsts<'tcx>)
-> Option<Block<'a, 'tcx>>

View File

@ -40,7 +40,8 @@ use middle::traits;
use middle::ty::{self, HasTypeFlags, Ty};
use middle::ty_fold;
use middle::ty_fold::{TypeFolder, TypeFoldable};
use rustc::ast_map::{PathElem, PathName};
use rustc::front::map::{PathElem, PathName};
use rustc_front::hir;
use util::nodemap::{FnvHashMap, NodeMap};
use arena::TypedArena;
@ -266,7 +267,7 @@ pub struct NodeIdAndSpan {
pub span: Span,
}
pub fn expr_info(expr: &ast::Expr) -> NodeIdAndSpan {
pub fn expr_info(expr: &hir::Expr) -> NodeIdAndSpan {
NodeIdAndSpan { id: expr.id, span: expr.span }
}
@ -1024,11 +1025,11 @@ pub fn node_id_type<'blk, 'tcx>(bcx: &BlockS<'blk, 'tcx>, id: ast::NodeId) -> Ty
monomorphize_type(bcx, t)
}
pub fn expr_ty<'blk, 'tcx>(bcx: &BlockS<'blk, 'tcx>, ex: &ast::Expr) -> Ty<'tcx> {
pub fn expr_ty<'blk, 'tcx>(bcx: &BlockS<'blk, 'tcx>, ex: &hir::Expr) -> Ty<'tcx> {
node_id_type(bcx, ex.id)
}
pub fn expr_ty_adjusted<'blk, 'tcx>(bcx: &BlockS<'blk, 'tcx>, ex: &ast::Expr) -> Ty<'tcx> {
pub fn expr_ty_adjusted<'blk, 'tcx>(bcx: &BlockS<'blk, 'tcx>, ex: &hir::Expr) -> Ty<'tcx> {
monomorphize_type(bcx, bcx.tcx().expr_ty_adjusted(ex))
}

View File

@ -38,28 +38,31 @@ use middle::subst::Substs;
use middle::ty::{self, Ty};
use util::nodemap::NodeMap;
use rustc_front::hir;
use rustc_front::attr;
use std::ffi::{CStr, CString};
use libc::c_uint;
use syntax::{ast, attr};
use syntax::ast;
use syntax::parse::token;
use syntax::ptr::P;
pub type FnArgMap<'a> = Option<&'a NodeMap<ValueRef>>;
pub fn const_lit(cx: &CrateContext, e: &ast::Expr, lit: &ast::Lit)
pub fn const_lit(cx: &CrateContext, e: &hir::Expr, lit: &hir::Lit)
-> ValueRef {
let _icx = push_ctxt("trans_lit");
debug!("const_lit: {:?}", lit);
match lit.node {
ast::LitByte(b) => C_integral(Type::uint_from_ty(cx, ast::TyU8), b as u64, false),
ast::LitChar(i) => C_integral(Type::char(cx), i as u64, false),
ast::LitInt(i, ast::SignedIntLit(t, _)) => {
hir::LitByte(b) => C_integral(Type::uint_from_ty(cx, hir::TyU8), b as u64, false),
hir::LitChar(i) => C_integral(Type::char(cx), i as u64, false),
hir::LitInt(i, hir::SignedIntLit(t, _)) => {
C_integral(Type::int_from_ty(cx, t), i, true)
}
ast::LitInt(u, ast::UnsignedIntLit(t)) => {
hir::LitInt(u, hir::UnsignedIntLit(t)) => {
C_integral(Type::uint_from_ty(cx, t), u, false)
}
ast::LitInt(i, ast::UnsuffixedIntLit(_)) => {
hir::LitInt(i, hir::UnsuffixedIntLit(_)) => {
let lit_int_ty = cx.tcx().node_id_to_type(e.id);
match lit_int_ty.sty {
ty::TyInt(t) => {
@ -74,10 +77,10 @@ pub fn const_lit(cx: &CrateContext, e: &ast::Expr, lit: &ast::Lit)
lit_int_ty))
}
}
ast::LitFloat(ref fs, t) => {
hir::LitFloat(ref fs, t) => {
C_floating(&fs, Type::float_from_ty(cx, t))
}
ast::LitFloatUnsuffixed(ref fs) => {
hir::LitFloatUnsuffixed(ref fs) => {
let lit_float_ty = cx.tcx().node_id_to_type(e.id);
match lit_float_ty.sty {
ty::TyFloat(t) => {
@ -89,9 +92,9 @@ pub fn const_lit(cx: &CrateContext, e: &ast::Expr, lit: &ast::Lit)
}
}
}
ast::LitBool(b) => C_bool(cx, b),
ast::LitStr(ref s, _) => C_str_slice(cx, (*s).clone()),
ast::LitBinary(ref data) => {
hir::LitBool(b) => C_bool(cx, b),
hir::LitStr(ref s, _) => C_str_slice(cx, (*s).clone()),
hir::LitBinary(ref data) => {
addr_of(cx, C_bytes(cx, &data[..]), "binary")
}
}
@ -194,8 +197,8 @@ fn const_fn_call<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
pub fn get_const_expr<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
def_id: DefId,
ref_expr: &ast::Expr)
-> &'tcx ast::Expr {
ref_expr: &hir::Expr)
-> &'tcx hir::Expr {
let def_id = inline::maybe_instantiate_inline(ccx, def_id);
if def_id.krate != LOCAL_CRATE {
@ -213,21 +216,21 @@ pub fn get_const_expr<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
fn get_const_val(ccx: &CrateContext,
def_id: DefId,
ref_expr: &ast::Expr) -> ValueRef {
ref_expr: &hir::Expr) -> ValueRef {
let expr = get_const_expr(ccx, def_id, ref_expr);
let empty_substs = ccx.tcx().mk_substs(Substs::trans_empty());
get_const_expr_as_global(ccx, expr, check_const::ConstQualif::empty(), empty_substs)
}
pub fn get_const_expr_as_global<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
expr: &ast::Expr,
expr: &hir::Expr,
qualif: check_const::ConstQualif,
param_substs: &'tcx Substs<'tcx>)
-> ValueRef {
debug!("get_const_expr_as_global: {:?}", expr.id);
// Special-case constants to cache a common global for all uses.
match expr.node {
ast::ExprPath(..) => {
hir::ExprPath(..) => {
let def = ccx.tcx().def_map.borrow().get(&expr.id).unwrap().full_def();
match def {
def::DefConst(def_id) | def::DefAssociatedConst(def_id) => {
@ -274,7 +277,7 @@ pub fn get_const_expr_as_global<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
}
pub fn const_expr<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
e: &ast::Expr,
e: &hir::Expr,
param_substs: &'tcx Substs<'tcx>,
fn_args: FnArgMap)
-> (ValueRef, Ty<'tcx>) {
@ -378,11 +381,11 @@ pub fn const_expr<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
(llconst, ety_adjusted)
}
fn check_unary_expr_validity(cx: &CrateContext, e: &ast::Expr, t: Ty,
fn check_unary_expr_validity(cx: &CrateContext, e: &hir::Expr, t: Ty,
te: ValueRef) {
// The only kind of unary expression that we check for validity
// here is `-expr`, to check if it "overflows" (e.g. `-i32::MIN`).
if let ast::ExprUnary(ast::UnNeg, ref inner_e) = e.node {
if let hir::ExprUnary(hir::UnNeg, ref inner_e) = e.node {
// An unfortunate special case: we parse e.g. -128 as a
// negation of the literal 128, which means if we're expecting
@ -392,7 +395,7 @@ fn check_unary_expr_validity(cx: &CrateContext, e: &ast::Expr, t: Ty,
//
// Catch this up front by looking for ExprLit directly,
// and just accepting it.
if let ast::ExprLit(_) = inner_e.node { return; }
if let hir::ExprLit(_) = inner_e.node { return; }
let result = match t.sty {
ty::TyInt(int_type) => {
@ -421,9 +424,9 @@ fn check_unary_expr_validity(cx: &CrateContext, e: &ast::Expr, t: Ty,
}
}
fn check_binary_expr_validity(cx: &CrateContext, e: &ast::Expr, t: Ty,
fn check_binary_expr_validity(cx: &CrateContext, e: &hir::Expr, t: Ty,
te1: ValueRef, te2: ValueRef) {
let b = if let ast::ExprBinary(b, _, _) = e.node { b } else { return };
let b = if let hir::ExprBinary(b, _, _) = e.node { b } else { return };
let result = match t.sty {
ty::TyInt(int_type) => {
@ -435,13 +438,13 @@ fn check_binary_expr_validity(cx: &CrateContext, e: &ast::Expr, t: Ty,
let opt_ety = Some(const_eval::IntTy::from(cx.tcx(), int_type));
match b.node {
ast::BiAdd => const_int_checked_add(lhs, rhs, e, opt_ety),
ast::BiSub => const_int_checked_sub(lhs, rhs, e, opt_ety),
ast::BiMul => const_int_checked_mul(lhs, rhs, e, opt_ety),
ast::BiDiv => const_int_checked_div(lhs, rhs, e, opt_ety),
ast::BiRem => const_int_checked_rem(lhs, rhs, e, opt_ety),
ast::BiShl => const_int_checked_shl(lhs, rhs, e, opt_ety),
ast::BiShr => const_int_checked_shr(lhs, rhs, e, opt_ety),
hir::BiAdd => const_int_checked_add(lhs, rhs, e, opt_ety),
hir::BiSub => const_int_checked_sub(lhs, rhs, e, opt_ety),
hir::BiMul => const_int_checked_mul(lhs, rhs, e, opt_ety),
hir::BiDiv => const_int_checked_div(lhs, rhs, e, opt_ety),
hir::BiRem => const_int_checked_rem(lhs, rhs, e, opt_ety),
hir::BiShl => const_int_checked_shl(lhs, rhs, e, opt_ety),
hir::BiShr => const_int_checked_shr(lhs, rhs, e, opt_ety),
_ => return,
}
}
@ -454,13 +457,13 @@ fn check_binary_expr_validity(cx: &CrateContext, e: &ast::Expr, t: Ty,
let opt_ety = Some(const_eval::UintTy::from(cx.tcx(), uint_type));
match b.node {
ast::BiAdd => const_uint_checked_add(lhs, rhs, e, opt_ety),
ast::BiSub => const_uint_checked_sub(lhs, rhs, e, opt_ety),
ast::BiMul => const_uint_checked_mul(lhs, rhs, e, opt_ety),
ast::BiDiv => const_uint_checked_div(lhs, rhs, e, opt_ety),
ast::BiRem => const_uint_checked_rem(lhs, rhs, e, opt_ety),
ast::BiShl => const_uint_checked_shl(lhs, rhs, e, opt_ety),
ast::BiShr => const_uint_checked_shr(lhs, rhs, e, opt_ety),
hir::BiAdd => const_uint_checked_add(lhs, rhs, e, opt_ety),
hir::BiSub => const_uint_checked_sub(lhs, rhs, e, opt_ety),
hir::BiMul => const_uint_checked_mul(lhs, rhs, e, opt_ety),
hir::BiDiv => const_uint_checked_div(lhs, rhs, e, opt_ety),
hir::BiRem => const_uint_checked_rem(lhs, rhs, e, opt_ety),
hir::BiShl => const_uint_checked_shl(lhs, rhs, e, opt_ety),
hir::BiShr => const_uint_checked_shr(lhs, rhs, e, opt_ety),
_ => return,
}
}
@ -473,7 +476,7 @@ fn check_binary_expr_validity(cx: &CrateContext, e: &ast::Expr, t: Ty,
}
fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
e: &ast::Expr,
e: &hir::Expr,
ety: Ty<'tcx>,
param_substs: &'tcx Substs<'tcx>,
fn_args: FnArgMap)
@ -484,17 +487,17 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
ety,
param_substs);
let map_list = |exprs: &[P<ast::Expr>]| -> Vec<ValueRef> {
let map_list = |exprs: &[P<hir::Expr>]| -> Vec<ValueRef> {
exprs.iter()
.map(|e| const_expr(cx, &**e, param_substs, fn_args).0)
.collect()
};
let _icx = push_ctxt("const_expr");
match e.node {
ast::ExprLit(ref lit) => {
hir::ExprLit(ref lit) => {
const_lit(cx, e, &**lit)
},
ast::ExprBinary(b, ref e1, ref e2) => {
hir::ExprBinary(b, ref e1, ref e2) => {
/* Neither type is bottom, and we expect them to be unified
* already, so the following is safe. */
let (te1, ty) = const_expr(cx, &**e1, param_substs, fn_args);
@ -510,38 +513,38 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
check_binary_expr_validity(cx, e, ty, te1, te2);
unsafe { match b.node {
ast::BiAdd if is_float => llvm::LLVMConstFAdd(te1, te2),
ast::BiAdd => llvm::LLVMConstAdd(te1, te2),
hir::BiAdd if is_float => llvm::LLVMConstFAdd(te1, te2),
hir::BiAdd => llvm::LLVMConstAdd(te1, te2),
ast::BiSub if is_float => llvm::LLVMConstFSub(te1, te2),
ast::BiSub => llvm::LLVMConstSub(te1, te2),
hir::BiSub if is_float => llvm::LLVMConstFSub(te1, te2),
hir::BiSub => llvm::LLVMConstSub(te1, te2),
ast::BiMul if is_float => llvm::LLVMConstFMul(te1, te2),
ast::BiMul => llvm::LLVMConstMul(te1, te2),
hir::BiMul if is_float => llvm::LLVMConstFMul(te1, te2),
hir::BiMul => llvm::LLVMConstMul(te1, te2),
ast::BiDiv if is_float => llvm::LLVMConstFDiv(te1, te2),
ast::BiDiv if signed => llvm::LLVMConstSDiv(te1, te2),
ast::BiDiv => llvm::LLVMConstUDiv(te1, te2),
hir::BiDiv if is_float => llvm::LLVMConstFDiv(te1, te2),
hir::BiDiv if signed => llvm::LLVMConstSDiv(te1, te2),
hir::BiDiv => llvm::LLVMConstUDiv(te1, te2),
ast::BiRem if is_float => llvm::LLVMConstFRem(te1, te2),
ast::BiRem if signed => llvm::LLVMConstSRem(te1, te2),
ast::BiRem => llvm::LLVMConstURem(te1, te2),
hir::BiRem if is_float => llvm::LLVMConstFRem(te1, te2),
hir::BiRem if signed => llvm::LLVMConstSRem(te1, te2),
hir::BiRem => llvm::LLVMConstURem(te1, te2),
ast::BiAnd => llvm::LLVMConstAnd(te1, te2),
ast::BiOr => llvm::LLVMConstOr(te1, te2),
ast::BiBitXor => llvm::LLVMConstXor(te1, te2),
ast::BiBitAnd => llvm::LLVMConstAnd(te1, te2),
ast::BiBitOr => llvm::LLVMConstOr(te1, te2),
ast::BiShl => {
hir::BiAnd => llvm::LLVMConstAnd(te1, te2),
hir::BiOr => llvm::LLVMConstOr(te1, te2),
hir::BiBitXor => llvm::LLVMConstXor(te1, te2),
hir::BiBitAnd => llvm::LLVMConstAnd(te1, te2),
hir::BiBitOr => llvm::LLVMConstOr(te1, te2),
hir::BiShl => {
let te2 = base::cast_shift_const_rhs(b.node, te1, te2);
llvm::LLVMConstShl(te1, te2)
},
ast::BiShr => {
hir::BiShr => {
let te2 = base::cast_shift_const_rhs(b.node, te1, te2);
if signed { llvm::LLVMConstAShr(te1, te2) }
else { llvm::LLVMConstLShr(te1, te2) }
},
ast::BiEq | ast::BiNe | ast::BiLt | ast::BiLe | ast::BiGt | ast::BiGe => {
hir::BiEq | hir::BiNe | hir::BiLt | hir::BiLe | hir::BiGt | hir::BiGe => {
if is_float {
let cmp = base::bin_op_to_fcmp_predicate(cx, b.node);
ConstFCmp(cmp, te1, te2)
@ -552,34 +555,34 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
},
} } // unsafe { match b.node {
},
ast::ExprUnary(u, ref inner_e) => {
hir::ExprUnary(u, ref inner_e) => {
let (te, ty) = const_expr(cx, &**inner_e, param_substs, fn_args);
check_unary_expr_validity(cx, e, ty, te);
let is_float = ty.is_fp();
unsafe { match u {
ast::UnUniq | ast::UnDeref => const_deref(cx, te, ty).0,
ast::UnNot => llvm::LLVMConstNot(te),
ast::UnNeg if is_float => llvm::LLVMConstFNeg(te),
ast::UnNeg => llvm::LLVMConstNeg(te),
hir::UnUniq | hir::UnDeref => const_deref(cx, te, ty).0,
hir::UnNot => llvm::LLVMConstNot(te),
hir::UnNeg if is_float => llvm::LLVMConstFNeg(te),
hir::UnNeg => llvm::LLVMConstNeg(te),
} }
},
ast::ExprField(ref base, field) => {
hir::ExprField(ref base, field) => {
let (bv, bt) = const_expr(cx, &**base, param_substs, fn_args);
let brepr = adt::represent_type(cx, bt);
let vinfo = VariantInfo::from_ty(cx.tcx(), bt, None);
let ix = vinfo.field_index(field.node.name);
adt::const_get_field(cx, &*brepr, bv, vinfo.discr, ix)
},
ast::ExprTupField(ref base, idx) => {
hir::ExprTupField(ref base, idx) => {
let (bv, bt) = const_expr(cx, &**base, param_substs, fn_args);
let brepr = adt::represent_type(cx, bt);
let vinfo = VariantInfo::from_ty(cx.tcx(), bt, None);
adt::const_get_field(cx, &*brepr, bv, vinfo.discr, idx.node)
},
ast::ExprIndex(ref base, ref index) => {
hir::ExprIndex(ref base, ref index) => {
let (bv, bt) = const_expr(cx, &**base, param_substs, fn_args);
let iv = match eval_const_expr_partial(cx.tcx(), &index, ExprTypeChecked) {
Ok(ConstVal::Int(i)) => i as u64,
@ -629,7 +632,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
const_get_elt(cx, arr, &[iv as c_uint])
}
},
ast::ExprCast(ref base, _) => {
hir::ExprCast(ref base, _) => {
let t_cast = ety;
let llty = type_of::type_of(cx, t_cast);
let (v, t_expr) = const_expr(cx, &**base, param_substs, fn_args);
@ -690,15 +693,15 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
},
} } // unsafe { match ( ... ) {
},
ast::ExprAddrOf(ast::MutImmutable, ref sub) => {
hir::ExprAddrOf(hir::MutImmutable, ref sub) => {
// If this is the address of some static, then we need to return
// the actual address of the static itself (short circuit the rest
// of const eval).
let mut cur = sub;
loop {
match cur.node {
ast::ExprParen(ref sub) => cur = sub,
ast::ExprBlock(ref blk) => {
hir::ExprParen(ref sub) => cur = sub,
hir::ExprBlock(ref blk) => {
if let Some(ref sub) = blk.expr {
cur = sub;
} else {
@ -718,16 +721,16 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
addr_of(cx, v, "ref")
}
},
ast::ExprAddrOf(ast::MutMutable, ref sub) => {
hir::ExprAddrOf(hir::MutMutable, ref sub) => {
let (v, _) = const_expr(cx, &**sub, param_substs, fn_args);
addr_of_mut(cx, v, "ref_mut_slice")
},
ast::ExprTup(ref es) => {
hir::ExprTup(ref es) => {
let repr = adt::represent_type(cx, ety);
let vals = map_list(&es[..]);
adt::trans_const(cx, &*repr, 0, &vals[..])
},
ast::ExprStruct(_, ref fs, ref base_opt) => {
hir::ExprStruct(_, ref fs, ref base_opt) => {
let repr = adt::represent_type(cx, ety);
let base_val = match *base_opt {
@ -749,7 +752,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
adt::trans_const(cx, &*repr, discr, &cs[..])
}
},
ast::ExprVec(ref es) => {
hir::ExprVec(ref es) => {
let unit_ty = ety.sequence_element_type(cx.tcx());
let llunitty = type_of::type_of(cx, unit_ty);
let vs = es.iter()
@ -762,7 +765,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
C_array(llunitty, &vs[..])
}
},
ast::ExprRepeat(ref elem, ref count) => {
hir::ExprRepeat(ref elem, ref count) => {
let unit_ty = ety.sequence_element_type(cx.tcx());
let llunitty = type_of::type_of(cx, unit_ty);
let n = cx.tcx().eval_repeat_count(count);
@ -774,7 +777,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
C_array(llunitty, &vs[..])
}
},
ast::ExprPath(..) => {
hir::ExprPath(..) => {
let def = cx.tcx().def_map.borrow().get(&e.id).unwrap().full_def();
match def {
def::DefLocal(id) => {
@ -820,12 +823,12 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
}
}
},
ast::ExprCall(ref callee, ref args) => {
hir::ExprCall(ref callee, ref args) => {
let mut callee = &**callee;
loop {
callee = match callee.node {
ast::ExprParen(ref inner) => &**inner,
ast::ExprBlock(ref block) => match block.expr {
hir::ExprParen(ref inner) => &**inner,
hir::ExprBlock(ref block) => match block.expr {
Some(ref tail) => &**tail,
None => break,
},
@ -857,21 +860,21 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
_ => cx.sess().span_bug(e.span, "expected a struct, variant, or const fn def"),
}
},
ast::ExprMethodCall(_, _, ref args) => {
hir::ExprMethodCall(_, _, ref args) => {
let arg_vals = map_list(args);
let method_call = ty::MethodCall::expr(e.id);
let method_did = cx.tcx().tables.borrow().method_map[&method_call].def_id;
const_fn_call(cx, MethodCallKey(method_call),
method_did, &arg_vals, param_substs)
},
ast::ExprParen(ref e) => const_expr(cx, &**e, param_substs, fn_args).0,
ast::ExprBlock(ref block) => {
hir::ExprParen(ref e) => const_expr(cx, &**e, param_substs, fn_args).0,
hir::ExprBlock(ref block) => {
match block.expr {
Some(ref expr) => const_expr(cx, &**expr, param_substs, fn_args).0,
None => C_nil(cx),
}
},
ast::ExprClosure(_, ref decl, ref body) => {
hir::ExprClosure(_, ref decl, ref body) => {
match ety.sty {
ty::TyClosure(_, ref substs) => {
closure::trans_closure_expr(closure::Dest::Ignore(cx), decl,
@ -889,10 +892,10 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
}
}
pub fn trans_static(ccx: &CrateContext,
m: ast::Mutability,
expr: &ast::Expr,
m: hir::Mutability,
expr: &hir::Expr,
id: ast::NodeId,
attrs: &Vec<ast::Attribute>)
attrs: &Vec<hir::Attribute>)
-> ValueRef {
unsafe {
let _icx = push_ctxt("trans_static");
@ -934,7 +937,7 @@ pub fn trans_static(ccx: &CrateContext,
// As an optimization, all shared statics which do not have interior
// mutability are placed into read-only memory.
if m != ast::MutMutable {
if m != hir::MutMutable {
let tcontents = ty.type_contents(ccx.tcx());
if !tcontents.interior_unsafe() {
llvm::LLVMSetGlobalConstant(g, llvm::True);

Some files were not shown because too many files have changed in this diff Show More