]> git.lizzy.rs Git - rust.git/commitdiff
Rollup merge of #34542 - jseyfried:fix_recursive_modules, r=nrc
authorManish Goregaokar <manishsmail@gmail.com>
Wed, 29 Jun 2016 15:51:24 +0000 (21:21 +0530)
committerGitHub <noreply@github.com>
Wed, 29 Jun 2016 15:51:24 +0000 (21:21 +0530)
Fix non-termination on recursive module re-exports in extern crates

Fixes #33776.
r? @nrc

45 files changed:
mk/llvm.mk
src/bootstrap/build/native.rs
src/doc/book/closures.md
src/doc/book/crates-and-modules.md
src/doc/book/ownership.md
src/doc/book/traits.md
src/doc/reference.md
src/libcollections/fmt.rs
src/librustc/diagnostics.rs
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/librustdoc/visit_ast.rs
src/libstd/io/util.rs
src/libstd/num/f32.rs
src/libstd/num/f64.rs
src/libstd/path.rs
src/libstd/primitive_docs.rs
src/libstd/thread/mod.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/issue-32950.rs
src/test/compile-fail/lint-type-overflow2.rs
src/test/compile-fail/macro-with-seps-err-msg.rs
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/issue-34473.rs [new file with mode: 0644]
src/test/rustdoc/module-impls.rs [new file with mode: 0644]
src/tools/compiletest/src/main.rs

index cc868a49e4b02201dee9b761d6672f74d9b0f5aa..6d8601f3dad6d3bee0c8ce725e2efc4418fe85b2 100644 (file)
@@ -27,12 +27,18 @@ endif
 
 define DEF_LLVM_RULES
 
+ifeq ($(1),$$(CFG_BUILD))
+LLVM_DEPS_TARGET_$(1) := $$(LLVM_DEPS)
+else
+LLVM_DEPS_TARGET_$(1) := $$(LLVM_DEPS) $$(LLVM_CONFIG_$$(CFG_BUILD))
+endif
+
 # If CFG_LLVM_ROOT is defined then we don't build LLVM ourselves
 ifeq ($(CFG_LLVM_ROOT),)
 
 LLVM_STAMP_$(1) = $$(CFG_LLVM_BUILD_DIR_$(1))/llvm-auto-clean-stamp
 
-$$(LLVM_CONFIG_$(1)): $$(LLVM_DEPS) $$(LLVM_STAMP_$(1))
+$$(LLVM_CONFIG_$(1)): $$(LLVM_DEPS_TARGET_$(1)) $$(LLVM_STAMP_$(1))
        @$$(call E, cmake: llvm)
 ifeq ($$(findstring msvc,$(1)),msvc)
        $$(Q)$$(CFG_CMAKE) --build $$(CFG_LLVM_BUILD_DIR_$(1)) \
@@ -42,7 +48,13 @@ else
 endif
        $$(Q)touch $$(LLVM_CONFIG_$(1))
 
+ifeq ($$(findstring msvc,$(1)),msvc)
 clean-llvm$(1):
+else
+clean-llvm$(1):
+       @$$(call E, clean: llvm)
+       $$(Q)$$(MAKE) -C $$(CFG_LLVM_BUILD_DIR_$(1)) clean
+endif
 
 else
 clean-llvm$(1):
index 5691b2da6a448856b76443106c817bfd606ea1d0..1e677aa48b0f664346ad29af25d756627578b4e7 100644 (file)
@@ -135,27 +135,64 @@ pub fn compiler_rt(build: &Build, target: &str) {
     let dst = build.compiler_rt_out(target);
     let arch = target.split('-').next().unwrap();
     let mode = if build.config.rust_optimize {"Release"} else {"Debug"};
+
+    let build_llvm_config = build.llvm_config(&build.config.build);
+    let mut cfg = cmake::Config::new(build.src.join("src/compiler-rt"));
+    cfg.target(target)
+       .host(&build.config.build)
+       .out_dir(&dst)
+       .profile(mode)
+       .define("LLVM_CONFIG_PATH", build_llvm_config)
+       .define("COMPILER_RT_DEFAULT_TARGET_TRIPLE", target)
+       .define("COMPILER_RT_BUILD_SANITIZERS", "OFF")
+       .define("COMPILER_RT_BUILD_EMUTLS", "OFF")
+       // inform about c/c++ compilers, the c++ compiler isn't actually used but
+       // it's needed to get the initial configure to work on all platforms.
+       .define("CMAKE_C_COMPILER", build.cc(target))
+       .define("CMAKE_CXX_COMPILER", build.cc(target));
+
     let (dir, build_target, libname) = if target.contains("linux") ||
                                           target.contains("freebsd") ||
                                           target.contains("netbsd") {
-        let os = if target.contains("android") {"-android"} else {""};
-        let arch = if arch.starts_with("arm") && target.contains("eabihf") {
-            "armhf"
+        let os_extra = if target.contains("android") && target.contains("arm") {
+            "-android"
         } else {
-            arch
+            ""
         };
-        let target = format!("clang_rt.builtins-{}{}", arch, os);
+        let builtins_arch = match arch {
+            "i586" => "i386",
+            "arm" | "armv7" if target.contains("android") => "armhf",
+            "arm" if target.contains("eabihf") => "armhf",
+            _ => arch,
+        };
+        let target = format!("clang_rt.builtins-{}{}", builtins_arch, os_extra);
         ("linux".to_string(), target.clone(), target)
-    } else if target.contains("darwin") {
-        let target = format!("clang_rt.builtins_{}_osx", arch);
+    } else if target.contains("apple-darwin") {
+        let builtins_arch = match arch {
+            "i686" => "i386",
+            _ => arch,
+        };
+        let target = format!("clang_rt.builtins_{}_osx", builtins_arch);
+        ("builtins".to_string(), target.clone(), target)
+    } else if target.contains("apple-ios") {
+        cfg.define("COMPILER_RT_ENABLE_IOS", "ON");
+        let target = match arch {
+            "armv7s" => "hard_pic_armv7em_macho_embedded".to_string(),
+            "aarch64" => "builtins_arm64_ios".to_string(),
+            _ => format!("hard_pic_{}_macho_embedded", arch),
+        };
         ("builtins".to_string(), target.clone(), target)
     } else if target.contains("windows-gnu") {
         let target = format!("clang_rt.builtins-{}", arch);
         ("windows".to_string(), target.clone(), target)
     } else if target.contains("windows-msvc") {
+        let builtins_arch = match arch {
+            "i586" | "i686" => "i386",
+            _ => arch,
+        };
         (format!("windows/{}", mode),
          "lib/builtins/builtins".to_string(),
-         format!("clang_rt.builtins-{}", arch.replace("i686", "i386")))
+         format!("clang_rt.builtins-{}", builtins_arch))
     } else {
         panic!("can't get os from target: {}", target)
     };
@@ -168,21 +205,7 @@ pub fn compiler_rt(build: &Build, target: &str) {
     }
     let _ = fs::remove_dir_all(&dst);
     t!(fs::create_dir_all(&dst));
-    let build_llvm_config = build.llvm_config(&build.config.build);
-    let mut cfg = cmake::Config::new(build.src.join("src/compiler-rt"));
-    cfg.target(target)
-       .host(&build.config.build)
-       .out_dir(&dst)
-       .profile(mode)
-       .define("LLVM_CONFIG_PATH", build_llvm_config)
-       .define("COMPILER_RT_DEFAULT_TARGET_TRIPLE", target)
-       .define("COMPILER_RT_BUILD_SANITIZERS", "OFF")
-       .define("COMPILER_RT_BUILD_EMUTLS", "OFF")
-       // inform about c/c++ compilers, the c++ compiler isn't actually used but
-       // it's needed to get the initial configure to work on all platforms.
-       .define("CMAKE_C_COMPILER", build.cc(target))
-       .define("CMAKE_CXX_COMPILER", build.cc(target))
-       .build_target(&build_target);
+    cfg.build_target(&build_target);
     cfg.build();
 }
 
index dedf9d5c28abd4d85ece1d4a13651ad3ac6c6dc8..a6b4e9492181c790fe5a3c040ca6e02397824d8f 100644 (file)
@@ -322,7 +322,7 @@ to our closure when we pass it to `call_with_one`, so we use `&||`.
 A quick note about closures that use explicit lifetimes. Sometimes you might have a closure
 that takes a reference like so:
 
-```
+```rust
 fn call_with_ref<F>(some_closure:F) -> i32
     where F: Fn(&i32) -> i32 {
 
@@ -334,8 +334,8 @@ fn call_with_ref<F>(some_closure:F) -> i32
 Normally you can specify the lifetime of the parameter to our closure. We
 could annotate it on the function declaration:
 
-```ignore
-fn call_with_ref<'a, F>(some_closure:F) -> i32 
+```rust,ignore
+fn call_with_ref<'a, F>(some_closure:F) -> i32
     where F: Fn(&'a 32) -> i32 {
 ```
 
@@ -353,11 +353,11 @@ fn call_with_ref<F>(some_closure:F) -> i32
     where F: for<'a> Fn(&'a 32) -> i32 {
 ```
 
-This lets the Rust compiler find the minimum lifetime to invoke our closure and 
+This lets the Rust compiler find the minimum lifetime to invoke our closure and
 satisfy the borrow checker's rules. Our function then compiles and excutes as we
 expect.
 
-```
+```rust
 fn call_with_ref<F>(some_closure:F) -> i32
     where F: for<'a> Fn(&'a i32) -> i32 {
 
index 43ac30c35c6c61d4c738f2161f40bf9755e04833..67fe8ba2c11a48e0d5bde95d9a769caeef0a4541 100644 (file)
@@ -22,12 +22,10 @@ As an example, let’s make a *phrases* crate, which will give us various phrase
 in different languages. To keep things simple, we’ll stick to ‘greetings’ and
 ‘farewells’ as two kinds of phrases, and use English and Japanese (日本語) as
 two languages for those phrases to be in. We’ll use this module layout:
-
 ```text
                                     +-----------+
                                 +---| greetings |
-                                |   +-----------+
-                  +---------+   |
+                  +---------+   |   +-----------+
               +---| english |---+
               |   +---------+   |   +-----------+
               |                 +---| farewells |
@@ -37,8 +35,7 @@ two languages for those phrases to be in. We’ll use this module layout:
               |                 +---| greetings |
               |   +----------+  |   +-----------+
               +---| japanese |--+
-                  +----------+  |
-                                |   +-----------+
+                  +----------+  |   +-----------+
                                 +---| farewells |
                                     +-----------+
 ```
index f445bed015c00d85c32e8a5a4d6b4e0d992ae7e7..c3e32e56c42666581f597ad0398f9c8f983d6115 100644 (file)
@@ -67,7 +67,7 @@ Vectors have a [generic type][generics] `Vec<T>`, so in this example `v` will ha
 
 [arrays]: primitive-types.html#arrays
 [vectors]: vectors.html
-[heap]: the-stack-and-the-heap.html
+[heap]: the-stack-and-the-heap.html#the-heap
 [stack]: the-stack-and-the-heap.html#the-stack
 [bindings]: variable-bindings.html
 [generics]: generics.html
@@ -136,6 +136,8 @@ Rust allocates memory for an integer [i32] on the [stack][sh], copies the bit
 pattern representing the value of 10 to the allocated memory and binds the
 variable name x to this memory region for future reference.
 
+[i32]: primitive-types.html#numeric-types
+
 Now consider the following code fragment:
 
 ```rust
index 107ef2b44d5eb07017ba08455f553239bf2e26eb..e685cb129b939669a235ec14ddb2091c9d06f086 100644 (file)
@@ -397,10 +397,10 @@ fn normal<T: ConvertTo<i64>>(x: &T) -> i64 {
 }
 
 // can be called with T == i64
-fn inverse<T>() -> T
+fn inverse<T>(x: i32) -> T
         // this is using ConvertTo as if it were "ConvertTo<i64>"
         where i32: ConvertTo<T> {
-    42.convert()
+    x.convert()
 }
 ```
 
index fb8ea0f5661d3f404df50c0c06c68e9625a48765..59dbffd6e28e7e705f679cb59bd9454015c8c339 100644 (file)
@@ -114,12 +114,20 @@ Non-doc comments are interpreted as a form of whitespace.
 
 ## Whitespace
 
-Whitespace is any non-empty string containing only the following characters:
-
+Whitespace is any non-empty string containing only characters that have the
+`Pattern_White_Space` Unicode property, namely:
+
+- `U+0009` (horizontal tab, `'\t'`)
+- `U+000A` (line feed, `'\n'`)
+- `U+000B` (vertical tab)
+- `U+000C` (form feed)
+- `U+000D` (carriage return, `'\r'`)
 - `U+0020` (space, `' '`)
-- `U+0009` (tab, `'\t'`)
-- `U+000A` (LF, `'\n'`)
-- `U+000D` (CR, `'\r'`)
+- `U+0085` (next line)
+- `U+200E` (left-to-right mark)
+- `U+200F` (right-to-left mark)
+- `U+2028` (line separator)
+- `U+2029` (paragraph separator)
 
 Rust is a "free-form" language, meaning that all forms of whitespace serve only
 to separate _tokens_ in the grammar, and have no semantic significance.
index 6f77d79ab0bfec4c419241588c42f0c3e97d7156..15de0dd802d99f0a067c6df18d086e1cdb3465b8 100644 (file)
@@ -28,6 +28,7 @@
 //! format!("{:?}", (3, 4));          // => "(3, 4)"
 //! format!("{value}", value=4);      // => "4"
 //! format!("{} {}", 1, 2);           // => "1 2"
+//! format!("{:04}", 42);             // => "0042" with leading zeros
 //! ```
 //!
 //! From these, you can see that the first argument is a format string. It is
index 538613c7fac9126ced763527e6fea95ca5f6e727..9040e4bf8db5f23661174bb68a27822e63aa5d88 100644 (file)
@@ -673,45 +673,35 @@ fn foo<'a, 'b, 'a>(x: &'a str, y: &'b str) { }
 "##,
 
 E0269: r##"
-Functions must eventually return a value of their return type. For example, in
-the following function:
+A returned value was expected but not all control paths return one.
+
+Erroneous code example:
 
 ```compile_fail,E0269
 fn abracada_FAIL() -> String {
     "this won't work".to_string();
+    // error: not all control paths return a value
 }
 ```
 
-If the condition is true, the value `x` is returned, but if the condition is
-false, control exits the `if` block and reaches a place where nothing is being
-returned. All possible control paths must eventually return a `u8`, which is not
-happening here.
-
-An easy fix for this in a complicated function is to specify a default return
-value, if possible:
+In the previous code, the function is supposed to return a `String`, however,
+the code returns nothing (because of the ';'). Another erroneous code would be:
 
-```ignore
-fn foo(x: u8) -> u8 {
-    if x > 0 {
-        x // alternatively, `return x`
+```compile_fail
+fn abracada_FAIL(b: bool) -> u32 {
+    if b {
+        0
+    } else {
+        "a" // It fails because an `u32` was expected and something else is
+            // returned.
     }
-    // lots of other if branches
-    0 // return 0 if all else fails
 }
 ```
 
 It is advisable to find out what the unhandled cases are and check for them,
 returning an appropriate value or panicking if necessary. Check if you need
-to remove a semicolon from the last expression, like in this case:
-
-```ignore
-fn foo(x: u8) -> u8 {
-    inner(2*x + 1);
-}
-```
-
-The semicolon discards the return value of `inner`, instead of returning
-it from `foo`.
+to remove a semicolon from the last expression, like in the first erroneous
+code example.
 "##,
 
 E0270: r##"
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 f983646479b9401ee1740652e7b7f77be3e5502b..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()
                             }
@@ -3456,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 f63d37b34032ef45118a19bf0c530455f1f8f000..48acf31b993679f4c2630c0159a15137f657e1d7 100644 (file)
@@ -1696,6 +1696,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 92424f113f987e806693e759028c9200db9d5ebb..0334c5ef5c4f4397120d1408d1f8aa6227c8e5f8 100644 (file)
@@ -189,8 +189,8 @@ fn visit_view_path(&mut self, path: hir::ViewPath_,
             }
             hir::ViewPathList(p, paths) => {
                 let mine = paths.into_iter().filter(|path| {
-                    !self.maybe_inline_local(path.node.id(), None, false, om,
-                                     please_inline)
+                    !self.maybe_inline_local(path.node.id(), path.node.rename(),
+                                             false, om, please_inline)
                 }).collect::<hir::HirVec<hir::PathListItem>>();
 
                 if mine.is_empty() {
index 2815c0163d68a86e448dc50f459b0c00663c4e21..07f43f72ff55ab1d987b60c70c37b909695f27a3 100644 (file)
@@ -78,14 +78,11 @@ pub struct Empty { _priv: () }
 /// A slightly sad example of not reading anything into a buffer:
 ///
 /// ```
-/// use std::io;
-/// use std::io::Read;
+/// use std::io::{self, Read};
 ///
-/// # fn foo() -> io::Result<String> {
 /// let mut buffer = String::new();
-/// try!(io::empty().read_to_string(&mut buffer));
-/// # Ok(buffer)
-/// # }
+/// io::empty().read_to_string(&mut buffer).unwrap();
+/// assert!(buffer.is_empty());
 /// ```
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn empty() -> Empty { Empty { _priv: () } }
@@ -113,6 +110,16 @@ pub struct Repeat { byte: u8 }
 ///
 /// All reads from this reader will succeed by filling the specified buffer with
 /// the given byte.
+///
+/// # Examples
+///
+/// ```
+/// use std::io::{self, Read};
+///
+/// let mut buffer = [0; 3];
+/// io::repeat(0b101).read_exact(&mut buffer).unwrap();
+/// assert_eq!(buffer, [0b101, 0b101, 0b101]);
+/// ```
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn repeat(byte: u8) -> Repeat { Repeat { byte: byte } }
 
@@ -139,6 +146,16 @@ pub struct Sink { _priv: () }
 ///
 /// All calls to `write` on the returned instance will return `Ok(buf.len())`
 /// and the contents of the buffer will not be inspected.
+///
+/// # Examples
+///
+/// ```rust
+/// use std::io::{self, Write};
+///
+/// let mut buffer = vec![1, 2, 3, 5, 8];
+/// let num_bytes = io::sink().write(&mut buffer).unwrap();
+/// assert_eq!(num_bytes, 5);
+/// ```
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn sink() -> Sink { Sink { _priv: () } }
 
index ff80a4e305359c1349df1bb6c50062e4ef231423..17d412411c0481fe47813bfca8f0270cdfdaf707 100644 (file)
@@ -217,7 +217,7 @@ pub fn is_finite(self) -> bool { num::Float::is_finite(self) }
     /// // Values between `0` and `min` are Subnormal.
     /// assert!(!lower_than_min.is_normal());
     /// ```
-    /// [subnormal]: http://en.wikipedia.org/wiki/Denormal_number
+    /// [subnormal]: https://en.wikipedia.org/wiki/Denormal_number
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn is_normal(self) -> bool { num::Float::is_normal(self) }
@@ -923,12 +923,12 @@ pub fn cos(self) -> f32 {
     /// Computes the tangent of a number (in radians).
     ///
     /// ```
-    /// use std::f64;
+    /// use std::f32;
     ///
-    /// let x = f64::consts::PI/4.0;
+    /// let x = f32::consts::PI / 4.0;
     /// let abs_difference = (x.tan() - 1.0).abs();
     ///
-    /// assert!(abs_difference < 1e-10);
+    /// assert!(abs_difference <= f32::EPSILON);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
@@ -1052,12 +1052,14 @@ pub fn sin_cos(self) -> (f32, f32) {
     /// number is close to zero.
     ///
     /// ```
-    /// let x = 7.0f64;
+    /// use std::f32;
     ///
-    /// // e^(ln(7)) - 1
-    /// let abs_difference = (x.ln().exp_m1() - 6.0).abs();
+    /// let x = 6.0f32;
     ///
-    /// assert!(abs_difference < 1e-10);
+    /// // e^(ln(6)) - 1
+    /// let abs_difference = (x.ln().exp_m1() - 5.0).abs();
+    ///
+    /// assert!(abs_difference <= f32::EPSILON);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
index b775031787084c97cf7efe85a1c8bb0c4cc946f7..70b7706535ca17784f4ebf81f95aac4b93110b5d 100644 (file)
@@ -147,23 +147,23 @@ pub fn is_finite(self) -> bool { num::Float::is_finite(self) }
     /// [subnormal][subnormal], or `NaN`.
     ///
     /// ```
-    /// use std::f32;
+    /// use std::f64;
     ///
-    /// let min = f32::MIN_POSITIVE; // 1.17549435e-38f64
-    /// let max = f32::MAX;
-    /// let lower_than_min = 1.0e-40_f32;
-    /// let zero = 0.0f32;
+    /// let min = f64::MIN_POSITIVE; // 2.2250738585072014e-308f64
+    /// let max = f64::MAX;
+    /// let lower_than_min = 1.0e-308_f64;
+    /// let zero = 0.0f64;
     ///
     /// assert!(min.is_normal());
     /// assert!(max.is_normal());
     ///
     /// assert!(!zero.is_normal());
-    /// assert!(!f32::NAN.is_normal());
-    /// assert!(!f32::INFINITY.is_normal());
+    /// assert!(!f64::NAN.is_normal());
+    /// assert!(!f64::INFINITY.is_normal());
     /// // Values between `0` and `min` are Subnormal.
     /// assert!(!lower_than_min.is_normal());
     /// ```
-    /// [subnormal]: http://en.wikipedia.org/wiki/Denormal_number
+    /// [subnormal]: https://en.wikipedia.org/wiki/Denormal_number
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn is_normal(self) -> bool { num::Float::is_normal(self) }
@@ -655,9 +655,9 @@ pub fn frexp(self) -> (f64, isize) {
     /// ```
     /// #![feature(float_extras)]
     ///
-    /// let x = 1.0f32;
+    /// let x = 1.0f64;
     ///
-    /// let abs_diff = (x.next_after(2.0) - 1.00000011920928955078125_f32).abs();
+    /// let abs_diff = (x.next_after(2.0) - 1.0000000000000002220446049250313_f64).abs();
     ///
     /// assert!(abs_diff < 1e-10);
     /// ```
index 8dc46239f3d036ebce0ca9844a534ba20c219df1..c103ff7f4b025345a260fd586f01eb01829b643e 100644 (file)
@@ -525,6 +525,26 @@ fn hash<H: Hasher>(&self, h: &mut H) {
 ///
 /// See the module documentation for an in-depth explanation of components and
 /// their role in the API.
+///
+/// This `enum` is created from iterating over the [`path::Components`]
+/// `struct`.
+///
+/// # Examples
+///
+/// ```rust
+/// use std::path::{Component, Path};
+///
+/// let path = Path::new("/tmp/foo/bar.txt");
+/// let components = path.components().collect::<Vec<_>>();
+/// assert_eq!(&components, &[
+///     Component::RootDir,
+///     Component::Normal("tmp".as_ref()),
+///     Component::Normal("foo".as_ref()),
+///     Component::Normal("bar.txt".as_ref()),
+/// ]);
+/// ```
+///
+/// [`path::Components`]: struct.Components.html
 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub enum Component<'a> {
index 11af768c5b9b0a0abc8c186a4fae546b00040370..be9cd6a688858ff2fc6b8da382babd1d0c496892 100644 (file)
@@ -490,9 +490,6 @@ mod prim_tuple { }
 ///
 /// *[See also the `std::f32` module](f32/index.html).*
 ///
-/// However, please note that examples are shared between the `f64` and `f32`
-/// primitive types. So it's normal if you see usage of `f64` in there.
-///
 mod prim_f32 { }
 
 #[doc(primitive = "f64")]
@@ -501,9 +498,6 @@ mod prim_f32 { }
 ///
 /// *[See also the `std::f64` module](f64/index.html).*
 ///
-/// However, please note that examples are shared between the `f64` and `f32`
-/// primitive types. So it's normal if you see usage of `f32` in there.
-///
 mod prim_f64 { }
 
 #[doc(primitive = "i8")]
index 3bee878de3585b143592120f9f2feac67f585616..e9736fea7b37f43955f04d7137cefa517cfaaa9b 100644 (file)
@@ -394,6 +394,19 @@ pub fn sleep_ms(ms: u32) {
 /// signal being received or a spurious wakeup. Platforms which do not support
 /// nanosecond precision for sleeping will have `dur` rounded up to the nearest
 /// granularity of time they can sleep for.
+///
+/// # Examples
+///
+/// ```rust,no_run
+/// use std::{thread, time};
+///
+/// let ten_millis = time::Duration::from_millis(10);
+/// let now = time::Instant::now();
+///
+/// thread::sleep(ten_millis);
+///
+/// assert!(now.elapsed() >= ten_millis);
+/// ```
 #[stable(feature = "thread_sleep", since = "1.4.0")]
 pub fn sleep(dur: Duration) {
     imp::Thread::sleep(dur)
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
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/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/issue-34473.rs b/src/test/rustdoc/issue-34473.rs
new file mode 100644 (file)
index 0000000..a6de638
--- /dev/null
@@ -0,0 +1,22 @@
+// 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 second {
+    pub struct SomeTypeWithLongName;
+}
+
+// @has foo/index.html
+// @!has - SomeTypeWithLongName
+// @has foo/struct.SomeType.html
+// @!has - SomeTypeWithLongName
+// @!has foo/struct.SomeTypeWithLongName.html
+pub use second::{SomeTypeWithLongName as SomeType};
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"
+}