Auto merge of #34552 - Manishearth:rollup, r=Manishearth

Rollup of 11 pull requests

- Successful merges: #34355, #34446, #34459, #34460, #34467, #34495, #34497, #34499, #34513, #34536, #34542
- Failed merges:
This commit is contained in:
bors 2016-06-29 18:44:27 -07:00 committed by GitHub
commit c2b56fb7a0
30 changed files with 621 additions and 446 deletions

View file

@ -50,6 +50,7 @@
use std::collections::BTreeMap; use std::collections::BTreeMap;
use std::iter; use std::iter;
use syntax::ast::*; use syntax::ast::*;
use syntax::errors;
use syntax::ptr::P; use syntax::ptr::P;
use syntax::codemap::{respan, Spanned}; use syntax::codemap::{respan, Spanned};
use syntax::parse::token; use syntax::parse::token;
@ -60,7 +61,7 @@
pub struct LoweringContext<'a> { pub struct LoweringContext<'a> {
crate_root: Option<&'static str>, crate_root: Option<&'static str>,
// Use to assign ids to hir nodes that do not directly correspond to an ast node // Use to assign ids to hir nodes that do not directly correspond to an ast node
id_assigner: &'a NodeIdAssigner, sess: Option<&'a Session>,
// As we walk the AST we must keep track of the current 'parent' def id (in // As we walk the AST we must keep track of the current 'parent' def id (in
// the form of a DefIndex) so that if we create a new node which introduces // the form of a DefIndex) so that if we create a new node which introduces
// a definition, then we can properly create the def id. // a definition, then we can properly create the def id.
@ -99,7 +100,6 @@ fn definitions(&mut self) -> Option<&mut Definitions> {
pub fn lower_crate(sess: &Session, pub fn lower_crate(sess: &Session,
krate: &Crate, krate: &Crate,
id_assigner: &NodeIdAssigner,
resolver: &mut Resolver) resolver: &mut Resolver)
-> hir::Crate { -> hir::Crate {
// We're constructing the HIR here; we don't care what we will // We're constructing the HIR here; we don't care what we will
@ -115,17 +115,17 @@ pub fn lower_crate(sess: &Session,
} else { } else {
Some("std") Some("std")
}, },
id_assigner: id_assigner, sess: Some(sess),
parent_def: None, parent_def: None,
resolver: resolver, resolver: resolver,
}.lower_crate(krate) }.lower_crate(krate)
} }
impl<'a> LoweringContext<'a> { impl<'a> LoweringContext<'a> {
pub fn testing_context(id_assigner: &'a NodeIdAssigner, resolver: &'a mut Resolver) -> Self { pub fn testing_context(resolver: &'a mut Resolver) -> Self {
LoweringContext { LoweringContext {
crate_root: None, crate_root: None,
id_assigner: id_assigner, sess: None,
parent_def: None, parent_def: None,
resolver: resolver, resolver: resolver,
} }
@ -161,7 +161,12 @@ fn visit_item(&mut self, item: &Item) {
} }
fn next_id(&self) -> NodeId { fn next_id(&self) -> NodeId {
self.id_assigner.next_node_id() self.sess.map(Session::next_node_id).unwrap_or(0)
}
fn diagnostic(&self) -> &errors::Handler {
self.sess.map(Session::diagnostic)
.unwrap_or_else(|| panic!("this lowerer cannot emit diagnostics"))
} }
fn str_to_ident(&self, s: &'static str) -> Name { fn str_to_ident(&self, s: &'static str) -> Name {
@ -786,7 +791,7 @@ fn lower_method_sig(&mut self, sig: &MethodSig) -> hir::MethodSig {
if let Some(SelfKind::Explicit(..)) = sig.decl.get_self().map(|eself| eself.node) { if let Some(SelfKind::Explicit(..)) = sig.decl.get_self().map(|eself| eself.node) {
match hir_sig.decl.get_self().map(|eself| eself.node) { match hir_sig.decl.get_self().map(|eself| eself.node) {
Some(hir::SelfKind::Value(..)) | Some(hir::SelfKind::Region(..)) => { Some(hir::SelfKind::Value(..)) | Some(hir::SelfKind::Region(..)) => {
self.id_assigner.diagnostic().span_err(sig.decl.inputs[0].ty.span, self.diagnostic().span_err(sig.decl.inputs[0].ty.span,
"the type placeholder `_` is not allowed within types on item signatures"); "the type placeholder `_` is not allowed within types on item signatures");
} }
_ => {} _ => {}
@ -1212,7 +1217,7 @@ fn make_struct(this: &mut LoweringContext,
make_struct(self, e, &["RangeInclusive", "NonEmpty"], make_struct(self, e, &["RangeInclusive", "NonEmpty"],
&[("start", e1), ("end", e2)]), &[("start", e1), ("end", e2)]),
_ => panic!(self.id_assigner.diagnostic() _ => panic!(self.diagnostic()
.span_fatal(e.span, "inclusive range with no end")), .span_fatal(e.span, "inclusive range with no end")),
}; };
} }

View file

@ -25,15 +25,15 @@ pub struct DefCollector<'ast> {
// If we are walking HIR (c.f., AST), we need to keep a reference to the // If we are walking HIR (c.f., AST), we need to keep a reference to the
// crate. // crate.
hir_crate: Option<&'ast hir::Crate>, hir_crate: Option<&'ast hir::Crate>,
pub definitions: Definitions, definitions: &'ast mut Definitions,
parent_def: Option<DefIndex>, parent_def: Option<DefIndex>,
} }
impl<'ast> DefCollector<'ast> { impl<'ast> DefCollector<'ast> {
pub fn root() -> DefCollector<'ast> { pub fn root(definitions: &'ast mut Definitions) -> DefCollector<'ast> {
let mut collector = DefCollector { let mut collector = DefCollector {
hir_crate: None, hir_crate: None,
definitions: Definitions::new(), definitions: definitions,
parent_def: None, parent_def: None,
}; };
let root = collector.create_def_with_parent(None, CRATE_NODE_ID, DefPathData::CrateRoot); let root = collector.create_def_with_parent(None, CRATE_NODE_ID, DefPathData::CrateRoot);
@ -48,7 +48,7 @@ pub fn root() -> DefCollector<'ast> {
pub fn extend(parent_node: NodeId, pub fn extend(parent_node: NodeId,
parent_def_path: DefPath, parent_def_path: DefPath,
parent_def_id: DefId, parent_def_id: DefId,
definitions: Definitions) definitions: &'ast mut Definitions)
-> DefCollector<'ast> { -> DefCollector<'ast> {
let mut collector = DefCollector { let mut collector = DefCollector {
hir_crate: None, hir_crate: None,

View file

@ -10,8 +10,9 @@
use middle::cstore::LOCAL_CRATE; use middle::cstore::LOCAL_CRATE;
use hir::def_id::{DefId, DefIndex}; use hir::def_id::{DefId, DefIndex};
use hir::map::def_collector::DefCollector;
use rustc_data_structures::fnv::FnvHashMap; use rustc_data_structures::fnv::FnvHashMap;
use syntax::ast; use syntax::{ast, visit};
use syntax::parse::token::InternedString; use syntax::parse::token::InternedString;
use util::nodemap::NodeMap; use util::nodemap::NodeMap;
@ -189,6 +190,11 @@ pub fn new() -> Definitions {
} }
} }
pub fn collect(&mut self, krate: &ast::Crate) {
let mut def_collector = DefCollector::root(self);
visit::walk_crate(&mut def_collector, krate);
}
/// Get the number of definitions. /// Get the number of definitions.
pub fn len(&self) -> usize { pub fn len(&self) -> usize {
self.data.len() self.data.len()

View file

@ -24,7 +24,6 @@
use syntax::abi::Abi; use syntax::abi::Abi;
use syntax::ast::{self, Name, NodeId, DUMMY_NODE_ID, }; use syntax::ast::{self, Name, NodeId, DUMMY_NODE_ID, };
use syntax::codemap::Spanned; use syntax::codemap::Spanned;
use syntax::visit;
use syntax_pos::Span; use syntax_pos::Span;
use hir::*; use hir::*;
@ -780,12 +779,6 @@ fn new_span(&mut self, span: Span) -> Span {
} }
} }
pub fn collect_definitions<'ast>(krate: &'ast ast::Crate) -> Definitions {
let mut def_collector = DefCollector::root();
visit::walk_crate(&mut def_collector, krate);
def_collector.definitions
}
pub fn map_crate<'ast>(forest: &'ast mut Forest, pub fn map_crate<'ast>(forest: &'ast mut Forest,
definitions: Definitions) definitions: Definitions)
-> Map<'ast> { -> Map<'ast> {
@ -842,13 +835,12 @@ pub fn map_decoded_item<'ast, F: FoldOps>(map: &Map<'ast>,
let ii = map.forest.inlined_items.alloc(ii); let ii = map.forest.inlined_items.alloc(ii);
let ii_parent_id = fld.new_id(DUMMY_NODE_ID); let ii_parent_id = fld.new_id(DUMMY_NODE_ID);
let defs = mem::replace(&mut *map.definitions.borrow_mut(), Definitions::new()); let defs = &mut *map.definitions.borrow_mut();
let mut def_collector = DefCollector::extend(ii_parent_id, let mut def_collector = DefCollector::extend(ii_parent_id,
parent_def_path.clone(), parent_def_path.clone(),
parent_def_id, parent_def_id,
defs); defs);
def_collector.walk_item(ii, map.krate()); def_collector.walk_item(ii, map.krate());
*map.definitions.borrow_mut() = def_collector.definitions;
let mut collector = NodeCollector::extend(map.krate(), let mut collector = NodeCollector::extend(map.krate(),
ii, ii,

View file

@ -20,7 +20,7 @@
use util::nodemap::{NodeMap, FnvHashMap}; use util::nodemap::{NodeMap, FnvHashMap};
use mir::transform as mir_pass; use mir::transform as mir_pass;
use syntax::ast::{NodeId, NodeIdAssigner, Name}; use syntax::ast::{NodeId, Name};
use errors::{self, DiagnosticBuilder}; use errors::{self, DiagnosticBuilder};
use errors::emitter::{Emitter, BasicEmitter, EmitterWriter}; use errors::emitter::{Emitter, BasicEmitter, EmitterWriter};
use syntax::json::JsonEmitter; use syntax::json::JsonEmitter;
@ -272,6 +272,9 @@ pub fn reserve_node_ids(&self, count: ast::NodeId) -> ast::NodeId {
id id
} }
pub fn next_node_id(&self) -> NodeId {
self.reserve_node_ids(1)
}
pub fn diagnostic<'a>(&'a self) -> &'a errors::Handler { pub fn diagnostic<'a>(&'a self) -> &'a errors::Handler {
&self.parse_sess.span_diagnostic &self.parse_sess.span_diagnostic
} }
@ -345,20 +348,6 @@ pub fn host_filesearch(&self, kind: PathKind) -> filesearch::FileSearch {
} }
} }
impl NodeIdAssigner for Session {
fn next_node_id(&self) -> NodeId {
self.reserve_node_ids(1)
}
fn peek_node_id(&self) -> NodeId {
self.next_node_id.get().checked_add(1).unwrap()
}
fn diagnostic(&self) -> &errors::Handler {
self.diagnostic()
}
}
fn split_msg_into_multilines(msg: &str) -> Option<String> { fn split_msg_into_multilines(msg: &str) -> Option<String> {
// Conditions for enabling multi-line errors: // Conditions for enabling multi-line errors:
if !msg.contains("mismatched types") && if !msg.contains("mismatched types") &&

View file

@ -543,8 +543,7 @@ pub fn eval_const_expr_partial<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
let result = match e.node { let result = match e.node {
hir::ExprUnary(hir::UnNeg, ref inner) => { hir::ExprUnary(hir::UnNeg, ref inner) => {
// unary neg literals already got their sign during creation // unary neg literals already got their sign during creation
match inner.node { if let hir::ExprLit(ref lit) = inner.node {
hir::ExprLit(ref lit) => {
use syntax::ast::*; use syntax::ast::*;
use syntax::ast::LitIntType::*; use syntax::ast::LitIntType::*;
const I8_OVERFLOW: u64 = ::std::i8::MAX as u64 + 1; const I8_OVERFLOW: u64 = ::std::i8::MAX as u64 + 1;
@ -585,12 +584,6 @@ pub fn eval_const_expr_partial<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
}, },
_ => {}, _ => {},
} }
},
hir::ExprUnary(hir::UnNeg, ref inner) => {
// skip `--$expr`
return eval_const_expr_partial(tcx, inner, ty_hint, fn_args);
},
_ => {},
} }
match eval_const_expr_partial(tcx, &inner, ty_hint, fn_args)? { match eval_const_expr_partial(tcx, &inner, ty_hint, fn_args)? {
Float(f) => Float(-f), Float(f) => Float(-f),

View file

@ -8,7 +8,6 @@
// 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.
use rustc::dep_graph::DepGraph;
use rustc::hir; use rustc::hir;
use rustc::hir::{map as hir_map, FreevarMap, TraitMap}; use rustc::hir::{map as hir_map, FreevarMap, TraitMap};
use rustc::hir::def::DefMap; use rustc::hir::def::DefMap;
@ -27,7 +26,7 @@
use rustc_back::sha2::{Sha256, Digest}; use rustc_back::sha2::{Sha256, Digest};
use rustc_borrowck as borrowck; use rustc_borrowck as borrowck;
use rustc_incremental; use rustc_incremental;
use rustc_resolve as resolve; use rustc_resolve::{MakeGlobMap, Resolver};
use rustc_metadata::macro_import; use rustc_metadata::macro_import;
use rustc_metadata::creader::read_local_crates; use rustc_metadata::creader::read_local_crates;
use rustc_metadata::cstore::CStore; use rustc_metadata::cstore::CStore;
@ -49,13 +48,11 @@
use std::fs; use std::fs;
use std::io::{self, Write}; use std::io::{self, Write};
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use syntax::ast::{self, NodeIdAssigner}; use syntax::{ast, diagnostics, visit};
use syntax::attr::{self, AttrMetaMethods}; use syntax::attr::{self, AttrMetaMethods};
use syntax::diagnostics;
use syntax::fold::Folder; use syntax::fold::Folder;
use syntax::parse::{self, PResult, token}; use syntax::parse::{self, PResult, token};
use syntax::util::node_count::NodeCounter; use syntax::util::node_count::NodeCounter;
use syntax::visit;
use syntax; use syntax;
use syntax_ext; use syntax_ext;
@ -293,7 +290,7 @@ pub struct CompileController<'a> {
pub after_analysis: PhaseController<'a>, pub after_analysis: PhaseController<'a>,
pub after_llvm: PhaseController<'a>, pub after_llvm: PhaseController<'a>,
pub make_glob_map: resolve::MakeGlobMap, pub make_glob_map: MakeGlobMap,
} }
impl<'a> CompileController<'a> { impl<'a> CompileController<'a> {
@ -305,7 +302,7 @@ pub fn basic() -> CompileController<'a> {
after_hir_lowering: PhaseController::basic(), after_hir_lowering: PhaseController::basic(),
after_analysis: PhaseController::basic(), after_analysis: PhaseController::basic(),
after_llvm: PhaseController::basic(), after_llvm: PhaseController::basic(),
make_glob_map: resolve::MakeGlobMap::No, make_glob_map: MakeGlobMap::No,
} }
} }
} }
@ -564,7 +561,7 @@ pub fn phase_2_configure_and_expand<'a>(sess: &Session,
mut krate: ast::Crate, mut krate: ast::Crate,
crate_name: &'a str, crate_name: &'a str,
addl_plugins: Option<Vec<String>>, addl_plugins: Option<Vec<String>>,
make_glob_map: resolve::MakeGlobMap) make_glob_map: MakeGlobMap)
-> Result<ExpansionResult<'a>, usize> { -> Result<ExpansionResult<'a>, usize> {
let time_passes = sess.time_passes(); let time_passes = sess.time_passes();
@ -729,13 +726,16 @@ pub fn phase_2_configure_and_expand<'a>(sess: &Session,
krate = assign_node_ids(sess, krate); krate = assign_node_ids(sess, krate);
// Collect defintions for def ids. let resolver_arenas = Resolver::arenas();
let mut defs = let mut resolver = Resolver::new(sess, make_glob_map, &resolver_arenas);
time(sess.time_passes(), "collecting defs", || hir_map::collect_definitions(&krate));
time(sess.time_passes(), // Collect defintions for def ids.
"external crate/lib resolution", time(sess.time_passes(), "collecting defs", || resolver.definitions.collect(&krate));
|| read_local_crates(sess, &cstore, &defs, &krate, crate_name, &sess.dep_graph));
time(sess.time_passes(), "external crate/lib resolution", || {
let defs = &resolver.definitions;
read_local_crates(sess, &cstore, defs, &krate, crate_name, &sess.dep_graph)
});
time(sess.time_passes(), time(sess.time_passes(),
"early lint checks", "early lint checks",
@ -745,8 +745,14 @@ pub fn phase_2_configure_and_expand<'a>(sess: &Session,
"AST validation", "AST validation",
|| ast_validation::check_crate(sess, &krate)); || ast_validation::check_crate(sess, &krate));
let (analysis, resolutions, hir_forest) = time(sess.time_passes(), "name resolution", || {
lower_and_resolve(sess, crate_name, &mut defs, &krate, &sess.dep_graph, make_glob_map); resolver.resolve_crate(&krate);
});
// Lower ast -> hir.
let hir_forest = time(sess.time_passes(), "lowering ast -> hir", || {
hir_map::Forest::new(lower_crate(sess, &krate, &mut resolver), &sess.dep_graph)
});
// Discard MTWT tables that aren't required past lowering to HIR. // Discard MTWT tables that aren't required past lowering to HIR.
if !keep_mtwt_tables(sess) { if !keep_mtwt_tables(sess) {
@ -755,9 +761,20 @@ pub fn phase_2_configure_and_expand<'a>(sess: &Session,
Ok(ExpansionResult { Ok(ExpansionResult {
expanded_crate: krate, expanded_crate: krate,
defs: defs, defs: resolver.definitions,
analysis: analysis, analysis: ty::CrateAnalysis {
resolutions: resolutions, export_map: resolver.export_map,
access_levels: AccessLevels::default(),
reachable: NodeSet(),
name: crate_name,
glob_map: if resolver.make_glob_map { Some(resolver.glob_map) } else { None },
},
resolutions: Resolutions {
def_map: resolver.def_map,
freevars: resolver.freevars,
trait_map: resolver.trait_map,
maybe_unused_trait_imports: resolver.maybe_unused_trait_imports,
},
hir_forest: hir_forest hir_forest: hir_forest
}) })
} }
@ -809,38 +826,6 @@ fn fold_block(&mut self, block: P<ast::Block>) -> P<ast::Block> {
krate krate
} }
pub fn lower_and_resolve<'a>(sess: &Session,
id: &'a str,
defs: &mut hir_map::Definitions,
krate: &ast::Crate,
dep_graph: &DepGraph,
make_glob_map: resolve::MakeGlobMap)
-> (ty::CrateAnalysis<'a>, Resolutions, hir_map::Forest) {
resolve::with_resolver(sess, defs, make_glob_map, |mut resolver| {
time(sess.time_passes(), "name resolution", || {
resolve::resolve_crate(&mut resolver, krate);
});
// Lower ast -> hir.
let hir_forest = time(sess.time_passes(), "lowering ast -> hir", || {
hir_map::Forest::new(lower_crate(sess, krate, sess, &mut resolver), dep_graph)
});
(ty::CrateAnalysis {
export_map: resolver.export_map,
access_levels: AccessLevels::default(),
reachable: NodeSet(),
name: &id,
glob_map: if resolver.make_glob_map { Some(resolver.glob_map) } else { None },
}, Resolutions {
def_map: resolver.def_map,
freevars: resolver.freevars,
trait_map: resolver.trait_map,
maybe_unused_trait_imports: resolver.maybe_unused_trait_imports,
}, hir_forest)
})
}
/// Run the resolution, typechecking, region checking and other /// Run the resolution, typechecking, region checking and other
/// miscellaneous analysis passes on the crate. Return various /// miscellaneous analysis passes on the crate. Return various
/// structures carrying the results of the analysis. /// structures carrying the results of the analysis.

View file

@ -38,7 +38,6 @@
use rustc::ty::{self, Ty, TyCtxt}; use rustc::ty::{self, Ty, TyCtxt};
use syntax::ast; use syntax::ast;
use syntax::ast::NodeIdAssigner;
use syntax::ptr::P; use syntax::ptr::P;
use syntax_pos; use syntax_pos;
@ -56,7 +55,6 @@
#[cfg(test)] use std::io::Cursor; #[cfg(test)] use std::io::Cursor;
#[cfg(test)] use syntax::parse; #[cfg(test)] use syntax::parse;
#[cfg(test)] use syntax::ast::NodeId;
#[cfg(test)] use rustc::hir::print as pprust; #[cfg(test)] use rustc::hir::print as pprust;
#[cfg(test)] use rustc::hir::lowering::{LoweringContext, DummyResolver}; #[cfg(test)] use rustc::hir::lowering::{LoweringContext, DummyResolver};
@ -1295,22 +1293,6 @@ fn name_of(&self, st: &str) -> ast::Name {
fn parse_sess(&self) -> &parse::ParseSess { self } fn parse_sess(&self) -> &parse::ParseSess { self }
} }
#[cfg(test)]
struct FakeNodeIdAssigner;
#[cfg(test)]
// It should go without saying that this may give unexpected results. Avoid
// lowering anything which needs new nodes.
impl NodeIdAssigner for FakeNodeIdAssigner {
fn next_node_id(&self) -> NodeId {
0
}
fn peek_node_id(&self) -> NodeId {
0
}
}
#[cfg(test)] #[cfg(test)]
fn mk_ctxt() -> parse::ParseSess { fn mk_ctxt() -> parse::ParseSess {
parse::ParseSess::new() parse::ParseSess::new()
@ -1318,9 +1300,8 @@ fn mk_ctxt() -> parse::ParseSess {
#[cfg(test)] #[cfg(test)]
fn with_testing_context<T, F: FnOnce(&mut LoweringContext) -> T>(f: F) -> T { fn with_testing_context<T, F: FnOnce(&mut LoweringContext) -> T>(f: F) -> T {
let assigner = FakeNodeIdAssigner;
let mut resolver = DummyResolver; let mut resolver = DummyResolver;
let mut lcx = LoweringContext::testing_context(&assigner, &mut resolver); let mut lcx = LoweringContext::testing_context(&mut resolver);
f(&mut lcx) f(&mut lcx)
} }

View file

@ -16,6 +16,8 @@
register_long_diagnostics! { register_long_diagnostics! {
E0154: r##" E0154: r##"
## Note: this error code is no longer emitted by the compiler.
Imports (`use` statements) are not allowed after non-item statements, such as Imports (`use` statements) are not allowed after non-item statements, such as
variable declarations and expression statements. variable declarations and expression statements.
@ -50,6 +52,8 @@ fn f() {
"##, "##,
E0251: r##" E0251: r##"
## Note: this error code is no longer emitted by the compiler.
Two items of the same name cannot be imported without rebinding one of the Two items of the same name cannot be imported without rebinding one of the
items under a new local name. items under a new local name.
@ -75,9 +79,9 @@ pub mod baz {}
Two items of the same name cannot be imported without rebinding one of the Two items of the same name cannot be imported without rebinding one of the
items under a new local name. items under a new local name.
An example of this error: Erroneous code example:
```compile_fail ```compile_fail,E0252
use foo::baz; use foo::baz;
use bar::baz; // error, do `use bar::baz as quux` instead use bar::baz; // error, do `use bar::baz as quux` instead
@ -87,6 +91,41 @@ mod foo {
pub struct baz; pub struct baz;
} }
mod bar {
pub mod baz {}
}
```
You can use aliases in order to fix this error. Example:
```
use foo::baz as foo_baz;
use bar::baz; // ok!
fn main() {}
mod foo {
pub struct baz;
}
mod bar {
pub mod baz {}
}
```
Or you can reference the item with its parent:
```
use bar::baz;
fn main() {
let x = foo::baz; // ok!
}
mod foo {
pub struct baz;
}
mod bar { mod bar {
pub mod baz {} pub mod baz {}
} }
@ -95,9 +134,11 @@ pub mod baz {}
E0253: r##" E0253: r##"
Attempt was made to import an unimportable value. This can happen when trying Attempt was made to import an unimportable value. This can happen when trying
to import a method from a trait. An example of this error: to import a method from a trait.
```compile_fail Erroneous code example:
```compile_fail,E0253
mod foo { mod foo {
pub trait MyTrait { pub trait MyTrait {
fn do_something(); fn do_something();
@ -105,6 +146,8 @@ pub trait MyTrait {
} }
use foo::MyTrait::do_something; use foo::MyTrait::do_something;
fn main() {}
``` ```
It's invalid to directly import methods belonging to a trait or concrete type. It's invalid to directly import methods belonging to a trait or concrete type.
@ -114,10 +157,10 @@ pub trait MyTrait {
You can't import a value whose name is the same as another value defined in the You can't import a value whose name is the same as another value defined in the
module. module.
An example of this error: Erroneous code example:
```compile_fail ```compile_fail,E0255
use bar::foo; // error, do `use bar::foo as baz` instead use bar::foo; // error: an item named `foo` is already in scope
fn foo() {} fn foo() {}
@ -127,9 +170,39 @@ pub fn foo() {}
fn main() {} fn main() {}
``` ```
You can use aliases in order to fix this error. Example:
```
use bar::foo as bar_foo; // ok!
fn foo() {}
mod bar {
pub fn foo() {}
}
fn main() {}
```
Or you can reference the item with its parent:
```
fn foo() {}
mod bar {
pub fn foo() {}
}
fn main() {
bar::foo(); // we get the item by referring to its parent
}
```
"##, "##,
E0256: r##" E0256: r##"
## Note: this error code is no longer emitted by the compiler.
You can't import a type or module when the name of the item being imported is You can't import a type or module when the name of the item being imported is
the same as another type or submodule defined in the module. the same as another type or submodule defined in the module.
@ -154,9 +227,11 @@ fn main() {}
Erroneous code example: Erroneous code example:
```compile_fail ```compile_fail,E0259
extern crate a; extern crate std;
extern crate crate_a as a; extern crate libc as std;
fn main() {}
``` ```
The solution is to choose a different name that doesn't conflict with any The solution is to choose a different name that doesn't conflict with any
@ -165,17 +240,17 @@ fn main() {}
Correct example: Correct example:
```ignore ```ignore
extern crate a; extern crate std;
extern crate crate_a as other_name; extern crate libc as other_name;
``` ```
"##, "##,
E0260: r##" E0260: r##"
The name for an item declaration conflicts with an external crate's name. The name for an item declaration conflicts with an external crate's name.
For instance: Erroneous code example:
```ignore ```ignore,E0260
extern crate abc; extern crate abc;
struct abc; struct abc;
@ -209,7 +284,7 @@ fn main() {}
Private items cannot be publicly re-exported. This error indicates that you Private items cannot be publicly re-exported. This error indicates that you
attempted to `pub use` a type or value that was not itself public. attempted to `pub use` a type or value that was not itself public.
Here is an example that demonstrates the error: Erroneous code example:
```compile_fail ```compile_fail
mod foo { mod foo {
@ -217,17 +292,21 @@ mod foo {
} }
pub use foo::X; pub use foo::X;
fn main() {}
``` ```
The solution to this problem is to ensure that the items that you are The solution to this problem is to ensure that the items that you are
re-exporting are themselves marked with `pub`: re-exporting are themselves marked with `pub`:
```ignore ```
mod foo { mod foo {
pub const X: u32 = 1; pub const X: u32 = 1;
} }
pub use foo::X; pub use foo::X;
fn main() {}
``` ```
See the 'Use Declarations' section of the reference for more information on See the 'Use Declarations' section of the reference for more information on
@ -240,25 +319,29 @@ mod foo {
Private modules cannot be publicly re-exported. This error indicates that you Private modules cannot be publicly re-exported. This error indicates that you
attempted to `pub use` a module that was not itself public. attempted to `pub use` a module that was not itself public.
Here is an example that demonstrates the error: Erroneous code example:
```compile_fail ```compile_fail,E0365
mod foo { mod foo {
pub const X: u32 = 1; pub const X: u32 = 1;
} }
pub use foo as foo2; pub use foo as foo2;
fn main() {}
``` ```
The solution to this problem is to ensure that the module that you are The solution to this problem is to ensure that the module that you are
re-exporting is itself marked with `pub`: re-exporting is itself marked with `pub`:
```ignore ```
pub mod foo { pub mod foo {
pub const X: u32 = 1; pub const X: u32 = 1;
} }
pub use foo as foo2; pub use foo as foo2;
fn main() {}
``` ```
See the 'Use Declarations' section of the reference for more information See the 'Use Declarations' section of the reference for more information
@ -269,9 +352,11 @@ pub mod foo {
E0401: r##" E0401: r##"
Inner items do not inherit type parameters from the functions they are embedded Inner items do not inherit type parameters from the functions they are embedded
in. For example, this will not compile: in.
```compile_fail Erroneous code example:
```compile_fail,E0401
fn foo<T>(x: T) { fn foo<T>(x: T) {
fn bar(y: T) { // T is defined in the "outer" function fn bar(y: T) { // T is defined in the "outer" function
// .. // ..
@ -282,7 +367,7 @@ fn bar(y: T) { // T is defined in the "outer" function
Nor will this: Nor will this:
```compile_fail ```compile_fail,E0401
fn foo<T>(x: T) { fn foo<T>(x: T) {
type MaybeT = Option<T>; type MaybeT = Option<T>;
// ... // ...
@ -291,7 +376,7 @@ fn foo<T>(x: T) {
Or this: Or this:
```compile_fail ```compile_fail,E0401
fn foo<T>(x: T) { fn foo<T>(x: T) {
struct Foo { struct Foo {
x: T, x: T,
@ -374,9 +459,11 @@ fn bar(&self, y: T) {
"##, "##,
E0403: r##" E0403: r##"
Some type parameters have the same name. Example of erroneous code: Some type parameters have the same name.
```compile_fail Erroneous code example:
```compile_fail,E0403
fn foo<T, T>(s: T, u: T) {} // error: the name `T` is already used for a type fn foo<T, T>(s: T, u: T) {} // error: the name `T` is already used for a type
// parameter in this type parameter list // parameter in this type parameter list
``` ```
@ -390,10 +477,11 @@ fn foo<T, Y>(s: T, u: Y) {} // ok!
"##, "##,
E0404: r##" E0404: r##"
You tried to implement something which was not a trait on an object. Example of You tried to implement something which was not a trait on an object.
erroneous code:
```compile_fail Erroneous code example:
```compile_fail,E0404
struct Foo; struct Foo;
struct Bar; struct Bar;
@ -416,9 +504,11 @@ impl Foo for Bar { // ok!
"##, "##,
E0405: r##" E0405: r##"
The code refers to a trait that is not in scope. Example of erroneous code: The code refers to a trait that is not in scope.
```compile_fail Erroneous code example:
```compile_fail,E0405
struct Foo; struct Foo;
impl SomeTrait for Foo {} // error: trait `SomeTrait` is not in scope impl SomeTrait for Foo {} // error: trait `SomeTrait` is not in scope
@ -446,9 +536,11 @@ impl SomeTrait for Foo { // ok!
E0407: r##" E0407: r##"
A definition of a method not in the implemented trait was given in a trait A definition of a method not in the implemented trait was given in a trait
implementation. Example of erroneous code: implementation.
```compile_fail Erroneous code example:
```compile_fail,E0407
trait Foo { trait Foo {
fn a(); fn a();
} }
@ -501,9 +593,9 @@ fn b() {}
An "or" pattern was used where the variable bindings are not consistently bound An "or" pattern was used where the variable bindings are not consistently bound
across patterns. across patterns.
Example of erroneous code: Erroneous code example:
```compile_fail ```compile_fail,E0408
match x { match x {
Some(y) | None => { /* use y */ } // error: variable `y` from pattern #1 is Some(y) | None => { /* use y */ } // error: variable `y` from pattern #1 is
// not bound in pattern #2 // not bound in pattern #2
@ -545,9 +637,9 @@ fn b() {}
An "or" pattern was used where the variable bindings are not consistently bound An "or" pattern was used where the variable bindings are not consistently bound
across patterns. across patterns.
Example of erroneous code: Erroneous code example:
```compile_fail ```compile_fail,E0409
let x = (0, 2); let x = (0, 2);
match x { match x {
(0, ref y) | (y, 0) => { /* use y */} // error: variable `y` is bound with (0, ref y) | (y, 0) => { /* use y */} // error: variable `y` is bound with
@ -583,9 +675,11 @@ fn b() {}
"##, "##,
E0411: r##" E0411: r##"
The `Self` keyword was used outside an impl or a trait. Erroneous code example: The `Self` keyword was used outside an impl or a trait.
```compile_fail Erroneous code example:
```compile_fail,E0411
<Self>::foo; // error: use of `Self` outside of an impl or trait <Self>::foo; // error: use of `Self` outside of an impl or trait
``` ```
@ -639,9 +733,11 @@ trait Baz : Foo + Foo2 {
"##, "##,
E0412: r##" E0412: r##"
The type name used is not in scope. Example of erroneous codes: The type name used is not in scope.
```compile_fail Erroneous code examples:
```compile_fail,E0412
impl Something {} // error: type name `Something` is not in scope impl Something {} // error: type name `Something` is not in scope
// or: // or:
@ -678,9 +774,11 @@ fn foo<T>(x: T) {} // ok!
"##, "##,
E0415: r##" E0415: r##"
More than one function parameter have the same name. Example of erroneous code: More than one function parameter have the same name.
```compile_fail Erroneous code example:
```compile_fail,E0415
fn foo(f: i32, f: i32) {} // error: identifier `f` is bound more than fn foo(f: i32, f: i32) {} // error: identifier `f` is bound more than
// once in this parameter list // once in this parameter list
``` ```
@ -693,9 +791,11 @@ fn foo(f: i32, g: i32) {} // ok!
"##, "##,
E0416: r##" E0416: r##"
An identifier is bound more than once in a pattern. Example of erroneous code: An identifier is bound more than once in a pattern.
```compile_fail Erroneous code example:
```compile_fail,E0416
match (1, 2) { match (1, 2) {
(x, x) => {} // error: identifier `x` is bound more than once in the (x, x) => {} // error: identifier `x` is bound more than once in the
// same pattern // same pattern
@ -722,9 +822,10 @@ fn foo(f: i32, g: i32) {} // ok!
E0422: r##" E0422: r##"
You are trying to use an identifier that is either undefined or not a struct. You are trying to use an identifier that is either undefined or not a struct.
For instance:
``` compile_fail Erroneous code example:
``` compile_fail,E0422
fn main () { fn main () {
let x = Foo { x: 1, y: 2 }; let x = Foo { x: 1, y: 2 };
} }
@ -733,7 +834,7 @@ fn main () {
In this case, `Foo` is undefined, so it inherently isn't anything, and In this case, `Foo` is undefined, so it inherently isn't anything, and
definitely not a struct. definitely not a struct.
```compile_fail ```compile_fail,E0422
fn main () { fn main () {
let foo = 1; let foo = 1;
let x = foo { x: 1, y: 2 }; let x = foo { x: 1, y: 2 };
@ -745,10 +846,11 @@ fn main () {
"##, "##,
E0423: r##" E0423: r##"
A `struct` variant name was used like a function name. Example of erroneous A `struct` variant name was used like a function name.
code:
```compile_fail Erroneous code example:
```compile_fail,E0423
struct Foo { a: bool}; struct Foo { a: bool};
let f = Foo(); let f = Foo();
@ -767,9 +869,11 @@ fn Foo() -> u32 { 0 }
"##, "##,
E0424: r##" E0424: r##"
The `self` keyword was used in a static method. Example of erroneous code: The `self` keyword was used in a static method.
```compile_fail Erroneous code example:
```compile_fail,E0424
struct Foo; struct Foo;
impl Foo { impl Foo {
@ -799,9 +903,11 @@ fn foo(self) {
"##, "##,
E0425: r##" E0425: r##"
An unresolved name was used. Example of erroneous codes: An unresolved name was used.
```compile_fail Erroneous code examples:
```compile_fail,E0425
something_that_doesnt_exist::foo; something_that_doesnt_exist::foo;
// error: unresolved name `something_that_doesnt_exist::foo` // error: unresolved name `something_that_doesnt_exist::foo`
@ -857,9 +963,11 @@ mod something_that_does_exist {
"##, "##,
E0426: r##" E0426: r##"
An undeclared label was used. Example of erroneous code: An undeclared label was used.
```compile_fail Erroneous code example:
```compile_fail,E0426
loop { loop {
break 'a; // error: use of undeclared label `'a` break 'a; // error: use of undeclared label `'a`
} }
@ -875,10 +983,11 @@ mod something_that_does_exist {
"##, "##,
E0428: r##" E0428: r##"
A type or module has been defined more than once. Example of erroneous A type or module has been defined more than once.
code:
```compile_fail Erroneous code example:
```compile_fail,E0428
struct Bar; struct Bar;
struct Bar; // error: duplicate definition of value `Bar` struct Bar; // error: duplicate definition of value `Bar`
``` ```
@ -896,9 +1005,9 @@ mod something_that_does_exist {
The `self` keyword cannot appear alone as the last segment in a `use` The `self` keyword cannot appear alone as the last segment in a `use`
declaration. declaration.
Example of erroneous code: Erroneous code example:
```compile_fail ```compile_fail,E0429
use std::fmt::self; // error: `self` imports are only allowed within a { } list use std::fmt::self; // error: `self` imports are only allowed within a { } list
``` ```
@ -917,9 +1026,11 @@ mod something_that_does_exist {
"##, "##,
E0430: r##" E0430: r##"
The `self` import appears more than once in the list. Erroneous code example: The `self` import appears more than once in the list.
```compile_fail Erroneous code example:
```compile_fail,E0430
use something::{self, self}; // error: `self` import can only appear once in use something::{self, self}; // error: `self` import can only appear once in
// the list // the list
``` ```
@ -933,9 +1044,11 @@ mod something_that_does_exist {
"##, "##,
E0431: r##" E0431: r##"
An invalid `self` import was made. Erroneous code example: An invalid `self` import was made.
```compile_fail Erroneous code example:
```compile_fail,E0431
use {self}; // error: `self` import can only appear in an import list with a use {self}; // error: `self` import can only appear in an import list with a
// non-empty prefix // non-empty prefix
``` ```
@ -945,9 +1058,11 @@ mod something_that_does_exist {
"##, "##,
E0432: r##" E0432: r##"
An import was unresolved. Erroneous code example: An import was unresolved.
```compile_fail Erroneous code example:
```compile_fail,E0432
use something::Foo; // error: unresolved import `something::Foo`. use something::Foo; // error: unresolved import `something::Foo`.
``` ```
@ -976,14 +1091,23 @@ mod something {
"##, "##,
E0433: r##" E0433: r##"
Invalid import. Example of erroneous code: An undeclared type or module was used.
```compile_fail Erroneous code example:
use something_which_doesnt_exist;
// error: unresolved import `something_which_doesnt_exist` ```compile_fail,E0433
let map = HashMap::new();
// error: failed to resolve. Use of undeclared type or module `HashMap`
``` ```
Please verify you didn't misspell the import's name. Please verify you didn't misspell the type/module's name or that you didn't
forgot to import it:
```
use std::collections::HashMap; // HashMap has been imported.
let map: HashMap<u32, u32> = HashMap::new(); // So it can be used!
```
"##, "##,
E0434: r##" E0434: r##"
@ -991,9 +1115,9 @@ mod something {
because the variable comes from a dynamic environment. Inner functions do not because the variable comes from a dynamic environment. Inner functions do not
have access to their containing environment. have access to their containing environment.
Example of erroneous code: Erroneous code example:
```compile_fail ```compile_fail,E0434
fn foo() { fn foo() {
let y = 5; let y = 5;
fn bar() -> u32 { fn bar() -> u32 {
@ -1032,10 +1156,11 @@ fn bar() -> u32 {
"##, "##,
E0435: r##" E0435: r##"
A non-constant value was used to initialise a constant. Example of erroneous A non-constant value was used to initialise a constant.
code:
```compile_fail Erroneous code example:
```compile_fail,E0435
let foo = 42u32; let foo = 42u32;
const FOO : u32 = foo; // error: attempt to use a non-constant value in a const FOO : u32 = foo; // error: attempt to use a non-constant value in a
// constant // constant
@ -1061,9 +1186,9 @@ fn bar() -> u32 {
an associated type whose name does not match the name of any associated type an associated type whose name does not match the name of any associated type
in the trait. in the trait.
Here is an example that demonstrates the error: Erroneous code example:
```compile_fail ```compile_fail,E0437
trait Foo {} trait Foo {}
impl Foo for i32 { impl Foo for i32 {
@ -1086,9 +1211,9 @@ impl Foo for i32 {}
attempted to implement an associated constant whose name does not attempted to implement an associated constant whose name does not
match the name of any associated constant in the trait. match the name of any associated constant in the trait.
Here is an example that demonstrates the error: Erroneous code example:
```compile_fail ```compile_fail,E0438
#![feature(associated_consts)] #![feature(associated_consts)]
trait Foo {} trait Foo {}

View file

@ -47,7 +47,7 @@
use rustc::session::Session; use rustc::session::Session;
use rustc::lint; use rustc::lint;
use rustc::hir::def::*; use rustc::hir::def::*;
use rustc::hir::def_id::DefId; use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId};
use rustc::ty; use rustc::ty;
use rustc::ty::subst::{ParamSpace, FnSpace, TypeSpace}; use rustc::ty::subst::{ParamSpace, FnSpace, TypeSpace};
use rustc::hir::{Freevar, FreevarMap, TraitCandidate, TraitMap, GlobMap}; use rustc::hir::{Freevar, FreevarMap, TraitCandidate, TraitMap, GlobMap};
@ -925,7 +925,7 @@ fn intern(&mut self, string: &str, primitive_type: PrimTy) {
pub struct Resolver<'a> { pub struct Resolver<'a> {
session: &'a Session, session: &'a Session,
definitions: &'a mut Definitions, pub definitions: Definitions,
graph_root: Module<'a>, graph_root: Module<'a>,
@ -1001,7 +1001,7 @@ pub struct Resolver<'a> {
arenas: &'a ResolverArenas<'a>, arenas: &'a ResolverArenas<'a>,
} }
struct ResolverArenas<'a> { pub struct ResolverArenas<'a> {
modules: arena::TypedArena<ModuleS<'a>>, modules: arena::TypedArena<ModuleS<'a>>,
local_modules: RefCell<Vec<Module<'a>>>, local_modules: RefCell<Vec<Module<'a>>>,
name_bindings: arena::TypedArena<NameBinding<'a>>, name_bindings: arena::TypedArena<NameBinding<'a>>,
@ -1079,7 +1079,7 @@ fn record_resolution(&mut self, id: NodeId, def: Def) {
} }
fn definitions(&mut self) -> Option<&mut Definitions> { fn definitions(&mut self) -> Option<&mut Definitions> {
Some(self.definitions) Some(&mut self.definitions)
} }
} }
@ -1100,12 +1100,9 @@ fn name(&self) -> Name {
} }
impl<'a> Resolver<'a> { impl<'a> Resolver<'a> {
fn new(session: &'a Session, pub fn new(session: &'a Session, make_glob_map: MakeGlobMap, arenas: &'a ResolverArenas<'a>)
definitions: &'a mut Definitions,
make_glob_map: MakeGlobMap,
arenas: &'a ResolverArenas<'a>)
-> Resolver<'a> { -> Resolver<'a> {
let root_def_id = definitions.local_def_id(CRATE_NODE_ID); let root_def_id = DefId::local(CRATE_DEF_INDEX);
let graph_root = let graph_root =
ModuleS::new(NoParentLink, Some(Def::Mod(root_def_id)), false, arenas); ModuleS::new(NoParentLink, Some(Def::Mod(root_def_id)), false, arenas);
let graph_root = arenas.alloc_module(graph_root); let graph_root = arenas.alloc_module(graph_root);
@ -1115,7 +1112,7 @@ fn new(session: &'a Session,
Resolver { Resolver {
session: session, session: session,
definitions: definitions, definitions: Definitions::new(),
// The outermost module has def ID 0; this is not reflected in the // The outermost module has def ID 0; this is not reflected in the
// AST. // AST.
@ -1158,7 +1155,7 @@ fn new(session: &'a Session,
} }
} }
fn arenas() -> ResolverArenas<'a> { pub fn arenas() -> ResolverArenas<'a> {
ResolverArenas { ResolverArenas {
modules: arena::TypedArena::new(), modules: arena::TypedArena::new(),
local_modules: RefCell::new(Vec::new()), local_modules: RefCell::new(Vec::new()),
@ -1168,6 +1165,27 @@ fn arenas() -> ResolverArenas<'a> {
} }
} }
/// Entry point to crate resolution.
pub fn resolve_crate(&mut self, krate: &Crate) {
// Currently, we ignore the name resolution data structures for
// the purposes of dependency tracking. Instead we will run name
// resolution and include its output in the hash of each item,
// much like we do for macro expansion. In other words, the hash
// reflects not just its contents but the results of name
// resolution on those contents. Hopefully we'll push this back at
// some point.
let _ignore = self.session.dep_graph.in_ignore();
self.build_reduced_graph(krate);
resolve_imports::resolve_imports(self);
self.current_module = self.graph_root;
visit::walk_crate(self, krate);
check_unused::check_crate(self, krate);
self.report_privacy_errors();
}
fn new_module(&self, parent_link: ParentLink<'a>, def: Option<Def>, external: bool) fn new_module(&self, parent_link: ParentLink<'a>, def: Option<Def>, external: bool)
-> Module<'a> { -> Module<'a> {
self.arenas.alloc_module(ModuleS::new(parent_link, def, external, self.arenas)) self.arenas.alloc_module(ModuleS::new(parent_link, def, external, self.arenas))
@ -1568,12 +1586,6 @@ fn search_label(&self, name: Name) -> Option<Def> {
None None
} }
fn resolve_crate(&mut self, krate: &Crate) {
debug!("(resolving crate) starting");
self.current_module = self.graph_root;
visit::walk_crate(self, krate);
}
fn resolve_item(&mut self, item: &Item) { fn resolve_item(&mut self, item: &Item) {
let name = item.ident.name; let name = item.ident.name;
@ -2287,24 +2299,25 @@ fn resolve_pattern(&mut self,
PatKind::Ident(bmode, ref ident, ref opt_pat) => { PatKind::Ident(bmode, ref ident, ref opt_pat) => {
// First try to resolve the identifier as some existing // First try to resolve the identifier as some existing
// entity, then fall back to a fresh binding. // entity, then fall back to a fresh binding.
let resolution = if let Ok(resolution) = self.resolve_path(pat.id, let local_def = self.resolve_identifier(ident.node, ValueNS, true);
&Path::from_ident(ident.span, ident.node), 0, ValueNS) { let resolution = if let Some(LocalDef { def, .. }) = local_def {
let always_binding = !pat_src.is_refutable() || opt_pat.is_some() || let always_binding = !pat_src.is_refutable() || opt_pat.is_some() ||
bmode != BindingMode::ByValue(Mutability::Immutable); bmode != BindingMode::ByValue(Mutability::Immutable);
match resolution.base_def { match def {
Def::Struct(..) | Def::Variant(..) | Def::Struct(..) | Def::Variant(..) |
Def::Const(..) | Def::AssociatedConst(..) if !always_binding => { Def::Const(..) | Def::AssociatedConst(..) if !always_binding => {
// A constant, unit variant, etc pattern. // A constant, unit variant, etc pattern.
resolution PathResolution::new(def)
} }
Def::Struct(..) | Def::Variant(..) | Def::Struct(..) | Def::Variant(..) |
Def::Const(..) | Def::AssociatedConst(..) | Def::Static(..) => { Def::Const(..) | Def::AssociatedConst(..) | Def::Static(..) => {
// A fresh binding that shadows something unacceptable. // A fresh binding that shadows something unacceptable.
let kind_name = PathResolution::new(def).kind_name();
resolve_error( resolve_error(
self, self,
ident.span, ident.span,
ResolutionError::BindingShadowsSomethingUnacceptable( ResolutionError::BindingShadowsSomethingUnacceptable(
pat_src.descr(), resolution.kind_name(), ident.node.name) pat_src.descr(), kind_name, ident.node.name)
); );
err_path_resolution() err_path_resolution()
} }
@ -3194,9 +3207,11 @@ fn lookup_candidates<FilterFn>(&mut self,
if !in_module_is_extern || name_binding.vis == ty::Visibility::Public { if !in_module_is_extern || name_binding.vis == ty::Visibility::Public {
// add the module to the lookup // add the module to the lookup
let is_extern = in_module_is_extern || name_binding.is_extern_crate(); let is_extern = in_module_is_extern || name_binding.is_extern_crate();
if !worklist.iter().any(|&(m, _, _)| m.def == module.def) {
worklist.push((module, path_segments, is_extern)); worklist.push((module, path_segments, is_extern));
} }
} }
}
}) })
} }
@ -3454,34 +3469,4 @@ pub enum MakeGlobMap {
No, No,
} }
/// Entry point to crate resolution.
pub fn resolve_crate<'a, 'b>(resolver: &'b mut Resolver<'a>, krate: &'b Crate) {
// Currently, we ignore the name resolution data structures for
// the purposes of dependency tracking. Instead we will run name
// resolution and include its output in the hash of each item,
// much like we do for macro expansion. In other words, the hash
// reflects not just its contents but the results of name
// resolution on those contents. Hopefully we'll push this back at
// some point.
let _ignore = resolver.session.dep_graph.in_ignore();
resolver.build_reduced_graph(krate);
resolve_imports::resolve_imports(resolver);
resolver.resolve_crate(krate);
check_unused::check_crate(resolver, krate);
resolver.report_privacy_errors();
}
pub fn with_resolver<'a, T, F>(session: &'a Session,
definitions: &'a mut Definitions,
make_glob_map: MakeGlobMap,
f: F) -> T
where F: for<'b> FnOnce(Resolver<'b>) -> T,
{
let arenas = Resolver::arenas();
let resolver = Resolver::new(session, definitions, make_glob_map, &arenas);
f(resolver)
}
__build_diagnostic_array! { librustc_resolve, DIAGNOSTICS } __build_diagnostic_array! { librustc_resolve, DIAGNOSTICS }

View file

@ -1696,6 +1696,9 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
document(w, cx, item)?; document(w, cx, item)?;
let mut indices = (0..items.len()).filter(|i| { let mut indices = (0..items.len()).filter(|i| {
if let clean::DefaultImplItem(..) = items[*i].inner {
return false;
}
!cx.maybe_ignore_item(&items[*i]) !cx.maybe_ignore_item(&items[*i])
}).collect::<Vec<usize>>(); }).collect::<Vec<usize>>();

View file

@ -12,6 +12,7 @@
use rustc::middle::privacy::AccessLevels; use rustc::middle::privacy::AccessLevels;
use rustc::util::nodemap::DefIdSet; use rustc::util::nodemap::DefIdSet;
use std::cmp; use std::cmp;
use std::mem;
use std::string::String; use std::string::String;
use std::usize; use std::usize;
@ -29,7 +30,8 @@ pub fn strip_hidden(krate: clean::Crate) -> plugins::PluginResult {
// strip all #[doc(hidden)] items // strip all #[doc(hidden)] items
let krate = { let krate = {
struct Stripper<'a> { struct Stripper<'a> {
retained: &'a mut DefIdSet retained: &'a mut DefIdSet,
update_retained: bool,
} }
impl<'a> fold::DocFolder for Stripper<'a> { impl<'a> fold::DocFolder for Stripper<'a> {
fn fold_item(&mut self, i: Item) -> Option<Item> { fn fold_item(&mut self, i: Item) -> Option<Item> {
@ -38,17 +40,25 @@ fn fold_item(&mut self, i: Item) -> Option<Item> {
// use a dedicated hidden item for given item type if any // use a dedicated hidden item for given item type if any
match i.inner { match i.inner {
clean::StructFieldItem(..) | clean::ModuleItem(..) => { clean::StructFieldItem(..) | clean::ModuleItem(..) => {
return Strip(i).fold() // We need to recurse into stripped modules to
// strip things like impl methods but when doing so
// we must not add any items to the `retained` set.
let old = mem::replace(&mut self.update_retained, false);
let ret = Strip(self.fold_item_recur(i).unwrap()).fold();
self.update_retained = old;
return ret;
} }
_ => return None, _ => return None,
} }
} else { } else {
if self.update_retained {
self.retained.insert(i.def_id); self.retained.insert(i.def_id);
} }
}
self.fold_item_recur(i) self.fold_item_recur(i)
} }
} }
let mut stripper = Stripper{ retained: &mut retained }; let mut stripper = Stripper{ retained: &mut retained, update_retained: true };
stripper.fold_crate(krate) stripper.fold_crate(krate)
}; };
@ -69,6 +79,7 @@ pub fn strip_private(mut krate: clean::Crate) -> plugins::PluginResult {
let mut stripper = Stripper { let mut stripper = Stripper {
retained: &mut retained, retained: &mut retained,
access_levels: &access_levels, access_levels: &access_levels,
update_retained: true,
}; };
krate = ImportStripper.fold_crate(stripper.fold_crate(krate)); krate = ImportStripper.fold_crate(stripper.fold_crate(krate));
} }
@ -81,12 +92,21 @@ pub fn strip_private(mut krate: clean::Crate) -> plugins::PluginResult {
struct Stripper<'a> { struct Stripper<'a> {
retained: &'a mut DefIdSet, retained: &'a mut DefIdSet,
access_levels: &'a AccessLevels<DefId>, access_levels: &'a AccessLevels<DefId>,
update_retained: bool,
} }
impl<'a> fold::DocFolder for Stripper<'a> { impl<'a> fold::DocFolder for Stripper<'a> {
fn fold_item(&mut self, i: Item) -> Option<Item> { fn fold_item(&mut self, i: Item) -> Option<Item> {
match i.inner { match i.inner {
clean::StrippedItem(..) => return Some(i), clean::StrippedItem(..) => {
// We need to recurse into stripped modules to strip things
// like impl methods but when doing so we must not add any
// items to the `retained` set.
let old = mem::replace(&mut self.update_retained, false);
let ret = self.fold_item_recur(i);
self.update_retained = old;
return ret;
}
// These items can all get re-exported // These items can all get re-exported
clean::TypedefItem(..) | clean::StaticItem(..) | clean::TypedefItem(..) | clean::StaticItem(..) |
clean::StructItem(..) | clean::EnumItem(..) | clean::StructItem(..) | clean::EnumItem(..) |
@ -109,18 +129,13 @@ fn fold_item(&mut self, i: Item) -> Option<Item> {
clean::ModuleItem(..) => { clean::ModuleItem(..) => {
if i.def_id.is_local() && i.visibility != Some(clean::Public) { if i.def_id.is_local() && i.visibility != Some(clean::Public) {
return Strip(self.fold_item_recur(i).unwrap()).fold() let old = mem::replace(&mut self.update_retained, false);
let ret = Strip(self.fold_item_recur(i).unwrap()).fold();
self.update_retained = old;
return ret;
} }
} }
// trait impls for private items should be stripped
clean::ImplItem(clean::Impl{
for_: clean::ResolvedPath{ did, is_generic, .. }, ..
}) => {
if did.is_local() && !is_generic && !self.access_levels.is_exported(did) {
return None;
}
}
// handled in the `strip-priv-imports` pass // handled in the `strip-priv-imports` pass
clean::ExternCrateItem(..) | clean::ImportItem(..) => {} clean::ExternCrateItem(..) | clean::ImportItem(..) => {}
@ -152,7 +167,9 @@ fn fold_item(&mut self, i: Item) -> Option<Item> {
}; };
let i = if fastreturn { let i = if fastreturn {
if self.update_retained {
self.retained.insert(i.def_id); self.retained.insert(i.def_id);
}
return Some(i); return Some(i);
} else { } else {
self.fold_item_recur(i) self.fold_item_recur(i)
@ -160,13 +177,14 @@ fn fold_item(&mut self, i: Item) -> Option<Item> {
i.and_then(|i| { i.and_then(|i| {
match i.inner { match i.inner {
// emptied modules/impls have no need to exist // emptied modules have no need to exist
clean::ModuleItem(ref m) clean::ModuleItem(ref m)
if m.items.is_empty() && if m.items.is_empty() &&
i.doc_value().is_none() => None, i.doc_value().is_none() => None,
clean::ImplItem(ref i) if i.items.is_empty() => None,
_ => { _ => {
if self.update_retained {
self.retained.insert(i.def_id); self.retained.insert(i.def_id);
}
Some(i) Some(i)
} }
} }
@ -182,6 +200,10 @@ struct ImplStripper<'a> {
impl<'a> fold::DocFolder for ImplStripper<'a> { impl<'a> fold::DocFolder for ImplStripper<'a> {
fn fold_item(&mut self, i: Item) -> Option<Item> { fn fold_item(&mut self, i: Item) -> Option<Item> {
if let clean::ImplItem(ref imp) = i.inner { if let clean::ImplItem(ref imp) = i.inner {
// emptied none trait impls can be stripped
if imp.trait_.is_none() && imp.items.is_empty() {
return None;
}
if let Some(did) = imp.for_.def_id() { if let Some(did) = imp.for_.def_id() {
if did.is_local() && !imp.for_.is_generic() && if did.is_local() && !imp.for_.is_generic() &&
!self.retained.contains(&did) !self.retained.contains(&did)

View file

@ -19,7 +19,6 @@
use syntax_pos::{mk_sp, Span, DUMMY_SP, ExpnId}; use syntax_pos::{mk_sp, Span, DUMMY_SP, ExpnId};
use codemap::{respan, Spanned}; use codemap::{respan, Spanned};
use abi::Abi; use abi::Abi;
use errors;
use parse::token::{self, keywords, InternedString}; use parse::token::{self, keywords, InternedString};
use print::pprust; use print::pprust;
use ptr::P; use ptr::P;
@ -362,15 +361,6 @@ pub struct ParenthesizedParameterData {
/// small, positive ids. /// small, positive ids.
pub const DUMMY_NODE_ID: NodeId = !0; pub const DUMMY_NODE_ID: NodeId = !0;
pub trait NodeIdAssigner {
fn next_node_id(&self) -> NodeId;
fn peek_node_id(&self) -> NodeId;
fn diagnostic(&self) -> &errors::Handler {
panic!("this ID assigner cannot emit diagnostics")
}
}
/// The AST represents all type param bounds as types. /// The AST represents all type param bounds as types.
/// typeck::collect::compute_bounds matches these against /// typeck::collect::compute_bounds matches these against
/// the "special" built-in traits (see middle::lang_items) and /// the "special" built-in traits (see middle::lang_items) and

View file

@ -839,7 +839,7 @@ impl HasAttrs for StmtKind {
fn attrs(&self) -> &[Attribute] { fn attrs(&self) -> &[Attribute] {
match *self { match *self {
StmtKind::Local(ref local) => local.attrs(), StmtKind::Local(ref local) => local.attrs(),
StmtKind::Item(ref item) => item.attrs(), StmtKind::Item(..) => &[],
StmtKind::Expr(ref expr) | StmtKind::Semi(ref expr) => expr.attrs(), StmtKind::Expr(ref expr) | StmtKind::Semi(ref expr) => expr.attrs(),
StmtKind::Mac(ref mac) => { StmtKind::Mac(ref mac) => {
let (_, _, ref attrs) = **mac; let (_, _, ref attrs) = **mac;
@ -851,7 +851,7 @@ fn attrs(&self) -> &[Attribute] {
fn map_attrs<F: FnOnce(Vec<Attribute>) -> Vec<Attribute>>(self, f: F) -> Self { fn map_attrs<F: FnOnce(Vec<Attribute>) -> Vec<Attribute>>(self, f: F) -> Self {
match self { match self {
StmtKind::Local(local) => StmtKind::Local(local.map_attrs(f)), StmtKind::Local(local) => StmtKind::Local(local.map_attrs(f)),
StmtKind::Item(item) => StmtKind::Item(item.map_attrs(f)), StmtKind::Item(..) => self,
StmtKind::Expr(expr) => StmtKind::Expr(expr.map_attrs(f)), StmtKind::Expr(expr) => StmtKind::Expr(expr.map_attrs(f)),
StmtKind::Semi(expr) => StmtKind::Semi(expr.map_attrs(f)), StmtKind::Semi(expr) => StmtKind::Semi(expr.map_attrs(f)),
StmtKind::Mac(mac) => StmtKind::Mac(mac.map(|(mac, style, attrs)| { StmtKind::Mac(mac) => StmtKind::Mac(mac.map(|(mac, style, attrs)| {

View file

@ -213,12 +213,7 @@ fn fold_opt_expr(&mut self, expr: P<ast::Expr>) -> Option<P<ast::Expr>> {
} }
fn fold_stmt(&mut self, stmt: ast::Stmt) -> SmallVector<ast::Stmt> { fn fold_stmt(&mut self, stmt: ast::Stmt) -> SmallVector<ast::Stmt> {
// avoid calling `visit_stmt_or_expr_attrs` on items self.visit_stmt_or_expr_attrs(stmt.attrs());
match stmt.node {
ast::StmtKind::Item(_) => {}
_ => self.visit_stmt_or_expr_attrs(stmt.attrs()),
}
self.configure(stmt).map(|stmt| fold::noop_fold_stmt(stmt, self)) self.configure(stmt).map(|stmt| fold::noop_fold_stmt(stmt, self))
.unwrap_or(SmallVector::zero()) .unwrap_or(SmallVector::zero())
} }

View file

@ -443,6 +443,10 @@ fn make_stmts(self: Box<DummyResult>) -> Option<SmallVector<ast::Stmt>> {
span: self.span, span: self.span,
})) }))
} }
fn make_ty(self: Box<DummyResult>) -> Option<P<ast::Ty>> {
Some(DummyResult::raw_ty(self.span))
}
} }
/// An enum representing the different kinds of syntax extensions. /// An enum representing the different kinds of syntax extensions.

View file

@ -43,18 +43,19 @@ trait MacroGenerable: Sized {
fn fold_with<F: Folder>(self, folder: &mut F) -> Self; fn fold_with<F: Folder>(self, folder: &mut F) -> Self;
fn visit_with<V: Visitor>(&self, visitor: &mut V); fn visit_with<V: Visitor>(&self, visitor: &mut V);
// Return a placeholder expansion to allow compilation to continue after an erroring expansion.
fn dummy(span: Span) -> Self;
// The user-friendly name of the node type (e.g. "expression", "item", etc.) for diagnostics. // The user-friendly name of the node type (e.g. "expression", "item", etc.) for diagnostics.
fn kind_name() -> &'static str; fn kind_name() -> &'static str;
// Return a placeholder expansion to allow compilation to continue after an erroring expansion.
fn dummy(span: Span) -> Self {
Self::make_with(DummyResult::any(span)).unwrap()
}
} }
macro_rules! impl_macro_generable { macro_rules! impl_macro_generable {
($($ty:ty: $kind_name:expr, .$make:ident, ($($ty:ty: $kind_name:expr, .$make:ident,
$(.$fold:ident)* $(lift .$fold_elt:ident)*, $(.$fold:ident)* $(lift .$fold_elt:ident)*,
$(.$visit:ident)* $(lift .$visit_elt:ident)*, $(.$visit:ident)* $(lift .$visit_elt:ident)*;)*) => { $(
|$span:ident| $dummy:expr;)*) => { $(
impl MacroGenerable for $ty { impl MacroGenerable for $ty {
fn kind_name() -> &'static str { $kind_name } fn kind_name() -> &'static str { $kind_name }
fn make_with<'a>(result: Box<MacResult + 'a>) -> Option<Self> { result.$make() } fn make_with<'a>(result: Box<MacResult + 'a>) -> Option<Self> { result.$make() }
@ -66,31 +67,24 @@ fn visit_with<V: Visitor>(&self, visitor: &mut V) {
$( visitor.$visit(self) )* $( visitor.$visit(self) )*
$( for item in self.as_slice() { visitor. $visit_elt (item) } )* $( for item in self.as_slice() { visitor. $visit_elt (item) } )*
} }
fn dummy($span: Span) -> Self { $dummy }
} }
)* } )* }
} }
impl_macro_generable! { impl_macro_generable! {
P<ast::Pat>: "pattern", .make_pat, .fold_pat, .visit_pat, |span| P(DummyResult::raw_pat(span)); P<ast::Expr>: "expression", .make_expr, .fold_expr, .visit_expr;
P<ast::Ty>: "type", .make_ty, .fold_ty, .visit_ty, |span| DummyResult::raw_ty(span); P<ast::Pat>: "pattern", .make_pat, .fold_pat, .visit_pat;
P<ast::Expr>: P<ast::Ty>: "type", .make_ty, .fold_ty, .visit_ty;
"expression", .make_expr, .fold_expr, .visit_expr, |span| DummyResult::raw_expr(span); SmallVector<ast::Stmt>: "statement", .make_stmts, lift .fold_stmt, lift .visit_stmt;
SmallVector<ast::Stmt>: SmallVector<P<ast::Item>>: "item", .make_items, lift .fold_item, lift .visit_item;
"statement", .make_stmts, lift .fold_stmt, lift .visit_stmt, |_span| SmallVector::zero();
SmallVector<P<ast::Item>>:
"item", .make_items, lift .fold_item, lift .visit_item, |_span| SmallVector::zero();
SmallVector<ast::TraitItem>: SmallVector<ast::TraitItem>:
"trait item", .make_trait_items, lift .fold_trait_item, lift .visit_trait_item, "trait item", .make_trait_items, lift .fold_trait_item, lift .visit_trait_item;
|_span| SmallVector::zero();
SmallVector<ast::ImplItem>: SmallVector<ast::ImplItem>:
"impl item", .make_impl_items, lift .fold_impl_item, lift .visit_impl_item, "impl item", .make_impl_items, lift .fold_impl_item, lift .visit_impl_item;
|_span| SmallVector::zero();
} }
impl MacroGenerable for Option<P<ast::Expr>> { impl MacroGenerable for Option<P<ast::Expr>> {
fn kind_name() -> &'static str { "expression" } fn kind_name() -> &'static str { "expression" }
fn dummy(_span: Span) -> Self { None }
fn make_with<'a>(result: Box<MacResult + 'a>) -> Option<Self> { fn make_with<'a>(result: Box<MacResult + 'a>) -> Option<Self> {
result.make_expr().map(Some) result.make_expr().map(Some)
} }
@ -208,7 +202,7 @@ fn mac_result<'a>(path: &ast::Path, ident: Option<Ident>, tts: Vec<TokenTree>, m
&fld.cx.ecfg.features.unwrap()); &fld.cx.ecfg.features.unwrap());
} }
if path.segments.len() > 1 { if path.segments.len() > 1 || path.global || !path.segments[0].parameters.is_empty() {
fld.cx.span_err(path.span, "expected macro name without module separators"); fld.cx.span_err(path.span, "expected macro name without module separators");
return None; return None;
} }
@ -691,7 +685,7 @@ fn fold_mac(&mut self, mac: ast::Mac) -> ast::Mac {
} }
fn expand_multi_modified(a: Annotatable, fld: &mut MacroExpander) -> SmallVector<Annotatable> { fn expand_multi_modified(a: Annotatable, fld: &mut MacroExpander) -> SmallVector<Annotatable> {
let new_items: SmallVector<Annotatable> = match a { match a {
Annotatable::Item(it) => match it.node { Annotatable::Item(it) => match it.node {
ast::ItemKind::Mac(..) => { ast::ItemKind::Mac(..) => {
it.and_then(|it| match it.node { it.and_then(|it| match it.node {
@ -728,63 +722,6 @@ fn expand_multi_modified(a: Annotatable, fld: &mut MacroExpander) -> SmallVector
expand_impl_item(ii.unwrap(), fld).into_iter(). expand_impl_item(ii.unwrap(), fld).into_iter().
map(|ii| Annotatable::ImplItem(P(ii))).collect() map(|ii| Annotatable::ImplItem(P(ii))).collect()
} }
};
new_items.into_iter().flat_map(|a| decorate(a, fld)).collect()
}
fn decorate(a: Annotatable, fld: &mut MacroExpander) -> SmallVector<Annotatable> {
let mut decorator_items = SmallVector::zero();
let mut new_attrs = Vec::new();
expand_decorators(a.clone(), fld, &mut decorator_items, &mut new_attrs);
let mut new_items = SmallVector::one(a.fold_attrs(new_attrs));
new_items.push_all(decorator_items);
new_items
}
fn expand_decorators(a: Annotatable,
fld: &mut MacroExpander,
decorator_items: &mut SmallVector<Annotatable>,
new_attrs: &mut Vec<ast::Attribute>)
{
for attr in a.attrs() {
let mname = intern(&attr.name());
match fld.cx.syntax_env.find(mname) {
Some(rc) => match *rc {
MultiDecorator(ref dec) => {
attr::mark_used(&attr);
fld.cx.bt_push(ExpnInfo {
call_site: attr.span,
callee: NameAndSpan {
format: MacroAttribute(mname),
span: Some(attr.span),
// attributes can do whatever they like,
// for now.
allow_internal_unstable: true,
}
});
let mut items: SmallVector<Annotatable> = SmallVector::zero();
dec.expand(fld.cx,
attr.span,
&attr.node.value,
&a,
&mut |ann| items.push(ann));
for item in items {
for configured_item in item.fold_with(&mut fld.strip_unconfigured()) {
decorator_items.extend(expand_annotatable(configured_item, fld));
}
}
fld.cx.bt_pop();
}
_ => new_attrs.push((*attr).clone()),
},
_ => new_attrs.push((*attr).clone()),
}
} }
} }
@ -793,10 +730,13 @@ fn expand_annotatable(mut item: Annotatable, fld: &mut MacroExpander) -> SmallVe
item = item.map_attrs(|mut attrs| { item = item.map_attrs(|mut attrs| {
for i in 0..attrs.len() { for i in 0..attrs.len() {
if let Some(extension) = fld.cx.syntax_env.find(intern(&attrs[i].name())) { if let Some(extension) = fld.cx.syntax_env.find(intern(&attrs[i].name())) {
if let MultiModifier(..) = *extension { match *extension {
MultiModifier(..) | MultiDecorator(..) => {
multi_modifier = Some((attrs.remove(i), extension)); multi_modifier = Some((attrs.remove(i), extension));
break; break;
} }
_ => {}
}
} }
} }
attrs attrs
@ -804,8 +744,7 @@ fn expand_annotatable(mut item: Annotatable, fld: &mut MacroExpander) -> SmallVe
match multi_modifier { match multi_modifier {
None => expand_multi_modified(item, fld), None => expand_multi_modified(item, fld),
Some((attr, extension)) => match *extension { Some((attr, extension)) => {
MultiModifier(ref mac) => {
attr::mark_used(&attr); attr::mark_used(&attr);
fld.cx.bt_push(ExpnInfo { fld.cx.bt_push(ExpnInfo {
call_site: attr.span, call_site: attr.span,
@ -816,11 +755,21 @@ fn expand_annotatable(mut item: Annotatable, fld: &mut MacroExpander) -> SmallVe
allow_internal_unstable: true, allow_internal_unstable: true,
} }
}); });
let modified = mac.expand(fld.cx, attr.span, &attr.node.value, item);
fld.cx.bt_pop(); let modified = match *extension {
modified.into_iter().flat_map(|it| expand_annotatable(it, fld)).collect() MultiModifier(ref mac) => mac.expand(fld.cx, attr.span, &attr.node.value, item),
MultiDecorator(ref mac) => {
let mut items = Vec::new();
mac.expand(fld.cx, attr.span, &attr.node.value, &item,
&mut |item| items.push(item));
items.push(item);
items
} }
_ => unreachable!(), _ => unreachable!(),
};
fld.cx.bt_pop();
modified.into_iter().flat_map(|it| expand_annotatable(it, fld)).collect()
} }
} }
} }

View file

@ -1102,7 +1102,6 @@ pub fn noop_fold_pat<T: Folder>(p: P<Pat>, folder: &mut T) -> P<Pat> {
pub fn noop_fold_expr<T: Folder>(Expr {id, node, span, attrs}: Expr, folder: &mut T) -> Expr { pub fn noop_fold_expr<T: Folder>(Expr {id, node, span, attrs}: Expr, folder: &mut T) -> Expr {
Expr { Expr {
id: folder.new_id(id),
node: match node { node: match node {
ExprKind::Box(e) => { ExprKind::Box(e) => {
ExprKind::Box(folder.fold_expr(e)) ExprKind::Box(folder.fold_expr(e))
@ -1270,9 +1269,19 @@ pub fn noop_fold_expr<T: Folder>(Expr {id, node, span, attrs}: Expr, folder: &mu
fields.move_map(|x| folder.fold_field(x)), fields.move_map(|x| folder.fold_field(x)),
maybe_expr.map(|x| folder.fold_expr(x))) maybe_expr.map(|x| folder.fold_expr(x)))
}, },
ExprKind::Paren(ex) => ExprKind::Paren(folder.fold_expr(ex)), ExprKind::Paren(ex) => {
let sub_expr = folder.fold_expr(ex);
return Expr {
// Nodes that are equal modulo `Paren` sugar no-ops should have the same ids.
id: sub_expr.id,
node: ExprKind::Paren(sub_expr),
span: folder.new_span(span),
attrs: fold_attrs(attrs.into(), folder).into(),
};
}
ExprKind::Try(ex) => ExprKind::Try(folder.fold_expr(ex)), ExprKind::Try(ex) => ExprKind::Try(folder.fold_expr(ex)),
}, },
id: folder.new_id(id),
span: folder.new_span(span), span: folder.new_span(span),
attrs: fold_attrs(attrs.into(), folder).into(), attrs: fold_attrs(attrs.into(), folder).into(),
} }

View file

@ -553,10 +553,6 @@ pub fn commit_stmt(&mut self, edible: &[token::Token],
self.expect_one_of(edible, inedible) self.expect_one_of(edible, inedible)
} }
pub fn commit_stmt_expecting(&mut self, edible: token::Token) -> PResult<'a, ()> {
self.commit_stmt(&[edible], &[])
}
/// returns the span of expr, if it was not interpolated or the span of the interpolated token /// returns the span of expr, if it was not interpolated or the span of the interpolated token
fn interpolated_or_expr_span(&self, fn interpolated_or_expr_span(&self,
expr: PResult<'a, P<Expr>>) expr: PResult<'a, P<Expr>>)
@ -4122,7 +4118,7 @@ fn parse_block_tail(&mut self, lo: BytePos, s: BlockCheckMode) -> PResult<'a, P<
_ => { // all other kinds of statements: _ => { // all other kinds of statements:
let mut hi = span.hi; let mut hi = span.hi;
if classify::stmt_ends_with_semi(&node) { if classify::stmt_ends_with_semi(&node) {
self.commit_stmt_expecting(token::Semi)?; self.commit_stmt(&[token::Semi], &[])?;
hi = self.last_span.hi; hi = self.last_span.hi;
} }

View file

@ -345,15 +345,18 @@ pub fn combine_substructure<'a>(f: CombineSubstructureFunc<'a>)
/// This method helps to extract all the type parameters referenced from a /// This method helps to extract all the type parameters referenced from a
/// type. For a type parameter `<T>`, it looks for either a `TyPath` that /// type. For a type parameter `<T>`, it looks for either a `TyPath` that
/// is not global and starts with `T`, or a `TyQPath`. /// is not global and starts with `T`, or a `TyQPath`.
fn find_type_parameters(ty: &ast::Ty, ty_param_names: &[ast::Name]) -> Vec<P<ast::Ty>> { fn find_type_parameters(ty: &ast::Ty, ty_param_names: &[ast::Name], span: Span, cx: &ExtCtxt)
-> Vec<P<ast::Ty>> {
use syntax::visit; use syntax::visit;
struct Visitor<'a> { struct Visitor<'a, 'b: 'a> {
cx: &'a ExtCtxt<'b>,
span: Span,
ty_param_names: &'a [ast::Name], ty_param_names: &'a [ast::Name],
types: Vec<P<ast::Ty>>, types: Vec<P<ast::Ty>>,
} }
impl<'a> visit::Visitor for Visitor<'a> { impl<'a, 'b> visit::Visitor for Visitor<'a, 'b> {
fn visit_ty(&mut self, ty: &ast::Ty) { fn visit_ty(&mut self, ty: &ast::Ty) {
match ty.node { match ty.node {
ast::TyKind::Path(_, ref path) if !path.global => { ast::TyKind::Path(_, ref path) if !path.global => {
@ -371,11 +374,18 @@ fn visit_ty(&mut self, ty: &ast::Ty) {
visit::walk_ty(self, ty) visit::walk_ty(self, ty)
} }
fn visit_mac(&mut self, mac: &ast::Mac) {
let span = Span { expn_id: self.span.expn_id, ..mac.span };
self.cx.span_err(span, "`derive` cannot be used on items with type macros");
}
} }
let mut visitor = Visitor { let mut visitor = Visitor {
ty_param_names: ty_param_names, ty_param_names: ty_param_names,
types: Vec::new(), types: Vec::new(),
span: span,
cx: cx,
}; };
visit::Visitor::visit_ty(&mut visitor, ty); visit::Visitor::visit_ty(&mut visitor, ty);
@ -556,7 +566,7 @@ fn create_derived_impl(&self,
let mut processed_field_types = HashSet::new(); let mut processed_field_types = HashSet::new();
for field_ty in field_tys { for field_ty in field_tys {
let tys = find_type_parameters(&field_ty, &ty_param_names); let tys = find_type_parameters(&field_ty, &ty_param_names, self.span, cx);
for ty in tys { for ty in tys {
// if we have already handled this type, skip it // if we have already handled this type, skip it

View file

@ -0,0 +1,13 @@
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
pub mod foo {
pub use foo;
}

View file

@ -8,11 +8,11 @@
// 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.
#![feature(type_macros, concat_idents, rustc_attrs)] #![feature(type_macros, concat_idents)]
#![allow(unused)]
#[derive(Debug)] struct FooBar; #[derive(Debug)] //~ NOTE in this expansion
#[derive(Debug)] struct Baz<T>(T, concat_idents!(Foo, Bar)); struct Baz<T>(
concat_idents!(Foo, Bar) //~ ERROR `derive` cannot be used on items with type macros
);
#[rustc_error] fn main() {}
fn main() {} //~ ERROR compilation successful

View file

@ -15,6 +15,7 @@
#[allow(unused_variables)] #[allow(unused_variables)]
fn main() { fn main() {
let x2: i8 = --128; //~ error: literal out of range for i8 let x2: i8 = --128; //~ error: literal out of range for i8
//~^ error: attempted to negate with overflow
let x = -3.40282348e+38_f32; //~ error: literal out of range for f32 let x = -3.40282348e+38_f32; //~ error: literal out of range for f32
let x = 3.40282348e+38_f32; //~ error: literal out of range for f32 let x = 3.40282348e+38_f32; //~ error: literal out of range for f32

View file

@ -8,8 +8,8 @@
// 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.
// error-pattern:expected macro name without module separators
fn main() { fn main() {
globnar::brotz!(); globnar::brotz!(); //~ ERROR expected macro name without module separators
::foo!(); //~ ERROR expected macro name without module separators
foo::<T>!(); //~ ERROR expected macro name without module separators
} }

View file

@ -0,0 +1,15 @@
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// aux-build:recursive_reexports.rs
fn f() -> recursive_reexports::S {} //~ ERROR undeclared
fn main() {}

View file

@ -0,0 +1,11 @@
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use foo.bar; //~ ERROR expected one of `::`, `;`, or `as`, found `.`

View file

@ -0,0 +1,27 @@
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![crate_name = "foo"]
mod hidden {
#[derive(Clone)]
pub struct Foo;
}
#[doc(hidden)]
pub mod __hidden {
pub use hidden::Foo;
}
// @has foo/trait.Clone.html
// @!has - 'Foo'
// @has implementors/foo/trait.Clone.js
// @!has - 'Foo'
pub use std::clone::Clone;

View file

@ -0,0 +1,39 @@
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![crate_name = "foo"]
#[doc(hidden)]
pub mod hidden {
pub struct Foo;
impl Foo {
#[doc(hidden)]
pub fn this_should_be_hidden() {}
}
pub struct Bar;
impl Bar {
fn this_should_be_hidden() {}
}
}
// @has foo/struct.Foo.html
// @!has - 'Methods'
// @!has - 'impl Foo'
// @!has - 'this_should_be_hidden'
pub use hidden::Foo;
// @has foo/struct.Bar.html
// @!has - 'Methods'
// @!has - 'impl Bar'
// @!has - 'this_should_be_hidden'
pub use hidden::Bar;

View file

@ -0,0 +1,15 @@
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![crate_name = "foo"]
pub use std::marker::Send;
// @!has foo/index.html 'Implementations'

View file

@ -254,6 +254,17 @@ pub fn run_tests(config: &Config) {
match config.mode { match config.mode {
DebugInfoLldb => { DebugInfoLldb => {
if let Some(lldb_version) = config.lldb_version.as_ref() {
if is_blacklisted_lldb_version(&lldb_version[..]) {
println!("WARNING: The used version of LLDB ({}) has a \
known issue that breaks debuginfo tests. See \
issue #32520 for more information. Skipping all \
LLDB-based tests!",
lldb_version);
return
}
}
// Some older versions of LLDB seem to have problems with multiple // Some older versions of LLDB seem to have problems with multiple
// instances running in parallel, so only run one test thread at a // instances running in parallel, so only run one test thread at a
// time. // time.
@ -524,3 +535,7 @@ fn extract_lldb_version(full_version_line: Option<String>) -> Option<String> {
} }
None None
} }
fn is_blacklisted_lldb_version(version: &str) -> bool {
version == "350"
}