]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #34541 - jseyfried:rollup, r=jseyfried
authorbors <bors@rust-lang.org>
Thu, 30 Jun 2016 08:49:45 +0000 (01:49 -0700)
committerGitHub <noreply@github.com>
Thu, 30 Jun 2016 08:49:45 +0000 (01:49 -0700)
Rollup of 5 pull requests

 - Successful merges: #34105, #34305, #34512, ~~#34531,~~ #34547

31 files changed:
configure
src/librustc/hir/lowering.rs
src/librustc/hir/map/def_collector.rs
src/librustc/hir/map/definitions.rs
src/librustc/hir/map/mod.rs
src/librustc/session/mod.rs
src/librustc_const_eval/eval.rs
src/librustc_driver/driver.rs
src/librustc_metadata/astencode.rs
src/librustc_resolve/diagnostics.rs
src/librustc_resolve/lib.rs
src/librustdoc/html/render.rs
src/librustdoc/passes.rs
src/libsyntax/ast.rs
src/libsyntax/attr.rs
src/libsyntax/config.rs
src/libsyntax/ext/base.rs
src/libsyntax/ext/expand.rs
src/libsyntax/fold.rs
src/libsyntax/parse/parser.rs
src/libsyntax_ext/deriving/generic/mod.rs
src/test/compile-fail/auxiliary/recursive_reexports.rs [new file with mode: 0644]
src/test/compile-fail/issue-32950.rs
src/test/compile-fail/lint-type-overflow2.rs
src/test/compile-fail/macro-with-seps-err-msg.rs
src/test/compile-fail/recursive-reexports.rs [new file with mode: 0644]
src/test/parse-fail/issue-33455.rs [new file with mode: 0644]
src/test/rustdoc/hidden-impls.rs [new file with mode: 0644]
src/test/rustdoc/hidden-methods.rs [new file with mode: 0644]
src/test/rustdoc/module-impls.rs [new file with mode: 0644]
src/tools/compiletest/src/main.rs

index e1319828e3f191b2e9492cc560f058a59f14c7fb..7389b073da13b219bd0367c45e513cce363fd04e 100755 (executable)
--- a/configure
+++ b/configure
@@ -1681,9 +1681,10 @@ do
     fi
 
     if [ "$t" != "$CFG_BUILD" ]; then
+        # see http://llvm.org/docs/HowToCrossCompileLLVM.html
         CMAKE_ARGS="$CMAKE_ARGS -DCMAKE_CROSSCOMPILING=True"
         CMAKE_ARGS="$CMAKE_ARGS -DLLVM_TARGET_ARCH=$arch"
-        CMAKE_ARGS="$CMAKE_ARGS -DLLVM_TABLEGEN=$LLVM_INST_DIR/bin/llvm-tablegen"
+        CMAKE_ARGS="$CMAKE_ARGS -DLLVM_TABLEGEN=$CFG_BUILD_DIR/$CFG_BUILD/llvm/bin/llvm-tblgen"
         CMAKE_ARGS="$CMAKE_ARGS -DLLVM_DEFAULT_TARGET_TRIPLE=$t"
     fi
 
index 5b655522f342f6ef82149b52f6009924e2093af3..2cc39412182dc5a771417a8f7e714cdf6cad4a3d 100644 (file)
@@ -50,6 +50,7 @@
 use std::collections::BTreeMap;
 use std::iter;
 use syntax::ast::*;
+use syntax::errors;
 use syntax::ptr::P;
 use syntax::codemap::{respan, Spanned};
 use syntax::parse::token;
@@ -60,7 +61,7 @@
 pub struct LoweringContext<'a> {
     crate_root: Option<&'static str>,
     // 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
     // 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.
@@ -99,7 +100,6 @@ fn definitions(&mut self) -> Option<&mut Definitions> {
 
 pub fn lower_crate(sess: &Session,
                    krate: &Crate,
-                   id_assigner: &NodeIdAssigner,
                    resolver: &mut Resolver)
                    -> hir::Crate {
     // We're constructing the HIR here; we don't care what we will
@@ -115,17 +115,17 @@ pub fn lower_crate(sess: &Session,
         } else {
             Some("std")
         },
-        id_assigner: id_assigner,
+        sess: Some(sess),
         parent_def: None,
         resolver: resolver,
     }.lower_crate(krate)
 }
 
 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 {
             crate_root: None,
-            id_assigner: id_assigner,
+            sess: None,
             parent_def: None,
             resolver: resolver,
         }
@@ -161,7 +161,12 @@ fn visit_item(&mut self, item: &Item) {
     }
 
     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 {
@@ -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) {
             match hir_sig.decl.get_self().map(|eself| eself.node) {
                 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");
                 }
                 _ => {}
@@ -1212,7 +1217,7 @@ fn make_struct(this: &mut LoweringContext,
                             make_struct(self, e, &["RangeInclusive", "NonEmpty"],
                                                  &[("start", e1), ("end", e2)]),
 
-                        _ => panic!(self.id_assigner.diagnostic()
+                        _ => panic!(self.diagnostic()
                                         .span_fatal(e.span, "inclusive range with no end")),
                     };
                 }
index ccb3e154d9204906146d775d032b8a088cb45896..2b89695ab41cad2fdbb39f846547a314f1ece101 100644 (file)
@@ -25,15 +25,15 @@ pub struct DefCollector<'ast> {
     // If we are walking HIR (c.f., AST), we need to keep a reference to the
     // crate.
     hir_crate: Option<&'ast hir::Crate>,
-    pub definitions: Definitions,
+    definitions: &'ast mut Definitions,
     parent_def: Option<DefIndex>,
 }
 
 impl<'ast> DefCollector<'ast> {
-    pub fn root() -> DefCollector<'ast> {
+    pub fn root(definitions: &'ast mut Definitions) -> DefCollector<'ast> {
         let mut collector = DefCollector {
             hir_crate: None,
-            definitions: Definitions::new(),
+            definitions: definitions,
             parent_def: None,
         };
         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,
                   parent_def_path: DefPath,
                   parent_def_id: DefId,
-                  definitions: Definitions)
+                  definitions: &'ast mut Definitions)
                   -> DefCollector<'ast> {
         let mut collector = DefCollector {
             hir_crate: None,
index d66df3e4e8fd274a70a11c0ad65d5e242e493509..3317585f820aa60b30647c97d7b33c1561a7b784 100644 (file)
@@ -10,8 +10,9 @@
 
 use middle::cstore::LOCAL_CRATE;
 use hir::def_id::{DefId, DefIndex};
+use hir::map::def_collector::DefCollector;
 use rustc_data_structures::fnv::FnvHashMap;
-use syntax::ast;
+use syntax::{ast, visit};
 use syntax::parse::token::InternedString;
 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.
     pub fn len(&self) -> usize {
         self.data.len()
index f9fb8ac66b7ef01292e3744ca870a9e58e375f7a..960e32ae99faf0810cdde1ff5fe9adf479c7f7dc 100644 (file)
@@ -24,7 +24,6 @@
 use syntax::abi::Abi;
 use syntax::ast::{self, Name, NodeId, DUMMY_NODE_ID, };
 use syntax::codemap::Spanned;
-use syntax::visit;
 use syntax_pos::Span;
 
 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,
                        definitions: Definitions)
                        -> 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_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,
                                                  parent_def_path.clone(),
                                                  parent_def_id,
                                                  defs);
     def_collector.walk_item(ii, map.krate());
-    *map.definitions.borrow_mut() = def_collector.definitions;
 
     let mut collector = NodeCollector::extend(map.krate(),
                                               ii,
index 77259cea24d28265ddac5472e72fb52bb35afe33..fdaf182c6054246e0ed2d62b6958f8dc38c1c5f1 100644 (file)
@@ -20,7 +20,7 @@
 use util::nodemap::{NodeMap, FnvHashMap};
 use mir::transform as mir_pass;
 
-use syntax::ast::{NodeId, NodeIdAssigner, Name};
+use syntax::ast::{NodeId, Name};
 use errors::{self, DiagnosticBuilder};
 use errors::emitter::{Emitter, BasicEmitter, EmitterWriter};
 use syntax::json::JsonEmitter;
@@ -272,6 +272,9 @@ pub fn reserve_node_ids(&self, count: ast::NodeId) -> ast::NodeId {
 
         id
     }
+    pub fn next_node_id(&self) -> NodeId {
+        self.reserve_node_ids(1)
+    }
     pub fn diagnostic<'a>(&'a self) -> &'a errors::Handler {
         &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> {
     // Conditions for enabling multi-line errors:
     if !msg.contains("mismatched types") &&
index c03903515abe6885c084d915172c1656263d7f1f..6c37662206ce252f5592eeeee86853fe43c4b1e6 100644 (file)
@@ -543,54 +543,47 @@ pub fn eval_const_expr_partial<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     let result = match e.node {
       hir::ExprUnary(hir::UnNeg, ref inner) => {
         // unary neg literals already got their sign during creation
-        match inner.node {
-            hir::ExprLit(ref lit) => {
-                use syntax::ast::*;
-                use syntax::ast::LitIntType::*;
-                const I8_OVERFLOW: u64 = ::std::i8::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 I64_OVERFLOW: u64 = ::std::i64::MAX as u64 + 1;
-                match (&lit.node, ety.map(|t| &t.sty)) {
-                    (&LitKind::Int(I8_OVERFLOW, Unsuffixed), Some(&ty::TyInt(IntTy::I8))) |
-                    (&LitKind::Int(I8_OVERFLOW, Signed(IntTy::I8)), _) => {
-                        return Ok(Integral(I8(::std::i8::MIN)))
-                    },
-                    (&LitKind::Int(I16_OVERFLOW, Unsuffixed), Some(&ty::TyInt(IntTy::I16))) |
-                    (&LitKind::Int(I16_OVERFLOW, Signed(IntTy::I16)), _) => {
-                        return Ok(Integral(I16(::std::i16::MIN)))
-                    },
-                    (&LitKind::Int(I32_OVERFLOW, Unsuffixed), Some(&ty::TyInt(IntTy::I32))) |
-                    (&LitKind::Int(I32_OVERFLOW, Signed(IntTy::I32)), _) => {
-                        return Ok(Integral(I32(::std::i32::MIN)))
-                    },
-                    (&LitKind::Int(I64_OVERFLOW, Unsuffixed), Some(&ty::TyInt(IntTy::I64))) |
-                    (&LitKind::Int(I64_OVERFLOW, Signed(IntTy::I64)), _) => {
-                        return Ok(Integral(I64(::std::i64::MIN)))
-                    },
-                    (&LitKind::Int(n, Unsuffixed), Some(&ty::TyInt(IntTy::Is))) |
-                    (&LitKind::Int(n, Signed(IntTy::Is)), _) => {
-                        match tcx.sess.target.int_type {
-                            IntTy::I16 => if n == I16_OVERFLOW {
-                                return Ok(Integral(Isize(Is16(::std::i16::MIN))));
-                            },
-                            IntTy::I32 => if n == I32_OVERFLOW {
-                                return Ok(Integral(Isize(Is32(::std::i32::MIN))));
-                            },
-                            IntTy::I64 => if n == I64_OVERFLOW {
-                                return Ok(Integral(Isize(Is64(::std::i64::MIN))));
-                            },
-                            _ => bug!(),
-                        }
-                    },
-                    _ => {},
-                }
-            },
-            hir::ExprUnary(hir::UnNeg, ref inner) => {
-                // skip `--$expr`
-                return eval_const_expr_partial(tcx, inner, ty_hint, fn_args);
-            },
-            _ => {},
+        if let hir::ExprLit(ref lit) = inner.node {
+            use syntax::ast::*;
+            use syntax::ast::LitIntType::*;
+            const I8_OVERFLOW: u64 = ::std::i8::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 I64_OVERFLOW: u64 = ::std::i64::MAX as u64 + 1;
+            match (&lit.node, ety.map(|t| &t.sty)) {
+                (&LitKind::Int(I8_OVERFLOW, Unsuffixed), Some(&ty::TyInt(IntTy::I8))) |
+                (&LitKind::Int(I8_OVERFLOW, Signed(IntTy::I8)), _) => {
+                    return Ok(Integral(I8(::std::i8::MIN)))
+                },
+                (&LitKind::Int(I16_OVERFLOW, Unsuffixed), Some(&ty::TyInt(IntTy::I16))) |
+                (&LitKind::Int(I16_OVERFLOW, Signed(IntTy::I16)), _) => {
+                    return Ok(Integral(I16(::std::i16::MIN)))
+                },
+                (&LitKind::Int(I32_OVERFLOW, Unsuffixed), Some(&ty::TyInt(IntTy::I32))) |
+                (&LitKind::Int(I32_OVERFLOW, Signed(IntTy::I32)), _) => {
+                    return Ok(Integral(I32(::std::i32::MIN)))
+                },
+                (&LitKind::Int(I64_OVERFLOW, Unsuffixed), Some(&ty::TyInt(IntTy::I64))) |
+                (&LitKind::Int(I64_OVERFLOW, Signed(IntTy::I64)), _) => {
+                    return Ok(Integral(I64(::std::i64::MIN)))
+                },
+                (&LitKind::Int(n, Unsuffixed), Some(&ty::TyInt(IntTy::Is))) |
+                (&LitKind::Int(n, Signed(IntTy::Is)), _) => {
+                    match tcx.sess.target.int_type {
+                        IntTy::I16 => if n == I16_OVERFLOW {
+                            return Ok(Integral(Isize(Is16(::std::i16::MIN))));
+                        },
+                        IntTy::I32 => if n == I32_OVERFLOW {
+                            return Ok(Integral(Isize(Is32(::std::i32::MIN))));
+                        },
+                        IntTy::I64 => if n == I64_OVERFLOW {
+                            return Ok(Integral(Isize(Is64(::std::i64::MIN))));
+                        },
+                        _ => bug!(),
+                    }
+                },
+                _ => {},
+            }
         }
         match eval_const_expr_partial(tcx, &inner, ty_hint, fn_args)? {
           Float(f) => Float(-f),
index eb442c0a34e74cb68ba015fb765b3f2e61e262c3..46009e581309444f7496ba886aff3f180899840f 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use rustc::dep_graph::DepGraph;
 use rustc::hir;
 use rustc::hir::{map as hir_map, FreevarMap, TraitMap};
 use rustc::hir::def::DefMap;
@@ -27,7 +26,7 @@
 use rustc_back::sha2::{Sha256, Digest};
 use rustc_borrowck as borrowck;
 use rustc_incremental;
-use rustc_resolve as resolve;
+use rustc_resolve::{MakeGlobMap, Resolver};
 use rustc_metadata::macro_import;
 use rustc_metadata::creader::read_local_crates;
 use rustc_metadata::cstore::CStore;
 use std::fs;
 use std::io::{self, Write};
 use std::path::{Path, PathBuf};
-use syntax::ast::{self, NodeIdAssigner};
+use syntax::{ast, diagnostics, visit};
 use syntax::attr::{self, AttrMetaMethods};
-use syntax::diagnostics;
 use syntax::fold::Folder;
 use syntax::parse::{self, PResult, token};
 use syntax::util::node_count::NodeCounter;
-use syntax::visit;
 use syntax;
 use syntax_ext;
 
@@ -293,7 +290,7 @@ pub struct CompileController<'a> {
     pub after_analysis: PhaseController<'a>,
     pub after_llvm: PhaseController<'a>,
 
-    pub make_glob_map: resolve::MakeGlobMap,
+    pub make_glob_map: MakeGlobMap,
 }
 
 impl<'a> CompileController<'a> {
@@ -305,7 +302,7 @@ pub fn basic() -> CompileController<'a> {
             after_hir_lowering: PhaseController::basic(),
             after_analysis: 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,
                                         crate_name: &'a str,
                                         addl_plugins: Option<Vec<String>>,
-                                        make_glob_map: resolve::MakeGlobMap)
+                                        make_glob_map: MakeGlobMap)
                                         -> Result<ExpansionResult<'a>, usize> {
     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);
 
+    let resolver_arenas = Resolver::arenas();
+    let mut resolver = Resolver::new(sess, make_glob_map, &resolver_arenas);
+
     // Collect defintions for def ids.
-    let mut defs =
-        time(sess.time_passes(), "collecting defs", || hir_map::collect_definitions(&krate));
+    time(sess.time_passes(), "collecting defs", || resolver.definitions.collect(&krate));
 
-    time(sess.time_passes(),
-         "external crate/lib resolution",
-         || 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(),
          "early lint checks",
@@ -745,8 +745,14 @@ pub fn phase_2_configure_and_expand<'a>(sess: &Session,
          "AST validation",
          || ast_validation::check_crate(sess, &krate));
 
-    let (analysis, resolutions, hir_forest) =
-        lower_and_resolve(sess, crate_name, &mut defs, &krate, &sess.dep_graph, make_glob_map);
+    time(sess.time_passes(), "name resolution", || {
+        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.
     if !keep_mtwt_tables(sess) {
@@ -755,9 +761,20 @@ pub fn phase_2_configure_and_expand<'a>(sess: &Session,
 
     Ok(ExpansionResult {
         expanded_crate: krate,
-        defs: defs,
-        analysis: analysis,
-        resolutions: resolutions,
+        defs: resolver.definitions,
+        analysis: ty::CrateAnalysis {
+            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
     })
 }
@@ -809,38 +826,6 @@ fn fold_block(&mut self, block: P<ast::Block>) -> P<ast::Block> {
     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
 /// miscellaneous analysis passes on the crate. Return various
 /// structures carrying the results of the analysis.
index dc37bdf6322af1b4f6a65c523e10b74aeceea4d5..7ef00b971c57ba6262f24be7b313c4798c9621ee 100644 (file)
@@ -38,7 +38,6 @@
 use rustc::ty::{self, Ty, TyCtxt};
 
 use syntax::ast;
-use syntax::ast::NodeIdAssigner;
 use syntax::ptr::P;
 use syntax_pos;
 
@@ -56,7 +55,6 @@
 
 #[cfg(test)] use std::io::Cursor;
 #[cfg(test)] use syntax::parse;
-#[cfg(test)] use syntax::ast::NodeId;
 #[cfg(test)] use rustc::hir::print as pprust;
 #[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 }
 }
 
-#[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)]
 fn mk_ctxt() -> parse::ParseSess {
     parse::ParseSess::new()
@@ -1318,9 +1300,8 @@ fn mk_ctxt() -> parse::ParseSess {
 
 #[cfg(test)]
 fn with_testing_context<T, F: FnOnce(&mut LoweringContext) -> T>(f: F) -> T {
-    let assigner = FakeNodeIdAssigner;
     let mut resolver = DummyResolver;
-    let mut lcx = LoweringContext::testing_context(&assigner, &mut resolver);
+    let mut lcx = LoweringContext::testing_context(&mut resolver);
     f(&mut lcx)
 }
 
index 4e4f6e276d1ddfaac9e7f80e39fb4af483c7989d..3e860150a35fdfbe3f2379e81cc727f3783f4778 100644 (file)
@@ -16,6 +16,8 @@
 register_long_diagnostics! {
 
 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
 variable declarations and expression statements.
 
@@ -50,6 +52,8 @@ fn f() {
 "##,
 
 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
 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
 items under a new local name.
 
-An example of this error:
+Erroneous code example:
 
-```compile_fail
+```compile_fail,E0252
 use foo::baz;
 use bar::baz; // error, do `use bar::baz as quux` instead
 
@@ -87,6 +91,41 @@ mod foo {
     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 {
     pub mod baz {}
 }
@@ -95,9 +134,11 @@ pub mod baz {}
 
 E0253: r##"
 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 {
     pub trait MyTrait {
         fn do_something();
@@ -105,6 +146,8 @@ pub trait MyTrait {
 }
 
 use foo::MyTrait::do_something;
+
+fn main() {}
 ```
 
 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
 module.
 
-An example of this error:
+Erroneous code example:
 
-```compile_fail
-use bar::foo; // error, do `use bar::foo as baz` instead
+```compile_fail,E0255
+use bar::foo; // error: an item named `foo` is already in scope
 
 fn foo() {}
 
@@ -127,9 +170,39 @@ pub fn foo() {}
 
 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##"
+## 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
 the same as another type or submodule defined in the module.
 
@@ -154,9 +227,11 @@ fn main() {}
 
 Erroneous code example:
 
-```compile_fail
-extern crate a;
-extern crate crate_a as a;
+```compile_fail,E0259
+extern crate std;
+extern crate libc as std;
+
+fn main() {}
 ```
 
 The solution is to choose a different name that doesn't conflict with any
@@ -165,17 +240,17 @@ fn main() {}
 Correct example:
 
 ```ignore
-extern crate a;
-extern crate crate_a as other_name;
+extern crate std;
+extern crate libc as other_name;
 ```
 "##,
 
 E0260: r##"
 The name for an item declaration conflicts with an external crate's name.
 
-For instance:
+Erroneous code example:
 
-```ignore
+```ignore,E0260
 extern crate abc;
 
 struct abc;
@@ -206,10 +281,10 @@ fn main() {}
 "##,
 
 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.
 
-Here is an example that demonstrates the error:
+Erroneous code example:
 
 ```compile_fail
 mod foo {
@@ -217,17 +292,21 @@ mod foo {
 }
 
 pub use foo::X;
+
+fn main() {}
 ```
 
 The solution to this problem is to ensure that the items that you are
 re-exporting are themselves marked with `pub`:
 
-```ignore
+```
 mod foo {
     pub const X: u32 = 1;
 }
 
 pub use foo::X;
+
+fn main() {}
 ```
 
 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
 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 {
     pub const X: u32 = 1;
 }
 
 pub use foo as foo2;
+
+fn main() {}
 ```
 
 The solution to this problem is to ensure that the module that you are
 re-exporting is itself marked with `pub`:
 
-```ignore
+```
 pub mod foo {
     pub const X: u32 = 1;
 }
 
 pub use foo as foo2;
+
+fn main() {}
 ```
 
 See the 'Use Declarations' section of the reference for more information
@@ -269,9 +352,11 @@ pub mod foo {
 
 E0401: r##"
 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 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:
 
-```compile_fail
+```compile_fail,E0401
 fn foo<T>(x: T) {
     type MaybeT = Option<T>;
     // ...
@@ -291,7 +376,7 @@ fn foo<T>(x: T) {
 
 Or this:
 
-```compile_fail
+```compile_fail,E0401
 fn foo<T>(x: T) {
     struct Foo {
         x: T,
@@ -374,9 +459,11 @@ fn bar(&self, y: T) {
 "##,
 
 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
                             //        parameter in this type parameter list
 ```
@@ -390,10 +477,11 @@ fn foo<T, Y>(s: T, u: Y) {} // ok!
 "##,
 
 E0404: r##"
-You tried to implement something which was not a trait on an object. Example of
-erroneous code:
+You tried to implement something which was not a trait on an object.
 
-```compile_fail
+Erroneous code example:
+
+```compile_fail,E0404
 struct Foo;
 struct Bar;
 
@@ -416,9 +504,11 @@ impl Foo for Bar { // ok!
 "##,
 
 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;
 
 impl SomeTrait for Foo {} // error: trait `SomeTrait` is not in scope
@@ -446,9 +536,11 @@ impl SomeTrait for Foo { // ok!
 
 E0407: r##"
 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 {
     fn a();
 }
@@ -501,9 +593,9 @@ fn b() {}
 An "or" pattern was used where the variable bindings are not consistently bound
 across patterns.
 
-Example of erroneous code:
+Erroneous code example:
 
-```compile_fail
+```compile_fail,E0408
 match x {
     Some(y) | None => { /* use y */ } // error: variable `y` from pattern #1 is
                                       //        not bound in pattern #2
@@ -545,9 +637,9 @@ fn b() {}
 An "or" pattern was used where the variable bindings are not consistently bound
 across patterns.
 
-Example of erroneous code:
+Erroneous code example:
 
-```compile_fail
+```compile_fail,E0409
 let x = (0, 2);
 match x {
     (0, ref y) | (y, 0) => { /* use y */} // error: variable `y` is bound with
@@ -583,9 +675,11 @@ fn b() {}
 "##,
 
 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
 ```
 
@@ -639,9 +733,11 @@ trait Baz : Foo + Foo2 {
 "##,
 
 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
 
 // or:
@@ -678,9 +774,11 @@ fn foo<T>(x: T) {} // ok!
 "##,
 
 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
                           //        once in this parameter list
 ```
@@ -693,9 +791,11 @@ fn foo(f: i32, g: i32) {} // ok!
 "##,
 
 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) {
     (x, x) => {} // error: identifier `x` is bound more than once in the
                  //        same pattern
@@ -722,9 +822,10 @@ fn foo(f: i32, g: i32) {} // ok!
 
 E0422: r##"
 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 () {
     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
 definitely not a struct.
 
-```compile_fail
+```compile_fail,E0422
 fn main () {
     let foo = 1;
     let x = foo { x: 1, y: 2 };
@@ -745,10 +846,11 @@ fn main () {
 "##,
 
 E0423: r##"
-A `struct` variant name was used like a function name. Example of erroneous
-code:
+A `struct` variant name was used like a function name.
 
-```compile_fail
+Erroneous code example:
+
+```compile_fail,E0423
 struct Foo { a: bool};
 
 let f = Foo();
@@ -767,9 +869,11 @@ fn Foo() -> u32 { 0 }
 "##,
 
 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;
 
 impl Foo {
@@ -799,9 +903,11 @@ fn foo(self) {
 "##,
 
 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;
 // error: unresolved name `something_that_doesnt_exist::foo`
 
@@ -857,9 +963,11 @@ mod something_that_does_exist {
 "##,
 
 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 {
     break 'a; // error: use of undeclared label `'a`
 }
@@ -875,10 +983,11 @@ mod something_that_does_exist {
 "##,
 
 E0428: r##"
-A type or module has been defined more than once. Example of erroneous
-code:
+A type or module has been defined more than once.
 
-```compile_fail
+Erroneous code example:
+
+```compile_fail,E0428
 struct 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`
 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
 ```
 
@@ -917,9 +1026,11 @@ mod something_that_does_exist {
 "##,
 
 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
                              //        the list
 ```
@@ -933,9 +1044,11 @@ mod something_that_does_exist {
 "##,
 
 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
             //        non-empty prefix
 ```
@@ -945,9 +1058,11 @@ mod something_that_does_exist {
 "##,
 
 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`.
 ```
 
@@ -976,14 +1091,23 @@ mod something {
 "##,
 
 E0433: r##"
-Invalid import. Example of erroneous code:
+An undeclared type or module was used.
 
-```compile_fail
-use something_which_doesnt_exist;
-// error: unresolved import `something_which_doesnt_exist`
+Erroneous code example:
+
+```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##"
@@ -991,9 +1115,9 @@ mod something {
 because the variable comes from a dynamic environment. Inner functions do not
 have access to their containing environment.
 
-Example of erroneous code:
+Erroneous code example:
 
-```compile_fail
+```compile_fail,E0434
 fn foo() {
     let y = 5;
     fn bar() -> u32 {
@@ -1032,10 +1156,11 @@ fn bar() -> u32 {
 "##,
 
 E0435: r##"
-A non-constant value was used to initialise a constant. Example of erroneous
-code:
+A non-constant value was used to initialise a constant.
 
-```compile_fail
+Erroneous code example:
+
+```compile_fail,E0435
 let foo = 42u32;
 const FOO : u32 = foo; // error: attempt to use a non-constant value in a
                        //        constant
@@ -1061,9 +1186,9 @@ fn bar() -> u32 {
 an associated type whose name does not match the name of any associated type
 in the trait.
 
-Here is an example that demonstrates the error:
+Erroneous code example:
 
-```compile_fail
+```compile_fail,E0437
 trait Foo {}
 
 impl Foo for i32 {
@@ -1086,9 +1211,9 @@ impl Foo for i32 {}
 attempted to implement an associated constant whose name does not
 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)]
 
 trait Foo {}
index 8ffa95ec7e96f2c860aa98833c7c9811b01bc8cc..ed400af66855a66145924a9cf66ac240e542e37b 100644 (file)
@@ -47,7 +47,7 @@
 use rustc::session::Session;
 use rustc::lint;
 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::subst::{ParamSpace, FnSpace, TypeSpace};
 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> {
     session: &'a Session,
 
-    definitions: &'a mut Definitions,
+    pub definitions: Definitions,
 
     graph_root: Module<'a>,
 
@@ -1001,7 +1001,7 @@ pub struct Resolver<'a> {
     arenas: &'a ResolverArenas<'a>,
 }
 
-struct ResolverArenas<'a> {
+pub struct ResolverArenas<'a> {
     modules: arena::TypedArena<ModuleS<'a>>,
     local_modules: RefCell<Vec<Module<'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> {
-        Some(self.definitions)
+        Some(&mut self.definitions)
     }
 }
 
@@ -1100,12 +1100,9 @@ fn name(&self) -> Name {
 }
 
 impl<'a> Resolver<'a> {
-    fn new(session: &'a Session,
-           definitions: &'a mut Definitions,
-           make_glob_map: MakeGlobMap,
-           arenas: &'a ResolverArenas<'a>)
-           -> Resolver<'a> {
-        let root_def_id = definitions.local_def_id(CRATE_NODE_ID);
+    pub fn new(session: &'a Session, make_glob_map: MakeGlobMap, arenas: &'a ResolverArenas<'a>)
+               -> Resolver<'a> {
+        let root_def_id = DefId::local(CRATE_DEF_INDEX);
         let graph_root =
             ModuleS::new(NoParentLink, Some(Def::Mod(root_def_id)), false, arenas);
         let graph_root = arenas.alloc_module(graph_root);
@@ -1115,7 +1112,7 @@ fn new(session: &'a Session,
         Resolver {
             session: session,
 
-            definitions: definitions,
+            definitions: Definitions::new(),
 
             // The outermost module has def ID 0; this is not reflected in the
             // AST.
@@ -1158,7 +1155,7 @@ fn new(session: &'a Session,
         }
     }
 
-    fn arenas() -> ResolverArenas<'a> {
+    pub fn arenas() -> ResolverArenas<'a> {
         ResolverArenas {
             modules: arena::TypedArena::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)
                   -> Module<'a> {
         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
     }
 
-    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) {
         let name = item.ident.name;
 
@@ -2287,24 +2299,25 @@ fn resolve_pattern(&mut self,
                 PatKind::Ident(bmode, ref ident, ref opt_pat) => {
                     // First try to resolve the identifier as some existing
                     // entity, then fall back to a fresh binding.
-                    let resolution = if let Ok(resolution) = self.resolve_path(pat.id,
-                                &Path::from_ident(ident.span, ident.node), 0, ValueNS) {
+                    let local_def = self.resolve_identifier(ident.node, ValueNS, true);
+                    let resolution = if let Some(LocalDef { def, .. }) = local_def {
                         let always_binding = !pat_src.is_refutable() || opt_pat.is_some() ||
                                              bmode != BindingMode::ByValue(Mutability::Immutable);
-                        match resolution.base_def {
+                        match def {
                             Def::Struct(..) | Def::Variant(..) |
                             Def::Const(..) | Def::AssociatedConst(..) if !always_binding => {
                                 // A constant, unit variant, etc pattern.
-                                resolution
+                                PathResolution::new(def)
                             }
                             Def::Struct(..) | Def::Variant(..) |
                             Def::Const(..) | Def::AssociatedConst(..) | Def::Static(..) => {
                                 // A fresh binding that shadows something unacceptable.
+                                let kind_name = PathResolution::new(def).kind_name();
                                 resolve_error(
                                     self,
                                     ident.span,
                                     ResolutionError::BindingShadowsSomethingUnacceptable(
-                                        pat_src.descr(), resolution.kind_name(), ident.node.name)
+                                        pat_src.descr(), kind_name, ident.node.name)
                                 );
                                 err_path_resolution()
                             }
@@ -3194,7 +3207,9 @@ fn lookup_candidates<FilterFn>(&mut self,
                     if !in_module_is_extern || name_binding.vis == ty::Visibility::Public {
                         // add the module to the lookup
                         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,
 }
 
-/// 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 }
index 21463527ab9ecdf96ea1d8259068679a7f03a9a4..9f2b33c0282ed71ec69ed9ff28e57ca3e50f4422 100644 (file)
@@ -1695,6 +1695,9 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
     document(w, cx, item)?;
 
     let mut indices = (0..items.len()).filter(|i| {
+        if let clean::DefaultImplItem(..) = items[*i].inner {
+            return false;
+        }
         !cx.maybe_ignore_item(&items[*i])
     }).collect::<Vec<usize>>();
 
index 1980d1f9cc45fc54ab9ccffde89ed3938a580e7f..b8e40790646a7eab87cdf78d558404baf8628823 100644 (file)
@@ -12,6 +12,7 @@
 use rustc::middle::privacy::AccessLevels;
 use rustc::util::nodemap::DefIdSet;
 use std::cmp;
+use std::mem;
 use std::string::String;
 use std::usize;
 
@@ -29,7 +30,8 @@ pub fn strip_hidden(krate: clean::Crate) -> plugins::PluginResult {
     // strip all #[doc(hidden)] items
     let krate = {
         struct Stripper<'a> {
-            retained: &'a mut DefIdSet
+            retained: &'a mut DefIdSet,
+            update_retained: bool,
         }
         impl<'a> fold::DocFolder for Stripper<'a> {
             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
                     match i.inner {
                         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,
                     }
                 } else {
-                    self.retained.insert(i.def_id);
+                    if self.update_retained {
+                        self.retained.insert(i.def_id);
+                    }
                 }
                 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)
     };
 
@@ -69,6 +79,7 @@ pub fn strip_private(mut krate: clean::Crate) -> plugins::PluginResult {
         let mut stripper = Stripper {
             retained: &mut retained,
             access_levels: &access_levels,
+            update_retained: true,
         };
         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> {
     retained: &'a mut DefIdSet,
     access_levels: &'a AccessLevels<DefId>,
+    update_retained: bool,
 }
 
 impl<'a> fold::DocFolder for Stripper<'a> {
     fn fold_item(&mut self, i: Item) -> Option<Item> {
         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
             clean::TypedefItem(..) | clean::StaticItem(..) |
             clean::StructItem(..) | clean::EnumItem(..) |
@@ -109,18 +129,13 @@ fn fold_item(&mut self, i: Item) -> Option<Item> {
 
             clean::ModuleItem(..) => {
                 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
             clean::ExternCrateItem(..) | clean::ImportItem(..) => {}
 
@@ -152,7 +167,9 @@ fn fold_item(&mut self, i: Item) -> Option<Item> {
         };
 
         let i = if fastreturn {
-            self.retained.insert(i.def_id);
+            if self.update_retained {
+                self.retained.insert(i.def_id);
+            }
             return Some(i);
         } else {
             self.fold_item_recur(i)
@@ -160,13 +177,14 @@ fn fold_item(&mut self, i: Item) -> Option<Item> {
 
         i.and_then(|i| {
             match i.inner {
-                // emptied modules/impls have no need to exist
+                // emptied modules have no need to exist
                 clean::ModuleItem(ref m)
                     if m.items.is_empty() &&
                        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)
                 }
             }
@@ -182,6 +200,10 @@ struct ImplStripper<'a> {
 impl<'a> fold::DocFolder for ImplStripper<'a> {
     fn fold_item(&mut self, i: Item) -> Option<Item> {
         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 did.is_local() && !imp.for_.is_generic() &&
                     !self.retained.contains(&did)
index a352715b20b129a21ec56e1776a8a897b932f778..cc033cec8b8b1db948ee3f47ae983315a6e8d81e 100644 (file)
@@ -19,7 +19,6 @@
 use syntax_pos::{mk_sp, Span, DUMMY_SP, ExpnId};
 use codemap::{respan, Spanned};
 use abi::Abi;
-use errors;
 use parse::token::{self, keywords, InternedString};
 use print::pprust;
 use ptr::P;
@@ -362,15 +361,6 @@ pub struct ParenthesizedParameterData {
 /// small, positive ids.
 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.
 /// typeck::collect::compute_bounds matches these against
 /// the "special" built-in traits (see middle::lang_items) and
index da2967e306f6500c69aaaa5f4d221d6c26ec8e44..3c88fb8f6703b6796655bdd20020943a2a118bee 100644 (file)
@@ -839,7 +839,7 @@ impl HasAttrs for StmtKind {
     fn attrs(&self) -> &[Attribute] {
         match *self {
             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::Mac(ref 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 {
         match self {
             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::Semi(expr) => StmtKind::Semi(expr.map_attrs(f)),
             StmtKind::Mac(mac) => StmtKind::Mac(mac.map(|(mac, style, attrs)| {
index 961763c6025fd8d84828165452961ac9488d8093..eaf82f5f43ded1fe71823722f8ddd4cdada45b7d 100644 (file)
@@ -213,12 +213,7 @@ fn fold_opt_expr(&mut self, expr: P<ast::Expr>) -> Option<P<ast::Expr>> {
     }
 
     fn fold_stmt(&mut self, stmt: ast::Stmt) -> SmallVector<ast::Stmt> {
-        // avoid calling `visit_stmt_or_expr_attrs` on items
-        match stmt.node {
-            ast::StmtKind::Item(_) => {}
-            _ => self.visit_stmt_or_expr_attrs(stmt.attrs()),
-        }
-
+        self.visit_stmt_or_expr_attrs(stmt.attrs());
         self.configure(stmt).map(|stmt| fold::noop_fold_stmt(stmt, self))
                             .unwrap_or(SmallVector::zero())
     }
index 757b039fcac8a658b535631d79c1a2c5a5bf9d50..ca38ef068d05f4c610f7480e9f5444392af7afbd 100644 (file)
@@ -443,6 +443,10 @@ fn make_stmts(self: Box<DummyResult>) -> Option<SmallVector<ast::Stmt>> {
             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.
index 3036a88430a2be6e82360049b2f121f745d15f91..c670283e559d9b8c60451dc964c617302ccada20 100644 (file)
@@ -43,18 +43,19 @@ trait MacroGenerable: Sized {
     fn fold_with<F: Folder>(self, folder: &mut F) -> Self;
     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.
     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 {
     ($($ty:ty: $kind_name:expr, .$make:ident,
                $(.$fold:ident)*  $(lift .$fold_elt:ident)*,
-               $(.$visit:ident)* $(lift .$visit_elt:ident)*,
-               |$span:ident| $dummy:expr;)*) => { $(
+               $(.$visit:ident)* $(lift .$visit_elt:ident)*;)*) => { $(
         impl MacroGenerable for $ty {
             fn kind_name() -> &'static str { $kind_name }
             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) )*
                 $( for item in self.as_slice() { visitor. $visit_elt (item) } )*
             }
-            fn dummy($span: Span) -> Self { $dummy }
         }
     )* }
 }
 
 impl_macro_generable! {
-    P<ast::Pat>: "pattern", .make_pat, .fold_pat, .visit_pat, |span| P(DummyResult::raw_pat(span));
-    P<ast::Ty>:  "type",    .make_ty,  .fold_ty,  .visit_ty,  |span| DummyResult::raw_ty(span);
-    P<ast::Expr>:
-        "expression", .make_expr, .fold_expr, .visit_expr, |span| DummyResult::raw_expr(span);
-    SmallVector<ast::Stmt>:
-        "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();
+    P<ast::Expr>: "expression", .make_expr, .fold_expr, .visit_expr;
+    P<ast::Pat>:  "pattern",    .make_pat,  .fold_pat,  .visit_pat;
+    P<ast::Ty>:   "type",       .make_ty,   .fold_ty,   .visit_ty;
+    SmallVector<ast::Stmt>: "statement", .make_stmts, lift .fold_stmt, lift .visit_stmt;
+    SmallVector<P<ast::Item>>: "item",   .make_items, lift .fold_item, lift .visit_item;
     SmallVector<ast::TraitItem>:
-        "trait item", .make_trait_items, lift .fold_trait_item, lift .visit_trait_item,
-        |_span| SmallVector::zero();
+        "trait item", .make_trait_items, lift .fold_trait_item, lift .visit_trait_item;
     SmallVector<ast::ImplItem>:
-        "impl item",  .make_impl_items,  lift .fold_impl_item,  lift .visit_impl_item,
-        |_span| SmallVector::zero();
+        "impl item",  .make_impl_items,  lift .fold_impl_item,  lift .visit_impl_item;
 }
 
 impl MacroGenerable for Option<P<ast::Expr>> {
     fn kind_name() -> &'static str { "expression" }
-    fn dummy(_span: Span) -> Self { None }
     fn make_with<'a>(result: Box<MacResult + 'a>) -> Option<Self> {
         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());
         }
 
-        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");
             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> {
-    let new_items: SmallVector<Annotatable> = match a {
+    match a {
         Annotatable::Item(it) => match it.node {
             ast::ItemKind::Mac(..) => {
                 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().
                 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| {
         for i in 0..attrs.len() {
             if let Some(extension) = fld.cx.syntax_env.find(intern(&attrs[i].name())) {
-                if let MultiModifier(..) = *extension {
-                    multi_modifier = Some((attrs.remove(i), extension));
-                    break;
+                match *extension {
+                    MultiModifier(..) | MultiDecorator(..) => {
+                        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 {
         None => expand_multi_modified(item, fld),
-        Some((attr, extension)) => match *extension {
-            MultiModifier(ref mac) => {
-                attr::mark_used(&attr);
-                fld.cx.bt_push(ExpnInfo {
-                    call_site: attr.span,
-                    callee: NameAndSpan {
-                        format: MacroAttribute(intern(&attr.name())),
-                        span: Some(attr.span),
-                        // attributes can do whatever they like, for now
-                        allow_internal_unstable: true,
-                    }
-                });
-                let modified = mac.expand(fld.cx, attr.span, &attr.node.value, item);
-                fld.cx.bt_pop();
-                modified.into_iter().flat_map(|it| expand_annotatable(it, fld)).collect()
-            }
-            _ => unreachable!(),
+        Some((attr, extension)) => {
+            attr::mark_used(&attr);
+            fld.cx.bt_push(ExpnInfo {
+                call_site: attr.span,
+                callee: NameAndSpan {
+                    format: MacroAttribute(intern(&attr.name())),
+                    span: Some(attr.span),
+                    // attributes can do whatever they like, for now
+                    allow_internal_unstable: true,
+                }
+            });
+
+            let modified = match *extension {
+                MultiModifier(ref mac) => mac.expand(fld.cx, attr.span, &attr.node.value, item),
+                MultiDecorator(ref mac) => {
+                    let mut items = Vec::new();
+                    mac.expand(fld.cx, attr.span, &attr.node.value, &item,
+                               &mut |item| items.push(item));
+                    items.push(item);
+                    items
+                }
+                _ => unreachable!(),
+            };
+
+            fld.cx.bt_pop();
+            modified.into_iter().flat_map(|it| expand_annotatable(it, fld)).collect()
         }
     }
 }
index 6789e7be058bfcd7177991c3e2bb7c0b5a9c7176..ed6f09eed645f7741951542aaeea87665667266c 100644 (file)
@@ -1102,7 +1102,6 @@ pub fn noop_fold_pat<T: Folder>(p: P<Pat>, folder: &mut T) -> P<Pat> {
 
 pub fn noop_fold_expr<T: Folder>(Expr {id, node, span, attrs}: Expr, folder: &mut T) -> Expr {
     Expr {
-        id: folder.new_id(id),
         node: match node {
             ExprKind::Box(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)),
                         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)),
         },
+        id: folder.new_id(id),
         span: folder.new_span(span),
         attrs: fold_attrs(attrs.into(), folder).into(),
     }
index 813d90103b8878000bf4f103078bc3781c3e28dd..20a54228d016cdb222a1975dc219332586227349 100644 (file)
@@ -553,10 +553,6 @@ pub fn commit_stmt(&mut self, edible: &[token::Token],
         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
     fn interpolated_or_expr_span(&self,
                                  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:
                     let mut hi = span.hi;
                     if classify::stmt_ends_with_semi(&node) {
-                        self.commit_stmt_expecting(token::Semi)?;
+                        self.commit_stmt(&[token::Semi], &[])?;
                         hi = self.last_span.hi;
                     }
 
index 647e414a7fd2736cf6443e36ed8ce7be8b36458d..e01f4ed1f9bd233a932762ebf3cd110078703805 100644 (file)
@@ -345,15 +345,18 @@ pub fn combine_substructure<'a>(f: CombineSubstructureFunc<'a>)
 /// This method helps to extract all the type parameters referenced from a
 /// type. For a type parameter `<T>`, it looks for either a `TyPath` that
 /// 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;
 
-    struct Visitor<'a> {
+    struct Visitor<'a, 'b: 'a> {
+        cx: &'a ExtCtxt<'b>,
+        span: Span,
         ty_param_names: &'a [ast::Name],
         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) {
             match ty.node {
                 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)
         }
+
+        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 {
         ty_param_names: ty_param_names,
         types: Vec::new(),
+        span: span,
+        cx: cx,
     };
 
     visit::Visitor::visit_ty(&mut visitor, ty);
@@ -556,7 +566,7 @@ fn create_derived_impl(&self,
 
             let mut processed_field_types = HashSet::new();
             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 {
                     // if we have already handled this type, skip it
diff --git a/src/test/compile-fail/auxiliary/recursive_reexports.rs b/src/test/compile-fail/auxiliary/recursive_reexports.rs
new file mode 100644 (file)
index 0000000..1186e3d
--- /dev/null
@@ -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;
+}
index e47ebdd6a6938c2613350e36e0163523c97fc102..e8ca1c1fa98ff4a99c755f274b3a7d3aa2c8f799 100644 (file)
@@ -8,11 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(type_macros, concat_idents, rustc_attrs)]
-#![allow(unused)]
+#![feature(type_macros, concat_idents)]
 
-#[derive(Debug)] struct FooBar;
-#[derive(Debug)] struct Baz<T>(T, concat_idents!(Foo, Bar));
+#[derive(Debug)] //~ NOTE in this expansion
+struct Baz<T>(
+    concat_idents!(Foo, Bar) //~ ERROR `derive` cannot be used on items with type macros
+);
 
-#[rustc_error]
-fn main() {} //~ ERROR compilation successful
+fn main() {}
index 9499d732a38355b03802ed58fc79159a800d4772..e99dfb9aa0f0e9b6a425e6c9329ff3896feb9899 100644 (file)
@@ -15,6 +15,7 @@
 #[allow(unused_variables)]
 fn main() {
     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
index 95250e36b8685a64ce3fcf84082d8ddc902d82bc..408bb15ba28cdd165cbf9246f2bdf1f891760b4e 100644 (file)
@@ -8,8 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// error-pattern:expected macro name without module separators
-
 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
 }
diff --git a/src/test/compile-fail/recursive-reexports.rs b/src/test/compile-fail/recursive-reexports.rs
new file mode 100644 (file)
index 0000000..6fd52be
--- /dev/null
@@ -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() {}
diff --git a/src/test/parse-fail/issue-33455.rs b/src/test/parse-fail/issue-33455.rs
new file mode 100644 (file)
index 0000000..9607033
--- /dev/null
@@ -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 `.`
diff --git a/src/test/rustdoc/hidden-impls.rs b/src/test/rustdoc/hidden-impls.rs
new file mode 100644 (file)
index 0000000..203c56e
--- /dev/null
@@ -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;
diff --git a/src/test/rustdoc/hidden-methods.rs b/src/test/rustdoc/hidden-methods.rs
new file mode 100644 (file)
index 0000000..18f5f08
--- /dev/null
@@ -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;
diff --git a/src/test/rustdoc/module-impls.rs b/src/test/rustdoc/module-impls.rs
new file mode 100644 (file)
index 0000000..7be3c50
--- /dev/null
@@ -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'
index cc687b532047e616ac3adc874afb676b3b1006f3..6830f32bb2ce117bb522b0762ef4a57fdf04a15f 100644 (file)
@@ -254,6 +254,17 @@ pub fn run_tests(config: &Config) {
 
     match config.mode {
         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
             // instances running in parallel, so only run one test thread at a
             // time.
@@ -524,3 +535,7 @@ fn extract_lldb_version(full_version_line: Option<String>) -> Option<String> {
     }
     None
 }
+
+fn is_blacklisted_lldb_version(version: &str) -> bool {
+    version == "350"
+}