mirror of
https://github.com/rust-lang/rust
synced 2024-10-06 08:40:35 +00:00
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:
commit
c2b56fb7a0
|
@ -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")),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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") &&
|
||||||
|
|
|
@ -543,54 +543,47 @@ 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;
|
const I16_OVERFLOW: u64 = ::std::i16::MAX as u64 + 1;
|
||||||
const I16_OVERFLOW: u64 = ::std::i16::MAX as u64 + 1;
|
const I32_OVERFLOW: u64 = ::std::i32::MAX as u64 + 1;
|
||||||
const I32_OVERFLOW: u64 = ::std::i32::MAX as u64 + 1;
|
const I64_OVERFLOW: u64 = ::std::i64::MAX as u64 + 1;
|
||||||
const I64_OVERFLOW: u64 = ::std::i64::MAX as u64 + 1;
|
match (&lit.node, ety.map(|t| &t.sty)) {
|
||||||
match (&lit.node, ety.map(|t| &t.sty)) {
|
(&LitKind::Int(I8_OVERFLOW, Unsuffixed), Some(&ty::TyInt(IntTy::I8))) |
|
||||||
(&LitKind::Int(I8_OVERFLOW, Unsuffixed), Some(&ty::TyInt(IntTy::I8))) |
|
(&LitKind::Int(I8_OVERFLOW, Signed(IntTy::I8)), _) => {
|
||||||
(&LitKind::Int(I8_OVERFLOW, Signed(IntTy::I8)), _) => {
|
return Ok(Integral(I8(::std::i8::MIN)))
|
||||||
return Ok(Integral(I8(::std::i8::MIN)))
|
},
|
||||||
},
|
(&LitKind::Int(I16_OVERFLOW, Unsuffixed), Some(&ty::TyInt(IntTy::I16))) |
|
||||||
(&LitKind::Int(I16_OVERFLOW, Unsuffixed), Some(&ty::TyInt(IntTy::I16))) |
|
(&LitKind::Int(I16_OVERFLOW, Signed(IntTy::I16)), _) => {
|
||||||
(&LitKind::Int(I16_OVERFLOW, Signed(IntTy::I16)), _) => {
|
return Ok(Integral(I16(::std::i16::MIN)))
|
||||||
return Ok(Integral(I16(::std::i16::MIN)))
|
},
|
||||||
},
|
(&LitKind::Int(I32_OVERFLOW, Unsuffixed), Some(&ty::TyInt(IntTy::I32))) |
|
||||||
(&LitKind::Int(I32_OVERFLOW, Unsuffixed), Some(&ty::TyInt(IntTy::I32))) |
|
(&LitKind::Int(I32_OVERFLOW, Signed(IntTy::I32)), _) => {
|
||||||
(&LitKind::Int(I32_OVERFLOW, Signed(IntTy::I32)), _) => {
|
return Ok(Integral(I32(::std::i32::MIN)))
|
||||||
return Ok(Integral(I32(::std::i32::MIN)))
|
},
|
||||||
},
|
(&LitKind::Int(I64_OVERFLOW, Unsuffixed), Some(&ty::TyInt(IntTy::I64))) |
|
||||||
(&LitKind::Int(I64_OVERFLOW, Unsuffixed), Some(&ty::TyInt(IntTy::I64))) |
|
(&LitKind::Int(I64_OVERFLOW, Signed(IntTy::I64)), _) => {
|
||||||
(&LitKind::Int(I64_OVERFLOW, Signed(IntTy::I64)), _) => {
|
return Ok(Integral(I64(::std::i64::MIN)))
|
||||||
return Ok(Integral(I64(::std::i64::MIN)))
|
},
|
||||||
},
|
(&LitKind::Int(n, Unsuffixed), Some(&ty::TyInt(IntTy::Is))) |
|
||||||
(&LitKind::Int(n, Unsuffixed), Some(&ty::TyInt(IntTy::Is))) |
|
(&LitKind::Int(n, Signed(IntTy::Is)), _) => {
|
||||||
(&LitKind::Int(n, Signed(IntTy::Is)), _) => {
|
match tcx.sess.target.int_type {
|
||||||
match tcx.sess.target.int_type {
|
IntTy::I16 => if n == I16_OVERFLOW {
|
||||||
IntTy::I16 => if n == I16_OVERFLOW {
|
return Ok(Integral(Isize(Is16(::std::i16::MIN))));
|
||||||
return Ok(Integral(Isize(Is16(::std::i16::MIN))));
|
},
|
||||||
},
|
IntTy::I32 => if n == I32_OVERFLOW {
|
||||||
IntTy::I32 => if n == I32_OVERFLOW {
|
return Ok(Integral(Isize(Is32(::std::i32::MIN))));
|
||||||
return Ok(Integral(Isize(Is32(::std::i32::MIN))));
|
},
|
||||||
},
|
IntTy::I64 => if n == I64_OVERFLOW {
|
||||||
IntTy::I64 => if n == I64_OVERFLOW {
|
return Ok(Integral(Isize(Is64(::std::i64::MIN))));
|
||||||
return Ok(Integral(Isize(Is64(::std::i64::MIN))));
|
},
|
||||||
},
|
_ => bug!(),
|
||||||
_ => bug!(),
|
}
|
||||||
}
|
},
|
||||||
},
|
_ => {},
|
||||||
_ => {},
|
}
|
||||||
}
|
|
||||||
},
|
|
||||||
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),
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
@ -206,10 +281,10 @@ fn main() {}
|
||||||
"##,
|
"##,
|
||||||
|
|
||||||
E0364: r##"
|
E0364: r##"
|
||||||
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 {}
|
||||||
|
|
|
@ -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,
|
-> Resolver<'a> {
|
||||||
make_glob_map: MakeGlobMap,
|
let root_def_id = DefId::local(CRATE_DEF_INDEX);
|
||||||
arenas: &'a ResolverArenas<'a>)
|
|
||||||
-> Resolver<'a> {
|
|
||||||
let root_def_id = definitions.local_def_id(CRATE_NODE_ID);
|
|
||||||
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,7 +3207,9 @@ 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();
|
||||||
worklist.push((module, path_segments, is_extern));
|
if !worklist.iter().any(|&(m, _, _)| m.def == module.def) {
|
||||||
|
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 }
|
||||||
|
|
|
@ -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>>();
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
||||||
self.retained.insert(i.def_id);
|
if self.update_retained {
|
||||||
|
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 {
|
||||||
self.retained.insert(i.def_id);
|
if self.update_retained {
|
||||||
|
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,
|
|
||||||
_ => {
|
_ => {
|
||||||
self.retained.insert(i.def_id);
|
if self.update_retained {
|
||||||
|
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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)| {
|
||||||
|
|
|
@ -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())
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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,9 +730,12 @@ 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 {
|
||||||
multi_modifier = Some((attrs.remove(i), extension));
|
MultiModifier(..) | MultiDecorator(..) => {
|
||||||
break;
|
multi_modifier = Some((attrs.remove(i), extension));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -804,23 +744,32 @@ 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,
|
callee: NameAndSpan {
|
||||||
callee: NameAndSpan {
|
format: MacroAttribute(intern(&attr.name())),
|
||||||
format: MacroAttribute(intern(&attr.name())),
|
span: Some(attr.span),
|
||||||
span: Some(attr.span),
|
// attributes can do whatever they like, for now
|
||||||
// attributes can do whatever they like, for now
|
allow_internal_unstable: true,
|
||||||
allow_internal_unstable: true,
|
}
|
||||||
}
|
});
|
||||||
});
|
|
||||||
let modified = mac.expand(fld.cx, attr.span, &attr.node.value, item);
|
let modified = match *extension {
|
||||||
fld.cx.bt_pop();
|
MultiModifier(ref mac) => mac.expand(fld.cx, attr.span, &attr.node.value, item),
|
||||||
modified.into_iter().flat_map(|it| expand_annotatable(it, fld)).collect()
|
MultiDecorator(ref mac) => {
|
||||||
}
|
let mut items = Vec::new();
|
||||||
_ => unreachable!(),
|
mac.expand(fld.cx, attr.span, &attr.node.value, &item,
|
||||||
|
&mut |item| items.push(item));
|
||||||
|
items.push(item);
|
||||||
|
items
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
|
||||||
|
fld.cx.bt_pop();
|
||||||
|
modified.into_iter().flat_map(|it| expand_annotatable(it, fld)).collect()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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(),
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
13
src/test/compile-fail/auxiliary/recursive_reexports.rs
Normal file
13
src/test/compile-fail/auxiliary/recursive_reexports.rs
Normal 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;
|
||||||
|
}
|
|
@ -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
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
15
src/test/compile-fail/recursive-reexports.rs
Normal file
15
src/test/compile-fail/recursive-reexports.rs
Normal 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() {}
|
11
src/test/parse-fail/issue-33455.rs
Normal file
11
src/test/parse-fail/issue-33455.rs
Normal 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 `.`
|
27
src/test/rustdoc/hidden-impls.rs
Normal file
27
src/test/rustdoc/hidden-impls.rs
Normal 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;
|
39
src/test/rustdoc/hidden-methods.rs
Normal file
39
src/test/rustdoc/hidden-methods.rs
Normal 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;
|
15
src/test/rustdoc/module-impls.rs
Normal file
15
src/test/rustdoc/module-impls.rs
Normal 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'
|
|
@ -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"
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue