auto merge of #19995 : eddyb/rust/split-resolve, r=nikomatsakis

r? @nikomatsakis
This commit is contained in:
bors 2014-12-20 05:52:18 +00:00
commit 8443b09e36
23 changed files with 565 additions and 475 deletions

View file

@ -53,7 +53,8 @@ TARGET_CRATES := libc std flate arena term \
serialize getopts collections test time rand \ serialize getopts collections test time rand \
log regex graphviz core rbml alloc \ log regex graphviz core rbml alloc \
unicode unicode
RUSTC_CRATES := rustc rustc_typeck rustc_borrowck rustc_driver rustc_trans rustc_back rustc_llvm RUSTC_CRATES := rustc rustc_typeck rustc_borrowck rustc_resolve rustc_driver \
rustc_trans rustc_back rustc_llvm
HOST_CRATES := syntax $(RUSTC_CRATES) rustdoc regex_macros fmt_macros HOST_CRATES := syntax $(RUSTC_CRATES) rustdoc regex_macros fmt_macros
CRATES := $(TARGET_CRATES) $(HOST_CRATES) CRATES := $(TARGET_CRATES) $(HOST_CRATES)
TOOLS := compiletest rustdoc rustc TOOLS := compiletest rustdoc rustc
@ -67,11 +68,12 @@ DEPS_std := core libc rand alloc collections unicode \
DEPS_graphviz := std DEPS_graphviz := std
DEPS_syntax := std term serialize log fmt_macros arena libc DEPS_syntax := std term serialize log fmt_macros arena libc
DEPS_rustc_driver := arena flate getopts graphviz libc rustc rustc_back rustc_borrowck \ DEPS_rustc_driver := arena flate getopts graphviz libc rustc rustc_back rustc_borrowck \
rustc_typeck log syntax serialize rustc_llvm rustc_trans rustc_typeck rustc_resolve log syntax serialize rustc_llvm rustc_trans
DEPS_rustc_trans := arena flate getopts graphviz libc rustc rustc_back \ DEPS_rustc_trans := arena flate getopts graphviz libc rustc rustc_back \
log syntax serialize rustc_llvm log syntax serialize rustc_llvm
DEPS_rustc_typeck := rustc syntax DEPS_rustc_typeck := rustc syntax
DEPS_rustc_borrowck := rustc log graphviz syntax DEPS_rustc_borrowck := rustc log graphviz syntax
DEPS_rustc_resolve := rustc log syntax
DEPS_rustc := syntax flate arena serialize getopts rbml \ DEPS_rustc := syntax flate arena serialize getopts rbml \
time log graphviz rustc_llvm rustc_back time log graphviz rustc_llvm rustc_back
DEPS_rustc_llvm := native:rustllvm libc std DEPS_rustc_llvm := native:rustllvm libc std
@ -118,9 +120,11 @@ DOC_CRATES := $(filter-out rustc, \
$(filter-out rustc_trans, \ $(filter-out rustc_trans, \
$(filter-out rustc_typeck, \ $(filter-out rustc_typeck, \
$(filter-out rustc_borrowck, \ $(filter-out rustc_borrowck, \
$(filter-out rustc_resolve, \
$(filter-out rustc_driver, \ $(filter-out rustc_driver, \
$(filter-out syntax, $(CRATES))))))) $(filter-out syntax, $(CRATES))))))))
COMPILER_DOC_CRATES := rustc rustc_trans rustc_borrowck rustc_typeck rustc_driver syntax COMPILER_DOC_CRATES := rustc rustc_trans rustc_borrowck rustc_resolve \
rustc_typeck rustc_driver syntax
# This macro creates some simple definitions for each crate being built, just # This macro creates some simple definitions for each crate being built, just
# some munging of all of the parameters above. # some munging of all of the parameters above.

View file

@ -21,7 +21,8 @@ $(eval $(call RUST_CRATE,coretest))
TEST_TARGET_CRATES = $(filter-out core unicode,$(TARGET_CRATES)) coretest TEST_TARGET_CRATES = $(filter-out core unicode,$(TARGET_CRATES)) coretest
TEST_DOC_CRATES = $(DOC_CRATES) TEST_DOC_CRATES = $(DOC_CRATES)
TEST_HOST_CRATES = $(filter-out rustc_typeck rustc_borrowck rustc_trans,$(HOST_CRATES)) TEST_HOST_CRATES = $(filter-out rustc_typeck rustc_borrowck rustc_resolve rustc_trans,\
$(HOST_CRATES))
TEST_CRATES = $(TEST_TARGET_CRATES) $(TEST_HOST_CRATES) TEST_CRATES = $(TEST_TARGET_CRATES) $(TEST_HOST_CRATES)
###################################################################### ######################################################################

View file

@ -90,7 +90,6 @@ pub mod middle {
pub mod reachable; pub mod reachable;
pub mod region; pub mod region;
pub mod recursion_limit; pub mod recursion_limit;
pub mod resolve;
pub mod resolve_lifetime; pub mod resolve_lifetime;
pub mod stability; pub mod stability;
pub mod subst; pub mod subst;

View file

@ -19,7 +19,6 @@ use metadata::cstore;
use metadata::decoder; use metadata::decoder;
use middle::def; use middle::def;
use middle::lang_items; use middle::lang_items;
use middle::resolve;
use middle::ty; use middle::ty;
use rbml; use rbml;
@ -148,7 +147,7 @@ pub fn get_impl_or_trait_item<'tcx>(tcx: &ty::ctxt<'tcx>, def: ast::DefId)
} }
pub fn get_trait_item_name_and_kind(cstore: &cstore::CStore, def: ast::DefId) pub fn get_trait_item_name_and_kind(cstore: &cstore::CStore, def: ast::DefId)
-> (ast::Name, resolve::TraitItemKind) { -> (ast::Name, def::TraitItemKind) {
let cdata = cstore.get_crate_data(def.krate); let cdata = cstore.get_crate_data(def.krate);
decoder::get_trait_item_name_and_kind(cstore.intr.clone(), decoder::get_trait_item_name_and_kind(cstore.intr.clone(),
&*cdata, &*cdata,

View file

@ -27,7 +27,6 @@ use metadata::tydecode::{parse_ty_data, parse_region_data, parse_def_id,
parse_predicate_data}; parse_predicate_data};
use middle::def; use middle::def;
use middle::lang_items; use middle::lang_items;
use middle::resolve::{TraitItemKind, TypeTraitItemKind};
use middle::subst; use middle::subst;
use middle::ty::{ImplContainer, TraitContainer}; use middle::ty::{ImplContainer, TraitContainer};
use middle::ty::{mod, Ty}; use middle::ty::{mod, Ty};
@ -785,15 +784,15 @@ pub fn get_impl_items(cdata: Cmd, impl_id: ast::NodeId)
pub fn get_trait_item_name_and_kind(intr: Rc<IdentInterner>, pub fn get_trait_item_name_and_kind(intr: Rc<IdentInterner>,
cdata: Cmd, cdata: Cmd,
id: ast::NodeId) id: ast::NodeId)
-> (ast::Name, TraitItemKind) { -> (ast::Name, def::TraitItemKind) {
let doc = lookup_item(id, cdata.data()); let doc = lookup_item(id, cdata.data());
let name = item_name(&*intr, doc); let name = item_name(&*intr, doc);
match item_sort(doc) { match item_sort(doc) {
'r' | 'p' => { 'r' | 'p' => {
let explicit_self = get_explicit_self(doc); let explicit_self = get_explicit_self(doc);
(name, TraitItemKind::from_explicit_self_category(explicit_self)) (name, def::TraitItemKind::from_explicit_self_category(explicit_self))
} }
't' => (name, TypeTraitItemKind), 't' => (name, def::TypeTraitItemKind),
c => { c => {
panic!("get_trait_item_name_and_kind(): unknown trait item kind \ panic!("get_trait_item_name_and_kind(): unknown trait item kind \
in metadata: `{}`", c) in metadata: `{}`", c)

View file

@ -21,10 +21,10 @@ use metadata::common::*;
use metadata::cstore; use metadata::cstore;
use metadata::decoder; use metadata::decoder;
use metadata::tyencode; use metadata::tyencode;
use middle::def;
use middle::ty::{lookup_item_type}; use middle::ty::{lookup_item_type};
use middle::ty::{mod, Ty}; use middle::ty::{mod, Ty};
use middle::stability; use middle::stability;
use middle;
use util::nodemap::{FnvHashMap, NodeMap, NodeSet}; use util::nodemap::{FnvHashMap, NodeMap, NodeSet};
use serialize::Encodable; use serialize::Encodable;
@ -66,7 +66,7 @@ pub type EncodeInlinedItem<'a> = |ecx: &EncodeContext,
pub struct EncodeParams<'a, 'tcx: 'a> { pub struct EncodeParams<'a, 'tcx: 'a> {
pub diag: &'a SpanHandler, pub diag: &'a SpanHandler,
pub tcx: &'a ty::ctxt<'tcx>, pub tcx: &'a ty::ctxt<'tcx>,
pub reexports2: &'a middle::resolve::ExportMap2, pub reexports: &'a def::ExportMap,
pub item_symbols: &'a RefCell<NodeMap<String>>, pub item_symbols: &'a RefCell<NodeMap<String>>,
pub link_meta: &'a LinkMeta, pub link_meta: &'a LinkMeta,
pub cstore: &'a cstore::CStore, pub cstore: &'a cstore::CStore,
@ -77,7 +77,7 @@ pub struct EncodeParams<'a, 'tcx: 'a> {
pub struct EncodeContext<'a, 'tcx: 'a> { pub struct EncodeContext<'a, 'tcx: 'a> {
pub diag: &'a SpanHandler, pub diag: &'a SpanHandler,
pub tcx: &'a ty::ctxt<'tcx>, pub tcx: &'a ty::ctxt<'tcx>,
pub reexports2: &'a middle::resolve::ExportMap2, pub reexports: &'a def::ExportMap,
pub item_symbols: &'a RefCell<NodeMap<String>>, pub item_symbols: &'a RefCell<NodeMap<String>>,
pub link_meta: &'a LinkMeta, pub link_meta: &'a LinkMeta,
pub cstore: &'a cstore::CStore, pub cstore: &'a cstore::CStore,
@ -379,7 +379,7 @@ fn encode_path<PI: Iterator<PathElem>>(rbml_w: &mut Encoder, path: PI) {
} }
fn encode_reexported_static_method(rbml_w: &mut Encoder, fn encode_reexported_static_method(rbml_w: &mut Encoder,
exp: &middle::resolve::Export2, exp: &def::Export,
method_def_id: DefId, method_def_id: DefId,
method_name: ast::Name) { method_name: ast::Name) {
debug!("(encode reexported static method) {}::{}", debug!("(encode reexported static method) {}::{}",
@ -398,7 +398,7 @@ fn encode_reexported_static_method(rbml_w: &mut Encoder,
fn encode_reexported_static_base_methods(ecx: &EncodeContext, fn encode_reexported_static_base_methods(ecx: &EncodeContext,
rbml_w: &mut Encoder, rbml_w: &mut Encoder,
exp: &middle::resolve::Export2) exp: &def::Export)
-> bool { -> bool {
let impl_items = ecx.tcx.impl_items.borrow(); let impl_items = ecx.tcx.impl_items.borrow();
match ecx.tcx.inherent_impls.borrow().get(&exp.def_id) { match ecx.tcx.inherent_impls.borrow().get(&exp.def_id) {
@ -428,7 +428,7 @@ fn encode_reexported_static_base_methods(ecx: &EncodeContext,
fn encode_reexported_static_trait_methods(ecx: &EncodeContext, fn encode_reexported_static_trait_methods(ecx: &EncodeContext,
rbml_w: &mut Encoder, rbml_w: &mut Encoder,
exp: &middle::resolve::Export2) exp: &def::Export)
-> bool { -> bool {
match ecx.tcx.trait_items_cache.borrow().get(&exp.def_id) { match ecx.tcx.trait_items_cache.borrow().get(&exp.def_id) {
Some(trait_items) => { Some(trait_items) => {
@ -449,10 +449,8 @@ fn encode_reexported_static_trait_methods(ecx: &EncodeContext,
fn encode_reexported_static_methods(ecx: &EncodeContext, fn encode_reexported_static_methods(ecx: &EncodeContext,
rbml_w: &mut Encoder, rbml_w: &mut Encoder,
mod_path: PathElems, mod_path: PathElems,
exp: &middle::resolve::Export2) { exp: &def::Export) {
if let Some(ast_map::NodeItem(item)) = ecx.tcx.map.find(exp.def_id.node) { if let Some(ast_map::NodeItem(item)) = ecx.tcx.map.find(exp.def_id.node) {
let original_name = token::get_ident(item.ident);
let path_differs = ecx.tcx.map.with_path(exp.def_id.node, |path| { let path_differs = ecx.tcx.map.with_path(exp.def_id.node, |path| {
let (mut a, mut b) = (path, mod_path.clone()); let (mut a, mut b) = (path, mod_path.clone());
loop { loop {
@ -474,16 +472,16 @@ fn encode_reexported_static_methods(ecx: &EncodeContext,
// encoded metadata for static methods relative to Bar, // encoded metadata for static methods relative to Bar,
// but not yet for Foo. // but not yet for Foo.
// //
if path_differs || original_name.get() != exp.name { if path_differs || item.ident.name != exp.name {
if !encode_reexported_static_base_methods(ecx, rbml_w, exp) { if !encode_reexported_static_base_methods(ecx, rbml_w, exp) {
if encode_reexported_static_trait_methods(ecx, rbml_w, exp) { if encode_reexported_static_trait_methods(ecx, rbml_w, exp) {
debug!("(encode reexported static methods) {} [trait]", debug!("(encode reexported static methods) {} [trait]",
original_name); item.ident.name);
} }
} }
else { else {
debug!("(encode reexported static methods) {} [base]", debug!("(encode reexported static methods) {} [base]",
original_name); item.ident.name);
} }
} }
} }
@ -519,7 +517,7 @@ fn encode_reexports(ecx: &EncodeContext,
id: NodeId, id: NodeId,
path: PathElems) { path: PathElems) {
debug!("(encoding info for module) encoding reexports for {}", id); debug!("(encoding info for module) encoding reexports for {}", id);
match ecx.reexports2.get(&id) { match ecx.reexports.get(&id) {
Some(ref exports) => { Some(ref exports) => {
debug!("(encoding info for module) found reexports for {}", id); debug!("(encoding info for module) found reexports for {}", id);
for exp in exports.iter() { for exp in exports.iter() {
@ -534,7 +532,7 @@ fn encode_reexports(ecx: &EncodeContext,
rbml_w.wr_str(def_to_string(exp.def_id).as_slice()); rbml_w.wr_str(def_to_string(exp.def_id).as_slice());
rbml_w.end_tag(); rbml_w.end_tag();
rbml_w.start_tag(tag_items_data_item_reexport_name); rbml_w.start_tag(tag_items_data_item_reexport_name);
rbml_w.wr_str(exp.name.as_slice()); rbml_w.wr_str(exp.name.as_str());
rbml_w.end_tag(); rbml_w.end_tag();
rbml_w.end_tag(); rbml_w.end_tag();
encode_reexported_static_methods(ecx, rbml_w, path.clone(), exp); encode_reexported_static_methods(ecx, rbml_w, path.clone(), exp);
@ -2071,7 +2069,7 @@ fn encode_metadata_inner(wr: &mut SeekableMemWriter,
item_symbols, item_symbols,
diag, diag,
tcx, tcx,
reexports2, reexports,
cstore, cstore,
encode_inlined_item, encode_inlined_item,
link_meta, link_meta,
@ -2081,7 +2079,7 @@ fn encode_metadata_inner(wr: &mut SeekableMemWriter,
let ecx = EncodeContext { let ecx = EncodeContext {
diag: diag, diag: diag,
tcx: tcx, tcx: tcx,
reexports2: reexports2, reexports: reexports,
item_symbols: item_symbols, item_symbols: item_symbols,
link_meta: link_meta, link_meta: link_meta,
cstore: cstore, cstore: cstore,

View file

@ -12,8 +12,7 @@
// recursively. // recursively.
use session::Session; use session::Session;
use middle::resolve; use middle::def::{DefStatic, DefConst, DefMap};
use middle::def::{DefStatic, DefConst};
use syntax::ast; use syntax::ast;
use syntax::{ast_util, ast_map}; use syntax::{ast_util, ast_map};
@ -22,7 +21,7 @@ use syntax::visit;
struct CheckCrateVisitor<'a, 'ast: 'a> { struct CheckCrateVisitor<'a, 'ast: 'a> {
sess: &'a Session, sess: &'a Session,
def_map: &'a resolve::DefMap, def_map: &'a DefMap,
ast_map: &'a ast_map::Map<'ast> ast_map: &'a ast_map::Map<'ast>
} }
@ -34,7 +33,7 @@ impl<'v, 'a, 'ast> Visitor<'v> for CheckCrateVisitor<'a, 'ast> {
pub fn check_crate<'ast>(sess: &Session, pub fn check_crate<'ast>(sess: &Session,
krate: &ast::Crate, krate: &ast::Crate,
def_map: &resolve::DefMap, def_map: &DefMap,
ast_map: &ast_map::Map<'ast>) { ast_map: &ast_map::Map<'ast>) {
let mut visitor = CheckCrateVisitor { let mut visitor = CheckCrateVisitor {
sess: sess, sess: sess,
@ -60,7 +59,7 @@ struct CheckItemRecursionVisitor<'a, 'ast: 'a> {
root_it: &'a ast::Item, root_it: &'a ast::Item,
sess: &'a Session, sess: &'a Session,
ast_map: &'a ast_map::Map<'ast>, ast_map: &'a ast_map::Map<'ast>,
def_map: &'a resolve::DefMap, def_map: &'a DefMap,
idstack: Vec<ast::NodeId> idstack: Vec<ast::NodeId>
} }
@ -68,7 +67,7 @@ struct CheckItemRecursionVisitor<'a, 'ast: 'a> {
// FIXME: Should use the dependency graph when it's available (#1356) // FIXME: Should use the dependency graph when it's available (#1356)
pub fn check_item_recursion<'a>(sess: &'a Session, pub fn check_item_recursion<'a>(sess: &'a Session,
ast_map: &'a ast_map::Map, ast_map: &'a ast_map::Map,
def_map: &'a resolve::DefMap, def_map: &'a DefMap,
it: &'a ast::Item) { it: &'a ast::Item) {
let mut visitor = CheckItemRecursionVisitor { let mut visitor = CheckItemRecursionVisitor {

View file

@ -10,11 +10,16 @@
pub use self::Def::*; pub use self::Def::*;
pub use self::MethodProvenance::*; pub use self::MethodProvenance::*;
pub use self::TraitItemKind::*;
use middle::subst::ParamSpace; use middle::subst::ParamSpace;
use middle::ty::{ExplicitSelfCategory, StaticExplicitSelfCategory};
use util::nodemap::NodeMap;
use syntax::ast; use syntax::ast;
use syntax::ast_util::local_def; use syntax::ast_util::local_def;
use std::cell::RefCell;
#[deriving(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Show)] #[deriving(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
pub enum Def { pub enum Def {
DefFn(ast::DefId, bool /* is_ctor */), DefFn(ast::DefId, bool /* is_ctor */),
@ -56,6 +61,18 @@ pub enum Def {
DefMethod(ast::DefId /* method */, Option<ast::DefId> /* trait */, MethodProvenance), DefMethod(ast::DefId /* method */, Option<ast::DefId> /* trait */, MethodProvenance),
} }
// Definition mapping
pub type DefMap = RefCell<NodeMap<Def>>;
// This is the replacement export map. It maps a module to all of the exports
// within.
pub type ExportMap = NodeMap<Vec<Export>>;
#[deriving(Copy)]
pub struct Export {
pub name: ast::Name, // The name of the target.
pub def_id: ast::DefId, // The definition of the target.
}
#[deriving(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Show)] #[deriving(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
pub enum MethodProvenance { pub enum MethodProvenance {
FromTrait(ast::DefId), FromTrait(ast::DefId),
@ -88,6 +105,25 @@ impl TyParamProvenance {
} }
} }
#[deriving(Clone, Copy, Eq, PartialEq)]
pub enum TraitItemKind {
NonstaticMethodTraitItemKind,
StaticMethodTraitItemKind,
TypeTraitItemKind,
}
impl TraitItemKind {
pub fn from_explicit_self_category(explicit_self_category:
ExplicitSelfCategory)
-> TraitItemKind {
if explicit_self_category == StaticExplicitSelfCategory {
StaticMethodTraitItemKind
} else {
NonstaticMethodTraitItemKind
}
}
}
impl Def { impl Def {
pub fn def_id(&self) -> ast::DefId { pub fn def_id(&self) -> ast::DefId {
match *self { match *self {
@ -122,4 +158,3 @@ impl Def {
} }
} }
} }

View file

@ -9,7 +9,6 @@
// except according to those terms. // except according to those terms.
use middle::def::*; use middle::def::*;
use middle::resolve;
use middle::ty; use middle::ty;
use util::nodemap::FnvHashMap; use util::nodemap::FnvHashMap;
@ -21,7 +20,7 @@ pub type PatIdMap = FnvHashMap<ast::Ident, ast::NodeId>;
// This is used because same-named variables in alternative patterns need to // This is used because same-named variables in alternative patterns need to
// use the NodeId of their namesake in the first pattern. // use the NodeId of their namesake in the first pattern.
pub fn pat_id_map(dm: &resolve::DefMap, pat: &ast::Pat) -> PatIdMap { pub fn pat_id_map(dm: &DefMap, pat: &ast::Pat) -> PatIdMap {
let mut map = FnvHashMap::new(); let mut map = FnvHashMap::new();
pat_bindings(dm, pat, |_bm, p_id, _s, path1| { pat_bindings(dm, pat, |_bm, p_id, _s, path1| {
map.insert(path1.node, p_id); map.insert(path1.node, p_id);
@ -29,7 +28,7 @@ pub fn pat_id_map(dm: &resolve::DefMap, pat: &ast::Pat) -> PatIdMap {
map map
} }
pub fn pat_is_refutable(dm: &resolve::DefMap, pat: &ast::Pat) -> bool { pub fn pat_is_refutable(dm: &DefMap, pat: &ast::Pat) -> bool {
match pat.node { match pat.node {
ast::PatLit(_) | ast::PatRange(_, _) => true, ast::PatLit(_) | ast::PatRange(_, _) => true,
ast::PatEnum(_, _) | ast::PatEnum(_, _) |
@ -45,7 +44,7 @@ pub fn pat_is_refutable(dm: &resolve::DefMap, pat: &ast::Pat) -> bool {
} }
} }
pub fn pat_is_variant_or_struct(dm: &resolve::DefMap, pat: &ast::Pat) -> bool { pub fn pat_is_variant_or_struct(dm: &DefMap, pat: &ast::Pat) -> bool {
match pat.node { match pat.node {
ast::PatEnum(_, _) | ast::PatEnum(_, _) |
ast::PatIdent(_, _, None) | ast::PatIdent(_, _, None) |
@ -59,7 +58,7 @@ pub fn pat_is_variant_or_struct(dm: &resolve::DefMap, pat: &ast::Pat) -> bool {
} }
} }
pub fn pat_is_const(dm: &resolve::DefMap, pat: &ast::Pat) -> bool { pub fn pat_is_const(dm: &DefMap, pat: &ast::Pat) -> bool {
match pat.node { match pat.node {
ast::PatIdent(_, _, None) | ast::PatEnum(..) => { ast::PatIdent(_, _, None) | ast::PatEnum(..) => {
match dm.borrow().get(&pat.id) { match dm.borrow().get(&pat.id) {
@ -71,7 +70,7 @@ pub fn pat_is_const(dm: &resolve::DefMap, pat: &ast::Pat) -> bool {
} }
} }
pub fn pat_is_binding(dm: &resolve::DefMap, pat: &ast::Pat) -> bool { pub fn pat_is_binding(dm: &DefMap, pat: &ast::Pat) -> bool {
match pat.node { match pat.node {
ast::PatIdent(..) => { ast::PatIdent(..) => {
!pat_is_variant_or_struct(dm, pat) && !pat_is_variant_or_struct(dm, pat) &&
@ -81,7 +80,7 @@ pub fn pat_is_binding(dm: &resolve::DefMap, pat: &ast::Pat) -> bool {
} }
} }
pub fn pat_is_binding_or_wild(dm: &resolve::DefMap, pat: &ast::Pat) -> bool { pub fn pat_is_binding_or_wild(dm: &DefMap, pat: &ast::Pat) -> bool {
match pat.node { match pat.node {
ast::PatIdent(..) => pat_is_binding(dm, pat), ast::PatIdent(..) => pat_is_binding(dm, pat),
ast::PatWild(_) => true, ast::PatWild(_) => true,
@ -91,7 +90,7 @@ pub fn pat_is_binding_or_wild(dm: &resolve::DefMap, pat: &ast::Pat) -> bool {
/// Call `it` on every "binding" in a pattern, e.g., on `a` in /// Call `it` on every "binding" in a pattern, e.g., on `a` in
/// `match foo() { Some(a) => (), None => () }` /// `match foo() { Some(a) => (), None => () }`
pub fn pat_bindings<I>(dm: &resolve::DefMap, pat: &ast::Pat, mut it: I) where pub fn pat_bindings<I>(dm: &DefMap, pat: &ast::Pat, mut it: I) where
I: FnMut(ast::BindingMode, ast::NodeId, Span, &ast::SpannedIdent), I: FnMut(ast::BindingMode, ast::NodeId, Span, &ast::SpannedIdent),
{ {
walk_pat(pat, |p| { walk_pat(pat, |p| {
@ -107,7 +106,7 @@ pub fn pat_bindings<I>(dm: &resolve::DefMap, pat: &ast::Pat, mut it: I) where
/// Checks if the pattern contains any patterns that bind something to /// Checks if the pattern contains any patterns that bind something to
/// an ident, e.g. `foo`, or `Foo(foo)` or `foo @ Bar(..)`. /// an ident, e.g. `foo`, or `Foo(foo)` or `foo @ Bar(..)`.
pub fn pat_contains_bindings(dm: &resolve::DefMap, pat: &ast::Pat) -> bool { pub fn pat_contains_bindings(dm: &DefMap, pat: &ast::Pat) -> bool {
let mut contains_bindings = false; let mut contains_bindings = false;
walk_pat(pat, |p| { walk_pat(pat, |p| {
if pat_is_binding(dm, p) { if pat_is_binding(dm, p) {

View file

@ -11,17 +11,20 @@
//! A pass that checks to make sure private fields and methods aren't used //! A pass that checks to make sure private fields and methods aren't used
//! outside their scopes. This pass will also generate a set of exported items //! outside their scopes. This pass will also generate a set of exported items
//! which are available for use externally when compiled as a library. //! which are available for use externally when compiled as a library.
pub use self::PrivateDep::*;
pub use self::ImportUse::*;
pub use self::LastPrivate::*;
use self::PrivacyResult::*; use self::PrivacyResult::*;
use self::FieldName::*; use self::FieldName::*;
use std::mem::replace; use std::mem::replace;
use metadata::csearch; use metadata::csearch;
use middle::{def, resolve}; use middle::def;
use middle::ty::{mod, Ty}; use middle::ty::{mod, Ty};
use middle::ty::{MethodCall, MethodMap, MethodOrigin, MethodParam, MethodTypeParam}; use middle::ty::{MethodCall, MethodMap, MethodOrigin, MethodParam, MethodTypeParam};
use middle::ty::{MethodStatic, MethodStaticUnboxedClosure, MethodObject, MethodTraitObject}; use middle::ty::{MethodStatic, MethodStaticUnboxedClosure, MethodObject, MethodTraitObject};
use util::nodemap::{NodeMap, NodeSet}; use util::nodemap::{DefIdSet, NodeMap, NodeSet};
use syntax::{ast, ast_map}; use syntax::{ast, ast_map};
use syntax::ast_util::{is_local, local_def, PostExpansionMethod}; use syntax::ast_util::{is_local, local_def, PostExpansionMethod};
@ -29,16 +32,59 @@ use syntax::codemap::Span;
use syntax::parse::token; use syntax::parse::token;
use syntax::visit::{mod, Visitor}; use syntax::visit::{mod, Visitor};
type Context<'a, 'tcx> = (&'a MethodMap<'tcx>, &'a resolve::ExportMap2); type Context<'a, 'tcx> = (&'a MethodMap<'tcx>, &'a def::ExportMap);
/// A set of AST nodes exported by the crate. /// A set of AST nodes exported by the crate.
pub type ExportedItems = NodeSet; pub type ExportedItems = NodeSet;
/// A set containing all exported definitions from external crates.
/// The set does not contain any entries from local crates.
pub type ExternalExports = DefIdSet;
/// A set of AST nodes that are fully public in the crate. This map is used for /// A set of AST nodes that are fully public in the crate. This map is used for
/// documentation purposes (reexporting a private struct inlines the doc, /// documentation purposes (reexporting a private struct inlines the doc,
/// reexporting a public struct doesn't inline the doc). /// reexporting a public struct doesn't inline the doc).
pub type PublicItems = NodeSet; pub type PublicItems = NodeSet;
// FIXME: dox
pub type LastPrivateMap = NodeMap<LastPrivate>;
#[deriving(Copy, Show)]
pub enum LastPrivate {
LastMod(PrivateDep),
// `use` directives (imports) can refer to two separate definitions in the
// type and value namespaces. We record here the last private node for each
// and whether the import is in fact used for each.
// If the Option<PrivateDep> fields are None, it means there is no definition
// in that namespace.
LastImport{value_priv: Option<PrivateDep>,
value_used: ImportUse,
type_priv: Option<PrivateDep>,
type_used: ImportUse},
}
#[deriving(Copy, Show)]
pub enum PrivateDep {
AllPublic,
DependsOn(ast::DefId),
}
// How an import is used.
#[deriving(Copy, PartialEq, Show)]
pub enum ImportUse {
Unused, // The import is not used.
Used, // The import is used.
}
impl LastPrivate {
pub fn or(self, other: LastPrivate) -> LastPrivate {
match (self, other) {
(me, LastMod(AllPublic)) => me,
(_, other) => other,
}
}
}
/// Result of a checking operation - None => no errors were found. Some => an /// Result of a checking operation - None => no errors were found. Some => an
/// error and contains the span and message for reporting that error and /// error and contains the span and message for reporting that error and
/// optionally the same for a note about the error. /// optionally the same for a note about the error.
@ -136,7 +182,7 @@ impl<'v> Visitor<'v> for ParentVisitor {
struct EmbargoVisitor<'a, 'tcx: 'a> { struct EmbargoVisitor<'a, 'tcx: 'a> {
tcx: &'a ty::ctxt<'tcx>, tcx: &'a ty::ctxt<'tcx>,
exp_map2: &'a resolve::ExportMap2, export_map: &'a def::ExportMap,
// This flag is an indicator of whether the previous item in the // This flag is an indicator of whether the previous item in the
// hierarchical chain was exported or not. This is the indicator of whether // hierarchical chain was exported or not. This is the indicator of whether
@ -342,8 +388,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> {
// This code is here instead of in visit_item so that the // This code is here instead of in visit_item so that the
// crate module gets processed as well. // crate module gets processed as well.
if self.prev_exported { if self.prev_exported {
assert!(self.exp_map2.contains_key(&id), "wut {}", id); assert!(self.export_map.contains_key(&id), "wut {}", id);
for export in self.exp_map2[id].iter() { for export in self.export_map[id].iter() {
if is_local(export.def_id) { if is_local(export.def_id) {
self.reexports.insert(export.def_id.node); self.reexports.insert(export.def_id.node);
} }
@ -362,8 +408,8 @@ struct PrivacyVisitor<'a, 'tcx: 'a> {
curitem: ast::NodeId, curitem: ast::NodeId,
in_foreign: bool, in_foreign: bool,
parents: NodeMap<ast::NodeId>, parents: NodeMap<ast::NodeId>,
external_exports: resolve::ExternalExports, external_exports: ExternalExports,
last_private_map: resolve::LastPrivateMap, last_private_map: LastPrivateMap,
} }
enum PrivacyResult { enum PrivacyResult {
@ -719,25 +765,25 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
}; };
match self.last_private_map[path_id] { match self.last_private_map[path_id] {
resolve::LastMod(resolve::AllPublic) => {}, LastMod(AllPublic) => {},
resolve::LastMod(resolve::DependsOn(def)) => { LastMod(DependsOn(def)) => {
self.report_error(ck_public(def)); self.report_error(ck_public(def));
}, },
resolve::LastImport{value_priv, LastImport { value_priv,
value_used: check_value, value_used: check_value,
type_priv, type_priv,
type_used: check_type} => { type_used: check_type } => {
// This dance with found_error is because we don't want to report // This dance with found_error is because we don't want to report
// a privacy error twice for the same directive. // a privacy error twice for the same directive.
let found_error = match (type_priv, check_type) { let found_error = match (type_priv, check_type) {
(Some(resolve::DependsOn(def)), resolve::Used) => { (Some(DependsOn(def)), Used) => {
!self.report_error(ck_public(def)) !self.report_error(ck_public(def))
}, },
_ => false, _ => false,
}; };
if !found_error { if !found_error {
match (value_priv, check_value) { match (value_priv, check_value) {
(Some(resolve::DependsOn(def)), resolve::Used) => { (Some(DependsOn(def)), Used) => {
self.report_error(ck_public(def)); self.report_error(ck_public(def));
}, },
_ => {}, _ => {},
@ -749,24 +795,24 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
// be illegal. We only report one error, even if it is // be illegal. We only report one error, even if it is
// illegal to import from both namespaces. // illegal to import from both namespaces.
match (value_priv, check_value, type_priv, check_type) { match (value_priv, check_value, type_priv, check_type) {
(Some(p), resolve::Unused, None, _) | (Some(p), Unused, None, _) |
(None, _, Some(p), resolve::Unused) => { (None, _, Some(p), Unused) => {
let p = match p { let p = match p {
resolve::AllPublic => None, AllPublic => None,
resolve::DependsOn(def) => ck_public(def), DependsOn(def) => ck_public(def),
}; };
if p.is_some() { if p.is_some() {
self.report_error(p); self.report_error(p);
} }
}, },
(Some(v), resolve::Unused, Some(t), resolve::Unused) => { (Some(v), Unused, Some(t), Unused) => {
let v = match v { let v = match v {
resolve::AllPublic => None, AllPublic => None,
resolve::DependsOn(def) => ck_public(def), DependsOn(def) => ck_public(def),
}; };
let t = match t { let t = match t {
resolve::AllPublic => None, AllPublic => None,
resolve::DependsOn(def) => ck_public(def), DependsOn(def) => ck_public(def),
}; };
if let (Some(_), Some(t)) = (v, t) { if let (Some(_), Some(t)) = (v, t) {
self.report_error(Some(t)); self.report_error(Some(t));
@ -1520,9 +1566,9 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> {
} }
pub fn check_crate(tcx: &ty::ctxt, pub fn check_crate(tcx: &ty::ctxt,
exp_map2: &resolve::ExportMap2, export_map: &def::ExportMap,
external_exports: resolve::ExternalExports, external_exports: ExternalExports,
last_private_map: resolve::LastPrivateMap) last_private_map: LastPrivateMap)
-> (ExportedItems, PublicItems) { -> (ExportedItems, PublicItems) {
let krate = tcx.map.krate(); let krate = tcx.map.krate();
@ -1561,7 +1607,7 @@ pub fn check_crate(tcx: &ty::ctxt,
exported_items: NodeSet::new(), exported_items: NodeSet::new(),
public_items: NodeSet::new(), public_items: NodeSet::new(),
reexports: NodeSet::new(), reexports: NodeSet::new(),
exp_map2: exp_map2, export_map: export_map,
prev_exported: true, prev_exported: true,
prev_public: true, prev_public: true,
}; };

View file

@ -19,9 +19,8 @@ pub use self::DefRegion::*;
use self::ScopeChain::*; use self::ScopeChain::*;
use session::Session; use session::Session;
use middle::def; use middle::def::{mod, DefMap};
use middle::region; use middle::region;
use middle::resolve::DefMap;
use middle::subst; use middle::subst;
use middle::ty; use middle::ty;
use std::fmt; use std::fmt;

View file

@ -46,13 +46,12 @@ use lint;
use metadata::csearch; use metadata::csearch;
use middle; use middle;
use middle::const_eval; use middle::const_eval;
use middle::def; use middle::def::{mod, DefMap, ExportMap};
use middle::dependency_format; use middle::dependency_format;
use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem}; use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem};
use middle::lang_items::{FnOnceTraitLangItem, TyDescStructLangItem}; use middle::lang_items::{FnOnceTraitLangItem, TyDescStructLangItem};
use middle::mem_categorization as mc; use middle::mem_categorization as mc;
use middle::region; use middle::region;
use middle::resolve;
use middle::resolve_lifetime; use middle::resolve_lifetime;
use middle::infer; use middle::infer;
use middle::stability; use middle::stability;
@ -99,7 +98,7 @@ pub const INITIAL_DISCRIMINANT_VALUE: Disr = 0;
/// The complete set of all analyses described in this module. This is /// The complete set of all analyses described in this module. This is
/// produced by the driver and fed to trans and later passes. /// produced by the driver and fed to trans and later passes.
pub struct CrateAnalysis<'tcx> { pub struct CrateAnalysis<'tcx> {
pub exp_map2: middle::resolve::ExportMap2, pub export_map: ExportMap,
pub exported_items: middle::privacy::ExportedItems, pub exported_items: middle::privacy::ExportedItems,
pub public_items: middle::privacy::PublicItems, pub public_items: middle::privacy::PublicItems,
pub ty_cx: ty::ctxt<'tcx>, pub ty_cx: ty::ctxt<'tcx>,
@ -615,7 +614,7 @@ pub struct ctxt<'tcx> {
// queried from a HashSet. // queried from a HashSet.
interner: RefCell<FnvHashMap<InternedTy<'tcx>, Ty<'tcx>>>, interner: RefCell<FnvHashMap<InternedTy<'tcx>, Ty<'tcx>>>,
pub sess: Session, pub sess: Session,
pub def_map: resolve::DefMap, pub def_map: DefMap,
pub named_region_map: resolve_lifetime::NamedRegionMap, pub named_region_map: resolve_lifetime::NamedRegionMap,
@ -1967,7 +1966,7 @@ impl UnboxedClosureKind {
pub fn mk_ctxt<'tcx>(s: Session, pub fn mk_ctxt<'tcx>(s: Session,
type_arena: &'tcx TypedArena<TyS<'tcx>>, type_arena: &'tcx TypedArena<TyS<'tcx>>,
dm: resolve::DefMap, dm: DefMap,
named_region_map: resolve_lifetime::NamedRegionMap, named_region_map: resolve_lifetime::NamedRegionMap,
map: ast_map::Map<'tcx>, map: ast_map::Map<'tcx>,
freevars: RefCell<FreevarMap>, freevars: RefCell<FreevarMap>,
@ -6263,6 +6262,9 @@ pub type FreevarMap = NodeMap<Vec<Freevar>>;
pub type CaptureModeMap = NodeMap<ast::CaptureClause>; pub type CaptureModeMap = NodeMap<ast::CaptureClause>;
// Trait method resolution
pub type TraitMap = NodeMap<Vec<DefId>>;
pub fn with_freevars<T, F>(tcx: &ty::ctxt, fid: ast::NodeId, f: F) -> T where pub fn with_freevars<T, F>(tcx: &ty::ctxt, fid: ast::NodeId, f: F) -> T where
F: FnOnce(&[Freevar]) -> T, F: FnOnce(&[Freevar]) -> T,
{ {

View file

@ -20,6 +20,7 @@ use rustc::plugin::registry::Registry;
use rustc::plugin; use rustc::plugin;
use rustc::util::common::time; use rustc::util::common::time;
use rustc_borrowck as borrowck; use rustc_borrowck as borrowck;
use rustc_resolve as resolve;
use rustc_trans::back::link; use rustc_trans::back::link;
use rustc_trans::back::write; use rustc_trans::back::write;
use rustc_trans::save; use rustc_trans::save;
@ -341,17 +342,17 @@ pub fn phase_3_run_analysis_passes<'tcx>(sess: Session,
let lang_items = time(time_passes, "language item collection", (), |_| let lang_items = time(time_passes, "language item collection", (), |_|
middle::lang_items::collect_language_items(krate, &sess)); middle::lang_items::collect_language_items(krate, &sess));
let middle::resolve::CrateMap { let resolve::CrateMap {
def_map, def_map,
freevars, freevars,
capture_mode_map, capture_mode_map,
exp_map2, export_map,
trait_map, trait_map,
external_exports, external_exports,
last_private_map last_private_map
} = } =
time(time_passes, "resolution", (), |_| time(time_passes, "resolution", (),
middle::resolve::resolve_crate(&sess, &lang_items, krate)); |_| resolve::resolve_crate(&sess, &lang_items, krate));
// Discard MTWT tables that aren't required past resolution. // Discard MTWT tables that aren't required past resolution.
syntax::ext::mtwt::clear_tables(); syntax::ext::mtwt::clear_tables();
@ -406,7 +407,7 @@ pub fn phase_3_run_analysis_passes<'tcx>(sess: Session,
let maps = (external_exports, last_private_map); let maps = (external_exports, last_private_map);
let (exported_items, public_items) = let (exported_items, public_items) =
time(time_passes, "privacy checking", maps, |(a, b)| time(time_passes, "privacy checking", maps, |(a, b)|
middle::privacy::check_crate(&ty_cx, &exp_map2, a, b)); middle::privacy::check_crate(&ty_cx, &export_map, a, b));
time(time_passes, "intrinsic checking", (), |_| time(time_passes, "intrinsic checking", (), |_|
middle::intrinsicck::check_crate(&ty_cx)); middle::intrinsicck::check_crate(&ty_cx));
@ -447,7 +448,7 @@ pub fn phase_3_run_analysis_passes<'tcx>(sess: Session,
lint::check_crate(&ty_cx, &exported_items)); lint::check_crate(&ty_cx, &exported_items));
ty::CrateAnalysis { ty::CrateAnalysis {
exp_map2: exp_map2, export_map: export_map,
ty_cx: ty_cx, ty_cx: ty_cx,
exported_items: exported_items, exported_items: exported_items,
public_items: public_items, public_items: public_items,

View file

@ -35,6 +35,7 @@ extern crate libc;
extern crate rustc; extern crate rustc;
extern crate rustc_back; extern crate rustc_back;
extern crate rustc_borrowck; extern crate rustc_borrowck;
extern crate rustc_resolve;
extern crate rustc_trans; extern crate rustc_trans;
extern crate rustc_typeck; extern crate rustc_typeck;
#[phase(plugin, link)] extern crate log; #[phase(plugin, link)] extern crate log;

View file

@ -13,9 +13,9 @@
use diagnostic; use diagnostic;
use diagnostic::Emitter; use diagnostic::Emitter;
use driver; use driver;
use rustc_resolve as resolve;
use rustc_typeck::middle::lang_items; use rustc_typeck::middle::lang_items;
use rustc_typeck::middle::region::{mod, CodeExtent}; use rustc_typeck::middle::region::{mod, CodeExtent};
use rustc_typeck::middle::resolve;
use rustc_typeck::middle::resolve_lifetime; use rustc_typeck::middle::resolve_lifetime;
use rustc_typeck::middle::stability; use rustc_typeck::middle::stability;
use rustc_typeck::middle::subst; use rustc_typeck::middle::subst;

View file

@ -0,0 +1,161 @@
// Copyright 2012-2014 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.
//
// Unused import checking
//
// Although this is mostly a lint pass, it lives in here because it depends on
// resolve data structures and because it finalises the privacy information for
// `use` directives.
//
use Resolver;
use Namespace::{TypeNS, ValueNS};
use rustc::lint;
use rustc::middle::privacy::{DependsOn, LastImport, Used, Unused};
use syntax::ast;
use syntax::ast::{ViewItem, ViewItemExternCrate, ViewItemUse};
use syntax::ast::{ViewPathGlob, ViewPathList, ViewPathSimple};
use syntax::codemap::{Span, DUMMY_SP};
use syntax::visit::{mod, Visitor};
struct UnusedImportCheckVisitor<'a, 'b:'a> {
resolver: &'a mut Resolver<'b>
}
// Deref and DerefMut impls allow treating UnusedImportCheckVisitor as Resolver.
impl<'a, 'b> Deref<Resolver<'b>> for UnusedImportCheckVisitor<'a, 'b> {
fn deref<'c>(&'c self) -> &'c Resolver<'b> {
&*self.resolver
}
}
impl<'a, 'b> DerefMut<Resolver<'b>> for UnusedImportCheckVisitor<'a, 'b> {
fn deref_mut<'c>(&'c mut self) -> &'c mut Resolver<'b> {
&mut *self.resolver
}
}
impl<'a, 'b> UnusedImportCheckVisitor<'a, 'b> {
// We have information about whether `use` (import) directives are actually used now.
// If an import is not used at all, we signal a lint error. If an import is only used
// for a single namespace, we remove the other namespace from the recorded privacy
// information. That means in privacy.rs, we will only check imports and namespaces
// which are used. In particular, this means that if an import could name either a
// public or private item, we will check the correct thing, dependent on how the import
// is used.
fn finalize_import(&mut self, id: ast::NodeId, span: Span) {
debug!("finalizing import uses for {}",
self.session.codemap().span_to_snippet(span));
if !self.used_imports.contains(&(id, TypeNS)) &&
!self.used_imports.contains(&(id, ValueNS)) {
self.session.add_lint(lint::builtin::UNUSED_IMPORTS,
id,
span,
"unused import".to_string());
}
let (v_priv, t_priv) = match self.last_private.get(&id) {
Some(&LastImport {
value_priv: v,
value_used: _,
type_priv: t,
type_used: _
}) => (v, t),
Some(_) => {
panic!("we should only have LastImport for `use` directives")
}
_ => return,
};
let mut v_used = if self.used_imports.contains(&(id, ValueNS)) {
Used
} else {
Unused
};
let t_used = if self.used_imports.contains(&(id, TypeNS)) {
Used
} else {
Unused
};
match (v_priv, t_priv) {
// Since some items may be both in the value _and_ type namespaces (e.g., structs)
// we might have two LastPrivates pointing at the same thing. There is no point
// checking both, so lets not check the value one.
(Some(DependsOn(def_v)), Some(DependsOn(def_t))) if def_v == def_t => v_used = Unused,
_ => {},
}
self.last_private.insert(id, LastImport{value_priv: v_priv,
value_used: v_used,
type_priv: t_priv,
type_used: t_used});
}
}
impl<'a, 'b, 'v> Visitor<'v> for UnusedImportCheckVisitor<'a, 'b> {
fn visit_view_item(&mut self, vi: &ViewItem) {
// 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 vi.vis == ast::Public || vi.span == DUMMY_SP {
visit::walk_view_item(self, vi);
return;
}
match vi.node {
ViewItemExternCrate(_, _, id) => {
if let Some(crate_num) = self.session.cstore.find_extern_mod_stmt_cnum(id) {
if !self.used_crates.contains(&crate_num) {
self.session.add_lint(lint::builtin::UNUSED_EXTERN_CRATES,
id,
vi.span,
"unused extern crate".to_string());
}
}
},
ViewItemUse(ref p) => {
match p.node {
ViewPathSimple(_, _, id) => {
self.finalize_import(id, p.span)
}
ViewPathList(_, ref list, _) => {
for i in list.iter() {
self.finalize_import(i.node.id(), i.span);
}
}
ViewPathGlob(_, id) => {
if !self.used_imports.contains(&(id, TypeNS)) &&
!self.used_imports.contains(&(id, ValueNS)) {
self.session
.add_lint(lint::builtin::UNUSED_IMPORTS,
id,
p.span,
"unused import".to_string());
}
}
}
}
}
visit::walk_view_item(self, vi);
}
}
pub fn check_crate(resolver: &mut Resolver, krate: &ast::Crate) {
let mut visitor = UnusedImportCheckVisitor { resolver: resolver };
visit::walk_crate(&mut visitor, krate);
}

View file

@ -8,12 +8,22 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
#![allow(non_camel_case_types)] #![crate_name = "rustc_resolve"]
#![experimental]
#![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 = "http://www.rust-lang.org/favicon.ico",
html_root_url = "http://doc.rust-lang.org/nightly/")]
#![feature(globs, phase, slicing_syntax)]
#![feature(rustc_diagnostic_macros)]
#[phase(plugin, link)] extern crate log;
#[phase(plugin, link)] extern crate syntax;
extern crate rustc;
pub use self::PrivateDep::*;
pub use self::ImportUse::*;
pub use self::TraitItemKind::*;
pub use self::LastPrivate::*;
use self::PatternBindingMode::*; use self::PatternBindingMode::*;
use self::Namespace::*; use self::Namespace::*;
use self::NamespaceError::*; use self::NamespaceError::*;
@ -36,26 +46,26 @@ use self::ModuleKind::*;
use self::TraitReferenceType::*; use self::TraitReferenceType::*;
use self::FallbackChecks::*; use self::FallbackChecks::*;
use session::Session; use rustc::session::Session;
use lint; use rustc::lint;
use metadata::csearch; use rustc::metadata::csearch;
use metadata::decoder::{DefLike, DlDef, DlField, DlImpl}; use rustc::metadata::decoder::{DefLike, DlDef, DlField, DlImpl};
use middle::def::*; use rustc::middle::def::*;
use middle::lang_items::LanguageItems; use rustc::middle::lang_items::LanguageItems;
use middle::pat_util::pat_bindings; use rustc::middle::pat_util::pat_bindings;
use middle::subst::{ParamSpace, FnSpace, TypeSpace}; use rustc::middle::privacy::*;
use middle::ty::{ExplicitSelfCategory, StaticExplicitSelfCategory}; use rustc::middle::subst::{ParamSpace, FnSpace, TypeSpace};
use middle::ty::{CaptureModeMap, Freevar, FreevarMap}; use rustc::middle::ty::{CaptureModeMap, Freevar, FreevarMap, TraitMap};
use util::nodemap::{NodeMap, NodeSet, DefIdSet, FnvHashMap}; use rustc::util::nodemap::{NodeMap, NodeSet, DefIdSet, FnvHashMap};
use syntax::ast::{Arm, BindByRef, BindByValue, BindingMode, Block, Crate, CrateNum}; use syntax::ast::{Arm, BindByRef, BindByValue, BindingMode, Block, Crate, CrateNum};
use syntax::ast::{DeclItem, DefId, Expr, ExprAgain, ExprBreak, ExprField}; use syntax::ast::{DeclItem, DefId, Expr, ExprAgain, ExprBreak, ExprField};
use syntax::ast::{ExprClosure, ExprForLoop, ExprLoop, ExprWhile, ExprMethodCall}; use syntax::ast::{ExprClosure, ExprForLoop, ExprLoop, ExprWhile, ExprMethodCall};
use syntax::ast::{ExprPath, ExprStruct, FnDecl}; use syntax::ast::{ExprPath, ExprStruct, FnDecl};
use syntax::ast::{ForeignItem, ForeignItemFn, ForeignItemStatic, Generics}; use syntax::ast::{ForeignItem, ForeignItemFn, ForeignItemStatic, Generics};
use syntax::ast::{Ident, ImplItem, Item, ItemEnum, ItemFn, ItemForeignMod}; use syntax::ast::{Ident, ImplItem, Item, ItemConst, ItemEnum, ItemFn};
use syntax::ast::{ItemImpl, ItemMac, ItemMod, ItemStatic, ItemStruct}; use syntax::ast::{ItemForeignMod, ItemImpl, ItemMac, ItemMod, ItemStatic};
use syntax::ast::{ItemTrait, ItemTy, LOCAL_CRATE, Local, ItemConst}; use syntax::ast::{ItemStruct, ItemTrait, ItemTy, Local};
use syntax::ast::{MethodImplItem, Mod, Name, NamedField, NodeId}; use syntax::ast::{MethodImplItem, Mod, Name, NamedField, NodeId};
use syntax::ast::{Pat, PatEnum, PatIdent, PatLit}; use syntax::ast::{Pat, PatEnum, PatIdent, PatLit};
use syntax::ast::{PatRange, PatStruct, Path, PathListIdent, PathListMod}; use syntax::ast::{PatRange, PatStruct, Path, PathListIdent, PathListMod};
@ -86,72 +96,17 @@ use std::mem::replace;
use std::rc::{Rc, Weak}; use std::rc::{Rc, Weak};
use std::uint; use std::uint;
// Definition mapping mod check_unused;
pub type DefMap = RefCell<NodeMap<Def>>; mod record_exports;
#[deriving(Copy)] #[deriving(Copy)]
struct binding_info { struct BindingInfo {
span: Span, span: Span,
binding_mode: BindingMode, binding_mode: BindingMode,
} }
// Map from the name in a pattern to its binding mode. // Map from the name in a pattern to its binding mode.
type BindingMap = HashMap<Name,binding_info>; type BindingMap = HashMap<Name, BindingInfo>;
// Trait method resolution
pub type TraitMap = NodeMap<Vec<DefId> >;
// This is the replacement export map. It maps a module to all of the exports
// within.
pub type ExportMap2 = NodeMap<Vec<Export2>>;
pub struct Export2 {
pub name: String, // The name of the target.
pub def_id: DefId, // The definition of the target.
}
// This set contains all exported definitions from external crates. The set does
// not contain any entries from local crates.
pub type ExternalExports = DefIdSet;
// FIXME: dox
pub type LastPrivateMap = NodeMap<LastPrivate>;
#[deriving(Copy, Show)]
pub enum LastPrivate {
LastMod(PrivateDep),
// `use` directives (imports) can refer to two separate definitions in the
// type and value namespaces. We record here the last private node for each
// and whether the import is in fact used for each.
// If the Option<PrivateDep> fields are None, it means there is no definition
// in that namespace.
LastImport{value_priv: Option<PrivateDep>,
value_used: ImportUse,
type_priv: Option<PrivateDep>,
type_used: ImportUse},
}
#[deriving(Copy, Show)]
pub enum PrivateDep {
AllPublic,
DependsOn(DefId),
}
// How an import is used.
#[deriving(Copy, PartialEq, Show)]
pub enum ImportUse {
Unused, // The import is not used.
Used, // The import is used.
}
impl LastPrivate {
fn or(self, other: LastPrivate) -> LastPrivate {
match (self, other) {
(me, LastMod(AllPublic)) => me,
(_, other) => other,
}
}
}
#[deriving(Copy, PartialEq)] #[deriving(Copy, PartialEq)]
enum PatternBindingMode { enum PatternBindingMode {
@ -340,25 +295,6 @@ enum ModulePrefixResult {
PrefixFound(Rc<Module>, uint) PrefixFound(Rc<Module>, uint)
} }
#[deriving(Clone, Copy, Eq, PartialEq)]
pub enum TraitItemKind {
NonstaticMethodTraitItemKind,
StaticMethodTraitItemKind,
TypeTraitItemKind,
}
impl TraitItemKind {
pub fn from_explicit_self_category(explicit_self_category:
ExplicitSelfCategory)
-> TraitItemKind {
if explicit_self_category == StaticExplicitSelfCategory {
StaticMethodTraitItemKind
} else {
NonstaticMethodTraitItemKind
}
}
}
#[deriving(Copy, PartialEq)] #[deriving(Copy, PartialEq)]
enum NameSearchType { enum NameSearchType {
/// We're doing a name search in order to resolve a `use` directive. /// We're doing a name search in order to resolve a `use` directive.
@ -948,7 +884,7 @@ struct Resolver<'a> {
freevars: RefCell<FreevarMap>, freevars: RefCell<FreevarMap>,
freevars_seen: RefCell<NodeMap<NodeSet>>, freevars_seen: RefCell<NodeMap<NodeSet>>,
capture_mode_map: CaptureModeMap, capture_mode_map: CaptureModeMap,
export_map2: ExportMap2, export_map: ExportMap,
trait_map: TraitMap, trait_map: TraitMap,
external_exports: ExternalExports, external_exports: ExternalExports,
last_private: LastPrivateMap, last_private: LastPrivateMap,
@ -1002,17 +938,6 @@ impl<'a, 'b, 'v> Visitor<'v> for BuildReducedGraphVisitor<'a, 'b> {
} }
struct UnusedImportCheckVisitor<'a, 'b:'a> {
resolver: &'a mut Resolver<'b>
}
impl<'a, 'b, 'v> Visitor<'v> for UnusedImportCheckVisitor<'a, 'b> {
fn visit_view_item(&mut self, vi: &ViewItem) {
self.resolver.check_for_item_unused_imports(vi);
visit::walk_view_item(self, vi);
}
}
#[deriving(PartialEq)] #[deriving(PartialEq)]
enum FallbackChecks { enum FallbackChecks {
Everything, Everything,
@ -1063,7 +988,7 @@ impl<'a> Resolver<'a> {
freevars: RefCell::new(NodeMap::new()), freevars: RefCell::new(NodeMap::new()),
freevars_seen: RefCell::new(NodeMap::new()), freevars_seen: RefCell::new(NodeMap::new()),
capture_mode_map: NodeMap::new(), capture_mode_map: NodeMap::new(),
export_map2: NodeMap::new(), export_map: NodeMap::new(),
trait_map: NodeMap::new(), trait_map: NodeMap::new(),
used_imports: HashSet::new(), used_imports: HashSet::new(),
used_crates: HashSet::new(), used_crates: HashSet::new(),
@ -1073,22 +998,6 @@ impl<'a> Resolver<'a> {
emit_errors: true, emit_errors: true,
} }
} }
/// The main name resolution procedure.
fn resolve(&mut self, krate: &ast::Crate) {
self.build_reduced_graph(krate);
self.session.abort_if_errors();
self.resolve_imports();
self.session.abort_if_errors();
self.record_exports();
self.session.abort_if_errors();
self.resolve_crate(krate);
self.session.abort_if_errors();
self.check_for_unused_imports(krate);
}
// //
// Reduced graph building // Reduced graph building
@ -3800,125 +3709,6 @@ impl<'a> Resolver<'a> {
} }
} }
// Export recording
//
// This pass simply determines what all "export" keywords refer to and
// writes the results into the export map.
//
// FIXME #4953 This pass will be removed once exports change to per-item.
// Then this operation can simply be performed as part of item (or import)
// processing.
fn record_exports(&mut self) {
let root_module = self.graph_root.get_module();
self.record_exports_for_module_subtree(root_module);
}
fn record_exports_for_module_subtree(&mut self,
module_: Rc<Module>) {
// If this isn't a local krate, then bail out. We don't need to record
// exports for nonlocal crates.
match module_.def_id.get() {
Some(def_id) if def_id.krate == LOCAL_CRATE => {
// OK. Continue.
debug!("(recording exports for module subtree) recording \
exports for local module `{}`",
self.module_to_string(&*module_));
}
None => {
// Record exports for the root module.
debug!("(recording exports for module subtree) recording \
exports for root module `{}`",
self.module_to_string(&*module_));
}
Some(_) => {
// Bail out.
debug!("(recording exports for module subtree) not recording \
exports for `{}`",
self.module_to_string(&*module_));
return;
}
}
self.record_exports_for_module(&*module_);
self.populate_module_if_necessary(&module_);
for (_, child_name_bindings) in module_.children.borrow().iter() {
match child_name_bindings.get_module_if_available() {
None => {
// Nothing to do.
}
Some(child_module) => {
self.record_exports_for_module_subtree(child_module);
}
}
}
for (_, child_module) in module_.anonymous_children.borrow().iter() {
self.record_exports_for_module_subtree(child_module.clone());
}
}
fn record_exports_for_module(&mut self, module_: &Module) {
let mut exports2 = Vec::new();
self.add_exports_for_module(&mut exports2, module_);
match module_.def_id.get() {
Some(def_id) => {
self.export_map2.insert(def_id.node, exports2);
debug!("(computing exports) writing exports for {} (some)",
def_id.node);
}
None => {}
}
}
fn add_exports_of_namebindings(&mut self,
exports2: &mut Vec<Export2> ,
name: Name,
namebindings: &NameBindings,
ns: Namespace) {
match namebindings.def_for_namespace(ns) {
Some(d) => {
let name = token::get_name(name);
debug!("(computing exports) YES: export '{}' => {}",
name, d.def_id());
exports2.push(Export2 {
name: name.get().to_string(),
def_id: d.def_id()
});
}
d_opt => {
debug!("(computing exports) NO: {}", d_opt);
}
}
}
fn add_exports_for_module(&mut self,
exports2: &mut Vec<Export2> ,
module_: &Module) {
for (name, importresolution) in module_.import_resolutions.borrow().iter() {
if !importresolution.is_public {
continue
}
let xs = [TypeNS, ValueNS];
for &ns in xs.iter() {
match importresolution.target_for_namespace(ns) {
Some(target) => {
debug!("(computing exports) maybe export '{}'",
token::get_name(*name));
self.add_exports_of_namebindings(exports2,
*name,
&*target.bindings,
ns)
}
_ => ()
}
}
}
}
// AST resolution // AST resolution
// //
// We maintain a list of value ribs and type ribs. // We maintain a list of value ribs and type ribs.
@ -4809,9 +4599,10 @@ impl<'a> Resolver<'a> {
let mut result = HashMap::new(); let mut result = HashMap::new();
pat_bindings(&self.def_map, pat, |binding_mode, _id, sp, path1| { pat_bindings(&self.def_map, pat, |binding_mode, _id, sp, path1| {
let name = mtwt::resolve(path1.node); let name = mtwt::resolve(path1.node);
result.insert(name, result.insert(name, BindingInfo {
binding_info {span: sp, span: sp,
binding_mode: binding_mode}); binding_mode: binding_mode
});
}); });
return result; return result;
} }
@ -6135,119 +5926,6 @@ impl<'a> Resolver<'a> {
} }
} }
//
// Unused import checking
//
// Although this is mostly a lint pass, it lives in here because it depends on
// resolve data structures and because it finalises the privacy information for
// `use` directives.
//
fn check_for_unused_imports(&mut self, krate: &ast::Crate) {
let mut visitor = UnusedImportCheckVisitor{ resolver: self };
visit::walk_crate(&mut visitor, krate);
}
fn check_for_item_unused_imports(&mut self, vi: &ViewItem) {
// 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 vi.vis == Public { return }
if vi.span == DUMMY_SP { return }
match vi.node {
ViewItemExternCrate(_, _, id) => {
if let Some(crate_num) = self.session.cstore.find_extern_mod_stmt_cnum(id) {
if !self.used_crates.contains(&crate_num) {
self.session.add_lint(lint::builtin::UNUSED_EXTERN_CRATES,
id,
vi.span,
"unused extern crate".to_string());
}
}
},
ViewItemUse(ref p) => {
match p.node {
ViewPathSimple(_, _, id) => self.finalize_import(id, p.span),
ViewPathList(_, ref list, _) => {
for i in list.iter() {
self.finalize_import(i.node.id(), i.span);
}
},
ViewPathGlob(_, id) => {
if !self.used_imports.contains(&(id, TypeNS)) &&
!self.used_imports.contains(&(id, ValueNS)) {
self.session
.add_lint(lint::builtin::UNUSED_IMPORTS,
id,
p.span,
"unused import".to_string());
}
},
}
}
}
}
// We have information about whether `use` (import) directives are actually used now.
// If an import is not used at all, we signal a lint error. If an import is only used
// for a single namespace, we remove the other namespace from the recorded privacy
// information. That means in privacy.rs, we will only check imports and namespaces
// which are used. In particular, this means that if an import could name either a
// public or private item, we will check the correct thing, dependent on how the import
// is used.
fn finalize_import(&mut self, id: NodeId, span: Span) {
debug!("finalizing import uses for {}",
self.session.codemap().span_to_snippet(span));
if !self.used_imports.contains(&(id, TypeNS)) &&
!self.used_imports.contains(&(id, ValueNS)) {
self.session.add_lint(lint::builtin::UNUSED_IMPORTS,
id,
span,
"unused import".to_string());
}
let (v_priv, t_priv) = match self.last_private.get(&id) {
Some(&LastImport {
value_priv: v,
value_used: _,
type_priv: t,
type_used: _
}) => (v, t),
Some(_) => {
panic!("we should only have LastImport for `use` directives")
}
_ => return,
};
let mut v_used = if self.used_imports.contains(&(id, ValueNS)) {
Used
} else {
Unused
};
let t_used = if self.used_imports.contains(&(id, TypeNS)) {
Used
} else {
Unused
};
match (v_priv, t_priv) {
// Since some items may be both in the value _and_ type namespaces (e.g., structs)
// we might have two LastPrivates pointing at the same thing. There is no point
// checking both, so lets not check the value one.
(Some(DependsOn(def_v)), Some(DependsOn(def_t))) if def_v == def_t => v_used = Unused,
_ => {},
}
self.last_private.insert(id, LastImport{value_priv: v_priv,
value_used: v_used,
type_priv: t_priv,
type_used: t_used});
}
// //
// Diagnostics // Diagnostics
// //
@ -6323,7 +6001,7 @@ pub struct CrateMap {
pub def_map: DefMap, pub def_map: DefMap,
pub freevars: RefCell<FreevarMap>, pub freevars: RefCell<FreevarMap>,
pub capture_mode_map: RefCell<CaptureModeMap>, pub capture_mode_map: RefCell<CaptureModeMap>,
pub exp_map2: ExportMap2, pub export_map: ExportMap,
pub trait_map: TraitMap, pub trait_map: TraitMap,
pub external_exports: ExternalExports, pub external_exports: ExternalExports,
pub last_private_map: LastPrivateMap, pub last_private_map: LastPrivateMap,
@ -6335,12 +6013,26 @@ pub fn resolve_crate(session: &Session,
krate: &Crate) krate: &Crate)
-> CrateMap { -> CrateMap {
let mut resolver = Resolver::new(session, krate.span); let mut resolver = Resolver::new(session, krate.span);
resolver.resolve(krate);
resolver.build_reduced_graph(krate);
session.abort_if_errors();
resolver.resolve_imports();
session.abort_if_errors();
record_exports::record(&mut resolver);
session.abort_if_errors();
resolver.resolve_crate(krate);
session.abort_if_errors();
check_unused::check_crate(&mut resolver, krate);
CrateMap { CrateMap {
def_map: resolver.def_map, def_map: resolver.def_map,
freevars: resolver.freevars, freevars: resolver.freevars,
capture_mode_map: RefCell::new(resolver.capture_mode_map), capture_mode_map: RefCell::new(resolver.capture_mode_map),
exp_map2: resolver.export_map2, export_map: resolver.export_map,
trait_map: resolver.trait_map, trait_map: resolver.trait_map,
external_exports: resolver.external_exports, external_exports: resolver.external_exports,
last_private_map: resolver.last_private, last_private_map: resolver.last_private,

View file

@ -0,0 +1,157 @@
// Copyright 2012-2014 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.
// Export recording
//
// This pass simply determines what all "export" keywords refer to and
// writes the results into the export map.
//
// FIXME #4953 This pass will be removed once exports change to per-item.
// Then this operation can simply be performed as part of item (or import)
// processing.
use {Module, NameBindings, Resolver};
use Namespace::{mod, TypeNS, ValueNS};
use rustc::middle::def::Export;
use syntax::ast;
use syntax::parse::token;
use std::rc::Rc;
struct ExportRecorder<'a, 'b:'a> {
resolver: &'a mut Resolver<'b>
}
// Deref and DerefMut impls allow treating ExportRecorder as Resolver.
impl<'a, 'b> Deref<Resolver<'b>> for ExportRecorder<'a, 'b> {
fn deref<'c>(&'c self) -> &'c Resolver<'b> {
&*self.resolver
}
}
impl<'a, 'b> DerefMut<Resolver<'b>> for ExportRecorder<'a, 'b> {
fn deref_mut<'c>(&'c mut self) -> &'c mut Resolver<'b> {
&mut *self.resolver
}
}
impl<'a, 'b> ExportRecorder<'a, 'b> {
fn record_exports_for_module_subtree(&mut self,
module_: Rc<Module>) {
// If this isn't a local krate, then bail out. We don't need to record
// exports for nonlocal crates.
match module_.def_id.get() {
Some(def_id) if def_id.krate == ast::LOCAL_CRATE => {
// OK. Continue.
debug!("(recording exports for module subtree) recording \
exports for local module `{}`",
self.module_to_string(&*module_));
}
None => {
// Record exports for the root module.
debug!("(recording exports for module subtree) recording \
exports for root module `{}`",
self.module_to_string(&*module_));
}
Some(_) => {
// Bail out.
debug!("(recording exports for module subtree) not recording \
exports for `{}`",
self.module_to_string(&*module_));
return;
}
}
self.record_exports_for_module(&*module_);
self.populate_module_if_necessary(&module_);
for (_, child_name_bindings) in module_.children.borrow().iter() {
match child_name_bindings.get_module_if_available() {
None => {
// Nothing to do.
}
Some(child_module) => {
self.record_exports_for_module_subtree(child_module);
}
}
}
for (_, child_module) in module_.anonymous_children.borrow().iter() {
self.record_exports_for_module_subtree(child_module.clone());
}
}
fn record_exports_for_module(&mut self, module_: &Module) {
let mut exports = Vec::new();
self.add_exports_for_module(&mut exports, module_);
match module_.def_id.get() {
Some(def_id) => {
self.export_map.insert(def_id.node, exports);
debug!("(computing exports) writing exports for {} (some)",
def_id.node);
}
None => {}
}
}
fn add_exports_of_namebindings(&mut self,
exports: &mut Vec<Export>,
name: ast::Name,
namebindings: &NameBindings,
ns: Namespace) {
match namebindings.def_for_namespace(ns) {
Some(d) => {
debug!("(computing exports) YES: export '{}' => {}",
name, d.def_id());
exports.push(Export {
name: name,
def_id: d.def_id()
});
}
d_opt => {
debug!("(computing exports) NO: {}", d_opt);
}
}
}
fn add_exports_for_module(&mut self,
exports: &mut Vec<Export>,
module_: &Module) {
for (name, importresolution) in module_.import_resolutions.borrow().iter() {
if !importresolution.is_public {
continue
}
let xs = [TypeNS, ValueNS];
for &ns in xs.iter() {
match importresolution.target_for_namespace(ns) {
Some(target) => {
debug!("(computing exports) maybe export '{}'",
token::get_name(*name));
self.add_exports_of_namebindings(exports,
*name,
&*target.bindings,
ns)
}
_ => ()
}
}
}
}
}
pub fn record(resolver: &mut Resolver) {
let mut recorder = ExportRecorder { resolver: resolver };
let root_module = recorder.graph_root.get_module();
recorder.record_exports_for_module_subtree(root_module);
}

View file

@ -193,12 +193,11 @@ use llvm::{ValueRef, BasicBlockRef};
use middle::check_match::StaticInliner; use middle::check_match::StaticInliner;
use middle::check_match; use middle::check_match;
use middle::const_eval; use middle::const_eval;
use middle::def; use middle::def::{mod, DefMap};
use middle::expr_use_visitor as euv; use middle::expr_use_visitor as euv;
use middle::lang_items::StrEqFnLangItem; use middle::lang_items::StrEqFnLangItem;
use middle::mem_categorization as mc; use middle::mem_categorization as mc;
use middle::pat_util::*; use middle::pat_util::*;
use middle::resolve::DefMap;
use trans::adt; use trans::adt;
use trans::base::*; use trans::base::*;
use trans::build::{AddCase, And, BitCast, Br, CondBr, GEPi, InBoundsGEP, Load}; use trans::build::{AddCase, And, BitCast, Br, CondBr, GEPi, InBoundsGEP, Load};

View file

@ -2938,7 +2938,7 @@ pub fn crate_ctxt_to_encode_parms<'a, 'tcx>(cx: &'a SharedCrateContext<'tcx>,
encoder::EncodeParams { encoder::EncodeParams {
diag: cx.sess().diagnostic(), diag: cx.sess().diagnostic(),
tcx: cx.tcx(), tcx: cx.tcx(),
reexports2: cx.exp_map2(), reexports: cx.export_map(),
item_symbols: cx.item_symbols(), item_symbols: cx.item_symbols(),
link_meta: cx.link_meta(), link_meta: cx.link_meta(),
cstore: &cx.sess().cstore, cstore: &cx.sess().cstore,
@ -3071,7 +3071,7 @@ fn internalize_symbols(cx: &SharedCrateContext, reachable: &HashSet<String>) {
pub fn trans_crate<'tcx>(analysis: ty::CrateAnalysis<'tcx>) pub fn trans_crate<'tcx>(analysis: ty::CrateAnalysis<'tcx>)
-> (ty::ctxt<'tcx>, CrateTranslation) { -> (ty::ctxt<'tcx>, CrateTranslation) {
let ty::CrateAnalysis { ty_cx: tcx, exp_map2, reachable, name, .. } = analysis; let ty::CrateAnalysis { ty_cx: tcx, export_map, reachable, name, .. } = analysis;
let krate = tcx.map.krate(); let krate = tcx.map.krate();
// Before we touch LLVM, make sure that multithreading is enabled. // Before we touch LLVM, make sure that multithreading is enabled.
@ -3098,7 +3098,7 @@ pub fn trans_crate<'tcx>(analysis: ty::CrateAnalysis<'tcx>)
let shared_ccx = SharedCrateContext::new(link_meta.crate_name.as_slice(), let shared_ccx = SharedCrateContext::new(link_meta.crate_name.as_slice(),
codegen_units, codegen_units,
tcx, tcx,
exp_map2, export_map,
Sha256::new(), Sha256::new(),
link_meta.clone(), link_meta.clone(),
reachable); reachable);

View file

@ -13,7 +13,7 @@ use llvm::{ContextRef, ModuleRef, ValueRef, BuilderRef};
use llvm::{TargetData}; use llvm::{TargetData};
use llvm::mk_target_data; use llvm::mk_target_data;
use metadata::common::LinkMeta; use metadata::common::LinkMeta;
use middle::resolve; use middle::def::ExportMap;
use middle::traits; use middle::traits;
use trans::adt; use trans::adt;
use trans::base; use trans::base;
@ -61,7 +61,7 @@ pub struct SharedCrateContext<'tcx> {
metadata_llmod: ModuleRef, metadata_llmod: ModuleRef,
metadata_llcx: ContextRef, metadata_llcx: ContextRef,
exp_map2: resolve::ExportMap2, export_map: ExportMap,
reachable: NodeSet, reachable: NodeSet,
item_symbols: RefCell<NodeMap<String>>, item_symbols: RefCell<NodeMap<String>>,
link_meta: LinkMeta, link_meta: LinkMeta,
@ -238,7 +238,7 @@ impl<'tcx> SharedCrateContext<'tcx> {
pub fn new(crate_name: &str, pub fn new(crate_name: &str,
local_count: uint, local_count: uint,
tcx: ty::ctxt<'tcx>, tcx: ty::ctxt<'tcx>,
emap2: resolve::ExportMap2, export_map: ExportMap,
symbol_hasher: Sha256, symbol_hasher: Sha256,
link_meta: LinkMeta, link_meta: LinkMeta,
reachable: NodeSet) reachable: NodeSet)
@ -251,7 +251,7 @@ impl<'tcx> SharedCrateContext<'tcx> {
local_ccxs: Vec::with_capacity(local_count), local_ccxs: Vec::with_capacity(local_count),
metadata_llmod: metadata_llmod, metadata_llmod: metadata_llmod,
metadata_llcx: metadata_llcx, metadata_llcx: metadata_llcx,
exp_map2: emap2, export_map: export_map,
reachable: reachable, reachable: reachable,
item_symbols: RefCell::new(NodeMap::new()), item_symbols: RefCell::new(NodeMap::new()),
link_meta: link_meta, link_meta: link_meta,
@ -329,8 +329,8 @@ impl<'tcx> SharedCrateContext<'tcx> {
self.metadata_llcx self.metadata_llcx
} }
pub fn exp_map2<'a>(&'a self) -> &'a resolve::ExportMap2 { pub fn export_map<'a>(&'a self) -> &'a ExportMap {
&self.exp_map2 &self.export_map
} }
pub fn reachable<'a>(&'a self) -> &'a NodeSet { pub fn reachable<'a>(&'a self) -> &'a NodeSet {
@ -553,8 +553,8 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
&self.local.item_vals &self.local.item_vals
} }
pub fn exp_map2<'a>(&'a self) -> &'a resolve::ExportMap2 { pub fn export_map<'a>(&'a self) -> &'a ExportMap {
&self.shared.exp_map2 &self.shared.export_map
} }
pub fn reachable<'a>(&'a self) -> &'a NodeSet { pub fn reachable<'a>(&'a self) -> &'a NodeSet {

View file

@ -90,7 +90,6 @@ pub use rustc::session;
pub use rustc::util; pub use rustc::util;
use middle::def; use middle::def;
use middle::resolve;
use middle::infer; use middle::infer;
use middle::subst; use middle::subst;
use middle::subst::VecPerParamSpace; use middle::subst::VecPerParamSpace;
@ -121,7 +120,7 @@ struct TypeAndSubsts<'tcx> {
struct CrateCtxt<'a, 'tcx: 'a> { struct CrateCtxt<'a, 'tcx: 'a> {
// A mapping from method call sites to traits that have that method. // A mapping from method call sites to traits that have that method.
trait_map: resolve::TraitMap, trait_map: ty::TraitMap,
tcx: &'a ty::ctxt<'tcx> tcx: &'a ty::ctxt<'tcx>
} }
@ -316,7 +315,7 @@ fn check_for_entry_fn(ccx: &CrateCtxt) {
} }
} }
pub fn check_crate(tcx: &ty::ctxt, trait_map: resolve::TraitMap) { pub fn check_crate(tcx: &ty::ctxt, trait_map: ty::TraitMap) {
let time_passes = tcx.sess.time_passes(); let time_passes = tcx.sess.time_passes();
let ccx = CrateCtxt { let ccx = CrateCtxt {
trait_map: trait_map, trait_map: trait_map,

View file

@ -24,7 +24,7 @@ impl BarTy {
fn b(&self) {} fn b(&self) {}
} }
// If these fail, it's necessary to update middle::resolve and the cfail tests. // If these fail, it's necessary to update rustc_resolve and the cfail tests.
impl Foo for *const BarTy { impl Foo for *const BarTy {
fn bar(&self) { fn bar(&self) {
self.baz(); self.baz();
@ -33,7 +33,7 @@ impl Foo for *const BarTy {
} }
} }
// If these fail, it's necessary to update middle::resolve and the cfail tests. // If these fail, it's necessary to update rustc_resolve and the cfail tests.
impl<'a> Foo for &'a BarTy { impl<'a> Foo for &'a BarTy {
fn bar(&self) { fn bar(&self) {
self.baz(); self.baz();
@ -45,7 +45,7 @@ impl<'a> Foo for &'a BarTy {
} }
} }
// If these fail, it's necessary to update middle::resolve and the cfail tests. // If these fail, it's necessary to update rustc_resolve and the cfail tests.
impl<'a> Foo for &'a mut BarTy { impl<'a> Foo for &'a mut BarTy {
fn bar(&self) { fn bar(&self) {
self.baz(); self.baz();
@ -57,7 +57,7 @@ impl<'a> Foo for &'a mut BarTy {
} }
} }
// If these fail, it's necessary to update middle::resolve and the cfail tests. // If these fail, it's necessary to update rustc_resolve and the cfail tests.
impl Foo for Box<BarTy> { impl Foo for Box<BarTy> {
fn bar(&self) { fn bar(&self) {
self.baz(); self.baz();
@ -65,7 +65,7 @@ impl Foo for Box<BarTy> {
} }
} }
// If these fail, it's necessary to update middle::resolve and the cfail tests. // If these fail, it's necessary to update rustc_resolve and the cfail tests.
impl Foo for *const int { impl Foo for *const int {
fn bar(&self) { fn bar(&self) {
self.baz(); self.baz();
@ -73,7 +73,7 @@ impl Foo for *const int {
} }
} }
// If these fail, it's necessary to update middle::resolve and the cfail tests. // If these fail, it's necessary to update rustc_resolve and the cfail tests.
impl<'a> Foo for &'a int { impl<'a> Foo for &'a int {
fn bar(&self) { fn bar(&self) {
self.baz(); self.baz();
@ -81,7 +81,7 @@ impl<'a> Foo for &'a int {
} }
} }
// If these fail, it's necessary to update middle::resolve and the cfail tests. // If these fail, it's necessary to update rustc_resolve and the cfail tests.
impl<'a> Foo for &'a mut int { impl<'a> Foo for &'a mut int {
fn bar(&self) { fn bar(&self) {
self.baz(); self.baz();
@ -89,7 +89,7 @@ impl<'a> Foo for &'a mut int {
} }
} }
// If these fail, it's necessary to update middle::resolve and the cfail tests. // If these fail, it's necessary to update rustc_resolve and the cfail tests.
impl Foo for Box<int> { impl Foo for Box<int> {
fn bar(&self) { fn bar(&self) {
self.baz(); self.baz();