]> git.lizzy.rs Git - rust.git/commitdiff
Rollup merge of #38486 - est31:master, r=petrochenkov
authorAlex Crichton <alex@alexcrichton.com>
Tue, 20 Dec 2016 19:16:49 +0000 (11:16 -0800)
committerAlex Crichton <alex@alexcrichton.com>
Tue, 20 Dec 2016 20:59:11 +0000 (12:59 -0800)
Add regression test for #38458

Closes #38458

124 files changed:
mk/main.mk
src/Cargo.lock
src/bootstrap/bootstrap.py
src/bootstrap/check.rs
src/bootstrap/config.rs
src/bootstrap/config.toml.example
src/bootstrap/dist.rs
src/bootstrap/step.rs
src/build_helper/lib.rs
src/ci/docker/x86_64-gnu-cargotest/Dockerfile
src/doc/reference.md
src/liballoc_jemalloc/build.rs
src/libcollections/btree/set.rs
src/libcollections/slice.rs
src/libcore/result.rs
src/libcore/slice.rs
src/librustc/dep_graph/README.md
src/librustc/dep_graph/visit.rs
src/librustc/diagnostics.rs
src/librustc/hir/def_id.rs
src/librustc/hir/intravisit.rs
src/librustc/hir/lowering.rs
src/librustc/hir/map/collector.rs
src/librustc/hir/map/def_collector.rs
src/librustc/hir/map/definitions.rs
src/librustc/hir/map/mod.rs
src/librustc/hir/mod.rs
src/librustc/middle/cstore.rs
src/librustc/middle/stability.rs
src/librustc/session/mod.rs
src/librustc/traits/error_reporting.rs
src/librustc/ty/context.rs
src/librustc/ty/item_path.rs
src/librustc/ty/mod.rs
src/librustc_back/target/mod.rs
src/librustc_driver/driver.rs
src/librustc_driver/pretty.rs
src/librustc_driver/test.rs
src/librustc_incremental/persist/hash.rs
src/librustc_llvm/build.rs
src/librustc_metadata/astencode.rs
src/librustc_metadata/creader.rs
src/librustc_metadata/cstore.rs
src/librustc_metadata/cstore_impl.rs
src/librustc_metadata/decoder.rs
src/librustc_metadata/encoder.rs
src/librustc_metadata/schema.rs
src/librustc_passes/ast_validation.rs
src/librustc_resolve/build_reduced_graph.rs
src/librustc_resolve/lib.rs
src/librustc_resolve/macros.rs
src/librustc_resolve/resolve_imports.rs
src/librustc_trans/back/write.rs
src/librustc_typeck/check/cast.rs
src/librustdoc/clean/mod.rs
src/librustdoc/doctree.rs
src/librustdoc/lib.rs
src/librustdoc/visit_ast.rs
src/libstd/ascii.rs
src/libstd/build.rs
src/libstd/collections/hash/map.rs
src/libstd/collections/hash/set.rs
src/libstd/collections/hash/table.rs
src/libstd/env.rs
src/libstd/fs.rs
src/libstd/io/mod.rs
src/libstd/io/stdio.rs
src/libstd/io/util.rs
src/libstd/lib.rs
src/libstd/net/ip.rs
src/libstd/net/mod.rs
src/libstd/net/tcp.rs
src/libstd/os/linux/raw.rs
src/libstd/os/macos/raw.rs
src/libstd/os/raw.rs
src/libstd/panic.rs
src/libstd/panicking.rs
src/libstd/process.rs
src/libstd/rand/mod.rs
src/libstd/sync/barrier.rs
src/libstd/sync/condvar.rs
src/libstd/sync/mpsc/mod.rs
src/libstd/sync/mutex.rs
src/libstd/sync/once.rs
src/libstd/sync/rwlock.rs
src/libstd/sys/unix/ext/net.rs
src/libstd/sys/unix/fast_thread_local.rs
src/libstd/sys/unix/fd.rs
src/libstd/sys/unix/fs.rs
src/libstd/sys/windows/fs.rs
src/libstd/thread/local.rs
src/libstd/thread/mod.rs
src/libstd/time/duration.rs
src/libsyntax/ast.rs
src/libsyntax/attr.rs
src/libsyntax/ext/base.rs
src/libsyntax/ext/build.rs
src/libsyntax/ext/expand.rs
src/libsyntax/ext/hygiene.rs
src/libsyntax/ext/placeholders.rs
src/libsyntax/ext/tt/macro_rules.rs
src/libsyntax/fold.rs
src/libsyntax/parse/mod.rs
src/libsyntax/parse/parser.rs
src/libsyntax/print/pprust.rs
src/libsyntax/std_inject.rs
src/libsyntax/test.rs
src/libsyntax/visit.rs
src/libsyntax_ext/concat_idents.rs
src/libsyntax_ext/lib.rs
src/stage0.txt
src/test/compile-fail/E0259.rs
src/test/compile-fail/E0277-2.rs [new file with mode: 0644]
src/test/compile-fail/E0277.rs
src/test/compile-fail/blind-item-item-shadow.rs
src/test/compile-fail/cast-rfc0401.rs [deleted file]
src/test/compile-fail/issue-19498.rs
src/test/compile-fail/issue-24081.rs
src/test/compile-fail/resolve-conflict-item-vs-import.rs
src/test/run-pass/backtrace.rs
src/test/ui/mismatched_types/cast-rfc0401.rs [new file with mode: 0644]
src/test/ui/mismatched_types/cast-rfc0401.stderr [new file with mode: 0644]
src/tools/compiletest/Cargo.toml
src/tools/compiletest/src/runtest.rs

index 49fdfc4118df5cb3b263d16c6bcdf437c9d3c911..d01ec07b4244e665b076c540969ecc5b22d6f9f7 100644 (file)
@@ -13,7 +13,7 @@
 ######################################################################
 
 # The version number
-CFG_RELEASE_NUM=1.15.0
+CFG_RELEASE_NUM=1.16.0
 
 # An optional number to put after the label, e.g. '.2' -> '-beta.2'
 # NB Make sure it starts with a dot to conform to semver pre-release
index 9cd77e71b82dde04638ee53c04353b5ced783024..01a19a0cca862dd797f44ff1458ba5f1894b590e 100644 (file)
@@ -87,6 +87,7 @@ dependencies = [
 name = "compiletest"
 version = "0.0.0"
 dependencies = [
+ "build_helper 0.1.0",
  "env_logger 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "serialize 0.0.0",
index 5f16542ed2f2b6ec0d3d088989b80cc584272aaf..89d297760e2864c8345b876d87112be2fb5c2998 100644 (file)
@@ -81,7 +81,7 @@ def verify(path, sha_path, verbose):
     with open(path, "rb") as f:
         found = hashlib.sha256(f.read()).hexdigest()
     with open(sha_path, "r") as f:
-        expected, _ = f.readline().split()
+        expected = f.readline().split()[0]
     verified = found == expected
     if not verified:
         print("invalid checksum:\n"
@@ -146,7 +146,7 @@ class RustBuild(object):
     def download_stage0(self):
         cache_dst = os.path.join(self.build_dir, "cache")
         rustc_cache = os.path.join(cache_dst, self.stage0_rustc_date())
-        cargo_cache = os.path.join(cache_dst, self.stage0_cargo_date())
+        cargo_cache = os.path.join(cache_dst, self.stage0_cargo_rev())
         if not os.path.exists(rustc_cache):
             os.makedirs(rustc_cache)
         if not os.path.exists(cargo_cache):
@@ -179,21 +179,17 @@ class RustBuild(object):
         if self.cargo().startswith(self.bin_root()) and \
                 (not os.path.exists(self.cargo()) or self.cargo_out_of_date()):
             self.print_what_it_means_to_bootstrap()
-            channel = self.stage0_cargo_channel()
-            filename = "cargo-{}-{}.tar.gz".format(channel, self.build)
-            url = "https://static.rust-lang.org/cargo-dist/" + self.stage0_cargo_date()
+            filename = "cargo-nightly-{}.tar.gz".format(self.build)
+            url = "https://s3.amazonaws.com/rust-lang-ci/cargo-builds/" + self.stage0_cargo_rev()
             tarball = os.path.join(cargo_cache, filename)
             if not os.path.exists(tarball):
                 get("{}/{}".format(url, filename), tarball, verbose=self.verbose)
             unpack(tarball, self.bin_root(), match="cargo", verbose=self.verbose)
             with open(self.cargo_stamp(), 'w') as f:
-                f.write(self.stage0_cargo_date())
+                f.write(self.stage0_cargo_rev())
 
-    def stage0_cargo_date(self):
-        return self._cargo_date
-
-    def stage0_cargo_channel(self):
-        return self._cargo_channel
+    def stage0_cargo_rev(self):
+        return self._cargo_rev
 
     def stage0_rustc_date(self):
         return self._rustc_date
@@ -217,7 +213,7 @@ class RustBuild(object):
         if not os.path.exists(self.cargo_stamp()) or self.clean:
             return True
         with open(self.cargo_stamp(), 'r') as f:
-            return self.stage0_cargo_date() != f.read()
+            return self.stage0_cargo_rev() != f.read()
 
     def bin_root(self):
         return os.path.join(self.build_dir, self.build, "stage0")
@@ -469,7 +465,7 @@ def main():
 
     data = stage0_data(rb.rust_root)
     rb._rustc_channel, rb._rustc_date = data['rustc'].split('-', 1)
-    rb._cargo_channel, rb._cargo_date = data['cargo'].split('-', 1)
+    rb._cargo_rev = data['cargo']
 
     start_time = time()
 
index 881da7b682ba8998324f1fc971a8aaf1e8526d8b..e7b0afeb8ce630447d596704c771aa8656922cc9 100644 (file)
@@ -13,6 +13,8 @@
 //! This file implements the various regression test suites that we execute on
 //! our CI.
 
+extern crate build_helper;
+
 use std::collections::HashSet;
 use std::env;
 use std::fmt;
@@ -543,7 +545,7 @@ pub fn distcheck(build: &Build) {
     build.run(&mut cmd);
     build.run(Command::new("./configure")
                      .current_dir(&dir));
-    build.run(Command::new("make")
+    build.run(Command::new(build_helper::make(&build.config.build))
                      .arg("check")
                      .current_dir(&dir));
 }
index f267f60d81407772e955e9f563742354fd142f9f..6b86e537b7d22098e8e2b2e47e1a77e8a04acd2f 100644 (file)
@@ -113,6 +113,7 @@ pub struct Target {
 #[derive(RustcDecodable, Default)]
 struct TomlConfig {
     build: Option<Build>,
+    install: Option<Install>,
     llvm: Option<Llvm>,
     rust: Option<Rust>,
     target: Option<HashMap<String, TomlTarget>>,
@@ -135,6 +136,12 @@ struct Build {
     python: Option<String>,
 }
 
+/// TOML representation of various global install decisions.
+#[derive(RustcDecodable, Default, Clone)]
+struct Install {
+    prefix: Option<String>,
+}
+
 /// TOML representation of how the LLVM build is configured.
 #[derive(RustcDecodable, Default)]
 struct Llvm {
@@ -258,6 +265,10 @@ pub fn parse(build: &str, file: Option<PathBuf>) -> Config {
         set(&mut config.submodules, build.submodules);
         set(&mut config.vendor, build.vendor);
 
+        if let Some(ref install) = toml.install {
+            config.prefix = install.prefix.clone();
+        }
+
         if let Some(ref llvm) = toml.llvm {
             match llvm.ccache {
                 Some(StringOrBool::String(ref s)) => {
@@ -275,6 +286,7 @@ pub fn parse(build: &str, file: Option<PathBuf>) -> Config {
             set(&mut config.llvm_version_check, llvm.version_check);
             set(&mut config.llvm_static_stdcpp, llvm.static_libstdcpp);
         }
+
         if let Some(ref rust) = toml.rust {
             set(&mut config.rust_debug_assertions, rust.debug_assertions);
             set(&mut config.rust_debuginfo, rust.debuginfo);
index 9e50e71bf7d313d809be3d5c9a6db2cfc804f023..5fc095137c793e0101d102ae64b22790ed3a29bd 100644 (file)
 # Indicate whether the vendored sources are used for Rust dependencies or not
 #vendor = false
 
+# =============================================================================
+# General install configuration options
+# =============================================================================
+[install]
+
+# Instead of installing to /usr/local, install to this path instead.
+#prefix = "/path/to/install"
+
 # =============================================================================
 # Options for compiling Rust code itself
 # =============================================================================
index be51a6753fb62fb74a8feb6f35704fc93e1eddb9..6e3174ed2f6d00cc6939c9f61f96414fe9634dd2 100644 (file)
@@ -346,8 +346,14 @@ pub fn analysis(build: &Build, compiler: &Compiler, target: &str) {
 }
 
 /// Creates the `rust-src` installer component and the plain source tarball
-pub fn rust_src(build: &Build) {
+pub fn rust_src(build: &Build, host: &str) {
     println!("Dist src");
+
+    if host != build.config.build {
+        println!("\tskipping, not a build host");
+        return
+    }
+
     let plain_name = format!("rustc-{}-src", package_vers(build));
     let name = format!("rust-src-{}", package_vers(build));
     let image = tmpdir(build).join(format!("{}-image", name));
index 95882cf8126cbf7af675dcd45d92550361c63102..c5898c1119a670d31ae710f31afb78152aca780c 100644 (file)
@@ -267,16 +267,18 @@ pub fn build_rules(build: &Build) -> Rules {
         // nothing to do for debuginfo tests
     } else if build.config.build.contains("apple") {
         rules.test("check-debuginfo", "src/test/debuginfo")
+             .default(true)
              .dep(|s| s.name("libtest"))
-             .dep(|s| s.name("tool-compiletest").host(s.host))
+             .dep(|s| s.name("tool-compiletest").target(s.host))
              .dep(|s| s.name("test-helpers"))
              .dep(|s| s.name("debugger-scripts"))
              .run(move |s| check::compiletest(build, &s.compiler(), s.target,
                                          "debuginfo-lldb", "debuginfo"));
     } else {
         rules.test("check-debuginfo", "src/test/debuginfo")
+             .default(true)
              .dep(|s| s.name("libtest"))
-             .dep(|s| s.name("tool-compiletest").host(s.host))
+             .dep(|s| s.name("tool-compiletest").target(s.host))
              .dep(|s| s.name("test-helpers"))
              .dep(|s| s.name("debugger-scripts"))
              .run(move |s| check::compiletest(build, &s.compiler(), s.target,
@@ -455,7 +457,7 @@ pub fn build_rules(build: &Build) -> Rules {
     for (krate, path, default) in krates("test_shim") {
         rules.doc(&krate.doc_step, path)
              .dep(|s| s.name("libtest"))
-             .default(default && build.config.docs)
+             .default(default && build.config.compiler_docs)
              .run(move |s| doc::test(build, s.stage, s.target));
     }
     for (krate, path, default) in krates("rustc-main") {
@@ -496,7 +498,7 @@ pub fn build_rules(build: &Build) -> Rules {
     rules.dist("dist-src", "src")
          .default(true)
          .host(true)
-         .run(move |_| dist::rust_src(build));
+         .run(move |s| dist::rust_src(build, s.target));
     rules.dist("dist-docs", "src/doc")
          .default(true)
          .dep(|s| s.name("default:doc"))
@@ -820,7 +822,16 @@ fn plan(&self) -> Vec<Step<'a>> {
             let hosts = if self.build.flags.host.len() > 0 {
                 &self.build.flags.host
             } else {
-                &self.build.config.host
+                if kind == Kind::Dist {
+                    // For 'dist' steps we only distribute artifacts built from
+                    // the build platform, so only consider that in the hosts
+                    // array.
+                    // NOTE: This relies on the fact that the build triple is
+                    // always placed first, as done in `config.rs`.
+                    &self.build.config.host[..1]
+                } else {
+                    &self.build.config.host
+                }
             };
             let targets = if self.build.flags.target.len() > 0 {
                 &self.build.flags.target
index 07f9c91d3c787b17f17c23be5225d1016d7142b3..d0d588f46a7549a9402f404b395aebe0a2868dde 100644 (file)
@@ -47,6 +47,8 @@ pub fn cc2ar(cc: &Path, target: &str) -> Option<PathBuf> {
         None
     } else if target.contains("musl") {
         Some(PathBuf::from("ar"))
+    } else if target.contains("openbsd") {
+        Some(PathBuf::from("ar"))
     } else {
         let parent = cc.parent().unwrap();
         let file = cc.file_name().unwrap().to_str().unwrap();
@@ -61,6 +63,16 @@ pub fn cc2ar(cc: &Path, target: &str) -> Option<PathBuf> {
     }
 }
 
+pub fn make(host: &str) -> PathBuf {
+    if host.contains("bitrig") || host.contains("dragonfly") ||
+        host.contains("freebsd") || host.contains("netbsd") ||
+        host.contains("openbsd") {
+        PathBuf::from("gmake")
+    } else {
+        PathBuf::from("make")
+    }
+}
+
 pub fn output(cmd: &mut Command) -> String {
     let output = match cmd.stderr(Stdio::inherit()).output() {
         Ok(status) => status,
index 0d9835e86d2a7f3a2ce8edff53af55709131f784..2c3db87d9fb1fdd716f22aa489483e44a983ea34 100644 (file)
@@ -12,7 +12,8 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   ccache \
   libssl-dev \
   sudo \
-  xz-utils
+  xz-utils \
+  pkg-config
 
 ENV SCCACHE_DIGEST=7237e38e029342fa27b7ac25412cb9d52554008b12389727320bd533fd7f05b6a96d55485f305caf95e5c8f5f97c3313e10012ccad3e752aba2518f3522ba783
 RUN curl -L https://api.pub.build.mozilla.org/tooltool/sha512/$SCCACHE_DIGEST | \
index bf286aaec4bb34631366b5d224bfa949f3a54fb7..b5a91a170d8ed478b71b0bedf1a4cfde5d600a20 100644 (file)
@@ -1731,7 +1731,8 @@ of an item to see whether it should be allowed or not. This is where privacy
 warnings are generated, or otherwise "you used a private item of another module
 and weren't allowed to."
 
-By default, everything in Rust is *private*, with one exception. Enum variants
+By default, everything in Rust is *private*, with two exceptions: Associated
+items in a `pub` Trait are public by default; Enum variants
 in a `pub` enum are also public by default. When an item is declared as `pub`,
 it can be thought of as being accessible to the outside world. For example:
 
index fc849e7a50cc40abda3fbdcff2b756189d8a2057..60b7875a97c84dd0cb01acadadda12371ce58abe 100644 (file)
@@ -151,7 +151,7 @@ fn main() {
     cmd.arg(format!("--build={}", build_helper::gnu_target(&host)));
 
     run(&mut cmd);
-    let mut make = Command::new("make");
+    let mut make = Command::new(build_helper::make(&host));
     make.current_dir(&build_dir)
         .arg("build_lib_static");
 
index c57266d9e3b4a5b013a97842bac3ef044220836a..34674e3a0bd3098da987525b68812ba805970817 100644 (file)
@@ -74,24 +74,44 @@ pub struct BTreeSet<T> {
     map: BTreeMap<T, ()>,
 }
 
-/// An iterator over a BTreeSet's items.
+/// An iterator over a `BTreeSet`'s items.
+///
+/// This structure is created by the [`iter`] method on [`BTreeSet`].
+///
+/// [`BTreeSet`]: struct.BTreeSet.html
+/// [`iter`]: struct.BTreeSet.html#method.iter
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Iter<'a, T: 'a> {
     iter: Keys<'a, T, ()>,
 }
 
-/// An owning iterator over a BTreeSet's items.
+/// An owning iterator over a `BTreeSet`'s items.
+///
+/// This structure is created by the `into_iter` method on [`BTreeSet`]
+/// [`BTreeSet`] (provided by the `IntoIterator` trait).
+///
+/// [`BTreeSet`]: struct.BTreeSet.html
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct IntoIter<T> {
     iter: ::btree_map::IntoIter<T, ()>,
 }
 
-/// An iterator over a sub-range of BTreeSet's items.
+/// An iterator over a sub-range of `BTreeSet`'s items.
+///
+/// This structure is created by the [`range`] method on [`BTreeSet`].
+///
+/// [`BTreeSet`]: struct.BTreeSet.html
+/// [`range`]: struct.BTreeSet.html#method.range
 pub struct Range<'a, T: 'a> {
     iter: ::btree_map::Range<'a, T, ()>,
 }
 
 /// A lazy iterator producing elements in the set difference (in-order).
+///
+/// This structure is created by the [`difference`] method on [`BTreeSet`].
+///
+/// [`BTreeSet`]: struct.BTreeSet.html
+/// [`difference`]: struct.BTreeSet.html#method.difference
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Difference<'a, T: 'a> {
     a: Peekable<Iter<'a, T>>,
@@ -99,6 +119,12 @@ pub struct Difference<'a, T: 'a> {
 }
 
 /// A lazy iterator producing elements in the set symmetric difference (in-order).
+///
+/// This structure is created by the [`symmetric_difference`] method on
+/// [`BTreeSet`].
+///
+/// [`BTreeSet`]: struct.BTreeSet.html
+/// [`symmetric_difference`]: struct.BTreeSet.html#method.symmetric_difference
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct SymmetricDifference<'a, T: 'a> {
     a: Peekable<Iter<'a, T>>,
@@ -106,6 +132,11 @@ pub struct SymmetricDifference<'a, T: 'a> {
 }
 
 /// A lazy iterator producing elements in the set intersection (in-order).
+///
+/// This structure is created by the [`intersection`] method on [`BTreeSet`].
+///
+/// [`BTreeSet`]: struct.BTreeSet.html
+/// [`intersection`]: struct.BTreeSet.html#method.intersection
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Intersection<'a, T: 'a> {
     a: Peekable<Iter<'a, T>>,
@@ -113,6 +144,11 @@ pub struct Intersection<'a, T: 'a> {
 }
 
 /// A lazy iterator producing elements in the set union (in-order).
+///
+/// This structure is created by the [`union`] method on [`BTreeSet`].
+///
+/// [`BTreeSet`]: struct.BTreeSet.html
+/// [`union`]: struct.BTreeSet.html#method.union
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Union<'a, T: 'a> {
     a: Peekable<Iter<'a, T>>,
@@ -120,7 +156,7 @@ pub struct Union<'a, T: 'a> {
 }
 
 impl<T: Ord> BTreeSet<T> {
-    /// Makes a new BTreeSet with a reasonable choice of B.
+    /// Makes a new `BTreeSet` with a reasonable choice of B.
     ///
     /// # Examples
     ///
@@ -137,21 +173,32 @@ pub fn new() -> BTreeSet<T> {
 }
 
 impl<T> BTreeSet<T> {
-    /// Gets an iterator over the BTreeSet's contents.
+    /// Gets an iterator that visits the values in the `BTreeSet` in ascending order.
     ///
     /// # Examples
     ///
     /// ```
     /// use std::collections::BTreeSet;
     ///
-    /// let set: BTreeSet<usize> = [1, 2, 3, 4].iter().cloned().collect();
+    /// let set: BTreeSet<usize> = [1, 2, 3].iter().cloned().collect();
+    /// let mut set_iter = set.iter();
+    /// assert_eq!(set_iter.next(), Some(&1));
+    /// assert_eq!(set_iter.next(), Some(&2));
+    /// assert_eq!(set_iter.next(), Some(&3));
+    /// assert_eq!(set_iter.next(), None);
+    /// ```
     ///
-    /// for x in set.iter() {
-    ///     println!("{}", x);
-    /// }
+    /// Values returned by the iterator are returned in ascending order:
     ///
-    /// let v: Vec<_> = set.iter().cloned().collect();
-    /// assert_eq!(v, [1, 2, 3, 4]);
+    /// ```
+    /// use std::collections::BTreeSet;
+    ///
+    /// let set: BTreeSet<usize> = [3, 1, 2].iter().cloned().collect();
+    /// let mut set_iter = set.iter();
+    /// assert_eq!(set_iter.next(), Some(&1));
+    /// assert_eq!(set_iter.next(), Some(&2));
+    /// assert_eq!(set_iter.next(), Some(&3));
+    /// assert_eq!(set_iter.next(), None);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn iter(&self) -> Iter<T> {
index 5fb8cd6e1e2b7a7b8b10f8135240c4629915b838..b5e6669220535282c1694e44c79264c970e62540 100644 (file)
@@ -1496,10 +1496,10 @@ fn drop(&mut self) {
 /// The algorithm identifies strictly descending and non-descending subsequences, which are called
 /// natural runs. There is a stack of pending runs yet to be merged. Each newly found run is pushed
 /// onto the stack, and then some pairs of adjacent runs are merged until these two invariants are
-/// satisfied, for every `i` in `0 .. runs.len() - 2`:
+/// satisfied:
 ///
-/// 1. `runs[i].len > runs[i + 1].len`
-/// 2. `runs[i].len > runs[i + 1].len + runs[i + 2].len`
+/// 1. for every `i` in `1..runs.len()`: `runs[i - 1].len > runs[i].len`
+/// 2. for every `i` in `2..runs.len()`: `runs[i - 2].len > runs[i - 1].len + runs[i].len`
 ///
 /// The invariants ensure that the total running time is `O(n log n)` worst-case.
 fn merge_sort<T, F>(v: &mut [T], mut compare: F)
index afed99d265f1921cebedd29697934b6a6a5bf8fe..99c407e5273eae922249ca45ee325e9c8f2028cd 100644 (file)
@@ -501,6 +501,8 @@ pub fn map_err<F, O: FnOnce(E) -> F>(self, op: O) -> Result<T,F> {
 
     /// Returns an iterator over the possibly contained value.
     ///
+    /// The iterator yields one value if the result is [`Ok`], otherwise none.
+    ///
     /// # Examples
     ///
     /// Basic usage:
@@ -512,6 +514,8 @@ pub fn map_err<F, O: FnOnce(E) -> F>(self, op: O) -> Result<T,F> {
     /// let x: Result<u32, &str> = Err("nothing!");
     /// assert_eq!(x.iter().next(), None);
     /// ```
+    ///
+    /// [`Ok`]: enum.Result.html#variant.Ok
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn iter(&self) -> Iter<T> {
@@ -520,6 +524,8 @@ pub fn iter(&self) -> Iter<T> {
 
     /// Returns a mutable iterator over the possibly contained value.
     ///
+    /// The iterator yields one value if the result is [`Ok`], otherwise none.
+    ///
     /// # Examples
     ///
     /// Basic usage:
@@ -535,6 +541,8 @@ pub fn iter(&self) -> Iter<T> {
     /// let mut x: Result<u32, &str> = Err("nothing!");
     /// assert_eq!(x.iter_mut().next(), None);
     /// ```
+    ///
+    /// [`Ok`]: enum.Result.html#variant.Ok
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn iter_mut(&mut self) -> IterMut<T> {
@@ -848,6 +856,8 @@ impl<T, E> IntoIterator for Result<T, E> {
 
     /// Returns a consuming iterator over the possibly contained value.
     ///
+    /// The iterator yields one value if the result is [`Ok`], otherwise none.
+    ///
     /// # Examples
     ///
     /// Basic usage:
@@ -861,6 +871,8 @@ impl<T, E> IntoIterator for Result<T, E> {
     /// let v: Vec<u32> = x.into_iter().collect();
     /// assert_eq!(v, []);
     /// ```
+    ///
+    /// [`Ok`]: enum.Result.html#variant.Ok
     #[inline]
     fn into_iter(self) -> IntoIter<T> {
         IntoIter { inner: self.ok() }
@@ -893,8 +905,13 @@ fn into_iter(mut self) -> IterMut<'a, T> {
 
 /// An iterator over a reference to the [`Ok`] variant of a [`Result`].
 ///
+/// The iterator yields one value if the result is [`Ok`], otherwise none.
+///
+/// Created by [`Result::iter`].
+///
 /// [`Ok`]: enum.Result.html#variant.Ok
 /// [`Result`]: enum.Result.html
+/// [`Result::iter`]: enum.Result.html#method.iter
 #[derive(Debug)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Iter<'a, T: 'a> { inner: Option<&'a T> }
@@ -934,8 +951,11 @@ fn clone(&self) -> Iter<'a, T> { Iter { inner: self.inner } }
 
 /// An iterator over a mutable reference to the [`Ok`] variant of a [`Result`].
 ///
+/// Created by [`Result::iter_mut`].
+///
 /// [`Ok`]: enum.Result.html#variant.Ok
 /// [`Result`]: enum.Result.html
+/// [`Result::iter_mut`]: enum.Result.html#method.iter_mut
 #[derive(Debug)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct IterMut<'a, T: 'a> { inner: Option<&'a mut T> }
@@ -968,9 +988,12 @@ impl<'a, T> FusedIterator for IterMut<'a, T> {}
 #[unstable(feature = "trusted_len", issue = "37572")]
 unsafe impl<'a, A> TrustedLen for IterMut<'a, A> {}
 
-/// An iterator over the value in a [`Ok`] variant of a [`Result`]. This struct is
-/// created by the [`into_iter`] method on [`Result`][`Result`] (provided by
-/// the [`IntoIterator`] trait).
+/// An iterator over the value in a [`Ok`] variant of a [`Result`].
+///
+/// The iterator yields one value if the result is [`Ok`], otherwise none.
+///
+/// This struct is created by the [`into_iter`] method on
+/// [`Result`][`Result`] (provided by the [`IntoIterator`] trait).
 ///
 /// [`Ok`]: enum.Result.html#variant.Ok
 /// [`Result`]: enum.Result.html
index a4a90e7a9da7a3bc80df580ea4b86bf25d054e5d..e0a49e2ae45d0b895af72f3018d6276e00106125 100644 (file)
@@ -33,6 +33,7 @@
 // * The `raw` and `bytes` submodules.
 // * Boilerplate trait implementations.
 
+use borrow::Borrow;
 use cmp::Ordering::{self, Less, Equal, Greater};
 use cmp;
 use fmt;
@@ -100,15 +101,17 @@ unsafe fn get_unchecked<I>(&self, index: I) -> &I::Output
     #[stable(feature = "core", since = "1.6.0")]
     fn as_ptr(&self) -> *const Self::Item;
     #[stable(feature = "core", since = "1.6.0")]
-    fn binary_search(&self, x: &Self::Item) -> Result<usize, usize>
-        where Self::Item: Ord;
+    fn binary_search<Q: ?Sized>(&self, x: &Q) -> Result<usize, usize>
+        where Self::Item: Borrow<Q>,
+              Q: Ord;
     #[stable(feature = "core", since = "1.6.0")]
     fn binary_search_by<'a, F>(&'a self, f: F) -> Result<usize, usize>
         where F: FnMut(&'a Self::Item) -> Ordering;
     #[stable(feature = "slice_binary_search_by_key", since = "1.10.0")]
-    fn binary_search_by_key<'a, B, F>(&'a self, b: &B, f: F) -> Result<usize, usize>
+    fn binary_search_by_key<'a, B, F, Q: ?Sized>(&'a self, b: &Q, f: F) -> Result<usize, usize>
         where F: FnMut(&'a Self::Item) -> B,
-              B: Ord;
+              B: Borrow<Q>,
+              Q: Ord;
     #[stable(feature = "core", since = "1.6.0")]
     fn len(&self) -> usize;
     #[stable(feature = "core", since = "1.6.0")]
@@ -493,8 +496,8 @@ fn ends_with(&self, needle: &[T]) -> bool where T: PartialEq {
         m >= n && needle == &self[m-n..]
     }
 
-    fn binary_search(&self, x: &T) -> Result<usize, usize> where T: Ord {
-        self.binary_search_by(|p| p.cmp(x))
+    fn binary_search<Q: ?Sized>(&self, x: &Q) -> Result<usize, usize> where T: Borrow<Q>, Q: Ord {
+        self.binary_search_by(|p| p.borrow().cmp(x))
     }
 
     #[inline]
@@ -522,11 +525,12 @@ fn copy_from_slice(&mut self, src: &[T]) where T: Copy {
     }
 
     #[inline]
-    fn binary_search_by_key<'a, B, F>(&'a self, b: &B, mut f: F) -> Result<usize, usize>
+    fn binary_search_by_key<'a, B, F, Q: ?Sized>(&'a self, b: &Q, mut f: F) -> Result<usize, usize>
         where F: FnMut(&'a Self::Item) -> B,
-              B: Ord
+              B: Borrow<Q>,
+              Q: Ord
     {
-        self.binary_search_by(|k| f(k).cmp(b))
+        self.binary_search_by(|k| f(k).borrow().cmp(b))
     }
 }
 
index 48f5b7ea2595d70c37eef2066452456661c10d4e..d2b94db689bc45c63b3bd1de3049739c45736e6e 100644 (file)
@@ -418,7 +418,7 @@ to see something like:
 
     Hir(foo) -> Collect(bar)
     Collect(bar) -> TypeckItemBody(bar)
-    
+
 That first edge looks suspicious to you. So you set
 `RUST_FORBID_DEP_GRAPH_EDGE` to `Hir&foo -> Collect&bar`, re-run, and
 then observe the backtrace. Voila, bug fixed!
@@ -440,6 +440,4 @@ To achieve this, the HIR map will detect if the def-id originates in
 an inlined node and add a dependency to a suitable `MetaData` node
 instead. If you are reading a HIR node and are not sure if it may be
 inlined or not, you can use `tcx.map.read(node_id)` and it will detect
-whether the node is inlined or not and do the right thing.  You can
-also use `tcx.map.is_inlined_def_id()` and
-`tcx.map.is_inlined_node_id()` to test.
+whether the node is inlined or not and do the right thing.
index 600732fc6f70b3e602d570ef5c9fb80d374a089a..f6a22e47cf21278051fd3f11fc5ab474cab25303 100644 (file)
@@ -40,7 +40,6 @@ fn visit_item(&mut self, i: &'tcx hir::Item) {
             let task_id = (self.dep_node_fn)(item_def_id);
             let _task = self.tcx.dep_graph.in_task(task_id.clone());
             debug!("Started task {:?}", task_id);
-            assert!(!self.tcx.map.is_inlined_def_id(item_def_id));
             self.tcx.dep_graph.read(DepNode::Hir(item_def_id));
             self.visitor.visit_item(i);
             debug!("Ended task {:?}", task_id);
@@ -51,7 +50,6 @@ fn visit_impl_item(&mut self, i: &'tcx hir::ImplItem) {
             let task_id = (self.dep_node_fn)(impl_item_def_id);
             let _task = self.tcx.dep_graph.in_task(task_id.clone());
             debug!("Started task {:?}", task_id);
-            assert!(!self.tcx.map.is_inlined_def_id(impl_item_def_id));
             self.tcx.dep_graph.read(DepNode::Hir(impl_item_def_id));
             self.visitor.visit_impl_item(i);
             debug!("Ended task {:?}", task_id);
index ec09877ae121cdfeba73bc638f2ecf3492afee51..1655c716b6bfa59dac2c36c52420a055b115e29d 100644 (file)
@@ -1236,6 +1236,23 @@ struct Foo<'a, T: 'a> {
     foo: &'a T
 }
 ```
+
+To see why this is important, consider the case where `T` is itself a reference
+(e.g., `T = &str`). If we don't include the restriction that `T: 'a`, the
+following code would be perfectly legal:
+
+```compile_fail,E0309
+struct Foo<'a, T> {
+    foo: &'a T
+}
+
+fn main() {
+    let v = "42".to_string();
+    let f = Foo{foo: &v};
+    drop(v);
+    println!("{}", f.foo); // but we've already dropped v!
+}
+```
 "##,
 
 E0310: r##"
index d3771b1755b1659d5b36c61d908a50981a4ba444..cbf162cc1366ef0401a061f1a7506c39ecea898c 100644 (file)
@@ -120,9 +120,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 
         ty::tls::with_opt(|opt_tcx| {
             if let Some(tcx) = opt_tcx {
-                if let Some(def_path) = tcx.opt_def_path(*self) {
-                    write!(f, " => {}", def_path.to_string(tcx))?;
-                }
+                write!(f, " => {}", tcx.def_path(*self).to_string(tcx))?;
             }
             Ok(())
         })?;
index 625bde2ca8b67c52dd99ea0be8df8cb602017336..186d6f626509fd0b0daf5f37ddeefa42d516ab1a 100644 (file)
@@ -365,7 +365,6 @@ pub fn walk_crate<'v, V: Visitor<'v>>(visitor: &mut V, krate: &'v Crate) {
 pub fn walk_macro_def<'v, V: Visitor<'v>>(visitor: &mut V, macro_def: &'v MacroDef) {
     visitor.visit_id(macro_def.id);
     visitor.visit_name(macro_def.span, macro_def.name);
-    walk_opt_name(visitor, macro_def.span, macro_def.imported_from);
     walk_list!(visitor, visit_attribute, &macro_def.attrs);
 }
 
index 74876eb59ee9a12eac05a524cff6393fc00ef507..e8c3492705a3f95da1e4886b661479e9748a27c6 100644 (file)
@@ -433,13 +433,19 @@ fn lower_path_segment(&mut self,
                           segment: &PathSegment,
                           param_mode: ParamMode)
                           -> hir::PathSegment {
-        let parameters = match segment.parameters {
-            PathParameters::AngleBracketed(ref data) => {
-                let data = self.lower_angle_bracketed_parameter_data(data, param_mode);
-                hir::AngleBracketedParameters(data)
+        let parameters = if let Some(ref parameters) = segment.parameters {
+            match **parameters {
+                PathParameters::AngleBracketed(ref data) => {
+                    let data = self.lower_angle_bracketed_parameter_data(data, param_mode);
+                    hir::AngleBracketedParameters(data)
+                }
+                PathParameters::Parenthesized(ref data) => {
+                    hir::ParenthesizedParameters(self.lower_parenthesized_parameter_data(data))
+                }
             }
-            PathParameters::Parenthesized(ref data) =>
-                hir::ParenthesizedParameters(self.lower_parenthesized_parameter_data(data)),
+        } else {
+            let data = self.lower_angle_bracketed_parameter_data(&Default::default(), param_mode);
+            hir::AngleBracketedParameters(data)
         };
 
         hir::PathSegment {
@@ -987,8 +993,6 @@ fn lower_macro_def(&mut self, m: &MacroDef) -> hir::MacroDef {
             attrs: self.lower_attrs(&m.attrs),
             id: m.id,
             span: m.span,
-            imported_from: m.imported_from.map(|x| x.name),
-            allow_internal_unstable: m.allow_internal_unstable,
             body: m.body.clone().into(),
         }
     }
index c46c8f044e0ffc3863feb0bfb7bd85b5fac414dd..45988886a608a30ff7ede1d35d39ca5096d63270 100644 (file)
@@ -11,7 +11,6 @@
 use super::*;
 
 use hir::intravisit::{Visitor, NestedVisitorMap};
-use hir::def_id::DefId;
 use middle::cstore::InlinedItem;
 use std::iter::repeat;
 use syntax::ast::{NodeId, CRATE_NODE_ID};
@@ -47,8 +46,6 @@ pub fn root(krate: &'ast Crate) -> NodeCollector<'ast> {
     pub fn extend(krate: &'ast Crate,
                   parent: &'ast InlinedItem,
                   parent_node: NodeId,
-                  parent_def_path: DefPath,
-                  parent_def_id: DefId,
                   map: Vec<MapEntry<'ast>>)
                   -> NodeCollector<'ast> {
         let mut collector = NodeCollector {
@@ -58,7 +55,6 @@ pub fn extend(krate: &'ast Crate,
             ignore_nested_items: true
         };
 
-        assert_eq!(parent_def_path.krate, parent_def_id.krate);
         collector.insert_entry(parent_node, RootInlinedParent(parent));
 
         collector
index eb5a89f320e7b3d325e9741e5e4802766dd4e599..256aee342a3fc448f83637f02a78d7401df22c3f 100644 (file)
@@ -9,12 +9,7 @@
 // except according to those terms.
 
 use hir::map::definitions::*;
-
-use hir;
-use hir::intravisit::{self, Visitor, NestedVisitorMap};
-use hir::def_id::{CRATE_DEF_INDEX, DefId, DefIndex};
-
-use middle::cstore::InlinedItem;
+use hir::def_id::{CRATE_DEF_INDEX, DefIndex};
 
 use syntax::ast::*;
 use syntax::ext::hygiene::Mark;
@@ -23,9 +18,6 @@
 
 /// Creates def ids for nodes in the HIR.
 pub struct DefCollector<'a> {
-    // If we are walking HIR (c.f., AST), we need to keep a reference to the
-    // crate.
-    hir_crate: Option<&'a hir::Crate>,
     definitions: &'a mut Definitions,
     parent_def: Option<DefIndex>,
     pub visit_macro_invoc: Option<&'a mut FnMut(MacroInvocationData)>,
@@ -40,43 +32,16 @@ pub struct MacroInvocationData {
 impl<'a> DefCollector<'a> {
     pub fn new(definitions: &'a mut Definitions) -> Self {
         DefCollector {
-            hir_crate: None,
             definitions: definitions,
             parent_def: None,
             visit_macro_invoc: None,
         }
     }
 
-    pub fn extend(parent_node: NodeId,
-                  parent_def_path: DefPath,
-                  parent_def_id: DefId,
-                  definitions: &'a mut Definitions)
-                  -> Self {
-        let mut collector = DefCollector::new(definitions);
-
-        assert_eq!(parent_def_path.krate, parent_def_id.krate);
-        let root_path = Box::new(InlinedRootPath {
-            data: parent_def_path.data,
-            def_id: parent_def_id,
-        });
-
-        let def = collector.create_def(parent_node, DefPathData::InlinedRoot(root_path));
-        collector.parent_def = Some(def);
-
-        collector
-    }
-
     pub fn collect_root(&mut self) {
         let root = self.create_def_with_parent(None, CRATE_NODE_ID, DefPathData::CrateRoot);
         assert_eq!(root, CRATE_DEF_INDEX);
         self.parent_def = Some(root);
-
-        self.create_def_with_parent(Some(CRATE_DEF_INDEX), DUMMY_NODE_ID, DefPathData::Misc);
-    }
-
-    pub fn walk_item(&mut self, ii: &'a InlinedItem, krate: &'a hir::Crate) {
-        self.hir_crate = Some(krate);
-        ii.visit(self);
     }
 
     fn create_def(&mut self, node_id: NodeId, data: DefPathData) -> DefIndex {
@@ -114,16 +79,6 @@ pub fn visit_ast_const_integer(&mut self, expr: &Expr) {
         self.create_def(expr.id, DefPathData::Initializer);
     }
 
-    fn visit_hir_const_integer(&mut self, expr: &hir::Expr) {
-        // FIXME(eddyb) Closures should have separate
-        // function definition IDs and expression IDs.
-        if let hir::ExprClosure(..) = expr.node {
-            return;
-        }
-
-        self.create_def(expr.id, DefPathData::Initializer);
-    }
-
     fn visit_macro_invoc(&mut self, id: NodeId, const_integer: bool) {
         if let Some(ref mut visit) = self.visit_macro_invoc {
             visit(MacroInvocationData {
@@ -324,169 +279,3 @@ fn visit_stmt(&mut self, stmt: &'a Stmt) {
         }
     }
 }
-
-// We walk the HIR rather than the AST when reading items from metadata.
-impl<'ast> Visitor<'ast> for DefCollector<'ast> {
-    fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'ast> {
-        // note however that we override `visit_body` below
-        NestedVisitorMap::None
-    }
-
-    fn visit_body(&mut self, id: hir::ExprId) {
-        if let Some(krate) = self.hir_crate {
-            self.visit_expr(krate.expr(id));
-        }
-    }
-
-    fn visit_item(&mut self, i: &'ast hir::Item) {
-        debug!("visit_item: {:?}", i);
-
-        // Pick the def data. This need not be unique, but the more
-        // information we encapsulate into
-        let def_data = match i.node {
-            hir::ItemDefaultImpl(..) | hir::ItemImpl(..) =>
-                DefPathData::Impl,
-            hir::ItemEnum(..) | hir::ItemStruct(..) | hir::ItemUnion(..) |
-            hir::ItemTrait(..) | hir::ItemExternCrate(..) | hir::ItemMod(..) |
-            hir::ItemForeignMod(..) | hir::ItemTy(..) =>
-                DefPathData::TypeNs(i.name.as_str()),
-            hir::ItemStatic(..) | hir::ItemConst(..) | hir::ItemFn(..) =>
-                DefPathData::ValueNs(i.name.as_str()),
-            hir::ItemUse(..) => DefPathData::Misc,
-        };
-        let def = self.create_def(i.id, def_data);
-
-        self.with_parent(def, |this| {
-            match i.node {
-                hir::ItemEnum(ref enum_definition, _) => {
-                    for v in &enum_definition.variants {
-                        let variant_def_index =
-                            this.create_def(v.node.data.id(),
-                                            DefPathData::EnumVariant(v.node.name.as_str()));
-
-                        this.with_parent(variant_def_index, |this| {
-                            for field in v.node.data.fields() {
-                                this.create_def(field.id,
-                                                DefPathData::Field(field.name.as_str()));
-                            }
-                            if let Some(ref expr) = v.node.disr_expr {
-                                this.visit_hir_const_integer(expr);
-                            }
-                        });
-                    }
-                }
-                hir::ItemStruct(ref struct_def, _) |
-                hir::ItemUnion(ref struct_def, _) => {
-                    // If this is a tuple-like struct, register the constructor.
-                    if !struct_def.is_struct() {
-                        this.create_def(struct_def.id(),
-                                        DefPathData::StructCtor);
-                    }
-
-                    for field in struct_def.fields() {
-                        this.create_def(field.id, DefPathData::Field(field.name.as_str()));
-                    }
-                }
-                _ => {}
-            }
-            intravisit::walk_item(this, i);
-        });
-    }
-
-    fn visit_foreign_item(&mut self, foreign_item: &'ast hir::ForeignItem) {
-        let def = self.create_def(foreign_item.id,
-                                  DefPathData::ValueNs(foreign_item.name.as_str()));
-
-        self.with_parent(def, |this| {
-            intravisit::walk_foreign_item(this, foreign_item);
-        });
-    }
-
-    fn visit_generics(&mut self, generics: &'ast hir::Generics) {
-        for ty_param in generics.ty_params.iter() {
-            self.create_def(ty_param.id, DefPathData::TypeParam(ty_param.name.as_str()));
-        }
-
-        intravisit::walk_generics(self, generics);
-    }
-
-    fn visit_trait_item(&mut self, ti: &'ast hir::TraitItem) {
-        let def_data = match ti.node {
-            hir::MethodTraitItem(..) | hir::ConstTraitItem(..) =>
-                DefPathData::ValueNs(ti.name.as_str()),
-            hir::TypeTraitItem(..) => DefPathData::TypeNs(ti.name.as_str()),
-        };
-
-        let def = self.create_def(ti.id, def_data);
-        self.with_parent(def, |this| {
-            if let hir::ConstTraitItem(_, Some(ref expr)) = ti.node {
-                this.create_def(expr.id, DefPathData::Initializer);
-            }
-
-            intravisit::walk_trait_item(this, ti);
-        });
-    }
-
-    fn visit_impl_item(&mut self, ii: &'ast hir::ImplItem) {
-        let def_data = match ii.node {
-            hir::ImplItemKind::Method(..) | hir::ImplItemKind::Const(..) =>
-                DefPathData::ValueNs(ii.name.as_str()),
-            hir::ImplItemKind::Type(..) => DefPathData::TypeNs(ii.name.as_str()),
-        };
-
-        let def = self.create_def(ii.id, def_data);
-        self.with_parent(def, |this| {
-            if let hir::ImplItemKind::Const(_, ref expr) = ii.node {
-                this.create_def(expr.id, DefPathData::Initializer);
-            }
-
-            intravisit::walk_impl_item(this, ii);
-        });
-    }
-
-    fn visit_pat(&mut self, pat: &'ast hir::Pat) {
-        let parent_def = self.parent_def;
-
-        if let hir::PatKind::Binding(_, _, name, _) = pat.node {
-            let def = self.create_def(pat.id, DefPathData::Binding(name.node.as_str()));
-            self.parent_def = Some(def);
-        }
-
-        intravisit::walk_pat(self, pat);
-        self.parent_def = parent_def;
-    }
-
-    fn visit_expr(&mut self, expr: &'ast hir::Expr) {
-        let parent_def = self.parent_def;
-
-        if let hir::ExprRepeat(_, ref count) = expr.node {
-            self.visit_hir_const_integer(count);
-        }
-
-        if let hir::ExprClosure(..) = expr.node {
-            let def = self.create_def(expr.id, DefPathData::ClosureExpr);
-            self.parent_def = Some(def);
-        }
-
-        intravisit::walk_expr(self, expr);
-        self.parent_def = parent_def;
-    }
-
-    fn visit_ty(&mut self, ty: &'ast hir::Ty) {
-        if let hir::TyArray(_, ref length) = ty.node {
-            self.visit_hir_const_integer(length);
-        }
-        if let hir::TyImplTrait(..) = ty.node {
-            self.create_def(ty.id, DefPathData::ImplTrait);
-        }
-        intravisit::walk_ty(self, ty);
-    }
-
-    fn visit_lifetime_def(&mut self, def: &'ast hir::LifetimeDef) {
-        self.create_def(def.lifetime.id, DefPathData::LifetimeDef(def.lifetime.name.as_str()));
-    }
-
-    fn visit_macro_def(&mut self, macro_def: &'ast hir::MacroDef) {
-        self.create_def(macro_def.id, DefPathData::MacroDef(macro_def.name.as_str()));
-    }
-}
index a684563512da652a726785817238d02efda070c5..4f64670f482796bde55b37dda9a0d31df0bf0817 100644 (file)
@@ -8,9 +8,16 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+//! For each definition, we track the following data.  A definition
+//! here is defined somewhat circularly as "something with a def-id",
+//! but it generally corresponds to things like structs, enums, etc.
+//! There are also some rather random cases (like const initializer
+//! expressions) that are mostly just leftovers.
+
 use hir::def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::stable_hasher::StableHasher;
+use serialize::{Encodable, Decodable, Encoder, Decoder};
 use std::fmt::Write;
 use std::hash::{Hash, Hasher};
 use syntax::ast;
 use ty::TyCtxt;
 use util::nodemap::NodeMap;
 
-/// The definition table containing node definitions
+/// The DefPathTable maps DefIndexes to DefKeys and vice versa.
+/// Internally the DefPathTable holds a tree of DefKeys, where each DefKey
+/// stores the DefIndex of its parent.
+/// There is one DefPathTable for each crate.
+#[derive(Clone)]
+pub struct DefPathTable {
+    index_to_key: Vec<DefKey>,
+    key_to_index: FxHashMap<DefKey, DefIndex>,
+}
+
+impl DefPathTable {
+    fn insert(&mut self, key: DefKey) -> DefIndex {
+        let index = DefIndex::new(self.index_to_key.len());
+        debug!("DefPathTable::insert() - {:?} <-> {:?}", key, index);
+        self.index_to_key.push(key.clone());
+        self.key_to_index.insert(key, index);
+        index
+    }
+
+    #[inline(always)]
+    pub fn def_key(&self, index: DefIndex) -> DefKey {
+        self.index_to_key[index.as_usize()].clone()
+    }
+
+    #[inline(always)]
+    pub fn def_index_for_def_key(&self, key: &DefKey) -> Option<DefIndex> {
+        self.key_to_index.get(key).cloned()
+    }
+
+    #[inline(always)]
+    pub fn contains_key(&self, key: &DefKey) -> bool {
+        self.key_to_index.contains_key(key)
+    }
+
+    pub fn retrace_path(&self,
+                        path_data: &[DisambiguatedDefPathData])
+                        -> Option<DefIndex> {
+        let root_key = DefKey {
+            parent: None,
+            disambiguated_data: DisambiguatedDefPathData {
+                data: DefPathData::CrateRoot,
+                disambiguator: 0,
+            },
+        };
+
+        let root_index = self.key_to_index
+                             .get(&root_key)
+                             .expect("no root key?")
+                             .clone();
+
+        debug!("retrace_path: root_index={:?}", root_index);
+
+        let mut index = root_index;
+        for data in path_data {
+            let key = DefKey { parent: Some(index), disambiguated_data: data.clone() };
+            debug!("retrace_path: key={:?}", key);
+            match self.key_to_index.get(&key) {
+                Some(&i) => index = i,
+                None => return None,
+            }
+        }
+
+        Some(index)
+    }
+}
+
+
+impl Encodable for DefPathTable {
+    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
+        self.index_to_key.encode(s)
+    }
+}
+
+impl Decodable for DefPathTable {
+    fn decode<D: Decoder>(d: &mut D) -> Result<DefPathTable, D::Error> {
+        let index_to_key: Vec<DefKey> = Decodable::decode(d)?;
+        let key_to_index = index_to_key.iter()
+                                       .enumerate()
+                                       .map(|(index, key)| (key.clone(), DefIndex::new(index)))
+                                       .collect();
+        Ok(DefPathTable {
+            index_to_key: index_to_key,
+            key_to_index: key_to_index,
+        })
+    }
+}
+
+
+/// The definition table containing node definitions.
+/// It holds the DefPathTable for local DefIds/DefPaths and it also stores a
+/// mapping from NodeIds to local DefIds.
 #[derive(Clone)]
 pub struct Definitions {
-    data: Vec<DefData>,
-    key_map: FxHashMap<DefKey, DefIndex>,
-    node_map: NodeMap<DefIndex>,
+    table: DefPathTable,
+    node_to_def_index: NodeMap<DefIndex>,
+    def_index_to_node: Vec<ast::NodeId>,
 }
 
 /// A unique identifier that we can use to lookup a definition
@@ -50,19 +147,6 @@ pub struct DisambiguatedDefPathData {
     pub disambiguator: u32
 }
 
-/// For each definition, we track the following data.  A definition
-/// here is defined somewhat circularly as "something with a def-id",
-/// but it generally corresponds to things like structs, enums, etc.
-/// There are also some rather random cases (like const initializer
-/// expressions) that are mostly just leftovers.
-#[derive(Clone, Debug)]
-pub struct DefData {
-    pub key: DefKey,
-
-    /// Local ID within the HIR.
-    pub node_id: ast::NodeId,
-}
-
 #[derive(Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
 pub struct DefPath {
     /// the path leading from the crate root to the item
@@ -77,12 +161,11 @@ pub fn is_local(&self) -> bool {
         self.krate == LOCAL_CRATE
     }
 
-    pub fn make<FN>(start_krate: CrateNum,
+    pub fn make<FN>(krate: CrateNum,
                     start_index: DefIndex,
                     mut get_key: FN) -> DefPath
         where FN: FnMut(DefIndex) -> DefKey
     {
-        let mut krate = start_krate;
         let mut data = vec![];
         let mut index = Some(start_index);
         loop {
@@ -95,13 +178,6 @@ pub fn make<FN>(start_krate: CrateNum,
                     assert!(key.parent.is_none());
                     break;
                 }
-                DefPathData::InlinedRoot(ref p) => {
-                    assert!(key.parent.is_none());
-                    assert!(!p.def_id.is_local());
-                    data.extend(p.data.iter().cloned().rev());
-                    krate = p.def_id.krate;
-                    break;
-                }
                 _ => {
                     data.push(key.disambiguated_data);
                     index = key.parent;
@@ -144,31 +220,6 @@ pub fn deterministic_hash_to<H: Hasher>(&self, tcx: TyCtxt, state: &mut H) {
     }
 }
 
-/// Root of an inlined item. We track the `DefPath` of the item within
-/// the original crate but also its def-id. This is kind of an
-/// augmented version of a `DefPath` that includes a `DefId`. This is
-/// all sort of ugly but the hope is that inlined items will be going
-/// away soon anyway.
-///
-/// Some of the constraints that led to the current approach:
-///
-/// - I don't want to have a `DefId` in the main `DefPath` because
-///   that gets serialized for incr. comp., and when reloaded the
-///   `DefId` is no longer valid. I'd rather maintain the invariant
-///   that every `DefId` is valid, and a potentially outdated `DefId` is
-///   represented as a `DefPath`.
-///   - (We don't serialize def-paths from inlined items, so it's ok to have one here.)
-/// - We need to be able to extract the def-id from inline items to
-///   make the symbol name. In theory we could retrace it from the
-///   data, but the metadata doesn't have the required indices, and I
-///   don't want to write the code to create one just for this.
-/// - It may be that we don't actually need `data` at all. We'll have
-///   to see about that.
-#[derive(Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
-pub struct InlinedRootPath {
-    pub data: Vec<DisambiguatedDefPathData>,
-    pub def_id: DefId,
-}
 
 #[derive(Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
 pub enum DefPathData {
@@ -176,8 +227,6 @@ pub enum DefPathData {
     // they are treated specially by the `def_path` function.
     /// The crate root (marker)
     CrateRoot,
-    /// An inlined root
-    InlinedRoot(Box<InlinedRootPath>),
 
     // Catch-all for random DefId things like DUMMY_NODE_ID
     Misc,
@@ -219,23 +268,30 @@ impl Definitions {
     /// Create new empty definition map.
     pub fn new() -> Definitions {
         Definitions {
-            data: vec![],
-            key_map: FxHashMap(),
-            node_map: NodeMap(),
+            table: DefPathTable {
+                index_to_key: vec![],
+                key_to_index: FxHashMap(),
+            },
+            node_to_def_index: NodeMap(),
+            def_index_to_node: vec![],
         }
     }
 
+    pub fn def_path_table(&self) -> &DefPathTable {
+        &self.table
+    }
+
     /// Get the number of definitions.
     pub fn len(&self) -> usize {
-        self.data.len()
+        self.def_index_to_node.len()
     }
 
     pub fn def_key(&self, index: DefIndex) -> DefKey {
-        self.data[index.as_usize()].key.clone()
+        self.table.def_key(index)
     }
 
     pub fn def_index_for_def_key(&self, key: DefKey) -> Option<DefIndex> {
-        self.key_map.get(&key).cloned()
+        self.table.def_index_for_def_key(&key)
     }
 
     /// Returns the path from the crate root to `index`. The root
@@ -248,7 +304,7 @@ pub fn def_path(&self, index: DefIndex) -> DefPath {
     }
 
     pub fn opt_def_index(&self, node: ast::NodeId) -> Option<DefIndex> {
-        self.node_map.get(&node).cloned()
+        self.node_to_def_index.get(&node).cloned()
     }
 
     pub fn opt_local_def_id(&self, node: ast::NodeId) -> Option<DefId> {
@@ -261,8 +317,8 @@ pub fn local_def_id(&self, node: ast::NodeId) -> DefId {
 
     pub fn as_local_node_id(&self, def_id: DefId) -> Option<ast::NodeId> {
         if def_id.krate == LOCAL_CRATE {
-            assert!(def_id.index.as_usize() < self.data.len());
-            Some(self.data[def_id.index.as_usize()].node_id)
+            assert!(def_id.index.as_usize() < self.def_index_to_node.len());
+            Some(self.def_index_to_node[def_id.index.as_usize()])
         } else {
             None
         }
@@ -277,16 +333,13 @@ pub fn create_def_with_parent(&mut self,
         debug!("create_def_with_parent(parent={:?}, node_id={:?}, data={:?})",
                parent, node_id, data);
 
-        assert!(!self.node_map.contains_key(&node_id),
+        assert!(!self.node_to_def_index.contains_key(&node_id),
                 "adding a def'n for node-id {:?} and data {:?} but a previous def'n exists: {:?}",
                 node_id,
                 data,
-                self.data[self.node_map[&node_id].as_usize()]);
+                self.table.def_key(self.node_to_def_index[&node_id]));
 
-        assert!(parent.is_some() ^ match data {
-            DefPathData::CrateRoot | DefPathData::InlinedRoot(_) => true,
-            _ => false,
-        });
+        assert!(parent.is_some() ^ (data == DefPathData::CrateRoot));
 
         // Find a unique DefKey. This basically means incrementing the disambiguator
         // until we get no match.
@@ -298,20 +351,18 @@ pub fn create_def_with_parent(&mut self,
             }
         };
 
-        while self.key_map.contains_key(&key) {
+        while self.table.contains_key(&key) {
             key.disambiguated_data.disambiguator += 1;
         }
 
         debug!("create_def_with_parent: after disambiguation, key = {:?}", key);
 
         // Create the definition.
-        let index = DefIndex::new(self.data.len());
-        self.data.push(DefData { key: key.clone(), node_id: node_id });
-        debug!("create_def_with_parent: node_map[{:?}] = {:?}", node_id, index);
-        self.node_map.insert(node_id, index);
-        debug!("create_def_with_parent: key_map[{:?}] = {:?}", key, index);
-        self.key_map.insert(key, index);
-
+        let index = self.table.insert(key);
+        debug!("create_def_with_parent: def_index_to_node[{:?} <-> {:?}", index, node_id);
+        self.node_to_def_index.insert(node_id, index);
+        assert_eq!(index.as_usize(), self.def_index_to_node.len());
+        self.def_index_to_node.push(node_id);
 
         index
     }
@@ -333,7 +384,6 @@ pub fn get_opt_name(&self) -> Option<ast::Name> {
 
             Impl |
             CrateRoot |
-            InlinedRoot(_) |
             Misc |
             ClosureExpr |
             StructCtor |
@@ -360,9 +410,6 @@ pub fn as_interned_str(&self) -> InternedString {
             // note that this does not show up in user printouts
             CrateRoot => "{{root}}",
 
-            // note that this does not show up in user printouts
-            InlinedRoot(_) => "{{inlined-root}}",
-
             Impl => "{{impl}}",
             Misc => "{{?}}",
             ClosureExpr => "{{closure}}",
index 117edcf14a1d169a5e718eb70cfc91a2e60ee79d..4546f6d8c27e6b64674c9fd166d8498de791c3db 100644 (file)
@@ -13,7 +13,7 @@
 use self::collector::NodeCollector;
 pub use self::def_collector::{DefCollector, MacroInvocationData};
 pub use self::definitions::{Definitions, DefKey, DefPath, DefPathData,
-                            DisambiguatedDefPathData, InlinedRootPath};
+                            DisambiguatedDefPathData};
 
 use dep_graph::{DepGraph, DepNode};
 
@@ -221,22 +221,14 @@ pub struct Map<'ast> {
     /// plain old integers.
     map: RefCell<Vec<MapEntry<'ast>>>,
 
-    definitions: RefCell<Definitions>,
+    definitions: Definitions,
 
     /// All NodeIds that are numerically greater or equal to this value come
     /// from inlined items.
     local_node_id_watermark: NodeId,
-
-    /// All def-indices that are numerically greater or equal to this value come
-    /// from inlined items.
-    local_def_id_watermark: usize,
 }
 
 impl<'ast> Map<'ast> {
-    pub fn is_inlined_def_id(&self, id: DefId) -> bool {
-        id.is_local() && id.index.as_usize() >= self.local_def_id_watermark
-    }
-
     pub fn is_inlined_node_id(&self, id: NodeId) -> bool {
         id >= self.local_node_id_watermark
     }
@@ -262,7 +254,6 @@ fn dep_node(&self, id0: NodeId) -> DepNode<DefId> {
                     EntryItem(_, item) => {
                         assert_eq!(id, item.id);
                         let def_id = self.local_def_id(id);
-                        assert!(!self.is_inlined_def_id(def_id));
 
                         if let Some(last_id) = last_expr {
                             // The body of the item may have a separate dep node
@@ -278,7 +269,6 @@ fn dep_node(&self, id0: NodeId) -> DepNode<DefId> {
 
                     EntryImplItem(_, item) => {
                         let def_id = self.local_def_id(id);
-                        assert!(!self.is_inlined_def_id(def_id));
 
                         if let Some(last_id) = last_expr {
                             // The body of the item may have a separate dep node
@@ -392,12 +382,16 @@ fn is_impl_item_body(&self, node_id: NodeId, item: &ImplItem) -> bool {
     }
 
     pub fn num_local_def_ids(&self) -> usize {
-        self.definitions.borrow().len()
+        self.definitions.len()
+    }
+
+    pub fn definitions(&self) -> &Definitions {
+        &self.definitions
     }
 
     pub fn def_key(&self, def_id: DefId) -> DefKey {
         assert!(def_id.is_local());
-        self.definitions.borrow().def_key(def_id.index)
+        self.definitions.def_key(def_id.index)
     }
 
     pub fn def_path_from_id(&self, id: NodeId) -> Option<DefPath> {
@@ -408,11 +402,11 @@ pub fn def_path_from_id(&self, id: NodeId) -> Option<DefPath> {
 
     pub fn def_path(&self, def_id: DefId) -> DefPath {
         assert!(def_id.is_local());
-        self.definitions.borrow().def_path(def_id.index)
+        self.definitions.def_path(def_id.index)
     }
 
     pub fn def_index_for_def_key(&self, def_key: DefKey) -> Option<DefIndex> {
-        self.definitions.borrow().def_index_for_def_key(def_key)
+        self.definitions.def_index_for_def_key(def_key)
     }
 
     pub fn local_def_id(&self, node: NodeId) -> DefId {
@@ -423,11 +417,11 @@ pub fn local_def_id(&self, node: NodeId) -> DefId {
     }
 
     pub fn opt_local_def_id(&self, node: NodeId) -> Option<DefId> {
-        self.definitions.borrow().opt_local_def_id(node)
+        self.definitions.opt_local_def_id(node)
     }
 
     pub fn as_local_node_id(&self, def_id: DefId) -> Option<NodeId> {
-        self.definitions.borrow().as_local_node_id(def_id)
+        self.definitions.as_local_node_id(def_id)
     }
 
     fn entry_count(&self) -> usize {
@@ -930,23 +924,19 @@ pub fn map_crate<'ast>(forest: &'ast mut Forest,
     }
 
     let local_node_id_watermark = NodeId::new(map.len());
-    let local_def_id_watermark = definitions.len();
 
     Map {
         forest: forest,
         dep_graph: forest.dep_graph.clone(),
         map: RefCell::new(map),
-        definitions: RefCell::new(definitions),
+        definitions: definitions,
         local_node_id_watermark: local_node_id_watermark,
-        local_def_id_watermark: local_def_id_watermark,
     }
 }
 
 /// Used for items loaded from external crate that are being inlined into this
 /// crate.
 pub fn map_decoded_item<'ast>(map: &Map<'ast>,
-                              parent_def_path: DefPath,
-                              parent_def_id: DefId,
                               ii: InlinedItem,
                               ii_parent_id: NodeId)
                               -> &'ast InlinedItem {
@@ -954,18 +944,9 @@ pub fn map_decoded_item<'ast>(map: &Map<'ast>,
 
     let ii = map.forest.inlined_items.alloc(ii);
 
-    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());
-
     let mut collector = NodeCollector::extend(map.krate(),
                                               ii,
                                               ii_parent_id,
-                                              parent_def_path,
-                                              parent_def_id,
                                               mem::replace(&mut *map.map.borrow_mut(), vec![]));
     ii.visit(&mut collector);
     *map.map.borrow_mut() = collector.map;
index 4fd8f96ba046a7a74526317c37d12a2bd09a69f6..f52ee35e1757306ae0605e1dd774db9d770398b4 100644 (file)
@@ -475,8 +475,6 @@ pub struct MacroDef {
     pub attrs: HirVec<Attribute>,
     pub id: NodeId,
     pub span: Span,
-    pub imported_from: Option<Name>,
-    pub allow_internal_unstable: bool,
     pub body: HirVec<TokenTree>,
 }
 
index f2be97c832370b2e5d5be2c0510d6ee9b9326dc2..9f9c6fd87aa856f590c83daa3d5c46a0198be2e9 100644 (file)
@@ -25,7 +25,7 @@
 use hir::def::{self, Def};
 use hir::def_id::{CrateNum, DefId, DefIndex};
 use hir::map as hir_map;
-use hir::map::definitions::{Definitions, DefKey};
+use hir::map::definitions::{Definitions, DefKey, DisambiguatedDefPathData};
 use hir::svh::Svh;
 use middle::lang_items;
 use ty::{self, Ty, TyCtxt};
@@ -336,12 +336,12 @@ fn dylib_dependency_formats(&self, cnum: CrateNum)
     fn is_no_builtins(&self, cnum: CrateNum) -> bool;
 
     // resolve
-    fn def_index_for_def_key(&self,
-                             cnum: CrateNum,
-                             def: DefKey)
-                             -> Option<DefIndex>;
-    fn def_key(&self, def: DefId) -> hir_map::DefKey;
-    fn relative_def_path(&self, def: DefId) -> Option<hir_map::DefPath>;
+    fn retrace_path(&self,
+                    cnum: CrateNum,
+                    path_data: &[DisambiguatedDefPathData])
+                    -> Option<DefId>;
+    fn def_key(&self, def: DefId) -> DefKey;
+    fn def_path(&self, def: DefId) -> hir_map::DefPath;
     fn struct_field_names(&self, def: DefId) -> Vec<ast::Name>;
     fn item_children(&self, did: DefId) -> Vec<def::Export>;
     fn load_macro(&self, did: DefId, sess: &Session) -> LoadedMacro;
@@ -442,12 +442,6 @@ fn inherent_implementations_for_type(&self, def_id: DefId) -> Vec<DefId> { vec![
 
     // trait info
     fn implementations_of_trait(&self, filter: Option<DefId>) -> Vec<DefId> { vec![] }
-    fn def_index_for_def_key(&self,
-                             cnum: CrateNum,
-                             def: DefKey)
-                             -> Option<DefIndex> {
-        None
-    }
 
     // impl info
     fn associated_item_def_ids(&self, def_id: DefId) -> Vec<DefId>
@@ -508,8 +502,15 @@ fn exported_symbols(&self, cnum: CrateNum) -> Vec<DefId> { bug!("exported_symbol
     fn is_no_builtins(&self, cnum: CrateNum) -> bool { bug!("is_no_builtins") }
 
     // resolve
-    fn def_key(&self, def: DefId) -> hir_map::DefKey { bug!("def_key") }
-    fn relative_def_path(&self, def: DefId) -> Option<hir_map::DefPath> {
+    fn retrace_path(&self,
+                    cnum: CrateNum,
+                    path_data: &[DisambiguatedDefPathData])
+                    -> Option<DefId> {
+        None
+    }
+
+    fn def_key(&self, def: DefId) -> DefKey { bug!("def_key") }
+    fn def_path(&self, def: DefId) -> hir_map::DefPath {
         bug!("relative_def_path")
     }
     fn struct_field_names(&self, def: DefId) -> Vec<ast::Name> { bug!("struct_field_names") }
index 3e32957aecfe07ab60fc0d8d5edf5685602e7d5b..f45e86f2f4b9615d32aae1b8c51fb41adf328ff2 100644 (file)
@@ -302,9 +302,7 @@ fn visit_foreign_item(&mut self, i: &'tcx hir::ForeignItem) {
     }
 
     fn visit_macro_def(&mut self, md: &'tcx hir::MacroDef) {
-        if md.imported_from.is_none() {
-            self.annotate(md.id, &md.attrs, md.span, AnnotationKind::Required, |_| {});
-        }
+        self.annotate(md.id, &md.attrs, md.span, AnnotationKind::Required, |_| {});
     }
 }
 
@@ -373,9 +371,7 @@ fn visit_foreign_item(&mut self, i: &'tcx hir::ForeignItem) {
     }
 
     fn visit_macro_def(&mut self, md: &'tcx hir::MacroDef) {
-        if md.imported_from.is_none() {
-            self.check_missing_stability(md.id, md.span);
-        }
+        self.check_missing_stability(md.id, md.span);
     }
 }
 
index 91765e68ae6e1a678c04f9cc34af957111da7dcb..36a887e062273b719d31edaa1311fba38432fa2c 100644 (file)
@@ -136,6 +136,8 @@ pub struct PerfStats {
     pub incr_comp_bytes_hashed: Cell<u64>,
     // The accumulated time spent on computing symbol hashes
     pub symbol_hash_time: Cell<Duration>,
+    // The accumulated time spent decoding def path tables from metadata
+    pub decode_def_path_tables_time: Cell<Duration>,
 }
 
 impl Session {
@@ -501,6 +503,8 @@ pub fn print_perf_stats(&self) {
                  self.perf_stats.incr_comp_hashes_count.get());
         println!("Total time spent computing symbol hashes:      {}",
                  duration_to_secs_str(self.perf_stats.symbol_hash_time.get()));
+        println!("Total time spent decoding DefPath tables:      {}",
+                 duration_to_secs_str(self.perf_stats.decode_def_path_tables_time.get()));
     }
 }
 
@@ -635,6 +639,7 @@ pub fn build_session_(sopts: config::Options,
             incr_comp_hashes_count: Cell::new(0),
             incr_comp_bytes_hashed: Cell::new(0),
             symbol_hash_time: Cell::new(Duration::from_secs(0)),
+            decode_def_path_tables_time: Cell::new(Duration::from_secs(0)),
         },
         code_stats: RefCell::new(CodeStats::new()),
     };
index 0c0d0c010e2e279dd58ee2750d36abda07688796..ab8c552d561f6100dc4cde5e5ccd5af1b4fe5788 100644 (file)
@@ -458,11 +458,28 @@ pub fn report_extra_impl_obligation(&self,
         err
     }
 
+
+    /// Get the parent trait chain start
+    fn get_parent_trait_ref(&self, code: &ObligationCauseCode<'tcx>) -> Option<String> {
+        match code {
+            &ObligationCauseCode::BuiltinDerivedObligation(ref data) => {
+                let parent_trait_ref = self.resolve_type_vars_if_possible(
+                    &data.parent_trait_ref);
+                match self.get_parent_trait_ref(&data.parent_code) {
+                    Some(t) => Some(t),
+                    None => Some(format!("{}", parent_trait_ref.0.self_ty())),
+                }
+            }
+            _ => None,
+        }
+    }
+
     pub fn report_selection_error(&self,
                                   obligation: &PredicateObligation<'tcx>,
                                   error: &SelectionError<'tcx>)
     {
         let span = obligation.cause.span;
+
         let mut err = match *error {
             SelectionError::Unimplemented => {
                 if let ObligationCauseCode::CompareImplMethodObligation {
@@ -487,14 +504,27 @@ pub fn report_selection_error(&self,
                                 return;
                             } else {
                                 let trait_ref = trait_predicate.to_poly_trait_ref();
-
-                                let mut err = struct_span_err!(self.tcx.sess, span, E0277,
-                                    "the trait bound `{}` is not satisfied",
-                                    trait_ref.to_predicate());
-                                err.span_label(span, &format!("the trait `{}` is not implemented \
-                                                               for `{}`",
-                                                              trait_ref,
-                                                              trait_ref.self_ty()));
+                                let (post_message, pre_message) = match self.get_parent_trait_ref(
+                                    &obligation.cause.code)
+                                {
+                                    Some(t) => {
+                                        (format!(" in `{}`", t), format!("within `{}`, ", t))
+                                    }
+                                    None => (String::new(), String::new()),
+                                };
+                                let mut err = struct_span_err!(
+                                    self.tcx.sess,
+                                    span,
+                                    E0277,
+                                    "the trait bound `{}` is not satisfied{}",
+                                    trait_ref.to_predicate(),
+                                    post_message);
+                                err.span_label(span,
+                                               &format!("{}the trait `{}` is not \
+                                                         implemented for `{}`",
+                                                        pre_message,
+                                                        trait_ref,
+                                                        trait_ref.self_ty()));
 
                                 // Try to report a help message
 
index 4854a14f733f552c89e10e3252e1cbdb72a792ec..f24ff98035532222905e7e32733d8f3d1f5b498a 100644 (file)
@@ -15,9 +15,9 @@
 use middle;
 use hir::TraitMap;
 use hir::def::Def;
-use hir::def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE};
+use hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
 use hir::map as ast_map;
-use hir::map::{DefKey, DefPathData, DisambiguatedDefPathData};
+use hir::map::DisambiguatedDefPathData;
 use middle::free_region::FreeRegionMap;
 use middle::region::RegionMaps;
 use middle::resolve_lifetime;
@@ -627,50 +627,21 @@ pub fn crate_disambiguator(self, cnum: CrateNum) -> Symbol {
         }
     }
 
-    /// Given a def-key `key` and a crate `krate`, finds the def-index
-    /// that `krate` assigned to `key`. This `DefIndex` will always be
-    /// relative to `krate`.
-    ///
-    /// Returns `None` if there is no `DefIndex` with that key.
-    pub fn def_index_for_def_key(self, krate: CrateNum, key: DefKey)
-                                 -> Option<DefIndex> {
-        if krate == LOCAL_CRATE {
-            self.map.def_index_for_def_key(key)
-        } else {
-            self.sess.cstore.def_index_for_def_key(krate, key)
-        }
-    }
-
     pub fn retrace_path(self,
                         krate: CrateNum,
                         path_data: &[DisambiguatedDefPathData])
                         -> Option<DefId> {
         debug!("retrace_path(path={:?}, krate={:?})", path_data, self.crate_name(krate));
 
-        let root_key = DefKey {
-            parent: None,
-            disambiguated_data: DisambiguatedDefPathData {
-                data: DefPathData::CrateRoot,
-                disambiguator: 0,
-            },
-        };
-
-        let root_index = self.def_index_for_def_key(krate, root_key)
-                             .expect("no root key?");
-
-        debug!("retrace_path: root_index={:?}", root_index);
-
-        let mut index = root_index;
-        for data in path_data {
-            let key = DefKey { parent: Some(index), disambiguated_data: data.clone() };
-            debug!("retrace_path: key={:?}", key);
-            match self.def_index_for_def_key(krate, key) {
-                Some(i) => index = i,
-                None => return None,
-            }
+        if krate == LOCAL_CRATE {
+            self.map
+                .definitions()
+                .def_path_table()
+                .retrace_path(path_data)
+                .map(|def_index| DefId { krate: krate, index: def_index })
+        } else {
+            self.sess.cstore.retrace_path(krate, path_data)
         }
-
-        Some(DefId { krate: krate, index: index })
     }
 
     pub fn type_parameter_def(self,
@@ -762,11 +733,9 @@ fn is_global(self) -> bool {
     /// reference to the context, to allow formatting values that need it.
     pub fn create_and_enter<F, R>(s: &'tcx Session,
                                   arenas: &'tcx CtxtArenas<'tcx>,
-                                  trait_map: TraitMap,
+                                  resolutions: ty::Resolutions,
                                   named_region_map: resolve_lifetime::NamedRegionMap,
                                   map: ast_map::Map<'tcx>,
-                                  freevars: FreevarMap,
-                                 maybe_unused_trait_imports: NodeSet,
                                   region_maps: RegionMaps,
                                   lang_items: middle::lang_items::LanguageItems,
                                   stability: stability::Index<'tcx>,
@@ -790,7 +759,7 @@ pub fn create_and_enter<F, R>(s: &'tcx Session,
             item_variance_map: RefCell::new(DepTrackingMap::new(dep_graph.clone())),
             variance_computed: Cell::new(false),
             sess: s,
-            trait_map: trait_map,
+            trait_map: resolutions.trait_map,
             tables: RefCell::new(Tables::empty()),
             impl_trait_refs: RefCell::new(DepTrackingMap::new(dep_graph.clone())),
             trait_defs: RefCell::new(DepTrackingMap::new(dep_graph.clone())),
@@ -802,8 +771,8 @@ pub fn create_and_enter<F, R>(s: &'tcx Session,
             fulfilled_predicates: RefCell::new(fulfilled_predicates),
             map: map,
             mir_map: RefCell::new(DepTrackingMap::new(dep_graph.clone())),
-            freevars: RefCell::new(freevars),
-            maybe_unused_trait_imports: maybe_unused_trait_imports,
+            freevars: RefCell::new(resolutions.freevars),
+            maybe_unused_trait_imports: resolutions.maybe_unused_trait_imports,
             item_types: RefCell::new(DepTrackingMap::new(dep_graph.clone())),
             rcache: RefCell::new(FxHashMap()),
             tc_cache: RefCell::new(FxHashMap()),
index 440a3916786fa3224fb25ecf8bc6a002d6fa8c77..0e4c14029e9b9860b3cc86942ab023c7c0ad96d2 100644 (file)
@@ -160,11 +160,6 @@ pub fn push_item_path<T>(self, buffer: &mut T, def_id: DefId)
                 self.push_krate_path(buffer, def_id.krate);
             }
 
-            DefPathData::InlinedRoot(ref root_path) => {
-                assert!(key.parent.is_none());
-                self.push_item_path(buffer, root_path.def_id);
-            }
-
             DefPathData::Impl => {
                 self.push_impl_path(buffer, def_id);
             }
index df12c252907a5a5f319ef34f8e2d10c21b3514c5..4e175e50194c332d446d80c66e195570a6bdc541 100644 (file)
@@ -17,7 +17,7 @@
 pub use self::fold::TypeFoldable;
 
 use dep_graph::{self, DepNode};
-use hir::map as ast_map;
+use hir::{map as ast_map, FreevarMap, TraitMap};
 use middle;
 use hir::def::{Def, CtorKind, ExportMap};
 use hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
@@ -112,6 +112,13 @@ pub struct CrateAnalysis<'tcx> {
     pub hir_ty_to_ty: NodeMap<Ty<'tcx>>,
 }
 
+#[derive(Clone)]
+pub struct Resolutions {
+    pub freevars: FreevarMap,
+    pub trait_map: TraitMap,
+    pub maybe_unused_trait_imports: NodeSet,
+}
+
 #[derive(Copy, Clone)]
 pub enum DtorKind {
     NoDtor,
@@ -2241,40 +2248,13 @@ pub fn def_key(self, id: DefId) -> ast_map::DefKey {
     /// Convert a `DefId` into its fully expanded `DefPath` (every
     /// `DefId` is really just an interned def-path).
     ///
-    /// Note that if `id` is not local to this crate -- or is
-    /// inlined into this crate -- the result will be a non-local
-    /// `DefPath`.
-    ///
-    /// This function is only safe to use when you are sure that the
-    /// full def-path is accessible. Examples that are known to be
-    /// safe are local def-ids or items; see `opt_def_path` for more
-    /// details.
+    /// Note that if `id` is not local to this crate, the result will
+    //  be a non-local `DefPath`.
     pub fn def_path(self, id: DefId) -> ast_map::DefPath {
-        self.opt_def_path(id).unwrap_or_else(|| {
-            bug!("could not load def-path for {:?}", id)
-        })
-    }
-
-    /// Convert a `DefId` into its fully expanded `DefPath` (every
-    /// `DefId` is really just an interned def-path).
-    ///
-    /// When going across crates, we do not save the full info for
-    /// every cross-crate def-id, and hence we may not always be able
-    /// to create a def-path. Therefore, this returns
-    /// `Option<DefPath>` to cover that possibility. It will always
-    /// return `Some` for local def-ids, however, as well as for
-    /// items. The problems arise with "minor" def-ids like those
-    /// associated with a pattern, `impl Trait`, or other internal
-    /// detail to a fn.
-    ///
-    /// Note that if `id` is not local to this crate -- or is
-    /// inlined into this crate -- the result will be a non-local
-    /// `DefPath`.
-    pub fn opt_def_path(self, id: DefId) -> Option<ast_map::DefPath> {
         if id.is_local() {
-            Some(self.map.def_path(id))
+            self.map.def_path(id)
         } else {
-            self.sess.cstore.relative_def_path(id)
+            self.sess.cstore.def_path(id)
         }
     }
 
index 351d469ea2809c5914b837194fb3665344ad9301..13333be66f5701a0dbb4c7123e1da9ab05d20cdd 100644 (file)
@@ -267,6 +267,9 @@ pub struct TargetOptions {
     /// user-defined libraries.
     pub post_link_args: Vec<String>,
 
+    /// Extra arguments to pass to the external assembler (when used)
+    pub asm_args: Vec<String>,
+
     /// Default CPU to pass to LLVM. Corresponds to `llc -mcpu=$cpu`. Defaults
     /// to "generic".
     pub cpu: String,
@@ -394,6 +397,7 @@ fn default() -> TargetOptions {
             ar: option_env!("CFG_DEFAULT_AR").unwrap_or("ar").to_string(),
             pre_link_args: Vec::new(),
             post_link_args: Vec::new(),
+            asm_args: Vec::new(),
             cpu: "generic".to_string(),
             features: "".to_string(),
             dynamic_linking: false,
@@ -561,6 +565,7 @@ macro_rules! key {
         key!(late_link_args, list);
         key!(post_link_objects, list);
         key!(post_link_args, list);
+        key!(asm_args, list);
         key!(cpu);
         key!(features);
         key!(dynamic_linking, bool);
@@ -723,6 +728,7 @@ macro_rules! target_option_val {
         target_option_val!(late_link_args);
         target_option_val!(post_link_objects);
         target_option_val!(post_link_args);
+        target_option_val!(asm_args);
         target_option_val!(cpu);
         target_option_val!(features);
         target_option_val!(dynamic_linking);
index ace00f031859dd43e30afdf6b1a958726ecb4e22..360933c6b669532457f61cf647dccf7a96813bee 100644 (file)
@@ -8,8 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use rustc::hir;
-use rustc::hir::{map as hir_map, FreevarMap, TraitMap};
+use rustc::hir::{self, map as hir_map};
 use rustc::hir::lowering::lower_crate;
 use rustc_data_structures::stable_hasher::StableHasher;
 use rustc_mir as mir;
@@ -20,7 +19,7 @@
 use rustc::lint;
 use rustc::middle::{self, dependency_format, stability, reachable};
 use rustc::middle::privacy::AccessLevels;
-use rustc::ty::{self, TyCtxt};
+use rustc::ty::{self, TyCtxt, Resolutions};
 use rustc::util::common::time;
 use rustc::util::nodemap::{NodeSet, NodeMap};
 use rustc_borrowck as borrowck;
 
 use derive_registrar;
 
-#[derive(Clone)]
-pub struct Resolutions {
-    pub freevars: FreevarMap,
-    pub trait_map: TraitMap,
-    pub maybe_unused_trait_imports: NodeSet,
-}
-
 pub fn compile_input(sess: &Session,
                      cstore: &CStore,
                      input: &Input,
@@ -864,11 +856,9 @@ macro_rules! try_with_f {
 
     TyCtxt::create_and_enter(sess,
                              arenas,
-                             resolutions.trait_map,
+                             resolutions,
                              named_region_map,
                              hir_map,
-                             resolutions.freevars,
-                             resolutions.maybe_unused_trait_imports,
                              region_map,
                              lang_items,
                              index,
index b055b043723e4ab769304d1a249fa2feff74cd38..74df1e52bde43143a7dab39a42aee28611022fc9 100644 (file)
 pub use self::PpMode::*;
 use self::NodesMatchingUII::*;
 
-use abort_on_err;
-use driver::{self, Resolutions};
+use {abort_on_err, driver};
 
-use rustc::ty::{self, TyCtxt};
+use rustc::ty::{self, TyCtxt, Resolutions};
 use rustc::cfg;
 use rustc::cfg::graphviz::LabelledCFG;
 use rustc::dep_graph::DepGraph;
index 2f8550e5acda70dcca033d3dbdd07de56cd18fc2..cbab39c390829422419cbacd3e6bd51320dee7fc 100644 (file)
@@ -138,11 +138,9 @@ fn test_env<F>(source_string: &str,
     let index = stability::Index::new(&ast_map);
     TyCtxt::create_and_enter(&sess,
                              &arenas,
-                             resolutions.trait_map,
+                             resolutions,
                              named_region_map.unwrap(),
                              ast_map,
-                             resolutions.freevars,
-                             resolutions.maybe_unused_trait_imports,
                              region_map,
                              lang_items,
                              index,
index e5203ea02b45a8095ba4c1b14b3810d7660a4535..799cb6c5e3d8c7d56d334fdea26869126accd844 100644 (file)
@@ -66,11 +66,6 @@ pub fn hash(&mut self, dep_node: &DepNode<DefId>) -> Option<Fingerprint> {
                         def_id,
                         self.tcx.item_path_str(def_id));
 
-                assert!(!self.tcx.map.is_inlined_def_id(def_id),
-                        "cannot hash HIR for inlined def-id {:?} => {:?}",
-                        def_id,
-                        self.tcx.item_path_str(def_id));
-
                 Some(self.incremental_hashes_map[dep_node])
             }
 
index 50bc3e7b6243f8d8743cb0da1a07398724b918e2..86c40a0208ad340755cb3630c38378d93a177f7d 100644 (file)
@@ -230,6 +230,13 @@ fn main() {
         }
     }
 
+    // OpenBSD has a particular C++ runtime library name
+    let stdcppname = if target.contains("openbsd") {
+        "estdc++"
+    } else {
+        "stdc++"
+    };
+
     // C++ runtime library
     if !target.contains("msvc") {
         if let Some(s) = env::var_os("LLVM_STATIC_STDCPP") {
@@ -237,11 +244,11 @@ fn main() {
             let path = PathBuf::from(s);
             println!("cargo:rustc-link-search=native={}",
                      path.parent().unwrap().display());
-            println!("cargo:rustc-link-lib=static=stdc++");
+            println!("cargo:rustc-link-lib=static={}", stdcppname);
         } else if cxxflags.contains("stdlib=libc++") {
             println!("cargo:rustc-link-lib=c++");
         } else {
-            println!("cargo:rustc-link-lib=stdc++");
+            println!("cargo:rustc-link-lib={}", stdcppname);
         }
     }
 }
index 6598b7dcc527faff76d00f6bf3fc19020be69309..926c44824ce482393083697b4569d9a8dbbeee16 100644 (file)
@@ -102,8 +102,6 @@ fn visit_id(&mut self, id: ast::NodeId) {
 /// ast-map.
 pub fn decode_inlined_item<'a, 'tcx>(cdata: &CrateMetadata,
                                      tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                                     parent_def_path: ast_map::DefPath,
-                                     parent_did: DefId,
                                      ast: Ast<'tcx>,
                                      orig_did: DefId)
                                      -> &'tcx InlinedItem {
@@ -120,17 +118,9 @@ pub fn decode_inlined_item<'a, 'tcx>(cdata: &CrateMetadata,
     let ii = ast.item.decode((cdata, tcx, id_ranges));
     let item_node_id = tcx.sess.next_node_id();
     let ii = ast_map::map_decoded_item(&tcx.map,
-                                       parent_def_path,
-                                       parent_did,
                                        ii,
                                        item_node_id);
 
-    let inlined_did = tcx.map.local_def_id(item_node_id);
-    let ty = tcx.item_type(orig_did);
-    let generics = tcx.item_generics(orig_did);
-    tcx.item_types.borrow_mut().insert(inlined_did, ty);
-    tcx.generics.borrow_mut().insert(inlined_did, generics);
-
     for (id, entry) in ast.side_tables.decode((cdata, tcx, id_ranges)) {
         match entry {
             TableEntry::TypeRelativeDef(def) => {
index d36242537b8e54a255f9920796d4102f7bb97c54..a9af4118c5957f7266fe05bfdf6252fe58192696 100644 (file)
@@ -22,6 +22,7 @@
 use rustc::session::search_paths::PathKind;
 use rustc::middle;
 use rustc::middle::cstore::{CrateStore, validate_crate_name, ExternCrate};
+use rustc::util::common::record_time;
 use rustc::util::nodemap::FxHashSet;
 use rustc::middle::cstore::NativeLibrary;
 use rustc::hir::map::Definitions;
@@ -297,10 +298,14 @@ fn register_crate(&mut self,
 
         let cnum_map = self.resolve_crate_deps(root, &crate_root, &metadata, cnum, span, dep_kind);
 
+        let def_path_table = record_time(&self.sess.perf_stats.decode_def_path_tables_time, || {
+            crate_root.def_path_table.decode(&metadata)
+        });
+
         let mut cmeta = cstore::CrateMetadata {
             name: name,
             extern_crate: Cell::new(None),
-            key_map: metadata.load_key_map(crate_root.index),
+            def_path_table: def_path_table,
             proc_macros: crate_root.macro_derive_registrar.map(|_| {
                 self.load_derive_macros(&crate_root, dylib.clone().map(|p| p.0), span)
             }),
index 7700ebde181333772a7fbda715e721ed85831e18..7ec847d24cfa3fc73823ce1a427550454ef172ba 100644 (file)
@@ -16,7 +16,7 @@
 
 use rustc::dep_graph::DepGraph;
 use rustc::hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE, CrateNum, DefIndex, DefId};
-use rustc::hir::map::DefKey;
+use rustc::hir::map::definitions::DefPathTable;
 use rustc::hir::svh::Svh;
 use rustc::middle::cstore::{DepKind, ExternCrate};
 use rustc_back::PanicStrategy;
@@ -78,7 +78,7 @@ pub struct CrateMetadata {
     /// hashmap, which gives the reverse mapping.  This allows us to
     /// quickly retrace a `DefPath`, which is needed for incremental
     /// compilation support.
-    pub key_map: FxHashMap<DefKey, DefIndex>,
+    pub def_path_table: DefPathTable,
 
     pub dep_kind: Cell<DepKind>,
     pub source: CrateSource,
index 1a1bb1432eec1fc2b625178df786104cdda97ee0..5c96d7f1826fd28e8664d2e607d83fb57e25f04c 100644 (file)
@@ -22,8 +22,7 @@
 use rustc::hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE};
 
 use rustc::dep_graph::DepNode;
-use rustc::hir::map as hir_map;
-use rustc::hir::map::DefKey;
+use rustc::hir::map::{DefKey, DefPath, DisambiguatedDefPathData};
 use rustc::mir::Mir;
 use rustc::util::nodemap::{NodeSet, DefIdMap};
 use rustc_back::PanicStrategy;
@@ -336,18 +335,20 @@ fn is_no_builtins(&self, cnum: CrateNum) -> bool {
         self.get_crate_data(cnum).is_no_builtins()
     }
 
-    fn def_index_for_def_key(&self,
-                             cnum: CrateNum,
-                             def: DefKey)
-                             -> Option<DefIndex> {
+    fn retrace_path(&self,
+                    cnum: CrateNum,
+                    path: &[DisambiguatedDefPathData])
+                    -> Option<DefId> {
         let cdata = self.get_crate_data(cnum);
-        cdata.key_map.get(&def).cloned()
+        cdata.def_path_table
+             .retrace_path(&path)
+             .map(|index| DefId { krate: cnum, index: index })
     }
 
     /// Returns the `DefKey` for a given `DefId`. This indicates the
     /// parent `DefId` as well as some idea of what kind of data the
     /// `DefId` refers to.
-    fn def_key(&self, def: DefId) -> hir_map::DefKey {
+    fn def_key(&self, def: DefId) -> DefKey {
         // Note: loading the def-key (or def-path) for a def-id is not
         // a *read* of its metadata. This is because the def-id is
         // really just an interned shorthand for a def-path, which is the
@@ -357,7 +358,7 @@ fn def_key(&self, def: DefId) -> hir_map::DefKey {
         self.get_crate_data(def.krate).def_key(def.index)
     }
 
-    fn relative_def_path(&self, def: DefId) -> Option<hir_map::DefPath> {
+    fn def_path(&self, def: DefId) -> DefPath {
         // See `Note` above in `def_key()` for why this read is
         // commented out:
         //
@@ -418,8 +419,6 @@ fn load_macro(&self, id: DefId, sess: &Session) -> LoadedMacro {
             ident: ast::Ident::with_empty_ctxt(name),
             id: ast::DUMMY_NODE_ID,
             span: local_span,
-            imported_from: None, // FIXME
-            allow_internal_unstable: attr::contains_name(&attrs, "allow_internal_unstable"),
             attrs: attrs,
             body: body,
         })
index 539c05b71bb1c13ce59c7043fe48d13013080c33..853a49dffc7b5ec71010c455a28194a022076d34 100644 (file)
 
 use astencode::decode_inlined_item;
 use cstore::{self, CrateMetadata, MetadataBlob, NativeLibrary};
-use index::Index;
 use schema::*;
 
-use rustc::hir::map as hir_map;
-use rustc::hir::map::{DefKey, DefPathData};
-use rustc::util::nodemap::FxHashMap;
+use rustc::hir::map::{DefKey, DefPath, DefPathData};
 use rustc::hir;
 use rustc::hir::intravisit::IdRange;
 
@@ -456,14 +453,6 @@ pub fn get_root(&self) -> CrateRoot {
         Lazy::with_position(pos).decode(self)
     }
 
-    /// Go through each item in the metadata and create a map from that
-    /// item's def-key to the item's DefIndex.
-    pub fn load_key_map(&self, index: LazySeq<Index>) -> FxHashMap<DefKey, DefIndex> {
-        index.iter_enumerated(self.raw_bytes())
-            .map(|(index, item)| (item.decode(self).def_key.decode(self), index))
-            .collect()
-    }
-
     pub fn list_crate_metadata(&self, out: &mut io::Write) -> io::Result<()> {
         write!(out, "=External Dependencies=\n")?;
         let root = self.get_root();
@@ -543,9 +532,8 @@ fn local_def_id(&self, index: DefIndex) -> DefId {
         }
     }
 
-    fn item_name(&self, item: &Entry<'tcx>) -> ast::Name {
-        item.def_key
-            .decode(self)
+    fn item_name(&self, item_index: DefIndex) -> ast::Name {
+        self.def_key(item_index)
             .disambiguated_data
             .data
             .get_opt_name()
@@ -578,7 +566,7 @@ pub fn get_trait_def(&self,
         ty::TraitDef::new(self.local_def_id(item_id),
                           data.unsafety,
                           data.paren_sugar,
-                          self.def_path(item_id).unwrap().deterministic_hash(tcx))
+                          self.def_path(item_id).deterministic_hash(tcx))
     }
 
     fn get_variant(&self,
@@ -594,12 +582,12 @@ fn get_variant(&self,
 
         (ty::VariantDef {
             did: self.local_def_id(data.struct_ctor.unwrap_or(index)),
-            name: self.item_name(item),
+            name: self.item_name(index),
             fields: item.children.decode(self).map(|index| {
                 let f = self.entry(index);
                 ty::FieldDef {
                     did: self.local_def_id(index),
-                    name: self.item_name(&f),
+                    name: self.item_name(index),
                     vis: f.visibility
                 }
             }).collect(),
@@ -771,7 +759,7 @@ pub fn each_child_of_item<F>(&self, id: DefIndex, mut callback: F)
                             if let Some(def) = self.get_def(child_index) {
                                 callback(def::Export {
                                     def: def,
-                                    name: self.item_name(&self.entry(child_index)),
+                                    name: self.item_name(child_index),
                                 });
                             }
                         }
@@ -783,7 +771,7 @@ pub fn each_child_of_item<F>(&self, id: DefIndex, mut callback: F)
                     _ => {}
                 }
 
-                let def_key = child.def_key.decode(self);
+                let def_key = self.def_key(child_index);
                 if let (Some(def), Some(name)) =
                     (self.get_def(child_index), def_key.disambiguated_data.data.get_opt_name()) {
                     callback(def::Export {
@@ -839,12 +827,9 @@ pub fn maybe_get_item_ast(&self,
         if self.is_proc_macro(id) { return None; }
         let item_doc = self.entry(id);
         let item_did = self.local_def_id(id);
-        let parent_def_id = self.local_def_id(self.def_key(id).parent.unwrap());
-        let mut parent_def_path = self.def_path(id).unwrap();
-        parent_def_path.data.pop();
         item_doc.ast.map(|ast| {
             let ast = ast.decode(self);
-            decode_inlined_item(self, tcx, parent_def_path, parent_def_id, ast, item_did)
+            decode_inlined_item(self, tcx, ast, item_did)
         })
     }
 
@@ -889,7 +874,7 @@ pub fn maybe_get_item_mir(&self,
     pub fn get_associated_item(&self, id: DefIndex) -> Option<ty::AssociatedItem> {
         let item = self.entry(id);
         let parent_and_name = || {
-            let def_key = item.def_key.decode(self);
+            let def_key = self.def_key(id);
             (self.local_def_id(def_key.parent.unwrap()),
              def_key.disambiguated_data.data.get_opt_name().unwrap())
         };
@@ -966,7 +951,7 @@ pub fn get_item_attrs(&self, node_id: DefIndex) -> Vec<ast::Attribute> {
         // we assume that someone passing in a tuple struct ctor is actually wanting to
         // look at the definition
         let mut item = self.entry(node_id);
-        let def_key = item.def_key.decode(self);
+        let def_key = self.def_key(node_id);
         if def_key.disambiguated_data.data == DefPathData::StructCtor {
             item = self.entry(def_key.parent.unwrap());
         }
@@ -977,7 +962,7 @@ pub fn get_struct_field_names(&self, id: DefIndex) -> Vec<ast::Name> {
         self.entry(id)
             .children
             .decode(self)
-            .map(|index| self.item_name(&self.entry(index)))
+            .map(|index| self.item_name(index))
             .collect()
     }
 
@@ -1039,7 +1024,7 @@ pub fn get_implementations_for_trait(&self, filter: Option<DefId>, result: &mut
     }
 
     pub fn get_trait_of_item(&self, id: DefIndex) -> Option<DefId> {
-        self.entry(id).def_key.decode(self).parent.and_then(|parent_index| {
+        self.def_key(id).parent.and_then(|parent_index| {
             match self.entry(parent_index).kind {
                 EntryKind::Trait(_) => Some(self.local_def_id(parent_index)),
                 _ => None,
@@ -1085,7 +1070,7 @@ pub fn get_exported_symbols(&self) -> Vec<DefId> {
     pub fn get_macro(&self, id: DefIndex) -> (ast::Name, MacroDef) {
         let entry = self.entry(id);
         match entry.kind {
-            EntryKind::MacroDef(macro_def) => (self.item_name(&entry), macro_def.decode(self)),
+            EntryKind::MacroDef(macro_def) => (self.item_name(id), macro_def.decode(self)),
             _ => bug!(),
         }
     }
@@ -1138,32 +1123,14 @@ pub fn closure_ty(&self,
         }
     }
 
-    pub fn def_key(&self, id: DefIndex) -> hir_map::DefKey {
-        debug!("def_key: id={:?}", id);
-        if self.is_proc_macro(id) {
-            let name = self.proc_macros.as_ref().unwrap()[id.as_usize() - 1].0;
-            hir_map::DefKey {
-                parent: Some(CRATE_DEF_INDEX),
-                disambiguated_data: hir_map::DisambiguatedDefPathData {
-                    data: hir_map::DefPathData::MacroDef(name.as_str()),
-                    disambiguator: 0,
-                },
-            }
-        } else {
-            self.entry(id).def_key.decode(self)
-        }
+    pub fn def_key(&self, index: DefIndex) -> DefKey {
+        self.def_path_table.def_key(index)
     }
 
-    // Returns the path leading to the thing with this `id`. Note that
-    // some def-ids don't wind up in the metadata, so `def_path` sometimes
-    // returns `None`
-    pub fn def_path(&self, id: DefIndex) -> Option<hir_map::DefPath> {
+    // Returns the path leading to the thing with this `id`.
+    pub fn def_path(&self, id: DefIndex) -> DefPath {
         debug!("def_path(id={:?})", id);
-        if self.is_proc_macro(id) || self.maybe_entry(id).is_some() {
-            Some(hir_map::DefPath::make(self.cnum, id, |parent| self.def_key(parent)))
-        } else {
-            None
-        }
+        DefPath::make(self.cnum, id, |parent| self.def_path_table.def_key(parent))
     }
 
     /// Imports the codemap from an external crate into the codemap of the crate
index 443f3fbaa6e41df93d4ef12f7e03da34fb208621..cf032013ac962976117a497cd3f9f0c41cd391ab 100644 (file)
@@ -16,6 +16,7 @@
 use rustc::middle::cstore::{LinkagePreference, NativeLibrary};
 use rustc::hir::def;
 use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefIndex, DefId};
+use rustc::hir::map::definitions::DefPathTable;
 use rustc::middle::dependency_format::Linkage;
 use rustc::middle::lang_items;
 use rustc::mir;
@@ -233,13 +234,6 @@ fn encode_with_shorthand<T, U, M>(&mut self,
         Ok(())
     }
 
-    /// For every DefId that we create a metadata item for, we include a
-    /// serialized copy of its DefKey, which allows us to recreate a path.
-    fn encode_def_key(&mut self, def_id: DefId) -> Lazy<hir::map::DefKey> {
-        let tcx = self.tcx;
-        self.lazy(&tcx.map.def_key(def_id))
-    }
-
     fn encode_item_variances(&mut self, def_id: DefId) -> LazySeq<ty::Variance> {
         let tcx = self.tcx;
         self.lazy_seq(tcx.item_variances(def_id).iter().cloned())
@@ -276,7 +270,6 @@ fn encode_enum_variant_info(&mut self,
             kind: EntryKind::Variant(self.lazy(&data)),
             visibility: enum_vis.simplify(),
             span: self.lazy(&tcx.def_span(def_id)),
-            def_key: self.encode_def_key(def_id),
             attributes: self.encode_attributes(&tcx.get_attrs(def_id)),
             children: self.lazy_seq(variant.fields.iter().map(|f| {
                 assert!(f.did.is_local());
@@ -315,7 +308,6 @@ fn encode_info_for_mod(&mut self,
             kind: EntryKind::Mod(self.lazy(&data)),
             visibility: vis.simplify(),
             span: self.lazy(&md.inner),
-            def_key: self.encode_def_key(def_id),
             attributes: self.encode_attributes(attrs),
             children: self.lazy_seq(md.item_ids.iter().map(|item_id| {
                 tcx.map.local_def_id(item_id.id).index
@@ -396,7 +388,6 @@ fn encode_field(&mut self,
             kind: EntryKind::Field,
             visibility: field.vis.simplify(),
             span: self.lazy(&tcx.def_span(def_id)),
-            def_key: self.encode_def_key(def_id),
             attributes: self.encode_attributes(&variant_data.fields()[field_index].attrs),
             children: LazySeq::empty(),
             stability: self.encode_stability(def_id),
@@ -430,7 +421,6 @@ fn encode_struct_ctor(&mut self, (adt_def_id, def_id): (DefId, DefId)) -> Entry<
             kind: EntryKind::Struct(self.lazy(&data)),
             visibility: struct_vis.simplify(),
             span: self.lazy(&tcx.def_span(def_id)),
-            def_key: self.encode_def_key(def_id),
             attributes: LazySeq::empty(),
             children: LazySeq::empty(),
             stability: self.encode_stability(def_id),
@@ -497,7 +487,6 @@ fn encode_info_for_trait_item(&mut self, def_id: DefId) -> Entry<'tcx> {
             kind: kind,
             visibility: trait_item.vis.simplify(),
             span: self.lazy(&ast_item.span),
-            def_key: self.encode_def_key(def_id),
             attributes: self.encode_attributes(&ast_item.attrs),
             children: LazySeq::empty(),
             stability: self.encode_stability(def_id),
@@ -587,7 +576,6 @@ fn encode_info_for_impl_item(&mut self, def_id: DefId) -> Entry<'tcx> {
             kind: kind,
             visibility: impl_item.vis.simplify(),
             span: self.lazy(&ast_item.span),
-            def_key: self.encode_def_key(def_id),
             attributes: self.encode_attributes(&ast_item.attrs),
             children: LazySeq::empty(),
             stability: self.encode_stability(def_id),
@@ -750,7 +738,6 @@ fn encode_info_for_item(&mut self, (def_id, item): (DefId, &'tcx hir::Item)) ->
             kind: kind,
             visibility: item.vis.simplify(),
             span: self.lazy(&item.span),
-            def_key: self.encode_def_key(def_id),
             attributes: self.encode_attributes(&item.attrs),
             children: match item.node {
                 hir::ItemForeignMod(ref fm) => {
@@ -858,14 +845,12 @@ fn encode_info_for_item(&mut self, (def_id, item): (DefId, &'tcx hir::Item)) ->
 
     /// Serialize the text of exported macros
     fn encode_info_for_macro_def(&mut self, macro_def: &hir::MacroDef) -> Entry<'tcx> {
-        let def_id = self.tcx.map.local_def_id(macro_def.id);
         Entry {
             kind: EntryKind::MacroDef(self.lazy(&MacroDef {
                 body: ::syntax::print::pprust::tts_to_string(&macro_def.body)
             })),
             visibility: ty::Visibility::Public,
             span: self.lazy(&macro_def.span),
-            def_key: self.encode_def_key(def_id),
 
             attributes: self.encode_attributes(&macro_def.attrs),
             children: LazySeq::empty(),
@@ -967,7 +952,6 @@ fn encode_info_for_foreign_item(&mut self,
             kind: kind,
             visibility: nitem.vis.simplify(),
             span: self.lazy(&nitem.span),
-            def_key: self.encode_def_key(def_id),
             attributes: self.encode_attributes(&nitem.attrs),
             children: LazySeq::empty(),
             stability: self.encode_stability(def_id),
@@ -1050,7 +1034,6 @@ fn encode_info_for_anon_ty(&mut self, def_id: DefId) -> Entry<'tcx> {
             kind: EntryKind::Type,
             visibility: ty::Visibility::Public,
             span: self.lazy(&tcx.def_span(def_id)),
-            def_key: self.encode_def_key(def_id),
             attributes: LazySeq::empty(),
             children: LazySeq::empty(),
             stability: None,
@@ -1079,7 +1062,6 @@ fn encode_info_for_closure(&mut self, def_id: DefId) -> Entry<'tcx> {
             kind: EntryKind::Closure(self.lazy(&data)),
             visibility: ty::Visibility::Public,
             span: self.lazy(&tcx.def_span(def_id)),
-            def_key: self.encode_def_key(def_id),
             attributes: self.encode_attributes(&tcx.get_attrs(def_id)),
             children: LazySeq::empty(),
             stability: None,
@@ -1179,6 +1161,11 @@ fn encode_codemap(&mut self) -> LazySeq<syntax_pos::FileMap> {
             })
             .map(|filemap| &**filemap))
     }
+
+    fn encode_def_path_table(&mut self) -> Lazy<DefPathTable> {
+        let definitions = self.tcx.map.definitions();
+        self.lazy(definitions.def_path_table())
+    }
 }
 
 struct ImplVisitor<'a, 'tcx: 'a> {
@@ -1276,6 +1263,11 @@ fn encode_crate_root(&mut self) -> Lazy<CrateRoot> {
         let codemap = self.encode_codemap();
         let codemap_bytes = self.position() - i;
 
+        // Encode DefPathTable
+        i = self.position();
+        let def_path_table = self.encode_def_path_table();
+        let def_path_table_bytes = self.position() - i;
+
         // Encode the def IDs of impls, for coherence checking.
         i = self.position();
         let impls = self.encode_impls();
@@ -1321,6 +1313,7 @@ fn encode_crate_root(&mut self) -> Lazy<CrateRoot> {
             lang_items_missing: lang_items_missing,
             native_libraries: native_libraries,
             codemap: codemap,
+            def_path_table: def_path_table,
             impls: impls,
             exported_symbols: exported_symbols,
             index: index,
@@ -1343,6 +1336,7 @@ fn encode_crate_root(&mut self) -> Lazy<CrateRoot> {
             println!("         codemap bytes: {}", codemap_bytes);
             println!("            impl bytes: {}", impl_bytes);
             println!("    exp. symbols bytes: {}", exported_symbols_bytes);
+            println!("  def-path table bytes: {}", def_path_table_bytes);
             println!("            item bytes: {}", item_bytes);
             println!("           index bytes: {}", index_bytes);
             println!("            zero bytes: {}", zero_bytes);
index f92051cbf1943a03338f8b3e8b1d8bcc5f4464f0..0b6606a00d3c041174759b55f50f5f27c036be39 100644 (file)
@@ -179,6 +179,7 @@ pub struct CrateRoot {
     pub lang_items_missing: LazySeq<lang_items::LangItem>,
     pub native_libraries: LazySeq<NativeLibrary>,
     pub codemap: LazySeq<syntax_pos::FileMap>,
+    pub def_path_table: Lazy<hir::map::definitions::DefPathTable>,
     pub impls: LazySeq<TraitImpls>,
     pub exported_symbols: LazySeq<DefIndex>,
     pub index: LazySeq<index::Index>,
@@ -202,7 +203,6 @@ pub struct Entry<'tcx> {
     pub kind: EntryKind<'tcx>,
     pub visibility: ty::Visibility,
     pub span: Lazy<Span>,
-    pub def_key: Lazy<hir::map::DefKey>,
     pub attributes: LazySeq<ast::Attribute>,
     pub children: LazySeq<DefIndex>,
     pub stability: Option<Lazy<attr::Stability>>,
index 2d0f0864752ab5739f064b3bc237301369c80cd0..bc150b847786f2c08531e847d08061b2f9600d3d 100644 (file)
@@ -171,7 +171,7 @@ fn visit_item(&mut self, item: &'a Item) {
         match item.node {
             ItemKind::Use(ref view_path) => {
                 let path = view_path.node.path();
-                if !path.segments.iter().all(|segment| segment.parameters.is_empty()) {
+                if path.segments.iter().any(|segment| segment.parameters.is_some()) {
                     self.err_handler()
                         .span_err(path.span, "type or lifetime parameters in import path");
                 }
@@ -275,7 +275,7 @@ fn visit_foreign_item(&mut self, fi: &'a ForeignItem) {
     fn visit_vis(&mut self, vis: &'a Visibility) {
         match *vis {
             Visibility::Restricted { ref path, .. } => {
-                if !path.segments.iter().all(|segment| segment.parameters.is_empty()) {
+                if !path.segments.iter().all(|segment| segment.parameters.is_none()) {
                     self.err_handler()
                         .span_err(path.span, "type or lifetime parameters in visibility path");
                 }
index 25a37931ba31fd05cb870ca2aae423ab1221c045..cd2a2767979144fdcb3272a5205ef71128f8d196 100644 (file)
@@ -16,7 +16,8 @@
 use macros::{InvocationData, LegacyScope};
 use resolve_imports::ImportDirective;
 use resolve_imports::ImportDirectiveSubclass::{self, GlobImport, SingleImport};
-use {Resolver, Module, ModuleS, ModuleKind, NameBinding, NameBindingKind, ToNameBinding};
+use {Module, ModuleData, ModuleKind, NameBinding, NameBindingKind, ToNameBinding};
+use {Resolver, ResolverArenas};
 use Namespace::{self, TypeNS, ValueNS, MacroNS};
 use {resolve_error, resolve_struct_error, ResolutionError};
 
@@ -28,7 +29,7 @@
 use std::cell::Cell;
 use std::rc::Rc;
 
-use syntax::ast::Name;
+use syntax::ast::{Name, Ident};
 use syntax::attr;
 
 use syntax::ast::{self, Block, ForeignItem, ForeignItemKind, Item, ItemKind};
 use syntax_pos::{Span, DUMMY_SP};
 
 impl<'a> ToNameBinding<'a> for (Module<'a>, ty::Visibility, Span, Mark) {
-    fn to_name_binding(self) -> NameBinding<'a> {
-        NameBinding {
+    fn to_name_binding(self, arenas: &'a ResolverArenas<'a>) -> &'a NameBinding<'a> {
+        arenas.alloc_name_binding(NameBinding {
             kind: NameBindingKind::Module(self.0),
             vis: self.1,
             span: self.2,
             expansion: self.3,
-        }
+        })
     }
 }
 
 impl<'a> ToNameBinding<'a> for (Def, ty::Visibility, Span, Mark) {
-    fn to_name_binding(self) -> NameBinding<'a> {
-        NameBinding {
+    fn to_name_binding(self, arenas: &'a ResolverArenas<'a>) -> &'a NameBinding<'a> {
+        arenas.alloc_name_binding(NameBinding {
             kind: NameBindingKind::Def(self.0),
             vis: self.1,
             span: self.2,
             expansion: self.3,
-        }
+        })
     }
 }
 
@@ -73,15 +74,15 @@ struct LegacyMacroImports {
     reexports: Vec<(Name, Span)>,
 }
 
-impl<'b> Resolver<'b> {
+impl<'a> Resolver<'a> {
     /// Defines `name` in namespace `ns` of module `parent` to be `def` if it is not yet defined;
     /// otherwise, reports an error.
-    fn define<T>(&mut self, parent: Module<'b>, name: Name, ns: Namespace, def: T)
-        where T: ToNameBinding<'b>,
+    fn define<T>(&mut self, parent: Module<'a>, ident: Ident, ns: Namespace, def: T)
+        where T: ToNameBinding<'a>,
     {
-        let binding = def.to_name_binding();
-        if let Err(old_binding) = self.try_define(parent, name, ns, binding.clone()) {
-            self.report_conflict(parent, name, ns, old_binding, &binding);
+        let binding = def.to_name_binding(self.arenas);
+        if let Err(old_binding) = self.try_define(parent, ident, ns, binding) {
+            self.report_conflict(parent, ident, ns, old_binding, &binding);
         }
     }
 
@@ -102,7 +103,7 @@ fn insert_field_names(&mut self, def_id: DefId, field_names: Vec<Name>) {
     /// Constructs the reduced graph for one item.
     fn build_reduced_graph_for_item(&mut self, item: &Item, expansion: Mark) {
         let parent = self.current_module;
-        let name = item.ident.name;
+        let ident = item.ident;
         let sp = item.span;
         let vis = self.resolve_visibility(&item.vis);
 
@@ -157,8 +158,8 @@ fn build_reduced_graph_for_item(&mut self, item: &Item, expansion: Mark) {
                         }
 
                         let subclass = SingleImport {
-                            target: binding.name,
-                            source: source.name,
+                            target: binding,
+                            source: source,
                             result: self.per_ns(|_, _| Cell::new(Err(Undetermined))),
                         };
                         self.add_import_directive(
@@ -187,13 +188,13 @@ fn build_reduced_graph_for_item(&mut self, item: &Item, expansion: Mark) {
 
                         for source_item in source_items {
                             let node = source_item.node;
-                            let (module_path, name, rename) = {
+                            let (module_path, ident, rename) = {
                                 if node.name.name != keywords::SelfValue.name() {
-                                    let rename = node.rename.unwrap_or(node.name).name;
-                                    (module_path.clone(), node.name.name, rename)
+                                    let rename = node.rename.unwrap_or(node.name);
+                                    (module_path.clone(), node.name, rename)
                                 } else {
-                                    let name = match module_path.last() {
-                                        Some(ident) => ident.name,
+                                    let ident = match module_path.last() {
+                                        Some(&ident) => ident,
                                         None => {
                                             resolve_error(
                                                 self,
@@ -205,13 +206,13 @@ fn build_reduced_graph_for_item(&mut self, item: &Item, expansion: Mark) {
                                         }
                                     };
                                     let module_path = module_path.split_last().unwrap().1;
-                                    let rename = node.rename.map(|i| i.name).unwrap_or(name);
-                                    (module_path.to_vec(), name, rename)
+                                    let rename = node.rename.unwrap_or(ident);
+                                    (module_path.to_vec(), ident, rename)
                                 }
                             };
                             let subclass = SingleImport {
                                 target: rename,
-                                source: name,
+                                source: ident,
                                 result: self.per_ns(|_, _| Cell::new(Err(Undetermined))),
                             };
                             let id = source_item.node.id;
@@ -238,8 +239,8 @@ fn build_reduced_graph_for_item(&mut self, item: &Item, expansion: Mark) {
                 // n.b. we don't need to look at the path option here, because cstore already did
                 let crate_id = self.session.cstore.extern_mod_stmt_cnum(item.id).unwrap();
                 let module = self.get_extern_crate_root(crate_id);
-                let binding = (module, ty::Visibility::Public, sp, expansion).to_name_binding();
-                let binding = self.arenas.alloc_name_binding(binding);
+                let binding =
+                    (module, ty::Visibility::Public, sp, expansion).to_name_binding(self.arenas);
                 let directive = self.arenas.alloc_import_directive(ImportDirective {
                     id: item.id,
                     parent: parent,
@@ -251,7 +252,7 @@ fn build_reduced_graph_for_item(&mut self, item: &Item, expansion: Mark) {
                     expansion: expansion,
                 });
                 let imported_binding = self.import(binding, directive);
-                self.define(parent, name, TypeNS, imported_binding);
+                self.define(parent, ident, TypeNS, imported_binding);
                 self.populate_module_if_necessary(module);
                 self.process_legacy_macro_imports(item, module, expansion);
             }
@@ -260,14 +261,14 @@ fn build_reduced_graph_for_item(&mut self, item: &Item, expansion: Mark) {
 
             ItemKind::Mod(..) => {
                 let def = Def::Mod(self.definitions.local_def_id(item.id));
-                let module = self.arenas.alloc_module(ModuleS {
+                let module = self.arenas.alloc_module(ModuleData {
                     no_implicit_prelude: parent.no_implicit_prelude || {
                         attr::contains_name(&item.attrs, "no_implicit_prelude")
                     },
                     normal_ancestor_id: Some(item.id),
-                    ..ModuleS::new(Some(parent), ModuleKind::Def(def, name))
+                    ..ModuleData::new(Some(parent), ModuleKind::Def(def, ident.name))
                 });
-                self.define(parent, name, TypeNS, (module, vis, sp, expansion));
+                self.define(parent, ident, TypeNS, (module, vis, sp, expansion));
                 self.module_map.insert(item.id, module);
 
                 // Descend into the module.
@@ -280,27 +281,27 @@ fn build_reduced_graph_for_item(&mut self, item: &Item, expansion: Mark) {
             ItemKind::Static(_, m, _) => {
                 let mutbl = m == Mutability::Mutable;
                 let def = Def::Static(self.definitions.local_def_id(item.id), mutbl);
-                self.define(parent, name, ValueNS, (def, vis, sp, expansion));
+                self.define(parent, ident, ValueNS, (def, vis, sp, expansion));
             }
             ItemKind::Const(..) => {
                 let def = Def::Const(self.definitions.local_def_id(item.id));
-                self.define(parent, name, ValueNS, (def, vis, sp, expansion));
+                self.define(parent, ident, ValueNS, (def, vis, sp, expansion));
             }
             ItemKind::Fn(..) => {
                 let def = Def::Fn(self.definitions.local_def_id(item.id));
-                self.define(parent, name, ValueNS, (def, vis, sp, expansion));
+                self.define(parent, ident, ValueNS, (def, vis, sp, expansion));
             }
 
             // These items live in the type namespace.
             ItemKind::Ty(..) => {
                 let def = Def::TyAlias(self.definitions.local_def_id(item.id));
-                self.define(parent, name, TypeNS, (def, vis, sp, expansion));
+                self.define(parent, ident, TypeNS, (def, vis, sp, expansion));
             }
 
             ItemKind::Enum(ref enum_definition, _) => {
                 let def = Def::Enum(self.definitions.local_def_id(item.id));
-                let module = self.new_module(parent, ModuleKind::Def(def, name), true);
-                self.define(parent, name, TypeNS, (module, vis, sp, expansion));
+                let module = self.new_module(parent, ModuleKind::Def(def, ident.name), true);
+                self.define(parent, ident, TypeNS, (module, vis, sp, expansion));
 
                 for variant in &(*enum_definition).variants {
                     self.build_reduced_graph_for_variant(variant, module, vis, expansion);
@@ -311,14 +312,14 @@ fn build_reduced_graph_for_item(&mut self, item: &Item, expansion: Mark) {
             ItemKind::Struct(ref struct_def, _) => {
                 // Define a name in the type namespace.
                 let def = Def::Struct(self.definitions.local_def_id(item.id));
-                self.define(parent, name, TypeNS, (def, vis, sp, expansion));
+                self.define(parent, ident, TypeNS, (def, vis, sp, expansion));
 
                 // If this is a tuple or unit struct, define a name
                 // in the value namespace as well.
                 if !struct_def.is_struct() {
                     let ctor_def = Def::StructCtor(self.definitions.local_def_id(struct_def.id()),
                                                    CtorKind::from_ast(struct_def));
-                    self.define(parent, name, ValueNS, (ctor_def, vis, sp, expansion));
+                    self.define(parent, ident, ValueNS, (ctor_def, vis, sp, expansion));
                 }
 
                 // Record field names for error reporting.
@@ -332,7 +333,7 @@ fn build_reduced_graph_for_item(&mut self, item: &Item, expansion: Mark) {
 
             ItemKind::Union(ref vdata, _) => {
                 let def = Def::Union(self.definitions.local_def_id(item.id));
-                self.define(parent, name, TypeNS, (def, vis, sp, expansion));
+                self.define(parent, ident, TypeNS, (def, vis, sp, expansion));
 
                 // Record field names for error reporting.
                 let field_names = vdata.fields().iter().filter_map(|field| {
@@ -350,8 +351,8 @@ fn build_reduced_graph_for_item(&mut self, item: &Item, expansion: Mark) {
 
                 // Add all the items within to a new module.
                 let module =
-                    self.new_module(parent, ModuleKind::Def(Def::Trait(def_id), name), true);
-                self.define(parent, name, TypeNS, (module, vis, sp, expansion));
+                    self.new_module(parent, ModuleKind::Def(Def::Trait(def_id), ident.name), true);
+                self.define(parent, ident, TypeNS, (module, vis, sp, expansion));
                 self.current_module = module;
             }
             ItemKind::Mac(_) => panic!("unexpanded macro in resolve!"),
@@ -362,29 +363,26 @@ fn build_reduced_graph_for_item(&mut self, item: &Item, expansion: Mark) {
     // type and value namespaces.
     fn build_reduced_graph_for_variant(&mut self,
                                        variant: &Variant,
-                                       parent: Module<'b>,
+                                       parent: Module<'a>,
                                        vis: ty::Visibility,
                                        expansion: Mark) {
-        let name = variant.node.name.name;
+        let ident = variant.node.name;
         let def_id = self.definitions.local_def_id(variant.node.data.id());
 
         // Define a name in the type namespace.
         let def = Def::Variant(def_id);
-        self.define(parent, name, TypeNS, (def, vis, variant.span, expansion));
+        self.define(parent, ident, TypeNS, (def, vis, variant.span, expansion));
 
         // Define a constructor name in the value namespace.
         // Braced variants, unlike structs, generate unusable names in
         // value namespace, they are reserved for possible future use.
         let ctor_kind = CtorKind::from_ast(&variant.node.data);
         let ctor_def = Def::VariantCtor(def_id, ctor_kind);
-        self.define(parent, name, ValueNS, (ctor_def, vis, variant.span, expansion));
+        self.define(parent, ident, ValueNS, (ctor_def, vis, variant.span, expansion));
     }
 
     /// Constructs the reduced graph for one foreign item.
     fn build_reduced_graph_for_foreign_item(&mut self, item: &ForeignItem, expansion: Mark) {
-        let parent = self.current_module;
-        let name = item.ident.name;
-
         let def = match item.node {
             ForeignItemKind::Fn(..) => {
                 Def::Fn(self.definitions.local_def_id(item.id))
@@ -393,8 +391,9 @@ fn build_reduced_graph_for_foreign_item(&mut self, item: &ForeignItem, expansion
                 Def::Static(self.definitions.local_def_id(item.id), m)
             }
         };
+        let parent = self.current_module;
         let vis = self.resolve_visibility(&item.vis);
-        self.define(parent, name, ValueNS, (def, vis, item.span, expansion));
+        self.define(parent, item.ident, ValueNS, (def, vis, item.span, expansion));
     }
 
     fn build_reduced_graph_for_block(&mut self, block: &Block) {
@@ -413,8 +412,8 @@ fn build_reduced_graph_for_block(&mut self, block: &Block) {
     }
 
     /// Builds the reduced graph for a single item in an external crate.
-    fn build_reduced_graph_for_external_crate_def(&mut self, parent: Module<'b>, child: Export) {
-        let name = child.name;
+    fn build_reduced_graph_for_external_crate_def(&mut self, parent: Module<'a>, child: Export) {
+        let ident = Ident::with_empty_ctxt(child.name);
         let def = child.def;
         let def_id = def.def_id();
         let vis = match def {
@@ -425,25 +424,25 @@ fn build_reduced_graph_for_external_crate_def(&mut self, parent: Module<'b>, chi
 
         match def {
             Def::Mod(..) | Def::Enum(..) => {
-                let module = self.new_module(parent, ModuleKind::Def(def, name), false);
-                self.define(parent, name, TypeNS, (module, vis, DUMMY_SP, Mark::root()));
+                let module = self.new_module(parent, ModuleKind::Def(def, ident.name), false);
+                self.define(parent, ident, TypeNS, (module, vis, DUMMY_SP, Mark::root()));
             }
             Def::Variant(..) => {
-                self.define(parent, name, TypeNS, (def, vis, DUMMY_SP, Mark::root()));
+                self.define(parent, ident, TypeNS, (def, vis, DUMMY_SP, Mark::root()));
             }
             Def::VariantCtor(..) => {
-                self.define(parent, name, ValueNS, (def, vis, DUMMY_SP, Mark::root()));
+                self.define(parent, ident, ValueNS, (def, vis, DUMMY_SP, Mark::root()));
             }
             Def::Fn(..) |
             Def::Static(..) |
             Def::Const(..) |
             Def::AssociatedConst(..) |
             Def::Method(..) => {
-                self.define(parent, name, ValueNS, (def, vis, DUMMY_SP, Mark::root()));
+                self.define(parent, ident, ValueNS, (def, vis, DUMMY_SP, Mark::root()));
             }
             Def::Trait(..) => {
-                let module = self.new_module(parent, ModuleKind::Def(def, name), false);
-                self.define(parent, name, TypeNS, (module, vis, DUMMY_SP, Mark::root()));
+                let module = self.new_module(parent, ModuleKind::Def(def, ident.name), false);
+                self.define(parent, ident, TypeNS, (module, vis, DUMMY_SP, Mark::root()));
 
                 // If this is a trait, add all the trait item names to the trait info.
                 let trait_item_def_ids = self.session.cstore.associated_item_def_ids(def_id);
@@ -455,27 +454,27 @@ fn build_reduced_graph_for_external_crate_def(&mut self, parent: Module<'b>, chi
                 }
             }
             Def::TyAlias(..) | Def::AssociatedTy(..) => {
-                self.define(parent, name, TypeNS, (def, vis, DUMMY_SP, Mark::root()));
+                self.define(parent, ident, TypeNS, (def, vis, DUMMY_SP, Mark::root()));
             }
             Def::Struct(..) => {
-                self.define(parent, name, TypeNS, (def, vis, DUMMY_SP, Mark::root()));
+                self.define(parent, ident, TypeNS, (def, vis, DUMMY_SP, Mark::root()));
 
                 // Record field names for error reporting.
                 let field_names = self.session.cstore.struct_field_names(def_id);
                 self.insert_field_names(def_id, field_names);
             }
             Def::StructCtor(..) => {
-                self.define(parent, name, ValueNS, (def, vis, DUMMY_SP, Mark::root()));
+                self.define(parent, ident, ValueNS, (def, vis, DUMMY_SP, Mark::root()));
             }
             Def::Union(..) => {
-                self.define(parent, name, TypeNS, (def, vis, DUMMY_SP, Mark::root()));
+                self.define(parent, ident, TypeNS, (def, vis, DUMMY_SP, Mark::root()));
 
                 // Record field names for error reporting.
                 let field_names = self.session.cstore.struct_field_names(def_id);
                 self.insert_field_names(def_id, field_names);
             }
             Def::Macro(..) => {
-                self.define(parent, name, MacroNS, (def, vis, DUMMY_SP, Mark::root()));
+                self.define(parent, ident, MacroNS, (def, vis, DUMMY_SP, Mark::root()));
             }
             Def::Local(..) |
             Def::PrimTy(..) |
@@ -489,14 +488,15 @@ fn build_reduced_graph_for_external_crate_def(&mut self, parent: Module<'b>, chi
         }
     }
 
-    fn get_extern_crate_root(&mut self, cnum: CrateNum) -> Module<'b> {
+    fn get_extern_crate_root(&mut self, cnum: CrateNum) -> Module<'a> {
         let def_id = DefId { krate: cnum, index: CRATE_DEF_INDEX };
+        let name = self.session.cstore.crate_name(cnum);
         let macros_only = self.session.cstore.dep_kind(cnum).macros_only();
         let arenas = self.arenas;
         *self.extern_crate_roots.entry((cnum, macros_only)).or_insert_with(|| {
-            arenas.alloc_module(ModuleS {
+            arenas.alloc_module(ModuleData {
                 populated: Cell::new(false),
-                ..ModuleS::new(None, ModuleKind::Def(Def::Mod(def_id), keywords::Invalid.name()))
+                ..ModuleData::new(None, ModuleKind::Def(Def::Mod(def_id), name))
             })
         })
     }
@@ -532,7 +532,7 @@ pub fn get_macro(&mut self, def: Def) -> Rc<SyntaxExtension> {
 
     /// Ensures that the reduced graph rooted at the given external module
     /// is built, building it if it is not.
-    pub fn populate_module_if_necessary(&mut self, module: Module<'b>) {
+    pub fn populate_module_if_necessary(&mut self, module: Module<'a>) {
         if module.populated.get() { return }
         for child in self.session.cstore.item_children(module.def_id().unwrap()) {
             self.build_reduced_graph_for_external_crate_def(module, child);
@@ -542,7 +542,7 @@ pub fn populate_module_if_necessary(&mut self, module: Module<'b>) {
 
     fn legacy_import_macro(&mut self,
                            name: Name,
-                           binding: &'b NameBinding<'b>,
+                           binding: &'a NameBinding<'a>,
                            span: Span,
                            allow_shadowing: bool) {
         self.used_crates.insert(binding.def().def_id().krate);
@@ -555,7 +555,7 @@ fn legacy_import_macro(&mut self,
         }
     }
 
-    fn process_legacy_macro_imports(&mut self, item: &Item, module: Module<'b>, expansion: Mark) {
+    fn process_legacy_macro_imports(&mut self, item: &Item, module: Module<'a>, expansion: Mark) {
         let allow_shadowing = expansion == Mark::root();
         let legacy_imports = self.legacy_macro_imports(&item.attrs);
         let cnum = module.def_id().unwrap().krate;
@@ -574,12 +574,13 @@ fn process_legacy_macro_imports(&mut self, item: &Item, module: Module<'b>, expa
         }
 
         if let Some(span) = legacy_imports.import_all {
-            module.for_each_child(|name, ns, binding| if ns == MacroNS {
-                self.legacy_import_macro(name, binding, span, allow_shadowing);
+            module.for_each_child(|ident, ns, binding| if ns == MacroNS {
+                self.legacy_import_macro(ident.name, binding, span, allow_shadowing);
             });
         } else {
             for (name, span) in legacy_imports.imports {
-                let result = self.resolve_name_in_module(module, name, MacroNS, false, None);
+                let ident = Ident::with_empty_ctxt(name);
+                let result = self.resolve_ident_in_module(module, ident, MacroNS, false, None);
                 if let Ok(binding) = result {
                     self.legacy_import_macro(name, binding, span, allow_shadowing);
                 } else {
@@ -591,7 +592,8 @@ fn process_legacy_macro_imports(&mut self, item: &Item, module: Module<'b>, expa
             let krate = module.def_id().unwrap().krate;
             self.used_crates.insert(krate);
             self.session.cstore.export_macros(krate);
-            let result = self.resolve_name_in_module(module, name, MacroNS, false, None);
+            let ident = Ident::with_empty_ctxt(name);
+            let result = self.resolve_ident_in_module(module, ident, MacroNS, false, None);
             if let Ok(binding) = result {
                 self.macro_exports.push(Export { name: name, def: binding.def() });
             } else {
@@ -696,9 +698,13 @@ impl<'a, 'b> Visitor<'a> for BuildReducedGraphVisitor<'a, 'b> {
 
     fn visit_item(&mut self, item: &'a Item) {
         let macro_use = match item.node {
-            ItemKind::Mac(..) if item.id == ast::DUMMY_NODE_ID => return, // Scope placeholder
-            ItemKind::Mac(..) => {
-                return self.legacy_scope = LegacyScope::Expansion(self.visit_invoc(item.id));
+            ItemKind::Mac(ref mac) => {
+                if mac.node.path.segments.is_empty() {
+                    self.legacy_scope = LegacyScope::Expansion(self.visit_invoc(item.id));
+                } else {
+                    self.resolver.define_macro(item, &mut self.legacy_scope);
+                }
+                return
             }
             ItemKind::Mod(..) => self.resolver.contains_macro_use(&item.attrs),
             _ => false,
@@ -759,7 +765,7 @@ fn visit_trait_item(&mut self, item: &'a TraitItem) {
         self.resolver.trait_item_map.insert((item.ident.name, def_id), is_static_method);
 
         let vis = ty::Visibility::Public;
-        self.resolver.define(parent, item.ident.name, ns, (def, vis, item.span, self.expansion));
+        self.resolver.define(parent, item.ident, ns, (def, vis, item.span, self.expansion));
 
         self.resolver.current_module = parent.parent.unwrap(); // nearest normal ancestor
         visit::walk_trait_item(self, item);
index 509ee704e2ea2551da9a0894250ed24f40657dc9..fb28b45d20e5a59b719f300555e9746f2b915146 100644 (file)
@@ -62,7 +62,7 @@
 use syntax::ast::{FnDecl, ForeignItem, ForeignItemKind, Generics};
 use syntax::ast::{Item, ItemKind, ImplItem, ImplItemKind};
 use syntax::ast::{Local, Mutability, Pat, PatKind, Path};
-use syntax::ast::{PathSegment, PathParameters, QSelf, TraitItemKind, TraitRef, Ty, TyKind};
+use syntax::ast::{QSelf, TraitItemKind, TraitRef, Ty, TyKind};
 
 use syntax_pos::{Span, DUMMY_SP};
 use errors::DiagnosticBuilder;
@@ -774,15 +774,15 @@ enum ModuleKind {
 }
 
 /// One node in the tree of modules.
-pub struct ModuleS<'a> {
+pub struct ModuleData<'a> {
     parent: Option<Module<'a>>,
     kind: ModuleKind,
 
     // The node id of the closest normal module (`mod`) ancestor (including this module).
     normal_ancestor_id: Option<NodeId>,
 
-    resolutions: RefCell<FxHashMap<(Name, Namespace), &'a RefCell<NameResolution<'a>>>>,
-    legacy_macro_resolutions: RefCell<Vec<(Mark, Name, Span)>>,
+    resolutions: RefCell<FxHashMap<(Ident, Namespace), &'a RefCell<NameResolution<'a>>>>,
+    legacy_macro_resolutions: RefCell<Vec<(Mark, Ident, Span)>>,
     macro_resolutions: RefCell<Vec<(Box<[Ident]>, PathScope, Span)>>,
 
     // Macro invocations that can expand into items in this module.
@@ -794,7 +794,7 @@ pub struct ModuleS<'a> {
     globs: RefCell<Vec<&'a ImportDirective<'a>>>,
 
     // Used to memoize the traits in this module for faster searches through all traits in scope.
-    traits: RefCell<Option<Box<[(Name, &'a NameBinding<'a>)]>>>,
+    traits: RefCell<Option<Box<[(Ident, &'a NameBinding<'a>)]>>>,
 
     // Whether this module is populated. If not populated, any attempt to
     // access the children must be preceded with a
@@ -802,11 +802,11 @@ pub struct ModuleS<'a> {
     populated: Cell<bool>,
 }
 
-pub type Module<'a> = &'a ModuleS<'a>;
+pub type Module<'a> = &'a ModuleData<'a>;
 
-impl<'a> ModuleS<'a> {
+impl<'a> ModuleData<'a> {
     fn new(parent: Option<Module<'a>>, kind: ModuleKind) -> Self {
-        ModuleS {
+        ModuleData {
             parent: parent,
             kind: kind,
             normal_ancestor_id: None,
@@ -822,9 +822,9 @@ fn new(parent: Option<Module<'a>>, kind: ModuleKind) -> Self {
         }
     }
 
-    fn for_each_child<F: FnMut(Name, Namespace, &'a NameBinding<'a>)>(&self, mut f: F) {
-        for (&(name, ns), name_resolution) in self.resolutions.borrow().iter() {
-            name_resolution.borrow().binding.map(|binding| f(name, ns, binding));
+    fn for_each_child<F: FnMut(Ident, Namespace, &'a NameBinding<'a>)>(&self, mut f: F) {
+        for (&(ident, ns), name_resolution) in self.resolutions.borrow().iter() {
+            name_resolution.borrow().binding.map(|binding| f(ident, ns, binding));
         }
     }
 
@@ -859,7 +859,7 @@ fn is_local(&self) -> bool {
     }
 }
 
-impl<'a> fmt::Debug for ModuleS<'a> {
+impl<'a> fmt::Debug for ModuleData<'a> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         write!(f, "{:?}", self.def())
     }
@@ -875,11 +875,11 @@ pub struct NameBinding<'a> {
 }
 
 pub trait ToNameBinding<'a> {
-    fn to_name_binding(self) -> NameBinding<'a>;
+    fn to_name_binding(self, arenas: &'a ResolverArenas<'a>) -> &'a NameBinding<'a>;
 }
 
-impl<'a> ToNameBinding<'a> for NameBinding<'a> {
-    fn to_name_binding(self) -> NameBinding<'a> {
+impl<'a> ToNameBinding<'a> for &'a NameBinding<'a> {
+    fn to_name_binding(self, _: &'a ResolverArenas<'a>) -> &'a NameBinding<'a> {
         self
     }
 }
@@ -1116,7 +1116,7 @@ pub struct Resolver<'a> {
 }
 
 pub struct ResolverArenas<'a> {
-    modules: arena::TypedArena<ModuleS<'a>>,
+    modules: arena::TypedArena<ModuleData<'a>>,
     local_modules: RefCell<Vec<Module<'a>>>,
     name_bindings: arena::TypedArena<NameBinding<'a>>,
     import_directives: arena::TypedArena<ImportDirective<'a>>,
@@ -1126,7 +1126,7 @@ pub struct ResolverArenas<'a> {
 }
 
 impl<'a> ResolverArenas<'a> {
-    fn alloc_module(&'a self, module: ModuleS<'a>) -> Module<'a> {
+    fn alloc_module(&'a self, module: ModuleData<'a>) -> Module<'a> {
         let module = self.modules.alloc(module);
         if module.def_id().map(|def_id| def_id.is_local()).unwrap_or(true) {
             self.local_modules.borrow_mut().push(module);
@@ -1206,10 +1206,10 @@ pub fn new(session: &'a Session,
                arenas: &'a ResolverArenas<'a>)
                -> Resolver<'a> {
         let root_def = Def::Mod(DefId::local(CRATE_DEF_INDEX));
-        let graph_root = arenas.alloc_module(ModuleS {
+        let graph_root = arenas.alloc_module(ModuleData {
             normal_ancestor_id: Some(CRATE_NODE_ID),
             no_implicit_prelude: attr::contains_name(&krate.attrs, "no_implicit_prelude"),
-            ..ModuleS::new(None, ModuleKind::Def(root_def, keywords::Invalid.name()))
+            ..ModuleData::new(None, ModuleKind::Def(root_def, keywords::Invalid.name()))
         });
         let mut module_map = NodeMap();
         module_map.insert(CRATE_NODE_ID, graph_root);
@@ -1327,17 +1327,17 @@ pub fn resolve_crate(&mut self, krate: &Crate) {
     }
 
     fn new_module(&self, parent: Module<'a>, kind: ModuleKind, local: bool) -> Module<'a> {
-        self.arenas.alloc_module(ModuleS {
+        self.arenas.alloc_module(ModuleData {
             normal_ancestor_id: if local { self.current_module.normal_ancestor_id } else { None },
             populated: Cell::new(local),
-            ..ModuleS::new(Some(parent), kind)
+            ..ModuleData::new(Some(parent), kind)
         })
     }
 
-    fn record_use(&mut self, name: Name, ns: Namespace, binding: &'a NameBinding<'a>, span: Span)
+    fn record_use(&mut self, ident: Ident, ns: Namespace, binding: &'a NameBinding<'a>, span: Span)
                   -> bool /* true if an error was reported */ {
         // track extern crates for unused_extern_crate lint
-        if let Some(DefId { krate, .. }) = binding.module().and_then(ModuleS::def_id) {
+        if let Some(DefId { krate, .. }) = binding.module().and_then(ModuleData::def_id) {
             self.used_crates.insert(krate);
         }
 
@@ -1345,13 +1345,13 @@ fn record_use(&mut self, name: Name, ns: Namespace, binding: &'a NameBinding<'a>
             NameBindingKind::Import { directive, binding, ref used } if !used.get() => {
                 used.set(true);
                 self.used_imports.insert((directive.id, ns));
-                self.add_to_glob_map(directive.id, name);
-                self.record_use(name, ns, binding, span)
+                self.add_to_glob_map(directive.id, ident);
+                self.record_use(ident, ns, binding, span)
             }
             NameBindingKind::Import { .. } => false,
             NameBindingKind::Ambiguity { b1, b2 } => {
                 self.ambiguity_errors.push(AmbiguityError {
-                    span: span, name: name, lexical: false, b1: b1, b2: b2,
+                    span: span, name: ident.name, lexical: false, b1: b1, b2: b2,
                 });
                 true
             }
@@ -1359,9 +1359,9 @@ fn record_use(&mut self, name: Name, ns: Namespace, binding: &'a NameBinding<'a>
         }
     }
 
-    fn add_to_glob_map(&mut self, id: NodeId, name: Name) {
+    fn add_to_glob_map(&mut self, id: NodeId, ident: Ident) {
         if self.make_glob_map {
-            self.glob_map.entry(id).or_insert_with(FxHashSet).insert(name);
+            self.glob_map.entry(id).or_insert_with(FxHashSet).insert(ident.name);
         }
     }
 
@@ -1388,7 +1388,7 @@ fn resolve_ident_in_lexical_scope(&mut self,
                                       record_used: Option<Span>)
                                       -> Option<LexicalScopeBinding<'a>> {
         if ns == TypeNS {
-            ident = Ident::with_empty_ctxt(ident.name);
+            ident = ident.unhygienize();
         }
 
         // Walk backwards up the ribs in scope.
@@ -1403,8 +1403,7 @@ fn resolve_ident_in_lexical_scope(&mut self,
             }
 
             if let ModuleRibKind(module) = self.ribs[ns][i].kind {
-                let name = ident.name;
-                let item = self.resolve_name_in_module(module, name, ns, false, record_used);
+                let item = self.resolve_ident_in_module(module, ident, ns, false, record_used);
                 if let Ok(binding) = item {
                     // The ident resolves to an item.
                     return Some(LexicalScopeBinding::Item(binding));
@@ -1413,7 +1412,7 @@ fn resolve_ident_in_lexical_scope(&mut self,
                 if let ModuleKind::Block(..) = module.kind { // We can see through blocks
                 } else if !module.no_implicit_prelude {
                     return self.prelude.and_then(|prelude| {
-                        self.resolve_name_in_module(prelude, name, ns, false, None).ok()
+                        self.resolve_ident_in_module(prelude, ident, ns, false, None).ok()
                     }).map(LexicalScopeBinding::Item)
                 } else {
                     return None;
@@ -2183,8 +2182,7 @@ fn resolve_pattern(&mut self,
                             Def::VariantCtor(_, CtorKind::Const) |
                             Def::Const(..) if !always_binding => {
                                 // A unit struct/variant or constant pattern.
-                                let name = ident.node.name;
-                                self.record_use(name, ValueNS, binding.unwrap(), ident.span);
+                                self.record_use(ident.node, ValueNS, binding.unwrap(), ident.span);
                                 Some(PathResolution::new(def))
                             }
                             Def::StructCtor(..) | Def::VariantCtor(..) |
@@ -2363,9 +2361,9 @@ fn resolve_path(&mut self,
             allow_super = false;
 
             let binding = if let Some(module) = module {
-                self.resolve_name_in_module(module, ident.name, ns, false, record_used)
+                self.resolve_ident_in_module(module, ident, ns, false, record_used)
             } else if opt_ns == Some(MacroNS) {
-                self.resolve_lexical_macro_path_segment(ident.name, ns, record_used)
+                self.resolve_lexical_macro_path_segment(ident, ns, record_used)
             } else {
                 match self.resolve_ident_in_lexical_scope(ident, ns, record_used) {
                     Some(LexicalScopeBinding::Item(binding)) => Ok(binding),
@@ -2405,7 +2403,7 @@ fn resolve_path(&mut self,
                             });
                         }
                     }
-                    let msg = if module.and_then(ModuleS::def) == self.graph_root.def() {
+                    let msg = if module.and_then(ModuleData::def) == self.graph_root.def() {
                         let is_mod = |def| match def { Def::Mod(..) => true, _ => false };
                         let mut candidates =
                             self.lookup_candidates(ident.name, TypeNS, is_mod).candidates;
@@ -2865,72 +2863,64 @@ fn record_candidate_traits_for_expr_if_necessary(&mut self, expr: &Expr) {
     fn get_traits_containing_item(&mut self, name: Name) -> Vec<TraitCandidate> {
         debug!("(getting traits containing item) looking for '{}'", name);
 
-        fn add_trait_info(found_traits: &mut Vec<TraitCandidate>,
-                          trait_def_id: DefId,
-                          import_id: Option<NodeId>,
-                          name: Name) {
-            debug!("(adding trait info) found trait {:?} for method '{}'",
-                   trait_def_id,
-                   name);
-            found_traits.push(TraitCandidate {
-                def_id: trait_def_id,
-                import_id: import_id,
-            });
-        }
-
         let mut found_traits = Vec::new();
         // Look for the current trait.
         if let Some((trait_def_id, _)) = self.current_trait_ref {
             if self.trait_item_map.contains_key(&(name, trait_def_id)) {
-                add_trait_info(&mut found_traits, trait_def_id, None, name);
+                found_traits.push(TraitCandidate { def_id: trait_def_id, import_id: None });
             }
         }
 
         let mut search_module = self.current_module;
         loop {
-            // Look for trait children.
-            let mut search_in_module = |this: &mut Self, module: Module<'a>| {
-                let mut traits = module.traits.borrow_mut();
-                if traits.is_none() {
-                    let mut collected_traits = Vec::new();
-                    module.for_each_child(|name, ns, binding| {
-                        if ns != TypeNS { return }
-                        if let Def::Trait(_) = binding.def() {
-                            collected_traits.push((name, binding));
-                        }
-                    });
-                    *traits = Some(collected_traits.into_boxed_slice());
-                }
-
-                for &(trait_name, binding) in traits.as_ref().unwrap().iter() {
-                    let trait_def_id = binding.def().def_id();
-                    if this.trait_item_map.contains_key(&(name, trait_def_id)) {
-                        let mut import_id = None;
-                        if let NameBindingKind::Import { directive, .. } = binding.kind {
-                            let id = directive.id;
-                            this.maybe_unused_trait_imports.insert(id);
-                            this.add_to_glob_map(id, trait_name);
-                            import_id = Some(id);
-                        }
-                        add_trait_info(&mut found_traits, trait_def_id, import_id, name);
-                    }
-                }
-            };
-            search_in_module(self, search_module);
+            self.get_traits_in_module_containing_item(name, search_module, &mut found_traits);
+            match search_module.kind {
+                ModuleKind::Block(..) => search_module = search_module.parent.unwrap(),
+                _ => break,
+            }
+        }
 
-            if let ModuleKind::Block(..) = search_module.kind {
-                search_module = search_module.parent.unwrap();
-            } else {
-                if !search_module.no_implicit_prelude {
-                    self.prelude.map(|prelude| search_in_module(self, prelude));
-                }
-                break;
+        if let Some(prelude) = self.prelude {
+            if !search_module.no_implicit_prelude {
+                self.get_traits_in_module_containing_item(name, prelude, &mut found_traits);
             }
         }
 
         found_traits
     }
 
+    fn get_traits_in_module_containing_item(&mut self,
+                                            name: Name,
+                                            module: Module,
+                                            found_traits: &mut Vec<TraitCandidate>) {
+        let mut traits = module.traits.borrow_mut();
+        if traits.is_none() {
+            let mut collected_traits = Vec::new();
+            module.for_each_child(|name, ns, binding| {
+                if ns != TypeNS { return }
+                if let Def::Trait(_) = binding.def() {
+                    collected_traits.push((name, binding));
+                }
+            });
+            *traits = Some(collected_traits.into_boxed_slice());
+        }
+
+        for &(trait_name, binding) in traits.as_ref().unwrap().iter() {
+            let trait_def_id = binding.def().def_id();
+            if self.trait_item_map.contains_key(&(name, trait_def_id)) {
+                let import_id = match binding.kind {
+                    NameBindingKind::Import { directive, .. } => {
+                        self.maybe_unused_trait_imports.insert(directive.id);
+                        self.add_to_glob_map(directive.id, trait_name);
+                        Some(directive.id)
+                    }
+                    _ => None,
+                };
+                found_traits.push(TraitCandidate { def_id: trait_def_id, import_id: import_id });
+            }
+        }
+    }
+
     /// When name resolution fails, this method can be used to look up candidate
     /// entities with the expected name. It allows filtering them using the
     /// supplied predicate (which should be used to only accept the types of
@@ -2953,24 +2943,18 @@ fn lookup_candidates<FilterFn>(&mut self,
                         in_module_is_extern)) = worklist.pop() {
             self.populate_module_if_necessary(in_module);
 
-            in_module.for_each_child(|name, ns, name_binding| {
+            in_module.for_each_child(|ident, ns, name_binding| {
 
                 // avoid imports entirely
                 if name_binding.is_import() && !name_binding.is_extern_crate() { return; }
 
                 // collect results based on the filter function
-                if name == lookup_name && ns == namespace {
+                if ident.name == lookup_name && ns == namespace {
                     if filter_fn(name_binding.def()) {
                         // create the path
-                        let ident = Ident::with_empty_ctxt(name);
-                        let params = PathParameters::none();
-                        let segment = PathSegment {
-                            identifier: ident,
-                            parameters: params,
-                        };
                         let span = name_binding.span;
                         let mut segms = path_segments.clone();
-                        segms.push(segment);
+                        segms.push(ident.into());
                         let path = Path {
                             span: span,
                             global: false,
@@ -2993,10 +2977,7 @@ fn lookup_candidates<FilterFn>(&mut self,
                 if let Some(module) = name_binding.module() {
                     // form the path
                     let mut path_segments = path_segments.clone();
-                    path_segments.push(PathSegment {
-                        identifier: Ident::with_empty_ctxt(name),
-                        parameters: PathParameters::none(),
-                    });
+                    path_segments.push(ident.into());
 
                     if !in_module_is_extern || name_binding.vis == ty::Visibility::Public {
                         // add the module to the lookup
@@ -3124,13 +3105,13 @@ fn report_shadowing_errors(&mut self) {
 
     fn report_conflict(&mut self,
                        parent: Module,
-                       name: Name,
+                       ident: Ident,
                        ns: Namespace,
                        binding: &NameBinding,
                        old_binding: &NameBinding) {
         // Error on the second of two conflicting names
         if old_binding.span.lo > binding.span.lo {
-            return self.report_conflict(parent, name, ns, old_binding, binding);
+            return self.report_conflict(parent, ident, ns, old_binding, binding);
         }
 
         let container = match parent.kind {
@@ -3145,7 +3126,7 @@ fn report_conflict(&mut self,
             false => ("defined", "definition"),
         };
 
-        let span = binding.span;
+        let (name, span) = (ident.name, binding.span);
 
         if let Some(s) = self.name_already_seen.get(&name) {
             if s == &span {
@@ -3167,40 +3148,19 @@ fn report_conflict(&mut self,
         };
 
         let mut err = match (old_binding.is_extern_crate(), binding.is_extern_crate()) {
-            (true, true) => {
-                let mut e = struct_span_err!(self.session, span, E0259, "{}", msg);
-                e.span_label(span, &format!("`{}` was already imported", name));
-                e
-            },
-            (true, _) | (_, true) if binding.is_import() && old_binding.is_import() => {
-                let mut e = struct_span_err!(self.session, span, E0254, "{}", msg);
-                e.span_label(span, &"already imported");
-                e
-            },
-            (true, _) | (_, true) => {
-                let mut e = struct_span_err!(self.session, span, E0260, "{}", msg);
-                e.span_label(span, &format!("`{}` already imported", name));
-                e
+            (true, true) => struct_span_err!(self.session, span, E0259, "{}", msg),
+            (true, _) | (_, true) => match binding.is_import() && old_binding.is_import() {
+                true => struct_span_err!(self.session, span, E0254, "{}", msg),
+                false => struct_span_err!(self.session, span, E0260, "{}", msg),
             },
             _ => match (old_binding.is_import(), binding.is_import()) {
-                (false, false) => {
-                    let mut e = struct_span_err!(self.session, span, E0428, "{}", msg);
-                    e.span_label(span, &format!("already defined"));
-                    e
-                },
-                (true, true) => {
-                    let mut e = struct_span_err!(self.session, span, E0252, "{}", msg);
-                    e.span_label(span, &format!("already imported"));
-                    e
-                },
-                _ => {
-                    let mut e = struct_span_err!(self.session, span, E0255, "{}", msg);
-                    e.span_label(span, &format!("`{}` was already imported", name));
-                    e
-                }
+                (false, false) => struct_span_err!(self.session, span, E0428, "{}", msg),
+                (true, true) => struct_span_err!(self.session, span, E0252, "{}", msg),
+                _ => struct_span_err!(self.session, span, E0255, "{}", msg),
             },
         };
 
+        err.span_label(span, &format!("`{}` already {}", name, participle));
         if old_binding.span != syntax_pos::DUMMY_SP {
             err.span_label(old_binding.span, &format!("previous {} of `{}` here", noun, name));
         }
index 6c02967672d84f48d0ffbadef20e2b9a18dcf888..dfeb66e1d8c7698d8c2baf26bb140a9f63867870 100644 (file)
 use rustc::ty;
 use std::cell::Cell;
 use std::rc::Rc;
-use syntax::ast::{self, Name};
+use syntax::ast::{self, Name, Ident};
+use syntax::attr;
 use syntax::errors::DiagnosticBuilder;
 use syntax::ext::base::{self, Determinacy, MultiModifier, MultiDecorator};
-use syntax::ext::base::{NormalTT, SyntaxExtension};
-use syntax::ext::expand::Expansion;
+use syntax::ext::base::{NormalTT, Resolver as SyntaxResolver, SyntaxExtension};
+use syntax::ext::expand::{Expansion, mark_tts};
 use syntax::ext::hygiene::Mark;
 use syntax::ext::tt::macro_rules;
 use syntax::feature_gate::{emit_feature_err, GateIssue};
@@ -138,34 +139,6 @@ fn visit_expansion(&mut self, mark: Mark, expansion: &Expansion) {
         invocation.expansion.set(visitor.legacy_scope);
     }
 
-    fn add_macro(&mut self, scope: Mark, mut def: ast::MacroDef, export: bool) {
-        if def.ident.name == "macro_rules" {
-            self.session.span_err(def.span, "user-defined macros may not be named `macro_rules`");
-        }
-
-        let invocation = self.invocations[&scope];
-        let binding = self.arenas.alloc_legacy_binding(LegacyBinding {
-            parent: Cell::new(invocation.legacy_scope.get()),
-            name: def.ident.name,
-            ext: Rc::new(macro_rules::compile(&self.session.parse_sess, &def)),
-            span: def.span,
-        });
-        invocation.legacy_scope.set(LegacyScope::Binding(binding));
-        self.macro_names.insert(def.ident.name);
-
-        if export {
-            def.id = self.next_node_id();
-            DefCollector::new(&mut self.definitions).with_parent(CRATE_DEF_INDEX, |collector| {
-                collector.visit_macro_def(&def)
-            });
-            self.macro_exports.push(Export {
-                name: def.ident.name,
-                def: Def::Macro(self.definitions.local_def_id(def.id)),
-            });
-            self.exported_macros.push(def);
-        }
-    }
-
     fn add_ext(&mut self, ident: ast::Ident, ext: Rc<SyntaxExtension>) {
         if let NormalTT(..) = *ext {
             self.macro_names.insert(ident.name);
@@ -210,9 +183,9 @@ fn find_attr_invoc(&mut self, attrs: &mut Vec<ast::Attribute>) -> Option<ast::At
     fn resolve_macro(&mut self, scope: Mark, path: &ast::Path, force: bool)
                      -> Result<Rc<SyntaxExtension>, Determinacy> {
         let ast::Path { ref segments, global, span } = *path;
-        if segments.iter().any(|segment| !segment.parameters.is_empty()) {
+        if segments.iter().any(|segment| segment.parameters.is_some()) {
             let kind =
-                if segments.last().unwrap().parameters.is_empty() { "module" } else { "macro" };
+                if segments.last().unwrap().parameters.is_some() { "macro" } else { "module" };
             let msg = format!("type parameters are not allowed on {}s", kind);
             self.session.span_err(path.span, &msg);
             return Err(Determinacy::Determined);
@@ -232,7 +205,10 @@ fn resolve_macro(&mut self, scope: Mark, path: &ast::Path, force: bool)
             }
 
             let ext = match self.resolve_path(&path, path_scope, Some(MacroNS), None) {
-                PathResult::NonModule(path_res) => Ok(self.get_macro(path_res.base_def)),
+                PathResult::NonModule(path_res) => match path_res.base_def {
+                    Def::Err => Err(Determinacy::Determined),
+                    def @ _ => Ok(self.get_macro(def)),
+                },
                 PathResult::Module(..) => unreachable!(),
                 PathResult::Indeterminate if !force => return Err(Determinacy::Undetermined),
                 _ => Err(Determinacy::Determined),
@@ -246,7 +222,7 @@ fn resolve_macro(&mut self, scope: Mark, path: &ast::Path, force: bool)
         let result = match self.resolve_legacy_scope(&invocation.legacy_scope, name, false) {
             Some(MacroBinding::Legacy(binding)) => Ok(binding.ext.clone()),
             Some(MacroBinding::Modern(binding)) => Ok(binding.get_macro(self)),
-            None => match self.resolve_lexical_macro_path_segment(name, MacroNS, None) {
+            None => match self.resolve_lexical_macro_path_segment(path[0], MacroNS, None) {
                 Ok(binding) => Ok(binding.get_macro(self)),
                 Err(Determinacy::Undetermined) if !force => return Err(Determinacy::Undetermined),
                 _ => {
@@ -260,7 +236,7 @@ fn resolve_macro(&mut self, scope: Mark, path: &ast::Path, force: bool)
         };
 
         if self.use_extern_macros {
-            self.current_module.legacy_macro_resolutions.borrow_mut().push((scope, name, span));
+            self.current_module.legacy_macro_resolutions.borrow_mut().push((scope, path[0], span));
         }
         result
     }
@@ -269,7 +245,7 @@ fn resolve_macro(&mut self, scope: Mark, path: &ast::Path, force: bool)
 impl<'a> Resolver<'a> {
     // Resolve the initial segment of a non-global macro path (e.g. `foo` in `foo::bar!();`)
     pub fn resolve_lexical_macro_path_segment(&mut self,
-                                              name: Name,
+                                              ident: Ident,
                                               ns: Namespace,
                                               record_used: Option<Span>)
                                               -> Result<&'a NameBinding<'a>, Determinacy> {
@@ -278,7 +254,7 @@ pub fn resolve_lexical_macro_path_segment(&mut self,
         loop {
             // Since expanded macros may not shadow the lexical scope (enforced below),
             // we can ignore unresolved invocations (indicated by the penultimate argument).
-            match self.resolve_name_in_module(module, name, ns, true, record_used) {
+            match self.resolve_ident_in_module(module, ident, ns, true, record_used) {
                 Ok(binding) => {
                     let span = match record_used {
                         Some(span) => span,
@@ -286,6 +262,7 @@ pub fn resolve_lexical_macro_path_segment(&mut self,
                     };
                     match potential_expanded_shadower {
                         Some(shadower) if shadower.def() != binding.def() => {
+                            let name = ident.name;
                             self.ambiguity_errors.push(AmbiguityError {
                                 span: span, name: name, b1: shadower, b2: binding, lexical: true,
                             });
@@ -383,10 +360,10 @@ pub fn finalize_current_module_macro_resolutions(&mut self) {
             }
         }
 
-        for &(mark, name, span) in module.legacy_macro_resolutions.borrow().iter() {
+        for &(mark, ident, span) in module.legacy_macro_resolutions.borrow().iter() {
             let legacy_scope = &self.invocations[&mark].legacy_scope;
-            let legacy_resolution = self.resolve_legacy_scope(legacy_scope, name, true);
-            let resolution = self.resolve_lexical_macro_path_segment(name, MacroNS, Some(span));
+            let legacy_resolution = self.resolve_legacy_scope(legacy_scope, ident.name, true);
+            let resolution = self.resolve_lexical_macro_path_segment(ident, MacroNS, Some(span));
             let (legacy_resolution, resolution) = match (legacy_resolution, resolution) {
                 (Some(legacy_resolution), Ok(resolution)) => (legacy_resolution, resolution),
                 _ => continue,
@@ -396,9 +373,9 @@ pub fn finalize_current_module_macro_resolutions(&mut self) {
                 MacroBinding::Modern(binding) => (binding.span, "imported"),
                 MacroBinding::Legacy(binding) => (binding.span, "defined"),
             };
-            let msg1 = format!("`{}` could resolve to the macro {} here", name, participle);
-            let msg2 = format!("`{}` could also resolve to the macro imported here", name);
-            self.session.struct_span_err(span, &format!("`{}` is ambiguous", name))
+            let msg1 = format!("`{}` could resolve to the macro {} here", ident, participle);
+            let msg2 = format!("`{}` could also resolve to the macro imported here", ident);
+            self.session.struct_span_err(span, &format!("`{}` is ambiguous", ident))
                 .span_note(legacy_span, &msg1)
                 .span_note(resolution.span, &msg2)
                 .emit();
@@ -442,4 +419,47 @@ fn collect_def_ids(&mut self, invocation: &'a InvocationData<'a>, expansion: &Ex
             expansion.visit_with(def_collector)
         });
     }
+
+    pub fn define_macro(&mut self, item: &ast::Item, legacy_scope: &mut LegacyScope<'a>) {
+        let tts = match item.node {
+            ast::ItemKind::Mac(ref mac) => &mac.node.tts,
+            _ => unreachable!(),
+        };
+
+        if item.ident.name == "macro_rules" {
+            self.session.span_err(item.span, "user-defined macros may not be named `macro_rules`");
+        }
+
+        let mark = Mark::from_placeholder_id(item.id);
+        let invocation = self.invocations[&mark];
+        invocation.module.set(self.current_module);
+
+        let mut def = ast::MacroDef {
+            ident: item.ident,
+            attrs: item.attrs.clone(),
+            id: ast::DUMMY_NODE_ID,
+            span: item.span,
+            body: mark_tts(tts, mark),
+        };
+
+        *legacy_scope = LegacyScope::Binding(self.arenas.alloc_legacy_binding(LegacyBinding {
+            parent: Cell::new(*legacy_scope),
+            name: def.ident.name,
+            ext: Rc::new(macro_rules::compile(&self.session.parse_sess, &def)),
+            span: def.span,
+        }));
+        self.macro_names.insert(def.ident.name);
+
+        if attr::contains_name(&def.attrs, "macro_export") {
+            def.id = self.next_node_id();
+            DefCollector::new(&mut self.definitions).with_parent(CRATE_DEF_INDEX, |collector| {
+                collector.visit_macro_def(&def)
+            });
+            self.macro_exports.push(Export {
+                name: def.ident.name,
+                def: Def::Macro(self.definitions.local_def_id(def.id)),
+            });
+            self.exported_macros.push(def);
+        }
+    }
 }
index 890891fd090183b5a7225f5d1462d2ee824cf4b6..2c35d7ec4423fcab73e9347094dce7a0bc0277f0 100644 (file)
@@ -12,7 +12,7 @@
 
 use {AmbiguityError, Module, PerNS};
 use Namespace::{self, TypeNS, MacroNS};
-use {NameBinding, NameBindingKind, PathResult, PathScope, PrivacyError, ToNameBinding};
+use {NameBinding, NameBindingKind, PathResult, PathScope, PrivacyError};
 use Resolver;
 use {names_to_string, module_to_string};
 use {resolve_error, ResolutionError};
@@ -21,7 +21,7 @@
 use rustc::lint::builtin::PRIVATE_IN_PUBLIC;
 use rustc::hir::def::*;
 
-use syntax::ast::{Ident, NodeId, Name};
+use syntax::ast::{Ident, NodeId};
 use syntax::ext::base::Determinacy::{self, Determined, Undetermined};
 use syntax::ext::hygiene::Mark;
 use syntax::symbol::keywords;
@@ -35,8 +35,8 @@
 #[derive(Clone, Debug)]
 pub enum ImportDirectiveSubclass<'a> {
     SingleImport {
-        target: Name,
-        source: Name,
+        target: Ident,
+        source: Ident,
         result: PerNS<Cell<Result<&'a NameBinding<'a>, Determinacy>>>,
     },
     GlobImport {
@@ -126,31 +126,32 @@ fn binding(&self) -> Option<&'a NameBinding<'a>> {
 }
 
 impl<'a> Resolver<'a> {
-    fn resolution(&self, module: Module<'a>, name: Name, ns: Namespace)
+    fn resolution(&self, module: Module<'a>, ident: Ident, ns: Namespace)
                   -> &'a RefCell<NameResolution<'a>> {
-        *module.resolutions.borrow_mut().entry((name, ns))
+        *module.resolutions.borrow_mut().entry((ident, ns))
                .or_insert_with(|| self.arenas.alloc_name_resolution())
     }
 
-    /// Attempts to resolve the supplied name in the given module for the given namespace.
-    /// If successful, returns the binding corresponding to the name.
+    /// Attempts to resolve `ident` in namespaces `ns` of `module`.
     /// Invariant: if `record_used` is `Some`, import resolution must be complete.
-    pub fn resolve_name_in_module(&mut self,
-                                  module: Module<'a>,
-                                  name: Name,
-                                  ns: Namespace,
-                                  ignore_unresolved_invocations: bool,
-                                  record_used: Option<Span>)
-                                  -> Result<&'a NameBinding<'a>, Determinacy> {
+    pub fn resolve_ident_in_module(&mut self,
+                                   module: Module<'a>,
+                                   ident: Ident,
+                                   ns: Namespace,
+                                   ignore_unresolved_invocations: bool,
+                                   record_used: Option<Span>)
+                                   -> Result<&'a NameBinding<'a>, Determinacy> {
+        let ident = ident.unhygienize();
         self.populate_module_if_necessary(module);
 
-        let resolution = self.resolution(module, name, ns)
+        let resolution = self.resolution(module, ident, ns)
             .try_borrow_mut()
             .map_err(|_| Determined)?; // This happens when there is a cycle of imports
 
         if let Some(span) = record_used {
             if let Some(binding) = resolution.binding {
                 if let Some(shadowed_glob) = resolution.shadows_glob {
+                    let name = ident.name;
                     // If we ignore unresolved invocations, we must forbid
                     // expanded shadowing to avoid time travel.
                     if ignore_unresolved_invocations &&
@@ -162,11 +163,11 @@ pub fn resolve_name_in_module(&mut self,
                         });
                     }
                 }
-                if self.record_use(name, ns, binding, span) {
+                if self.record_use(ident, ns, binding, span) {
                     return Ok(self.dummy_binding);
                 }
                 if !self.is_accessible(binding.vis) {
-                    self.privacy_errors.push(PrivacyError(span, name, binding));
+                    self.privacy_errors.push(PrivacyError(span, ident.name, binding));
                 }
             }
 
@@ -194,11 +195,11 @@ pub fn resolve_name_in_module(&mut self,
                     Some(module) => module,
                     None => return Err(Undetermined),
                 };
-                let name = match directive.subclass {
+                let ident = match directive.subclass {
                     SingleImport { source, .. } => source,
                     _ => unreachable!(),
                 };
-                match self.resolve_name_in_module(module, name, ns, false, None) {
+                match self.resolve_ident_in_module(module, ident, ns, false, None) {
                     Err(Determined) => {}
                     _ => return Err(Undetermined),
                 }
@@ -220,7 +221,7 @@ pub fn resolve_name_in_module(&mut self,
         for directive in module.globs.borrow().iter() {
             if self.is_accessible(directive.vis.get()) {
                 if let Some(module) = directive.imported_module.get() {
-                    let result = self.resolve_name_in_module(module, name, ns, false, None);
+                    let result = self.resolve_ident_in_module(module, ident, ns, false, None);
                     if let Err(Undetermined) = result {
                         return Err(Undetermined);
                     }
@@ -272,7 +273,7 @@ pub fn add_import_directive(&mut self,
     // Given a binding and an import directive that resolves to it,
     // return the corresponding binding defined by the import directive.
     pub fn import(&mut self, binding: &'a NameBinding<'a>, directive: &'a ImportDirective<'a>)
-                  -> NameBinding<'a> {
+                  -> &'a NameBinding<'a> {
         let vis = if binding.pseudo_vis().is_at_least(directive.vis.get(), self) ||
                      !directive.is_glob() && binding.is_extern_crate() { // c.f. `PRIVATE_IN_PUBLIC`
             directive.vis.get()
@@ -286,7 +287,7 @@ pub fn import(&mut self, binding: &'a NameBinding<'a>, directive: &'a ImportDire
             }
         }
 
-        NameBinding {
+        self.arenas.alloc_name_binding(NameBinding {
             kind: NameBindingKind::Import {
                 binding: binding,
                 directive: directive,
@@ -295,16 +296,18 @@ pub fn import(&mut self, binding: &'a NameBinding<'a>, directive: &'a ImportDire
             span: directive.span,
             vis: vis,
             expansion: directive.expansion,
-        }
+        })
     }
 
     // Define the name or return the existing binding if there is a collision.
-    pub fn try_define<T>(&mut self, module: Module<'a>, name: Name, ns: Namespace, binding: T)
-                         -> Result<(), &'a NameBinding<'a>>
-        where T: ToNameBinding<'a>
-    {
-        let binding = self.arenas.alloc_name_binding(binding.to_name_binding());
-        self.update_resolution(module, name, ns, |this, resolution| {
+    pub fn try_define(&mut self,
+                      module: Module<'a>,
+                      ident: Ident,
+                      ns: Namespace,
+                      binding: &'a NameBinding<'a>)
+                      -> Result<(), &'a NameBinding<'a>> {
+        let ident = ident.unhygienize();
+        self.update_resolution(module, ident, ns, |this, resolution| {
             if let Some(old_binding) = resolution.binding {
                 if binding.is_glob_import() {
                     if !old_binding.is_glob_import() &&
@@ -347,13 +350,14 @@ pub fn ambiguity(&mut self, b1: &'a NameBinding<'a>, b2: &'a NameBinding<'a>)
 
     // Use `f` to mutate the resolution of the name in the module.
     // If the resolution becomes a success, define it in the module's glob importers.
-    fn update_resolution<T, F>(&mut self, module: Module<'a>, name: Name, ns: Namespace, f: F) -> T
+    fn update_resolution<T, F>(&mut self, module: Module<'a>, ident: Ident, ns: Namespace, f: F)
+                               -> T
         where F: FnOnce(&mut Resolver<'a>, &mut NameResolution<'a>) -> T
     {
         // Ensure that `resolution` isn't borrowed when defining in the module's glob importers,
         // during which the resolution might end up getting re-defined via a glob cycle.
         let (binding, t) = {
-            let mut resolution = &mut *self.resolution(module, name, ns).borrow_mut();
+            let mut resolution = &mut *self.resolution(module, ident, ns).borrow_mut();
             let old_binding = resolution.binding();
 
             let t = f(self, resolution);
@@ -372,7 +376,7 @@ fn update_resolution<T, F>(&mut self, module: Module<'a>, name: Name, ns: Namesp
         for directive in module.glob_importers.borrow_mut().iter() {
             if self.is_accessible_from(binding.vis, directive.parent) {
                 let imported_binding = self.import(binding, directive);
-                let _ = self.try_define(directive.parent, name, ns, imported_binding);
+                let _ = self.try_define(directive.parent, ident, ns, imported_binding);
             }
         }
 
@@ -386,7 +390,7 @@ fn import_dummy_binding(&mut self, directive: &'a ImportDirective<'a>) {
             let dummy_binding = self.dummy_binding;
             let dummy_binding = self.import(dummy_binding, directive);
             self.per_ns(|this, ns| {
-                let _ = this.try_define(directive.parent, target, ns, dummy_binding.clone());
+                let _ = this.try_define(directive.parent, target, ns, dummy_binding);
             });
         }
     }
@@ -508,15 +512,16 @@ fn resolve_import(&mut self, directive: &'b ImportDirective<'b>) -> bool {
         let mut indeterminate = false;
         self.per_ns(|this, ns| {
             if let Err(Undetermined) = result[ns].get() {
-                result[ns].set(this.resolve_name_in_module(module, source, ns, false, None));
+                result[ns].set(this.resolve_ident_in_module(module, source, ns, false, None));
             } else {
                 return
             };
 
+            let parent = directive.parent;
             match result[ns].get() {
                 Err(Undetermined) => indeterminate = true,
                 Err(Determined) => {
-                    this.update_resolution(directive.parent, target, ns, |_, resolution| {
+                    this.update_resolution(parent, target, ns, |_, resolution| {
                         resolution.single_imports.directive_failed()
                     });
                 }
@@ -531,10 +536,9 @@ fn resolve_import(&mut self, directive: &'b ImportDirective<'b>) -> bool {
                 }
                 Ok(binding) => {
                     let imported_binding = this.import(binding, directive);
-                    let conflict = this.try_define(directive.parent, target, ns, imported_binding);
+                    let conflict = this.try_define(parent, target, ns, imported_binding);
                     if let Err(old_binding) = conflict {
-                        let binding = &this.import(binding, directive);
-                        this.report_conflict(directive.parent, target, ns, binding, old_binding);
+                        this.report_conflict(parent, target, ns, imported_binding, old_binding);
                     }
                 }
             }
@@ -564,7 +568,7 @@ fn finalize_import(&mut self, directive: &'b ImportDirective<'b>) -> Option<Stri
             _ => return None,
         };
 
-        let (name, result) = match directive.subclass {
+        let (ident, result) = match directive.subclass {
             SingleImport { source, ref result, .. } => (source, result),
             GlobImport { .. } if module.def_id() == directive.parent.def_id() => {
                 // Importing a module into itself is not allowed.
@@ -586,8 +590,8 @@ fn finalize_import(&mut self, directive: &'b ImportDirective<'b>) -> Option<Stri
         self.per_ns(|this, ns| {
             if let Ok(binding) = result[ns].get() {
                 all_ns_err = false;
-                if this.record_use(name, ns, binding, directive.span) {
-                    this.resolution(module, name, ns).borrow_mut().binding =
+                if this.record_use(ident, ns, binding, directive.span) {
+                    this.resolution(module, ident, ns).borrow_mut().binding =
                         Some(this.dummy_binding);
                 }
             }
@@ -596,7 +600,7 @@ fn finalize_import(&mut self, directive: &'b ImportDirective<'b>) -> Option<Stri
         if all_ns_err {
             let mut all_ns_failed = true;
             self.per_ns(|this, ns| {
-                match this.resolve_name_in_module(module, name, ns, false, Some(span)) {
+                match this.resolve_ident_in_module(module, ident, ns, false, Some(span)) {
                     Ok(_) => all_ns_failed = false,
                     _ => {}
                 }
@@ -604,27 +608,28 @@ fn finalize_import(&mut self, directive: &'b ImportDirective<'b>) -> Option<Stri
 
             return if all_ns_failed {
                 let resolutions = module.resolutions.borrow();
-                let names = resolutions.iter().filter_map(|(&(ref n, _), resolution)| {
-                    if *n == name { return None; } // Never suggest the same name
+                let names = resolutions.iter().filter_map(|(&(ref i, _), resolution)| {
+                    if *i == ident { return None; } // Never suggest the same name
                     match *resolution.borrow() {
-                        NameResolution { binding: Some(_), .. } => Some(n),
+                        NameResolution { binding: Some(_), .. } => Some(&i.name),
                         NameResolution { single_imports: SingleImports::None, .. } => None,
-                        _ => Some(n),
+                        _ => Some(&i.name),
                     }
                 });
-                let lev_suggestion = match find_best_match_for_name(names, &name.as_str(), None) {
-                    Some(name) => format!(". Did you mean to use `{}`?", name),
-                    None => "".to_owned(),
-                };
+                let lev_suggestion =
+                    match find_best_match_for_name(names, &ident.name.as_str(), None) {
+                        Some(name) => format!(". Did you mean to use `{}`?", name),
+                        None => "".to_owned(),
+                    };
                 let module_str = module_to_string(module);
                 let msg = if &module_str == "???" {
-                    format!("no `{}` in the root{}", name, lev_suggestion)
+                    format!("no `{}` in the root{}", ident, lev_suggestion)
                 } else {
-                    format!("no `{}` in `{}`{}", name, module_str, lev_suggestion)
+                    format!("no `{}` in `{}`{}", ident, module_str, lev_suggestion)
                 };
                 Some(msg)
             } else {
-                // `resolve_name_in_module` reported a privacy error.
+                // `resolve_ident_in_module` reported a privacy error.
                 self.import_dummy_binding(directive);
                 None
             }
@@ -649,18 +654,18 @@ fn finalize_import(&mut self, directive: &'b ImportDirective<'b>) -> Option<Stri
             if ns == TypeNS && binding.is_extern_crate() {
                 let msg = format!("extern crate `{}` is private, and cannot be reexported \
                                    (error E0364), consider declaring with `pub`",
-                                   name);
+                                   ident);
                 self.session.add_lint(PRIVATE_IN_PUBLIC, directive.id, directive.span, msg);
             } else if ns == TypeNS {
                 struct_span_err!(self.session, directive.span, E0365,
-                                 "`{}` is private, and cannot be reexported", name)
-                    .span_label(directive.span, &format!("reexport of private `{}`", name))
-                    .note(&format!("consider declaring type or module `{}` with `pub`", name))
+                                 "`{}` is private, and cannot be reexported", ident)
+                    .span_label(directive.span, &format!("reexport of private `{}`", ident))
+                    .note(&format!("consider declaring type or module `{}` with `pub`", ident))
                     .emit();
             } else {
-                let msg = format!("`{}` is private, and cannot be reexported", name);
+                let msg = format!("`{}` is private, and cannot be reexported", ident);
                 let note_msg =
-                    format!("consider marking `{}` as `pub` in the imported module", name);
+                    format!("consider marking `{}` as `pub` in the imported module", ident);
                 struct_span_err!(self.session, directive.span, E0364, "{}", &msg)
                     .span_note(directive.span, &note_msg)
                     .emit();
@@ -697,21 +702,18 @@ fn resolve_glob_import(&mut self, directive: &'b ImportDirective<'b>) {
 
         // Ensure that `resolutions` isn't borrowed during `try_define`,
         // since it might get updated via a glob cycle.
-        let bindings = module.resolutions.borrow().iter().filter_map(|(name, resolution)| {
-            resolution.borrow().binding().map(|binding| (*name, binding))
+        let bindings = module.resolutions.borrow().iter().filter_map(|(&ident, resolution)| {
+            resolution.borrow().binding().map(|binding| (ident, binding))
         }).collect::<Vec<_>>();
-        for ((name, ns), binding) in bindings {
+        for ((ident, ns), binding) in bindings {
             if binding.pseudo_vis() == ty::Visibility::Public || self.is_accessible(binding.vis) {
                 let imported_binding = self.import(binding, directive);
-                let _ = self.try_define(directive.parent, name, ns, imported_binding);
+                let _ = self.try_define(directive.parent, ident, ns, imported_binding);
             }
         }
 
         // Record the destination of this import
-        if let Some(did) = module.def_id() {
-            let resolution = PathResolution::new(Def::Mod(did));
-            self.def_map.insert(directive.id, resolution);
-        }
+        self.def_map.insert(directive.id, PathResolution::new(module.def().unwrap()));
     }
 
     // Miscellaneous post-processing, including recording reexports, reporting conflicts,
@@ -725,7 +727,7 @@ fn finalize_resolutions_in(&mut self, module: Module<'b>) {
             reexports = mem::replace(&mut self.macro_exports, Vec::new());
         }
 
-        for (&(name, ns), resolution) in module.resolutions.borrow().iter() {
+        for (&(ident, ns), resolution) in module.resolutions.borrow().iter() {
             let resolution = resolution.borrow();
             let binding = match resolution.binding {
                 Some(binding) => binding,
@@ -739,7 +741,7 @@ fn finalize_resolutions_in(&mut self, module: Module<'b>) {
                     if !def.def_id().is_local() {
                         self.session.cstore.export_macros(def.def_id().krate);
                     }
-                    reexports.push(Export { name: name, def: def });
+                    reexports.push(Export { name: ident.name, def: def });
                 }
             }
 
@@ -748,7 +750,7 @@ fn finalize_resolutions_in(&mut self, module: Module<'b>) {
                    !orig_binding.vis.is_at_least(binding.vis, self) {
                     let msg = format!("variant `{}` is private, and cannot be reexported \
                                        (error E0364), consider declaring its enum as `pub`",
-                                      name);
+                                      ident);
                     self.session.add_lint(PRIVATE_IN_PUBLIC, directive.id, binding.span, msg);
                 }
             }
index ffab0bde7abde743cff20dce98787caeb0e4df62..de8814f143e04f62b4c07b046a7c5ac0039b01f7 100644 (file)
@@ -1085,6 +1085,10 @@ fn run_work_multithreaded(sess: &Session,
 pub fn run_assembler(sess: &Session, outputs: &OutputFilenames) {
     let (pname, mut cmd, _) = get_linker(sess);
 
+    for arg in &sess.target.target.options.asm_args {
+        cmd.arg(arg);
+    }
+
     cmd.arg("-c").arg("-o").arg(&outputs.path(OutputType::Object))
                            .arg(&outputs.temp_path(OutputType::Assembly, None));
     debug!("{:?}", cmd);
index f2c8ef46a7e252db6a090ee80222797cec8d5fe1..265dcada1f810651a76401793644cfb0d17c1261 100644 (file)
@@ -142,20 +142,21 @@ pub fn new(fcx: &FnCtxt<'a, 'gcx, 'tcx>,
     fn report_cast_error(&self, fcx: &FnCtxt<'a, 'gcx, 'tcx>, e: CastError) {
         match e {
             CastError::NeedDeref => {
+                let error_span = self.span;
                 let cast_ty = fcx.ty_to_string(self.cast_ty);
-                let mut err = fcx.type_error_struct(self.cast_span,
+                let mut err = fcx.type_error_struct(error_span,
                                        |actual| {
                                            format!("casting `{}` as `{}` is invalid",
                                                    actual,
                                                    cast_ty)
                                        },
                                        self.expr_ty);
-                err.span_label(self.expr.span,
+                err.span_label(error_span,
                                &format!("cannot cast `{}` as `{}`",
                                         fcx.ty_to_string(self.expr_ty),
                                         cast_ty));
                 if let Ok(snippet) = fcx.sess().codemap().span_to_snippet(self.expr.span) {
-                    err.span_label(self.expr.span,
+                    err.span_help(self.expr.span,
                                    &format!("did you mean `*{}`?", snippet));
                 }
                 err.emit();
index 28ca92f5db6f69e7ed80460d958fade26386261f..123516dc89d746fcad14b912ca96e3328c2230d3 100644 (file)
@@ -2801,7 +2801,7 @@ fn clean(&self, cx: &DocContext) -> Item {
             visibility: Some(Public),
             stability: self.stab.clean(cx),
             deprecation: self.depr.clean(cx),
-            def_id: cx.tcx.map.local_def_id(self.id),
+            def_id: self.def_id,
             inner: MacroItem(Macro {
                 source: format!("macro_rules! {} {{\n{}}}",
                                 name,
index 21fc135eaadae7c0822de78e97d2130bce50702e..31e10fbd3b7d3e16ca57628798caceba41d79661 100644 (file)
@@ -233,9 +233,11 @@ pub struct DefaultImpl {
     pub whence: Span,
 }
 
+// For Macro we store the DefId instead of the NodeId, since we also create
+// these imported macro_rules (which only have a DUMMY_NODE_ID).
 pub struct Macro {
     pub name: Name,
-    pub id: ast::NodeId,
+    pub def_id: hir::def_id::DefId,
     pub attrs: hir::HirVec<ast::Attribute>,
     pub whence: Span,
     pub matchers: hir::HirVec<Span>,
index 174118db93e0b1ff55c6b38f0406a9871eaa9de0..835825d31eec98f46e954707fdf3dea03a2e7ff1 100644 (file)
@@ -259,10 +259,11 @@ pub fn main_args(args: &[String]) -> isize {
     }
 
     let external_html = match ExternalHtml::load(
-            &matches.opt_strs("html-in-header"), &matches.opt_strs("html-before-content"),
+            &matches.opt_strs("html-in-header"),
+            &matches.opt_strs("html-before-content"),
             &matches.opt_strs("html-after-content")) {
         Some(eh) => eh,
-        None => return 3
+        None => return 3,
     };
     let crate_name = matches.opt_str("crate-name");
     let playground_url = matches.opt_str("playground-url");
index 4087b9a761f97dfc44f066eb3de568b1ae276e4e..c93112657b96db239e9b9528f53754f50108919e 100644 (file)
@@ -85,7 +85,7 @@ pub fn visit(&mut self, krate: &hir::Crate) {
                                               None);
         // attach the crate's exported macros to the top-level module:
         let macro_exports: Vec<_> =
-            krate.exported_macros.iter().map(|def| self.visit_macro(def)).collect();
+            krate.exported_macros.iter().map(|def| self.visit_local_macro(def)).collect();
         self.module.macros.extend(macro_exports);
         self.module.is_crate = true;
     }
@@ -201,6 +201,7 @@ pub fn visit_mod_contents(&mut self, span: Span, attrs: hir::HirVec<ast::Attribu
                     if def_id.krate == LOCAL_CRATE {
                         continue // These are `krate.exported_macros`, handled in `self.visit()`.
                     }
+                    let imported_from = self.cx.sess().cstore.original_crate_name(def_id.krate);
                     let def = match self.cx.sess().cstore.load_macro(def_id, self.cx.sess()) {
                         LoadedMacro::MacroRules(macro_rules) => macro_rules,
                         // FIXME(jseyfried): document proc macro reexports
@@ -210,14 +211,14 @@ pub fn visit_mod_contents(&mut self, span: Span, attrs: hir::HirVec<ast::Attribu
                     // FIXME(jseyfried) merge with `self.visit_macro()`
                     let matchers = def.body.chunks(4).map(|arm| arm[0].get_span()).collect();
                     om.macros.push(Macro {
-                        id: def.id,
+                        def_id: def_id,
                         attrs: def.attrs.clone().into(),
                         name: def.ident.name,
                         whence: def.span,
                         matchers: matchers,
                         stab: self.stability(def.id),
                         depr: self.deprecation(def.id),
-                        imported_from: def.imported_from.map(|ident| ident.name),
+                        imported_from: Some(imported_from),
                     })
                 }
             }
@@ -513,19 +514,19 @@ pub fn visit_item(&mut self, item: &hir::Item,
     }
 
     // convert each exported_macro into a doc item
-    fn visit_macro(&self, def: &hir::MacroDef) -> Macro {
+    fn visit_local_macro(&self, def: &hir::MacroDef) -> Macro {
         // Extract the spans of all matchers. They represent the "interface" of the macro.
         let matchers = def.body.chunks(4).map(|arm| arm[0].get_span()).collect();
 
         Macro {
-            id: def.id,
+            def_id: self.cx.tcx.map.local_def_id(def.id),
             attrs: def.attrs.clone(),
             name: def.name,
             whence: def.span,
             matchers: matchers,
             stab: self.stability(def.id),
             depr: self.deprecation(def.id),
-            imported_from: def.imported_from,
+            imported_from: None,
         }
     }
 }
index a063b85646809f3e2c89c7b58b24bf9c0699b8c5..f5e9ec6d89d0f62603bf0fc35700e6e2eb81847d 100644 (file)
@@ -12,6 +12,7 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
+use fmt;
 use mem;
 use ops::Range;
 use iter::FusedIterator;
@@ -370,6 +371,13 @@ impl ExactSizeIterator for EscapeDefault {}
 #[unstable(feature = "fused", issue = "35602")]
 impl FusedIterator for EscapeDefault {}
 
+#[stable(feature = "std_debug", since = "1.15.0")]
+impl fmt::Debug for EscapeDefault {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.pad("EscapeDefault { .. }")
+    }
+}
+
 
 static ASCII_LOWERCASE_MAP: [u8; 256] = [
     0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
index 1087d1f24471b75e1a641ddd453fc79d6e2c5da7..b3eba508316981682638773827c3e04d9e5d7a82 100644 (file)
@@ -104,7 +104,7 @@ fn build_libbacktrace(host: &str, target: &str) {
                 .env("AR", &ar)
                 .env("RANLIB", format!("{} s", ar.display()))
                 .env("CFLAGS", cflags));
-    run(Command::new("make")
+    run(Command::new(build_helper::make(host))
                 .current_dir(&build_dir)
                 .arg(format!("INCDIR={}", src_dir.display()))
                 .arg("-j").arg(env::var("NUM_JOBS").expect("NUM_JOBS was not set")));
index 0b310eb2585778f553e8a3b74acc8d0769ef298b..2fa3a9c4844b5502515f14ac07f6c14ee52e7bf8 100644 (file)
@@ -1276,6 +1276,15 @@ fn clone(&self) -> Iter<'a, K, V> {
     }
 }
 
+#[stable(feature = "std_debug", since = "1.15.0")]
+impl<'a, K: Debug, V: Debug> fmt::Debug for Iter<'a, K, V> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_list()
+            .entries(self.clone())
+            .finish()
+    }
+}
+
 /// HashMap mutable values iterator.
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct IterMut<'a, K: 'a, V: 'a> {
@@ -1285,7 +1294,7 @@ pub struct IterMut<'a, K: 'a, V: 'a> {
 /// HashMap move iterator.
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct IntoIter<K, V> {
-    inner: table::IntoIter<K, V>,
+    pub(super) inner: table::IntoIter<K, V>,
 }
 
 /// HashMap keys iterator.
@@ -1302,6 +1311,15 @@ fn clone(&self) -> Keys<'a, K, V> {
     }
 }
 
+#[stable(feature = "std_debug", since = "1.15.0")]
+impl<'a, K: Debug, V: Debug> fmt::Debug for Keys<'a, K, V> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_list()
+            .entries(self.clone())
+            .finish()
+    }
+}
+
 /// HashMap values iterator.
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Values<'a, K: 'a, V: 'a> {
@@ -1316,10 +1334,19 @@ fn clone(&self) -> Values<'a, K, V> {
     }
 }
 
+#[stable(feature = "std_debug", since = "1.15.0")]
+impl<'a, K: Debug, V: Debug> fmt::Debug for Values<'a, K, V> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_list()
+            .entries(self.clone())
+            .finish()
+    }
+}
+
 /// HashMap drain iterator.
 #[stable(feature = "drain", since = "1.6.0")]
 pub struct Drain<'a, K: 'a, V: 'a> {
-    inner: table::Drain<'a, K, V>,
+    pub(super) inner: table::Drain<'a, K, V>,
 }
 
 /// Mutable HashMap values iterator.
@@ -1557,6 +1584,18 @@ fn len(&self) -> usize {
 #[unstable(feature = "fused", issue = "35602")]
 impl<'a, K, V> FusedIterator for IterMut<'a, K, V> {}
 
+#[stable(feature = "std_debug", since = "1.15.0")]
+impl<'a, K, V> fmt::Debug for IterMut<'a, K, V>
+    where K: fmt::Debug,
+          V: fmt::Debug,
+{
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_list()
+            .entries(self.inner.iter())
+            .finish()
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<K, V> Iterator for IntoIter<K, V> {
     type Item = (K, V);
@@ -1580,6 +1619,15 @@ fn len(&self) -> usize {
 #[unstable(feature = "fused", issue = "35602")]
 impl<K, V> FusedIterator for IntoIter<K, V> {}
 
+#[stable(feature = "std_debug", since = "1.15.0")]
+impl<K: Debug, V: Debug> fmt::Debug for IntoIter<K, V> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_list()
+            .entries(self.inner.iter())
+            .finish()
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, K, V> Iterator for Keys<'a, K, V> {
     type Item = &'a K;
@@ -1649,6 +1697,18 @@ fn len(&self) -> usize {
 #[unstable(feature = "fused", issue = "35602")]
 impl<'a, K, V> FusedIterator for ValuesMut<'a, K, V> {}
 
+#[stable(feature = "std_debug", since = "1.15.0")]
+impl<'a, K, V> fmt::Debug for ValuesMut<'a, K, V>
+    where K: fmt::Debug,
+          V: fmt::Debug,
+{
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_list()
+            .entries(self.inner.inner.iter())
+            .finish()
+    }
+}
+
 #[stable(feature = "drain", since = "1.6.0")]
 impl<'a, K, V> Iterator for Drain<'a, K, V> {
     type Item = (K, V);
@@ -1672,6 +1732,18 @@ fn len(&self) -> usize {
 #[unstable(feature = "fused", issue = "35602")]
 impl<'a, K, V> FusedIterator for Drain<'a, K, V> {}
 
+#[stable(feature = "std_debug", since = "1.15.0")]
+impl<'a, K, V> fmt::Debug for Drain<'a, K, V>
+    where K: fmt::Debug,
+          V: fmt::Debug,
+{
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_list()
+            .entries(self.inner.iter())
+            .finish()
+    }
+}
+
 impl<'a, K, V> Entry<'a, K, V> {
     #[stable(feature = "rust1", since = "1.0.0")]
     /// Ensures a value is in the entry by inserting the default if empty, and returns
@@ -2148,6 +2220,13 @@ fn default() -> RandomState {
     }
 }
 
+#[stable(feature = "std_debug", since = "1.15.0")]
+impl fmt::Debug for RandomState {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.pad("RandomState { .. }")
+    }
+}
+
 impl<K, S, Q: ?Sized> super::Recover<Q> for HashMap<K, (), S>
     where K: Eq + Hash + Borrow<Q>,
           S: BuildHasher,
index 72af612f5696f51c8676bb2b91da6a6864d57859..341b050862f5c455520c25d6496c7a264782fb0b 100644 (file)
@@ -948,6 +948,15 @@ fn len(&self) -> usize {
 #[unstable(feature = "fused", issue = "35602")]
 impl<'a, K> FusedIterator for Iter<'a, K> {}
 
+#[stable(feature = "std_debug", since = "1.15.0")]
+impl<'a, K: fmt::Debug> fmt::Debug for Iter<'a, K> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_list()
+            .entries(self.clone())
+            .finish()
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<K> Iterator for IntoIter<K> {
     type Item = K;
@@ -968,6 +977,16 @@ fn len(&self) -> usize {
 #[unstable(feature = "fused", issue = "35602")]
 impl<K> FusedIterator for IntoIter<K> {}
 
+#[stable(feature = "std_debug", since = "1.15.0")]
+impl<K: fmt::Debug> fmt::Debug for IntoIter<K> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        let entries_iter = self.iter.inner.iter().map(|(k, _)| k);
+        f.debug_list()
+            .entries(entries_iter)
+            .finish()
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, K> Iterator for Drain<'a, K> {
     type Item = K;
@@ -988,6 +1007,16 @@ fn len(&self) -> usize {
 #[unstable(feature = "fused", issue = "35602")]
 impl<'a, K> FusedIterator for Drain<'a, K> {}
 
+#[stable(feature = "std_debug", since = "1.15.0")]
+impl<'a, K: fmt::Debug> fmt::Debug for Drain<'a, K> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        let entries_iter = self.iter.inner.iter().map(|(k, _)| k);
+        f.debug_list()
+            .entries(entries_iter)
+            .finish()
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, T, S> Clone for Intersection<'a, T, S> {
     fn clone(&self) -> Intersection<'a, T, S> {
@@ -1021,6 +1050,18 @@ fn size_hint(&self) -> (usize, Option<usize>) {
     }
 }
 
+#[stable(feature = "std_debug", since = "1.15.0")]
+impl<'a, T, S> fmt::Debug for Intersection<'a, T, S>
+    where T: fmt::Debug + Eq + Hash,
+          S: BuildHasher,
+{
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_list()
+            .entries(self.clone())
+            .finish()
+    }
+}
+
 #[unstable(feature = "fused", issue = "35602")]
 impl<'a, T, S> FusedIterator for Intersection<'a, T, S>
     where T: Eq + Hash,
@@ -1068,6 +1109,18 @@ impl<'a, T, S> FusedIterator for Difference<'a, T, S>
 {
 }
 
+#[stable(feature = "std_debug", since = "1.15.0")]
+impl<'a, T, S> fmt::Debug for Difference<'a, T, S>
+    where T: fmt::Debug + Eq + Hash,
+          S: BuildHasher,
+{
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_list()
+            .entries(self.clone())
+            .finish()
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, T, S> Clone for SymmetricDifference<'a, T, S> {
     fn clone(&self) -> SymmetricDifference<'a, T, S> {
@@ -1097,6 +1150,18 @@ impl<'a, T, S> FusedIterator for SymmetricDifference<'a, T, S>
 {
 }
 
+#[stable(feature = "std_debug", since = "1.15.0")]
+impl<'a, T, S> fmt::Debug for SymmetricDifference<'a, T, S>
+    where T: fmt::Debug + Eq + Hash,
+          S: BuildHasher,
+{
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_list()
+            .entries(self.clone())
+            .finish()
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, T, S> Clone for Union<'a, T, S> {
     fn clone(&self) -> Union<'a, T, S> {
@@ -1111,6 +1176,18 @@ impl<'a, T, S> FusedIterator for Union<'a, T, S>
 {
 }
 
+#[stable(feature = "std_debug", since = "1.15.0")]
+impl<'a, T, S> fmt::Debug for Union<'a, T, S>
+    where T: fmt::Debug + Eq + Hash,
+          S: BuildHasher,
+{
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_list()
+            .entries(self.clone())
+            .finish()
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, T, S> Iterator for Union<'a, T, S>
     where T: Eq + Hash,
index a784d8e50f9d0d197af856ebd6bf09e68bc79770..2cd9362a65791408f9ece6192f1857b7636e5b56 100644 (file)
@@ -882,6 +882,15 @@ unsafe impl<'a, K: Sync, V: Sync> Sync for IterMut<'a, K, V> {}
 // but Send is the more useful bound
 unsafe impl<'a, K: Send, V: Send> Send for IterMut<'a, K, V> {}
 
+impl<'a, K: 'a, V: 'a> IterMut<'a, K, V> {
+    pub fn iter(&self) -> Iter<K, V> {
+        Iter {
+            iter: self.iter.clone(),
+            elems_left: self.elems_left,
+        }
+    }
+}
+
 /// Iterator over the entries in a table, consuming the table.
 pub struct IntoIter<K, V> {
     table: RawTable<K, V>,
@@ -891,6 +900,15 @@ pub struct IntoIter<K, V> {
 unsafe impl<K: Sync, V: Sync> Sync for IntoIter<K, V> {}
 unsafe impl<K: Send, V: Send> Send for IntoIter<K, V> {}
 
+impl<K, V> IntoIter<K, V> {
+    pub fn iter(&self) -> Iter<K, V> {
+        Iter {
+            iter: self.iter.clone(),
+            elems_left: self.table.size,
+        }
+    }
+}
+
 /// Iterator over the entries in a table, clearing the table.
 pub struct Drain<'a, K: 'a, V: 'a> {
     table: Shared<RawTable<K, V>>,
@@ -901,6 +919,17 @@ pub struct Drain<'a, K: 'a, V: 'a> {
 unsafe impl<'a, K: Sync, V: Sync> Sync for Drain<'a, K, V> {}
 unsafe impl<'a, K: Send, V: Send> Send for Drain<'a, K, V> {}
 
+impl<'a, K, V> Drain<'a, K, V> {
+    pub fn iter(&self) -> Iter<K, V> {
+        unsafe {
+            Iter {
+                iter: self.iter.clone(),
+                elems_left: (**self.table).size,
+            }
+        }
+    }
+}
+
 impl<'a, K, V> Iterator for Iter<'a, K, V> {
     type Item = (&'a K, &'a V);
 
index ee6a907f6160ee4a45ec79935f844a542dcadef8..0521f301321a736e08a5392dc1686e5913fb0abc 100644 (file)
@@ -143,6 +143,13 @@ fn next(&mut self) -> Option<(String, String)> {
     fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
 }
 
+#[stable(feature = "std_debug", since = "1.15.0")]
+impl fmt::Debug for Vars {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.pad("Vars { .. }")
+    }
+}
+
 #[stable(feature = "env", since = "1.0.0")]
 impl Iterator for VarsOs {
     type Item = (OsString, OsString);
@@ -150,6 +157,13 @@ fn next(&mut self) -> Option<(OsString, OsString)> { self.inner.next() }
     fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
 }
 
+#[stable(feature = "std_debug", since = "1.15.0")]
+impl fmt::Debug for VarsOs {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.pad("VarsOs { .. }")
+    }
+}
+
 /// Fetches the environment variable `key` from the current process.
 ///
 /// The returned result is `Ok(s)` if the environment variable is present and is
@@ -364,6 +378,13 @@ fn next(&mut self) -> Option<PathBuf> { self.inner.next() }
     fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
 }
 
+#[stable(feature = "std_debug", since = "1.15.0")]
+impl<'a> fmt::Debug for SplitPaths<'a> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.pad("SplitPaths { .. }")
+    }
+}
+
 /// Error type returned from `std::env::join_paths` when paths fail to be
 /// joined.
 #[derive(Debug)]
@@ -640,6 +661,13 @@ fn next_back(&mut self) -> Option<String> {
     }
 }
 
+#[stable(feature = "std_debug", since = "1.15.0")]
+impl fmt::Debug for Args {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.pad("Args { .. }")
+    }
+}
+
 #[stable(feature = "env", since = "1.0.0")]
 impl Iterator for ArgsOs {
     type Item = OsString;
@@ -657,6 +685,14 @@ fn is_empty(&self) -> bool { self.inner.is_empty() }
 impl DoubleEndedIterator for ArgsOs {
     fn next_back(&mut self) -> Option<OsString> { self.inner.next_back() }
 }
+
+#[stable(feature = "std_debug", since = "1.15.0")]
+impl fmt::Debug for ArgsOs {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.pad("ArgsOs { .. }")
+    }
+}
+
 /// Constants associated with the current target
 #[stable(feature = "env", since = "1.0.0")]
 pub mod consts {
index e91e808c5489a48a6a2d2cd03929e73384996a8d..176b5f66fc4e8500ff4d9a8eaf8b740bfeddd13f 100644 (file)
@@ -140,7 +140,7 @@ pub struct File {
 ///             .create(true)
 ///             .open("foo.txt");
 /// ```
-#[derive(Clone)]
+#[derive(Clone, Debug)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct OpenOptions(fs_imp::OpenOptions);
 
@@ -168,6 +168,7 @@ pub struct File {
 ///
 /// This builder also supports platform-specific options.
 #[stable(feature = "dir_builder", since = "1.6.0")]
+#[derive(Debug)]
 pub struct DirBuilder {
     inner: fs_imp::DirBuilder,
     recursive: bool,
@@ -834,6 +835,21 @@ pub fn created(&self) -> io::Result<SystemTime> {
     }
 }
 
+#[stable(feature = "std_debug", since = "1.15.0")]
+impl fmt::Debug for Metadata {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_struct("Metadata")
+            .field("file_type", &self.file_type())
+            .field("is_dir", &self.is_dir())
+            .field("is_file", &self.is_file())
+            .field("permissions", &self.permissions())
+            .field("modified", &self.modified())
+            .field("accessed", &self.accessed())
+            .field("created", &self.created())
+            .finish()
+    }
+}
+
 impl AsInner<fs_imp::FileAttr> for Metadata {
     fn as_inner(&self) -> &fs_imp::FileAttr { &self.0 }
 }
index b07da0dc268c481f5ef73a11d6a2d817f64165da..143a85ae321846c6c8b4342c32a54f9fe93b5489 100644 (file)
@@ -1444,6 +1444,16 @@ pub struct Chain<T, U> {
     done_first: bool,
 }
 
+#[stable(feature = "std_debug", since = "1.15.0")]
+impl<T: fmt::Debug, U: fmt::Debug> fmt::Debug for Chain<T, U> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_struct("Chain")
+            .field("t", &self.first)
+            .field("u", &self.second)
+            .finish()
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: Read, U: Read> Read for Chain<T, U> {
     fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
@@ -1485,6 +1495,7 @@ fn consume(&mut self, amt: usize) {
 ///
 /// [`take()`]: trait.Read.html#method.take
 #[stable(feature = "rust1", since = "1.0.0")]
+#[derive(Debug)]
 pub struct Take<T> {
     inner: T,
     limit: u64,
@@ -1602,6 +1613,7 @@ fn read_one_byte(reader: &mut Read) -> Option<Result<u8>> {
 ///
 /// [`bytes()`]: trait.Read.html#method.bytes
 #[stable(feature = "rust1", since = "1.0.0")]
+#[derive(Debug)]
 pub struct Bytes<R> {
     inner: R,
 }
@@ -1623,6 +1635,7 @@ fn next(&mut self) -> Option<Result<u8>> {
 /// [chars]: trait.Read.html#method.chars
 #[unstable(feature = "io", reason = "awaiting stability of Read::chars",
            issue = "27802")]
+#[derive(Debug)]
 pub struct Chars<R> {
     inner: R,
 }
@@ -1712,6 +1725,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 ///
 /// [split]: trait.BufRead.html#method.split
 #[stable(feature = "rust1", since = "1.0.0")]
+#[derive(Debug)]
 pub struct Split<B> {
     buf: B,
     delim: u8,
@@ -1743,6 +1757,7 @@ fn next(&mut self) -> Option<Result<Vec<u8>>> {
 ///
 /// [lines]: trait.BufRead.html#method.lines
 #[stable(feature = "rust1", since = "1.0.0")]
+#[derive(Debug)]
 pub struct Lines<B> {
     buf: B,
 }
index 1a65bee13b8fb63188c877bf5a72d764366c66aa..9d1c8942f8cf80605dab780459dcc69297786470 100644 (file)
@@ -282,6 +282,13 @@ pub fn read_line(&self, buf: &mut String) -> io::Result<usize> {
     }
 }
 
+#[stable(feature = "std_debug", since = "1.15.0")]
+impl fmt::Debug for Stdin {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.pad("Stdin { .. }")
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl Read for Stdin {
     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
@@ -314,6 +321,13 @@ fn fill_buf(&mut self) -> io::Result<&[u8]> { self.inner.fill_buf() }
     fn consume(&mut self, n: usize) { self.inner.consume(n) }
 }
 
+#[stable(feature = "std_debug", since = "1.15.0")]
+impl<'a> fmt::Debug for StdinLock<'a> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.pad("StdinLock { .. }")
+    }
+}
+
 /// A handle to the global standard output stream of the current process.
 ///
 /// Each handle shares a global buffer of data to be written to the standard
@@ -424,6 +438,13 @@ pub fn lock(&self) -> StdoutLock {
     }
 }
 
+#[stable(feature = "std_debug", since = "1.15.0")]
+impl fmt::Debug for Stdout {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.pad("Stdout { .. }")
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl Write for Stdout {
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
@@ -449,6 +470,13 @@ fn flush(&mut self) -> io::Result<()> {
     }
 }
 
+#[stable(feature = "std_debug", since = "1.15.0")]
+impl<'a> fmt::Debug for StdoutLock<'a> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.pad("StdoutLock { .. }")
+    }
+}
+
 /// A handle to the standard error stream of a process.
 ///
 /// For more information, see the [`io::stderr`] method.
@@ -545,6 +573,13 @@ pub fn lock(&self) -> StderrLock {
     }
 }
 
+#[stable(feature = "std_debug", since = "1.15.0")]
+impl fmt::Debug for Stderr {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.pad("Stderr { .. }")
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl Write for Stderr {
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
@@ -570,6 +605,13 @@ fn flush(&mut self) -> io::Result<()> {
     }
 }
 
+#[stable(feature = "std_debug", since = "1.15.0")]
+impl<'a> fmt::Debug for StderrLock<'a> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.pad("StderrLock { .. }")
+    }
+}
+
 /// Resets the thread-local stderr handle to the specified writer
 ///
 /// This will replace the current thread's stderr handle, returning the old
index 2c6880281b5e60088b36c6497ba747056b19fab9..436511031ef53f777e20eb09cd115ceca67f250a 100644 (file)
@@ -10,6 +10,7 @@
 
 #![allow(missing_copy_implementations)]
 
+use fmt;
 use io::{self, Read, Write, ErrorKind, BufRead};
 
 /// Copies the entire contents of a reader into a writer.
@@ -97,6 +98,13 @@ fn fill_buf(&mut self) -> io::Result<&[u8]> { Ok(&[]) }
     fn consume(&mut self, _n: usize) {}
 }
 
+#[stable(feature = "std_debug", since = "1.15.0")]
+impl fmt::Debug for Empty {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.pad("Empty { .. }")
+    }
+}
+
 /// A reader which yields one byte over and over and over and over and over and...
 ///
 /// This struct is generally created by calling [`repeat()`][repeat]. Please
@@ -133,6 +141,13 @@ fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
     }
 }
 
+#[stable(feature = "std_debug", since = "1.15.0")]
+impl fmt::Debug for Repeat {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.pad("Repeat { .. }")
+    }
+}
+
 /// A writer which will move data into the void.
 ///
 /// This struct is generally created by calling [`sink()`][sink]. Please
@@ -165,6 +180,13 @@ fn write(&mut self, buf: &[u8]) -> io::Result<usize> { Ok(buf.len()) }
     fn flush(&mut self) -> io::Result<()> { Ok(()) }
 }
 
+#[stable(feature = "std_debug", since = "1.15.0")]
+impl fmt::Debug for Sink {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.pad("Sink { .. }")
+    }
+}
+
 #[cfg(test)]
 mod tests {
     use io::prelude::*;
index 414f25fa5eb33af7bfb54edd797601d9fc1bef0c..fc5c6968544e80d22d25b0a0d255ee331a15e86a 100644 (file)
 #![no_std]
 
 #![deny(missing_docs)]
+#![deny(missing_debug_implementations)]
 
 // Tell the compiler to link to either panic_abort or panic_unwind
 #![needs_panic_runtime]
 #![feature(panic_unwind)]
 #![feature(placement_in_syntax)]
 #![feature(prelude_import)]
+#![feature(pub_restricted)]
 #![feature(rand)]
 #![feature(raw)]
 #![feature(repr_simd)]
index c1e610f33fb705777a5979bc601832c6833bb819..6aab7486004f89e132c65e706a607760554ceed3 100644 (file)
@@ -1068,6 +1068,14 @@ fn from_inner(addr: c::in6_addr) -> Ipv6Addr {
     }
 }
 
+#[stable(feature = "ipv6_from_segments", since = "1.15.0")]
+impl From<[u16; 8]> for Ipv6Addr {
+    fn from(segments: [u16; 8]) -> Ipv6Addr {
+        let [a, b, c, d, e, f, g, h] = segments;
+        Ipv6Addr::new(a, b, c, d, e, f, g, h)
+    }
+}
+
 // Tests for this module
 #[cfg(all(test, not(target_os = "emscripten")))]
 mod tests {
@@ -1413,10 +1421,28 @@ fn test_int_to_ipv4() {
     }
 
     #[test]
-    fn ipv4_from_u32_slice() {
+    fn ipv4_from_octets() {
         assert_eq!(Ipv4Addr::from([127, 0, 0, 1]), Ipv4Addr::new(127, 0, 0, 1))
     }
 
+    #[test]
+    fn ipv6_from_segments() {
+        let from_u16s = Ipv6Addr::from([0x0011, 0x2233, 0x4455, 0x6677,
+                                        0x8899, 0xaabb, 0xccdd, 0xeeff]);
+        let new = Ipv6Addr::new(0x0011, 0x2233, 0x4455, 0x6677,
+                                0x8899, 0xaabb, 0xccdd, 0xeeff);
+        assert_eq!(new, from_u16s);
+    }
+
+    #[test]
+    fn ipv6_from_octets() {
+        let from_u16s = Ipv6Addr::from([0x0011, 0x2233, 0x4455, 0x6677,
+                                        0x8899, 0xaabb, 0xccdd, 0xeeff]);
+        let from_u8s = Ipv6Addr::from([0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+                                       0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff]);
+        assert_eq!(from_u16s, from_u8s);
+    }
+
     #[test]
     fn ord() {
         assert!(Ipv4Addr::new(100, 64, 3, 3) < Ipv4Addr::new(192, 0, 2, 2));
index 56286fbe25399a62a322c24e815475cf6c69085a..cadf87f32b14a6a93b58b7bbd1868cef0b9de794 100644 (file)
@@ -12,6 +12,7 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
+use fmt;
 use io::{self, Error, ErrorKind};
 use sys_common::net as net_imp;
 
@@ -105,6 +106,13 @@ impl Iterator for LookupHost {
     fn next(&mut self) -> Option<SocketAddr> { self.0.next() }
 }
 
+#[stable(feature = "std_debug", since = "1.15.0")]
+impl fmt::Debug for LookupHost {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.pad("LookupHost { .. }")
+    }
+}
+
 /// Resolve the host specified by `host` as a number of `SocketAddr` instances.
 ///
 /// This method may perform a DNS query to resolve `host` and may also inspect
index be9636a0a19a1bdc4c422e264443ae3e1f54fcd0..63817c9f10f5fbb19892e61759b8e0f30f7858a5 100644 (file)
@@ -76,6 +76,7 @@
 /// [`incoming`]: struct.TcpListener.html#method.incoming
 /// [`TcpListener`]: struct.TcpListener.html
 #[stable(feature = "rust1", since = "1.0.0")]
+#[derive(Debug)]
 pub struct Incoming<'a> { listener: &'a TcpListener }
 
 impl TcpStream {
index e6a95bc831ffbafdbea5df3a14e5610d2c8cb32f..7c9274d06016180e0bd7c1afab07e185984bd30c 100644 (file)
@@ -17,6 +17,7 @@
                               crates.io should be used instead for the correct \
                               definitions")]
 #![allow(deprecated)]
+#![allow(missing_debug_implementations)]
 
 use os::raw::c_ulong;
 
index 8f9b29462c4f938bc584133bd4a064774940c366..0b96295f9e69e0e1a04a65c0b9a51393cb03e920 100644 (file)
@@ -33,7 +33,7 @@
 pub type pthread_t = usize;
 
 #[repr(C)]
-#[derive(Clone)]
+#[derive(Clone, Debug)]
 #[stable(feature = "raw_ext", since = "1.1.0")]
 pub struct stat {
     #[stable(feature = "raw_ext", since = "1.1.0")]
index 2a918d8aeb7b8a2310785cf70a9b994b2a9b7af4..cc154f7ab413b4341307d9eb127b91eb696f86f2 100644 (file)
@@ -12,6 +12,8 @@
 
 #![stable(feature = "raw_os", since = "1.1.0")]
 
+use fmt;
+
 #[cfg(any(target_os = "android",
           target_os = "emscripten",
           all(target_os = "linux", any(target_arch = "aarch64",
@@ -71,6 +73,13 @@ pub enum c_void {
     #[doc(hidden)] __variant2,
 }
 
+#[stable(feature = "std_debug", since = "1.15.0")]
+impl fmt::Debug for c_void {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.pad("c_void")
+    }
+}
+
 #[cfg(test)]
 #[allow(unused_imports)]
 mod tests {
index a7e8c4fab3735031cab62da9896c41949a309a38..faf4949e86192e2d76ba2cc7199f9a6a7a67ead7 100644 (file)
@@ -14,6 +14,7 @@
 
 use any::Any;
 use cell::UnsafeCell;
+use fmt;
 use ops::{Deref, DerefMut};
 use panicking;
 use ptr::{Unique, Shared};
@@ -296,6 +297,15 @@ extern "rust-call" fn call_once(self, _args: ()) -> R {
     }
 }
 
+#[stable(feature = "std_debug", since = "1.15.0")]
+impl<T: fmt::Debug> fmt::Debug for AssertUnwindSafe<T> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_tuple("AssertUnwindSafe")
+            .field(&self.0)
+            .finish()
+    }
+}
+
 /// Invokes a closure, capturing the cause of an unwinding panic if one occurs.
 ///
 /// This function will return `Ok` with the closure's result if the closure
index 45a10d2452851a573f08e85485763cab2d8bf364..e5edea241e1990654e10d0113cc1dae57440363c 100644 (file)
@@ -177,6 +177,7 @@ pub fn take_hook() -> Box<Fn(&PanicInfo) + 'static + Sync + Send> {
 /// panic!("Normal panic");
 /// ```
 #[stable(feature = "panic_hooks", since = "1.10.0")]
+#[derive(Debug)]
 pub struct PanicInfo<'a> {
     payload: &'a (Any + Send),
     location: Location<'a>,
@@ -256,6 +257,7 @@ pub fn location(&self) -> Option<&Location> {
 ///
 /// panic!("Normal panic");
 /// ```
+#[derive(Debug)]
 #[stable(feature = "panic_hooks", since = "1.10.0")]
 pub struct Location<'a> {
     file: &'a str,
index 2dcb8c2f1529c3c2c497c220ddab13dac0a6fe35..e15c37aaf24911ac6ade0258109aa5150b084350 100644 (file)
@@ -114,6 +114,17 @@ impl IntoInner<imp::Process> for Child {
     fn into_inner(self) -> imp::Process { self.handle }
 }
 
+#[stable(feature = "std_debug", since = "1.15.0")]
+impl fmt::Debug for Child {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_struct("Child")
+            .field("stdin", &self.stdin)
+            .field("stdout", &self.stdout)
+            .field("stderr", &self.stderr)
+            .finish()
+    }
+}
+
 /// A handle to a child process's stdin. This struct is used in the [`stdin`]
 /// field on [`Child`].
 ///
@@ -149,6 +160,13 @@ fn from_inner(pipe: AnonPipe) -> ChildStdin {
     }
 }
 
+#[stable(feature = "std_debug", since = "1.15.0")]
+impl fmt::Debug for ChildStdin {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.pad("ChildStdin { .. }")
+    }
+}
+
 /// A handle to a child process's stdout. This struct is used in the [`stdout`]
 /// field on [`Child`].
 ///
@@ -183,6 +201,13 @@ fn from_inner(pipe: AnonPipe) -> ChildStdout {
     }
 }
 
+#[stable(feature = "std_debug", since = "1.15.0")]
+impl fmt::Debug for ChildStdout {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.pad("ChildStdout { .. }")
+    }
+}
+
 /// A handle to a child process's stderr. This struct is used in the [`stderr`]
 /// field on [`Child`].
 ///
@@ -217,6 +242,13 @@ fn from_inner(pipe: AnonPipe) -> ChildStderr {
     }
 }
 
+#[stable(feature = "std_debug", since = "1.15.0")]
+impl fmt::Debug for ChildStderr {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.pad("ChildStderr { .. }")
+    }
+}
+
 /// A process builder, providing fine-grained control
 /// over how a new process should be spawned.
 ///
@@ -622,6 +654,13 @@ fn from_inner(inner: imp::Stdio) -> Stdio {
     }
 }
 
+#[stable(feature = "std_debug", since = "1.15.0")]
+impl fmt::Debug for Stdio {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.pad("Stdio { .. }")
+    }
+}
+
 /// Describes the result of a process after it has terminated.
 #[derive(PartialEq, Eq, Clone, Copy, Debug)]
 #[stable(feature = "process", since = "1.0.0")]
index f48325218fb4908ecc36c8fc8212d067fd1b7727..b853e83de5d6cb035b112da1a1fa1d2971db4add 100644 (file)
@@ -59,6 +59,7 @@
 #![unstable(feature = "rand", issue = "0")]
 
 use cell::RefCell;
+use fmt;
 use io;
 use mem;
 use rc::Rc;
@@ -143,6 +144,12 @@ pub struct ThreadRng {
     rng: Rc<RefCell<ThreadRngInner>>,
 }
 
+impl fmt::Debug for ThreadRng {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.pad("ThreadRng { .. }")
+    }
+}
+
 /// Retrieve the lazily-initialized thread-local random number
 /// generator, seeded by the system. Intended to be used in method
 /// chaining style, e.g. `thread_rng().gen::<isize>()`.
index f46eab684846384a9b5245657d11f20bd450d867..b8e83dced8d4b100bae84db8804628bb78bef740 100644 (file)
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use fmt;
 use sync::{Mutex, Condvar};
 
 /// A barrier enables multiple threads to synchronize the beginning
@@ -54,6 +55,13 @@ struct BarrierState {
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct BarrierWaitResult(bool);
 
+#[stable(feature = "std_debug", since = "1.15.0")]
+impl fmt::Debug for Barrier {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.pad("Barrier { .. }")
+    }
+}
+
 impl Barrier {
     /// Creates a new barrier that can block a given number of threads.
     ///
@@ -102,6 +110,15 @@ pub fn wait(&self) -> BarrierWaitResult {
     }
 }
 
+#[stable(feature = "std_debug", since = "1.15.0")]
+impl fmt::Debug for BarrierWaitResult {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_struct("BarrierWaitResult")
+            .field("is_leader", &self.is_leader())
+            .finish()
+    }
+}
+
 impl BarrierWaitResult {
     /// Returns whether this thread from `wait` is the "leader thread".
     ///
index a983ae716a4816d387c75659c4dedafc3a5007e3..8ab30c51b282eb601ffba3f3eefbe3f01847851d 100644 (file)
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use fmt;
 use sync::atomic::{AtomicUsize, Ordering};
 use sync::{mutex, MutexGuard, PoisonError};
 use sys_common::condvar as sys;
@@ -239,6 +240,13 @@ fn verify(&self, mutex: &sys_mutex::Mutex) {
     }
 }
 
+#[stable(feature = "std_debug", since = "1.15.0")]
+impl fmt::Debug for Condvar {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.pad("Condvar { .. }")
+    }
+}
+
 #[stable(feature = "condvar_default", since = "1.9.0")]
 impl Default for Condvar {
     /// Creates a `Condvar` which is ready to be waited on and notified.
index 8bcf008649f222cdc70b16a11302d8445064faa7..aeeab170deafe9cfdd92324197a2bf14c74ffacd 100644 (file)
@@ -306,6 +306,7 @@ impl<T> !Sync for Receiver<T> { }
 /// whenever `next` is called, waiting for a new message, and `None` will be
 /// returned when the corresponding channel has hung up.
 #[stable(feature = "rust1", since = "1.0.0")]
+#[derive(Debug)]
 pub struct Iter<'a, T: 'a> {
     rx: &'a Receiver<T>
 }
@@ -317,6 +318,7 @@ pub struct Iter<'a, T: 'a> {
 /// This Iterator will never block the caller in order to wait for data to
 /// become available. Instead, it will return `None`.
 #[stable(feature = "receiver_try_iter", since = "1.15.0")]
+#[derive(Debug)]
 pub struct TryIter<'a, T: 'a> {
     rx: &'a Receiver<T>
 }
@@ -325,6 +327,7 @@ pub struct TryIter<'a, T: 'a> {
 /// whenever `next` is called, waiting for a new message, and `None` will be
 /// returned when the corresponding channel has hung up.
 #[stable(feature = "receiver_into_iter", since = "1.1.0")]
+#[derive(Debug)]
 pub struct IntoIter<T> {
     rx: Receiver<T>
 }
index df4a3746a49bd7480ae37eb1d536e12de816b34f..f6dbe01d7bdbf05fab89719ccdf962370629ac4f 100644 (file)
@@ -351,6 +351,15 @@ fn drop(&mut self) {
     }
 }
 
+#[stable(feature = "std_debug", since = "1.15.0")]
+impl<'a, T: ?Sized + fmt::Debug> fmt::Debug for MutexGuard<'a, T> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_struct("MutexGuard")
+            .field("lock", &self.__lock)
+            .finish()
+    }
+}
+
 pub fn guard_lock<'a, T: ?Sized>(guard: &MutexGuard<'a, T>) -> &'a sys::Mutex {
     &guard.__lock.inner
 }
index 71e163321aea23a71b0e83e437ed187fcd4ee59b..a9747639aacd797381e8df74d4eb2b44ecbf13a4 100644 (file)
@@ -64,6 +64,7 @@
 // You'll find a few more details in the implementation, but that's the gist of
 // it!
 
+use fmt;
 use marker;
 use ptr;
 use sync::atomic::{AtomicUsize, AtomicBool, Ordering};
@@ -103,6 +104,7 @@ unsafe impl Send for Once {}
 /// State yielded to the `call_once_force` method which can be used to query
 /// whether the `Once` was previously poisoned or not.
 #[unstable(feature = "once_poison", issue = "33577")]
+#[derive(Debug)]
 pub struct OnceState {
     poisoned: bool,
 }
@@ -328,6 +330,13 @@ fn call_inner(&'static self,
     }
 }
 
+#[stable(feature = "std_debug", since = "1.15.0")]
+impl fmt::Debug for Once {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.pad("Once { .. }")
+    }
+}
+
 impl Drop for Finish {
     fn drop(&mut self) {
         // Swap out our state with however we finished. We should only ever see
index f83cf7ba9c29e41dc21679f63cff17e0c44df7ed..0a11c71706b7e45565349fd771619cc8f50598d0 100644 (file)
@@ -362,6 +362,24 @@ unsafe fn new(lock: &'rwlock RwLock<T>)
     }
 }
 
+#[stable(feature = "std_debug", since = "1.15.0")]
+impl<'a, T: fmt::Debug> fmt::Debug for RwLockReadGuard<'a, T> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_struct("RwLockReadGuard")
+            .field("lock", &self.__lock)
+            .finish()
+    }
+}
+
+#[stable(feature = "std_debug", since = "1.15.0")]
+impl<'a, T: fmt::Debug> fmt::Debug for RwLockWriteGuard<'a, T> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_struct("RwLockWriteGuard")
+            .field("lock", &self.__lock)
+            .finish()
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'rwlock, T: ?Sized> Deref for RwLockReadGuard<'rwlock, T> {
     type Target = T;
index 80f53da1cefe051a2e9dba0afa09b87d7c4fc055..e822488c01851a7107c1e30f12313f93e5373e14 100644 (file)
@@ -85,6 +85,21 @@ enum AddressKind<'a> {
 }
 
 /// An address associated with a Unix socket.
+///
+/// # Examples
+///
+/// ```
+/// use std::os::unix::net::UnixListener;
+///
+/// let socket = match UnixListener::bind("/tmp/sock") {
+///     Ok(sock) => sock,
+///     Err(e) => {
+///         println!("Couldn't bind: {:?}", e);
+///         return
+///     }
+/// };
+/// let addr = socket.local_addr().expect("Couldn't get local address");
+/// ```
 #[derive(Clone)]
 #[stable(feature = "unix_socket", since = "1.10.0")]
 pub struct SocketAddr {
@@ -121,6 +136,28 @@ fn from_parts(addr: libc::sockaddr_un, mut len: libc::socklen_t) -> io::Result<S
     }
 
     /// Returns true if and only if the address is unnamed.
+    ///
+    /// # Examples
+    ///
+    /// A named address:
+    ///
+    /// ```
+    /// use std::os::unix::net::UnixListener;
+    ///
+    /// let socket = UnixListener::bind("/tmp/sock").unwrap();
+    /// let addr = socket.local_addr().expect("Couldn't get local address");
+    /// assert_eq!(addr.is_unnamed(), false);
+    /// ```
+    ///
+    /// An unnamed address:
+    ///
+    /// ```
+    /// use std::os::unix::net::UnixDatagram;
+    ///
+    /// let socket = UnixDatagram::unbound().unwrap();
+    /// let addr = socket.local_addr().expect("Couldn't get local address");
+    /// assert_eq!(addr.is_unnamed(), true);
+    /// ```
     #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn is_unnamed(&self) -> bool {
         if let AddressKind::Unnamed = self.address() {
@@ -131,6 +168,30 @@ pub fn is_unnamed(&self) -> bool {
     }
 
     /// Returns the contents of this address if it is a `pathname` address.
+    ///
+    /// # Examples
+    ///
+    /// With a pathname:
+    ///
+    /// ```
+    /// use std::os::unix::net::UnixListener;
+    /// use std::path::Path;
+    ///
+    /// let socket = UnixListener::bind("/tmp/sock").unwrap();
+    /// let addr = socket.local_addr().expect("Couldn't get local address");
+    /// assert_eq!(addr.as_pathname(), Some(Path::new("/tmp/sock")));
+    /// ```
+    ///
+    /// Without a pathname:
+    ///
+    /// ```
+    /// use std::os::unix::net::UnixDatagram;
+    /// use std::path::Path;
+    ///
+    /// let socket = UnixDatagram::unbound().unwrap();
+    /// let addr = socket.local_addr().expect("Couldn't get local address");
+    /// assert_eq!(addr.as_pathname(), None);
+    /// ```
     #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn as_pathname(&self) -> Option<&Path> {
         if let AddressKind::Pathname(path) = self.address() {
@@ -182,7 +243,7 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
 ///
 /// # Examples
 ///
-/// ```rust,no_run
+/// ```no_run
 /// use std::os::unix::net::UnixStream;
 /// use std::io::prelude::*;
 ///
@@ -212,6 +273,20 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
 
 impl UnixStream {
     /// Connects to the socket named by `path`.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixStream;
+    ///
+    /// let socket = match UnixStream::connect("/tmp/sock") {
+    ///     Ok(sock) => sock,
+    ///     Err(e) => {
+    ///         println!("Couldn't connect: {:?}", e);
+    ///         return
+    ///     }
+    /// };
+    /// ```
     #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn connect<P: AsRef<Path>>(path: P) -> io::Result<UnixStream> {
         fn inner(path: &Path) -> io::Result<UnixStream> {
@@ -229,6 +304,20 @@ fn inner(path: &Path) -> io::Result<UnixStream> {
     /// Creates an unnamed pair of connected sockets.
     ///
     /// Returns two `UnixStream`s which are connected to each other.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixStream;
+    ///
+    /// let (sock1, sock2) = match UnixStream::pair() {
+    ///     Ok((sock1, sock2)) => (sock1, sock2),
+    ///     Err(e) => {
+    ///         println!("Couldn't create a pair of sockets: {:?}", e);
+    ///         return
+    ///     }
+    /// };
+    /// ```
     #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn pair() -> io::Result<(UnixStream, UnixStream)> {
         let (i1, i2) = Socket::new_pair(libc::AF_UNIX, libc::SOCK_STREAM)?;
@@ -241,18 +330,45 @@ pub fn pair() -> io::Result<(UnixStream, UnixStream)> {
     /// object references. Both handles will read and write the same stream of
     /// data, and options set on one stream will be propogated to the other
     /// stream.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixStream;
+    ///
+    /// let socket = UnixStream::connect("/tmp/sock").unwrap();
+    /// let sock_copy = socket.try_clone().expect("Couldn't clone socket");
+    /// ```
     #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn try_clone(&self) -> io::Result<UnixStream> {
         self.0.duplicate().map(UnixStream)
     }
 
     /// Returns the socket address of the local half of this connection.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixStream;
+    ///
+    /// let socket = UnixStream::connect("/tmp/sock").unwrap();
+    /// let addr = socket.local_addr().expect("Couldn't get local address");
+    /// ```
     #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn local_addr(&self) -> io::Result<SocketAddr> {
         SocketAddr::new(|addr, len| unsafe { libc::getsockname(*self.0.as_inner(), addr, len) })
     }
 
     /// Returns the socket address of the remote half of this connection.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixStream;
+    ///
+    /// let socket = UnixStream::connect("/tmp/sock").unwrap();
+    /// let addr = socket.peer_addr().expect("Couldn't get peer address");
+    /// ```
     #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn peer_addr(&self) -> io::Result<SocketAddr> {
         SocketAddr::new(|addr, len| unsafe { libc::getpeername(*self.0.as_inner(), addr, len) })
@@ -260,9 +376,23 @@ pub fn peer_addr(&self) -> io::Result<SocketAddr> {
 
     /// Sets the read timeout for the socket.
     ///
-    /// If the provided value is `None`, then `read` calls will block
-    /// indefinitely. It is an error to pass the zero `Duration` to this
+    /// If the provided value is [`None`], then [`read()`] calls will block
+    /// indefinitely. It is an error to pass the zero [`Duration`] to this
     /// method.
+    ///
+    /// [`None`]: ../../../../std/option/enum.Option.html#variant.None
+    /// [`read()`]: ../../../../std/io/trait.Read.html#tymethod.read
+    /// [`Duration`]: ../../../../std/time/struct.Duration.html
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixStream;
+    /// use std::time::Duration;
+    ///
+    /// let socket = UnixStream::connect("/tmp/sock").unwrap();
+    /// socket.set_read_timeout(Some(Duration::new(1, 0))).expect("Couldn't set read timeout");
+    /// ```
     #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn set_read_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
         self.0.set_timeout(timeout, libc::SO_RCVTIMEO)
@@ -270,33 +400,89 @@ pub fn set_read_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
 
     /// Sets the write timeout for the socket.
     ///
-    /// If the provided value is `None`, then `write` calls will block
-    /// indefinitely. It is an error to pass the zero `Duration` to this
+    /// If the provided value is [`None`], then [`write()`] calls will block
+    /// indefinitely. It is an error to pass the zero [`Duration`] to this
     /// method.
+    ///
+    /// [`None`]: ../../../../std/option/enum.Option.html#variant.None
+    /// [`read()`]: ../../../../std/io/trait.Write.html#tymethod.write
+    /// [`Duration`]: ../../../../std/time/struct.Duration.html
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixStream;
+    /// use std::time::Duration;
+    ///
+    /// let socket = UnixStream::connect("/tmp/sock").unwrap();
+    /// socket.set_write_timeout(Some(Duration::new(1, 0))).expect("Couldn't set write timeout");
+    /// ```
     #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn set_write_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
         self.0.set_timeout(timeout, libc::SO_SNDTIMEO)
     }
 
     /// Returns the read timeout of this socket.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixStream;
+    /// use std::time::Duration;
+    ///
+    /// let socket = UnixStream::connect("/tmp/sock").unwrap();
+    /// socket.set_read_timeout(Some(Duration::new(1, 0))).expect("Couldn't set read timeout");
+    /// assert_eq!(socket.read_timeout().unwrap(), Some(Duration::new(1, 0)));
+    /// ```
     #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
         self.0.timeout(libc::SO_RCVTIMEO)
     }
 
     /// Returns the write timeout of this socket.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixStream;
+    /// use std::time::Duration;
+    ///
+    /// let socket = UnixStream::connect("/tmp/sock").unwrap();
+    /// socket.set_write_timeout(Some(Duration::new(1, 0))).expect("Couldn't set write timeout");
+    /// assert_eq!(socket.write_timeout().unwrap(), Some(Duration::new(1, 0)));
+    /// ```
     #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
         self.0.timeout(libc::SO_SNDTIMEO)
     }
 
     /// Moves the socket into or out of nonblocking mode.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixStream;
+    ///
+    /// let socket = UnixStream::connect("/tmp/sock").unwrap();
+    /// socket.set_nonblocking(true).expect("Couldn't set nonblocking");
+    /// ```
     #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
         self.0.set_nonblocking(nonblocking)
     }
 
     /// Returns the value of the `SO_ERROR` option.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixStream;
+    ///
+    /// let socket = UnixStream::connect("/tmp/sock").unwrap();
+    /// if let Ok(Some(err)) = socket.take_error() {
+    ///     println!("Got error: {:?}", err);
+    /// }
+    /// ```
     #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn take_error(&self) -> io::Result<Option<io::Error>> {
         self.0.take_error()
@@ -306,7 +492,19 @@ pub fn take_error(&self) -> io::Result<Option<io::Error>> {
     ///
     /// This function will cause all pending and future I/O calls on the
     /// specified portions to immediately return with an appropriate value
-    /// (see the documentation of `Shutdown`).
+    /// (see the documentation of [`Shutdown`]).
+    ///
+    /// [`Shutdown`]: ../../../../std/net/enum.Shutdown.html
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixStream;
+    /// use std::net::Shutdown;
+    ///
+    /// let socket = UnixStream::connect("/tmp/sock").unwrap();
+    /// socket.shutdown(Shutdown::Both).expect("shutdown function failed");
+    /// ```
     #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
         self.0.shutdown(how)
@@ -382,7 +580,7 @@ fn into_raw_fd(self) -> RawFd {
 ///
 /// # Examples
 ///
-/// ```rust,no_run
+/// ```no_run
 /// use std::thread;
 /// use std::os::unix::net::{UnixStream, UnixListener};
 ///
@@ -405,9 +603,6 @@ fn into_raw_fd(self) -> RawFd {
 ///         }
 ///     }
 /// }
-///
-/// // close the listener socket
-/// drop(listener);
 /// ```
 #[stable(feature = "unix_socket", since = "1.10.0")]
 pub struct UnixListener(Socket);
@@ -426,6 +621,20 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
 
 impl UnixListener {
     /// Creates a new `UnixListener` bound to the specified socket.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::os::unix::net::UnixListener;
+    ///
+    /// let listener = match UnixListener::bind("/path/to/the/socket") {
+    ///     Ok(sock) => sock,
+    ///     Err(e) => {
+    ///         println!("Couldn't connect: {:?}", e);
+    ///         return
+    ///     }
+    /// };
+    /// ```
     #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn bind<P: AsRef<Path>>(path: P) -> io::Result<UnixListener> {
         fn inner(path: &Path) -> io::Result<UnixListener> {
@@ -445,8 +654,23 @@ fn inner(path: &Path) -> io::Result<UnixListener> {
     /// Accepts a new incoming connection to this listener.
     ///
     /// This function will block the calling thread until a new Unix connection
-    /// is established. When established, the corersponding `UnixStream` and
+    /// is established. When established, the corersponding [`UnixStream`] and
     /// the remote peer's address will be returned.
+    ///
+    /// [`UnixStream`]: ../../../../std/os/unix/net/struct.UnixStream.html
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixListener;
+    ///
+    /// let listener = UnixListener::bind("/path/to/the/socket").unwrap();
+    ///
+    /// match listener.accept() {
+    ///     Ok((socket, addr)) => println!("Got a client: {:?}", addr),
+    ///     Err(e) => println!("accept function failed: {:?}", e),
+    /// }
+    /// ```
     #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn accept(&self) -> io::Result<(UnixStream, SocketAddr)> {
         let mut storage: libc::sockaddr_un = unsafe { mem::zeroed() };
@@ -461,24 +685,66 @@ pub fn accept(&self) -> io::Result<(UnixStream, SocketAddr)> {
     /// The returned `UnixListener` is a reference to the same socket that this
     /// object references. Both handles can be used to accept incoming
     /// connections and options set on one listener will affect the other.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixListener;
+    ///
+    /// let listener = UnixListener::bind("/path/to/the/socket").unwrap();
+    ///
+    /// let listener_copy = listener.try_clone().expect("try_clone failed");
+    /// ```
     #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn try_clone(&self) -> io::Result<UnixListener> {
         self.0.duplicate().map(UnixListener)
     }
 
     /// Returns the local socket address of this listener.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixListener;
+    ///
+    /// let listener = UnixListener::bind("/path/to/the/socket").unwrap();
+    ///
+    /// let addr = listener.local_addr().expect("Couldn't get local address");
+    /// ```
     #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn local_addr(&self) -> io::Result<SocketAddr> {
         SocketAddr::new(|addr, len| unsafe { libc::getsockname(*self.0.as_inner(), addr, len) })
     }
 
     /// Moves the socket into or out of nonblocking mode.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixListener;
+    ///
+    /// let listener = UnixListener::bind("/path/to/the/socket").unwrap();
+    ///
+    /// listener.set_nonblocking(true).expect("Couldn't set non blocking");
+    /// ```
     #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
         self.0.set_nonblocking(nonblocking)
     }
 
     /// Returns the value of the `SO_ERROR` option.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixListener;
+    ///
+    /// let listener = UnixListener::bind("/tmp/sock").unwrap();
+    ///
+    /// if let Ok(Some(err)) = listener.take_error() {
+    ///     println!("Got error: {:?}", err);
+    /// }
+    /// ```
     #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn take_error(&self) -> io::Result<Option<io::Error>> {
         self.0.take_error()
@@ -486,8 +752,35 @@ pub fn take_error(&self) -> io::Result<Option<io::Error>> {
 
     /// Returns an iterator over incoming connections.
     ///
-    /// The iterator will never return `None` and will also not yield the
-    /// peer's `SocketAddr` structure.
+    /// The iterator will never return [`None`] and will also not yield the
+    /// peer's [`SocketAddr`] structure.
+    ///
+    /// [`None`]: ../../../../std/option/enum.Option.html#variant.None
+    /// [`SocketAddr`]: struct.SocketAddr.html
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::thread;
+    /// use std::os::unix::net::{UnixStream, UnixListener};
+    ///
+    /// fn handle_client(stream: UnixStream) {
+    ///     // ...
+    /// }
+    ///
+    /// let listener = UnixListener::bind("/path/to/the/socket").unwrap();
+    ///
+    /// for stream in listener.incoming() {
+    ///     match stream {
+    ///         Ok(stream) => {
+    ///             thread::spawn(|| handle_client(stream));
+    ///         }
+    ///         Err(err) => {
+    ///             break;
+    ///         }
+    ///     }
+    /// }
+    /// ```
     #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn incoming<'a>(&'a self) -> Incoming<'a> {
         Incoming { listener: self }
@@ -525,9 +818,36 @@ fn into_iter(self) -> Incoming<'a> {
     }
 }
 
-/// An iterator over incoming connections to a `UnixListener`.
+/// An iterator over incoming connections to a [`UnixListener`].
+///
+/// It will never return [`None`].
+///
+/// [`None`]: ../../../../std/option/enum.Option.html#variant.None
+/// [`UnixListener`]: struct.UnixListener.html
+///
+/// # Examples
 ///
-/// It will never return `None`.
+/// ```no_run
+/// use std::thread;
+/// use std::os::unix::net::{UnixStream, UnixListener};
+///
+/// fn handle_client(stream: UnixStream) {
+///     // ...
+/// }
+///
+/// let listener = UnixListener::bind("/path/to/the/socket").unwrap();
+///
+/// for stream in listener.incoming() {
+///     match stream {
+///         Ok(stream) => {
+///             thread::spawn(|| handle_client(stream));
+///         }
+///         Err(err) => {
+///             break;
+///         }
+///     }
+/// }
+/// ```
 #[derive(Debug)]
 #[stable(feature = "unix_socket", since = "1.10.0")]
 pub struct Incoming<'a> {
@@ -551,7 +871,7 @@ fn size_hint(&self) -> (usize, Option<usize>) {
 ///
 /// # Examples
 ///
-/// ```rust,no_run
+/// ```no_run
 /// use std::os::unix::net::UnixDatagram;
 ///
 /// let socket = UnixDatagram::bind("/path/to/my/socket").unwrap();
@@ -580,6 +900,20 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
 
 impl UnixDatagram {
     /// Creates a Unix datagram socket bound to the given path.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixDatagram;
+    ///
+    /// let sock = match UnixDatagram::bind("/path/to/the/socket") {
+    ///     Ok(sock) => sock,
+    ///     Err(e) => {
+    ///         println!("Couldn't bind: {:?}", e);
+    ///         return
+    ///     }
+    /// };
+    /// ```
     #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn bind<P: AsRef<Path>>(path: P) -> io::Result<UnixDatagram> {
         fn inner(path: &Path) -> io::Result<UnixDatagram> {
@@ -596,6 +930,20 @@ fn inner(path: &Path) -> io::Result<UnixDatagram> {
     }
 
     /// Creates a Unix Datagram socket which is not bound to any address.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixDatagram;
+    ///
+    /// let sock = match UnixDatagram::unbound() {
+    ///     Ok(sock) => sock,
+    ///     Err(e) => {
+    ///         println!("Couldn't unbound: {:?}", e);
+    ///         return
+    ///     }
+    /// };
+    /// ```
     #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn unbound() -> io::Result<UnixDatagram> {
         let inner = Socket::new_raw(libc::AF_UNIX, libc::SOCK_DGRAM)?;
@@ -605,6 +953,20 @@ pub fn unbound() -> io::Result<UnixDatagram> {
     /// Create an unnamed pair of connected sockets.
     ///
     /// Returns two `UnixDatagrams`s which are connected to each other.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixDatagram;
+    ///
+    /// let (sock1, sock2) = match UnixDatagram::pair() {
+    ///     Ok((sock1, sock2)) => (sock1, sock2),
+    ///     Err(e) => {
+    ///         println!("Couldn't unbound: {:?}", e);
+    ///         return
+    ///     }
+    /// };
+    /// ```
     #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn pair() -> io::Result<(UnixDatagram, UnixDatagram)> {
         let (i1, i2) = Socket::new_pair(libc::AF_UNIX, libc::SOCK_DGRAM)?;
@@ -613,8 +975,27 @@ pub fn pair() -> io::Result<(UnixDatagram, UnixDatagram)> {
 
     /// Connects the socket to the specified address.
     ///
-    /// The `send` method may be used to send data to the specified address.
-    /// `recv` and `recv_from` will only receive data from that address.
+    /// The [`send()`] method may be used to send data to the specified address.
+    /// [`recv()`] and [`recv_from()`] will only receive data from that address.
+    ///
+    /// [`send()`]: #method.send
+    /// [`recv()`]: #method.recv
+    /// [`recv_from()`]: #method.recv_from
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixDatagram;
+    ///
+    /// let sock = UnixDatagram::unbound().unwrap();
+    /// match sock.connect("/path/to/the/socket") {
+    ///     Ok(sock) => sock,
+    ///     Err(e) => {
+    ///         println!("Couldn't connect: {:?}", e);
+    ///         return
+    ///     }
+    /// };
+    /// ```
     #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn connect<P: AsRef<Path>>(&self, path: P) -> io::Result<()> {
         fn inner(d: &UnixDatagram, path: &Path) -> io::Result<()> {
@@ -631,15 +1012,35 @@ fn inner(d: &UnixDatagram, path: &Path) -> io::Result<()> {
 
     /// Creates a new independently owned handle to the underlying socket.
     ///
-    /// The returned `UnixListener` is a reference to the same socket that this
+    /// The returned `UnixDatagram` is a reference to the same socket that this
     /// object references. Both handles can be used to accept incoming
-    /// connections and options set on one listener will affect the other.
+    /// connections and options set on one side will affect the other.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixDatagram;
+    ///
+    /// let sock = UnixDatagram::bind("/path/to/the/socket").unwrap();
+    ///
+    /// let sock_copy = sock.try_clone().expect("try_clone failed");
+    /// ```
     #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn try_clone(&self) -> io::Result<UnixDatagram> {
         self.0.duplicate().map(UnixDatagram)
     }
 
     /// Returns the address of this socket.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixDatagram;
+    ///
+    /// let sock = UnixDatagram::bind("/path/to/the/socket").unwrap();
+    ///
+    /// let addr = sock.local_addr().expect("Couldn't get local address");
+    /// ```
     #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn local_addr(&self) -> io::Result<SocketAddr> {
         SocketAddr::new(|addr, len| unsafe { libc::getsockname(*self.0.as_inner(), addr, len) })
@@ -647,7 +1048,20 @@ pub fn local_addr(&self) -> io::Result<SocketAddr> {
 
     /// Returns the address of this socket's peer.
     ///
-    /// The `connect` method will connect the socket to a peer.
+    /// The [`connect()`] method will connect the socket to a peer.
+    ///
+    /// [`connect()`]: #method.connect
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixDatagram;
+    ///
+    /// let sock = UnixDatagram::unbound().unwrap();
+    /// sock.connect("/path/to/the/socket").unwrap();
+    ///
+    /// let addr = sock.peer_addr().expect("Couldn't get peer address");
+    /// ```
     #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn peer_addr(&self) -> io::Result<SocketAddr> {
         SocketAddr::new(|addr, len| unsafe { libc::getpeername(*self.0.as_inner(), addr, len) })
@@ -657,6 +1071,19 @@ pub fn peer_addr(&self) -> io::Result<SocketAddr> {
     ///
     /// On success, returns the number of bytes read and the address from
     /// whence the data came.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixDatagram;
+    ///
+    /// let sock = UnixDatagram::unbound().unwrap();
+    /// let mut buf = vec![0; 10];
+    /// match sock.recv_from(buf.as_mut_slice()) {
+    ///     Ok((size, sender)) => println!("received {} bytes from {:?}", size, sender),
+    ///     Err(e) => println!("recv_from function failed: {:?}", e),
+    /// }
+    /// ```
     #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
         let mut count = 0;
@@ -684,6 +1111,16 @@ pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
     /// Receives data from the socket.
     ///
     /// On success, returns the number of bytes read.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixDatagram;
+    ///
+    /// let sock = UnixDatagram::bind("/path/to/the/socket").unwrap();
+    /// let mut buf = vec![0; 10];
+    /// sock.recv(buf.as_mut_slice()).expect("recv function failed");
+    /// ```
     #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn recv(&self, buf: &mut [u8]) -> io::Result<usize> {
         self.0.read(buf)
@@ -692,6 +1129,15 @@ pub fn recv(&self, buf: &mut [u8]) -> io::Result<usize> {
     /// Sends data on the socket to the specified address.
     ///
     /// On success, returns the number of bytes written.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixDatagram;
+    ///
+    /// let sock = UnixDatagram::unbound().unwrap();
+    /// sock.send_to(b"omelette au fromage", "/some/sock").expect("send_to function failed");
+    /// ```
     #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn send_to<P: AsRef<Path>>(&self, buf: &[u8], path: P) -> io::Result<usize> {
         fn inner(d: &UnixDatagram, buf: &[u8], path: &Path) -> io::Result<usize> {
@@ -716,6 +1162,16 @@ fn inner(d: &UnixDatagram, buf: &[u8], path: &Path) -> io::Result<usize> {
     /// will return an error if the socket has not already been connected.
     ///
     /// On success, returns the number of bytes written.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixDatagram;
+    ///
+    /// let sock = UnixDatagram::unbound().unwrap();
+    /// sock.connect("/some/sock").expect("Couldn't connect");
+    /// sock.send(b"omelette au fromage").expect("send_to function failed");
+    /// ```
     #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn send(&self, buf: &[u8]) -> io::Result<usize> {
         self.0.write(buf)
@@ -723,9 +1179,24 @@ pub fn send(&self, buf: &[u8]) -> io::Result<usize> {
 
     /// Sets the read timeout for the socket.
     ///
-    /// If the provided value is `None`, then `recv` and `recv_from` calls will
-    /// block indefinitely. It is an error to pass the zero `Duration` to this
+    /// If the provided value is [`None`], then [`recv()`] and [`recv_from()`] calls will
+    /// block indefinitely. It is an error to pass the zero [`Duration`] to this
     /// method.
+    ///
+    /// [`None`]: ../../../../std/option/enum.Option.html#variant.None
+    /// [`recv()`]: #method.recv
+    /// [`recv_from()`]: #method.recv_from
+    /// [`Duration`]: ../../../../std/time/struct.Duration.html
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::os::unix::net::UnixDatagram;
+    /// use std::time::Duration;
+    ///
+    /// let sock = UnixDatagram::unbound().unwrap();
+    /// sock.set_read_timeout(Some(Duration::new(1, 0))).expect("set_read_timeout function failed");
+    /// ```
     #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn set_read_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
         self.0.set_timeout(timeout, libc::SO_RCVTIMEO)
@@ -733,33 +1204,92 @@ pub fn set_read_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
 
     /// Sets the write timeout for the socket.
     ///
-    /// If the provided value is `None`, then `send` and `send_to` calls will
-    /// block indefinitely. It is an error to pass the zero `Duration` to this
+    /// If the provided value is [`None`], then [`send()`] and [`send_to()`] calls will
+    /// block indefinitely. It is an error to pass the zero [`Duration`] to this
     /// method.
+    ///
+    /// [`None`]: ../../../../std/option/enum.Option.html#variant.None
+    /// [`send()`]: #method.send
+    /// [`send_to()`]: #method.send_to
+    /// [`Duration`]: ../../../../std/time/struct.Duration.html
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::os::unix::net::UnixDatagram;
+    /// use std::time::Duration;
+    ///
+    /// let sock = UnixDatagram::unbound().unwrap();
+    /// sock.set_write_timeout(Some(Duration::new(1, 0)))
+    ///     .expect("set_write_timeout function failed");
+    /// ```
     #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn set_write_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
         self.0.set_timeout(timeout, libc::SO_SNDTIMEO)
     }
 
     /// Returns the read timeout of this socket.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::os::unix::net::UnixDatagram;
+    /// use std::time::Duration;
+    ///
+    /// let sock = UnixDatagram::unbound().unwrap();
+    /// sock.set_read_timeout(Some(Duration::new(1, 0))).expect("set_read_timeout function failed");
+    /// assert_eq!(sock.read_timeout().unwrap(), Some(Duration::new(1, 0)));
+    /// ```
     #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
         self.0.timeout(libc::SO_RCVTIMEO)
     }
 
     /// Returns the write timeout of this socket.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::os::unix::net::UnixDatagram;
+    /// use std::time::Duration;
+    ///
+    /// let sock = UnixDatagram::unbound().unwrap();
+    /// sock.set_write_timeout(Some(Duration::new(1, 0)))
+    ///     .expect("set_write_timeout function failed");
+    /// assert_eq!(sock.write_timeout().unwrap(), Some(Duration::new(1, 0)));
+    /// ```
     #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
         self.0.timeout(libc::SO_SNDTIMEO)
     }
 
     /// Moves the socket into or out of nonblocking mode.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::os::unix::net::UnixDatagram;
+    ///
+    /// let sock = UnixDatagram::unbound().unwrap();
+    /// sock.set_nonblocking(true).expect("set_nonblocking function failed");
+    /// ```
     #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
         self.0.set_nonblocking(nonblocking)
     }
 
     /// Returns the value of the `SO_ERROR` option.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixDatagram;
+    ///
+    /// let sock = UnixDatagram::unbound().unwrap();
+    /// if let Ok(Some(err)) = sock.take_error() {
+    ///     println!("Got error: {:?}", err);
+    /// }
+    /// ```
     #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn take_error(&self) -> io::Result<Option<io::Error>> {
         self.0.take_error()
@@ -769,7 +1299,17 @@ pub fn take_error(&self) -> io::Result<Option<io::Error>> {
     ///
     /// This function will cause all pending and future I/O calls on the
     /// specified portions to immediately return with an appropriate value
-    /// (see the documentation of `Shutdown`).
+    /// (see the documentation of [`Shutdown`]).
+    ///
+    /// [`Shutdown`]: ../../../../std/net/enum.Shutdown.html
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixDatagram;
+    /// use std::net::Shutdown;
+    ///
+    /// let sock = UnixDatagram::unbound().unwrap();
+    /// sock.shutdown(Shutdown::Both).expect("shutdown function failed");
+    /// ```
     #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
         self.0.shutdown(how)
index 0c625e7add9d0eb81b3efa976a3374eaf929c8d4..f4f73646e1b7e088e6d844ac1230b4f430a425ee 100644 (file)
@@ -12,6 +12,7 @@
 #![unstable(feature = "thread_local_internals", issue = "0")]
 
 use cell::{Cell, UnsafeCell};
+use fmt;
 use intrinsics;
 use ptr;
 
@@ -24,6 +25,12 @@ pub struct Key<T> {
     dtor_running: Cell<bool>,
 }
 
+impl<T> fmt::Debug for Key<T> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.pad("Key { .. }")
+    }
+}
+
 unsafe impl<T> ::marker::Sync for Key<T> { }
 
 impl<T> Key<T> {
index 61eb60da486c95e07af92462ef15fd515c0c0534..2384d959881a238662648ceb50b59e935844174f 100644 (file)
@@ -18,6 +18,7 @@
 use sys_common::AsInner;
 use sys_common::io::read_to_end_uninitialized;
 
+#[derive(Debug)]
 pub struct FileDesc {
     fd: c_int,
 }
index 9ee0458b5da365d1fae1c99bfa17fbdf0d20113f..8b5c0c04276b164882604cf195bedcd30adab4e0 100644 (file)
@@ -66,7 +66,7 @@ pub struct DirEntry {
     name: Box<[u8]>
 }
 
-#[derive(Clone)]
+#[derive(Clone, Debug)]
 pub struct OpenOptions {
     // generic
     read: bool,
@@ -86,6 +86,7 @@ pub struct FilePermissions { mode: mode_t }
 #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
 pub struct FileType { mode: mode_t }
 
+#[derive(Debug)]
 pub struct DirBuilder { mode: mode_t }
 
 impl FileAttr {
index 7d7d78bbd87308315d75551a88c9ac5ef4558ac1..c410fcd1ee0ed59f0c2533172541f3cd64a89a17 100644 (file)
@@ -58,7 +58,7 @@ pub struct DirEntry {
     data: c::WIN32_FIND_DATAW,
 }
 
-#[derive(Clone)]
+#[derive(Clone, Debug)]
 pub struct OpenOptions {
     // generic
     read: bool,
@@ -79,6 +79,7 @@ pub struct OpenOptions {
 #[derive(Clone, PartialEq, Eq, Debug)]
 pub struct FilePermissions { attrs: c::DWORD }
 
+#[derive(Debug)]
 pub struct DirBuilder;
 
 impl fmt::Debug for ReadDir {
index f74dd5924951c1f02daaa2d6835e91ac919bbcba..01584979aabaae59c57e769cee73dd8e25e49477 100644 (file)
@@ -13,6 +13,7 @@
 #![unstable(feature = "thread_local_internals", issue = "0")]
 
 use cell::UnsafeCell;
+use fmt;
 use mem;
 
 /// A thread local storage key which owns its contents.
@@ -98,6 +99,13 @@ pub struct LocalKey<T: 'static> {
     init: fn() -> T,
 }
 
+#[stable(feature = "std_debug", since = "1.15.0")]
+impl<T: 'static> fmt::Debug for LocalKey<T> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.pad("LocalKey { .. }")
+    }
+}
+
 /// Declare a new thread local storage key of type `std::thread::LocalKey`.
 ///
 /// # Syntax
@@ -184,7 +192,7 @@ fn __getit() -> $crate::option::Option<
 #[unstable(feature = "thread_local_state",
            reason = "state querying was recently added",
            issue = "27716")]
-#[derive(Eq, PartialEq, Copy, Clone)]
+#[derive(Debug, Eq, PartialEq, Copy, Clone)]
 pub enum LocalKeyState {
     /// All keys are in this state whenever a thread starts. Keys will
     /// transition to the `Valid` state once the first call to `with` happens
@@ -313,6 +321,7 @@ pub fn state(&'static self) -> LocalKeyState {
 #[doc(hidden)]
 pub mod os {
     use cell::{Cell, UnsafeCell};
+    use fmt;
     use marker;
     use ptr;
     use sys_common::thread_local::StaticKey as OsStaticKey;
@@ -323,6 +332,13 @@ pub struct Key<T> {
         marker: marker::PhantomData<Cell<T>>,
     }
 
+    #[stable(feature = "std_debug", since = "1.15.0")]
+    impl<T> fmt::Debug for Key<T> {
+        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+            f.pad("Key { .. }")
+        }
+    }
+
     unsafe impl<T> ::marker::Sync for Key<T> { }
 
     struct Value<T: 'static> {
index 55adc3dabf40fa7e54763730ecf938012663f8ad..2a3fb5ec43f2abeb8a33df697a94e382217d7f65 100644 (file)
 /// Thread configuration. Provides detailed control over the properties
 /// and behavior of new threads.
 #[stable(feature = "rust1", since = "1.0.0")]
+#[derive(Debug)]
 pub struct Builder {
     // A name for the thread-to-be, for identification in panic messages
     name: Option<String>,
@@ -587,6 +588,13 @@ fn new() -> ThreadId {
     }
 }
 
+#[stable(feature = "std_debug", since = "1.15.0")]
+impl fmt::Debug for ThreadId {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.pad("ThreadId { .. }")
+    }
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // Thread
 ////////////////////////////////////////////////////////////////////////////////
@@ -802,6 +810,13 @@ impl<T> IntoInner<imp::Thread> for JoinHandle<T> {
     fn into_inner(self) -> imp::Thread { self.0.native.unwrap() }
 }
 
+#[stable(feature = "std_debug", since = "1.15.0")]
+impl<T> fmt::Debug for JoinHandle<T> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.pad("JoinHandle { .. }")
+    }
+}
+
 fn _assert_sync_and_send() {
     fn _assert_both<T: Send + Sync>() {}
     _assert_both::<JoinHandle<()>>();
index 41d675b6f88fc4f7be2819536c8da5c1d9670a21..162ce530f17cdb427508b9f39b9e4366dd20adad 100644 (file)
 const NANOS_PER_MILLI: u32 = 1_000_000;
 const MILLIS_PER_SEC: u64 = 1_000;
 
-/// A duration type to represent a span of time, typically used for system
+/// A `Duration` type to represent a span of time, typically used for system
 /// timeouts.
 ///
-/// Each duration is composed of a number of seconds and nanosecond precision.
+/// Each `Duration` is composed of a number of seconds and nanosecond precision.
 /// APIs binding a system timeout will typically round up the nanosecond
 /// precision if the underlying system does not support that level of precision.
 ///
-/// Durations implement many common traits, including `Add`, `Sub`, and other
-/// ops traits. Currently a duration may only be inspected for its number of
-/// seconds and its nanosecond precision.
+/// `Duration`s implement many common traits, including [`Add`], [`Sub`], and other
+/// [`ops`] traits.
+///
+/// [`Add`]: ../../std/ops/trait.Add.html
+/// [`Sub`]: ../../std/ops/trait.Sub.html
+/// [`ops`]: ../../std/ops/index.html
 ///
 /// # Examples
 ///
@@ -56,6 +59,14 @@ impl Duration {
     ///
     /// This constructor will panic if the carry from the nanoseconds overflows
     /// the seconds counter.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::time::Duration;
+    ///
+    /// let five_seconds = Duration::new(5, 0);
+    /// ```
     #[stable(feature = "duration", since = "1.3.0")]
     #[inline]
     pub fn new(secs: u64, nanos: u32) -> Duration {
@@ -66,6 +77,14 @@ pub fn new(secs: u64, nanos: u32) -> Duration {
     }
 
     /// Creates a new `Duration` from the specified number of seconds.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::time::Duration;
+    ///
+    /// let five_seconds = Duration::from_secs(5);
+    /// ```
     #[stable(feature = "duration", since = "1.3.0")]
     #[inline]
     pub fn from_secs(secs: u64) -> Duration {
@@ -73,6 +92,14 @@ pub fn from_secs(secs: u64) -> Duration {
     }
 
     /// Creates a new `Duration` from the specified number of milliseconds.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::time::Duration;
+    ///
+    /// let five_seconds = Duration::from_millis(5000);
+    /// ```
     #[stable(feature = "duration", since = "1.3.0")]
     #[inline]
     pub fn from_millis(millis: u64) -> Duration {
@@ -81,26 +108,46 @@ pub fn from_millis(millis: u64) -> Duration {
         Duration { secs: secs, nanos: nanos }
     }
 
-    /// Returns the number of whole seconds represented by this duration.
+    /// Returns the number of whole seconds represented by this `Duration`.
     ///
     /// The extra precision represented by this duration is ignored (i.e. extra
     /// nanoseconds are not represented in the returned value).
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::time::Duration;
+    ///
+    /// let five_seconds = Duration::new(5, 0);
+    /// assert_eq!(five_seconds.as_secs(), 5);
+    /// ```
     #[stable(feature = "duration", since = "1.3.0")]
     #[inline]
     pub fn as_secs(&self) -> u64 { self.secs }
 
-    /// Returns the nanosecond precision represented by this duration.
+    /// Returns the nanosecond precision represented by this `Duration`.
     ///
     /// This method does **not** return the length of the duration when
     /// represented by nanoseconds. The returned number always represents a
     /// fractional portion of a second (i.e. it is less than one billion).
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::time::Duration;
+    ///
+    /// let duration = Duration::from_millis(5010);
+    /// assert_eq!(duration.subsec_nanos(), 10000000);
+    /// ```
     #[stable(feature = "duration", since = "1.3.0")]
     #[inline]
     pub fn subsec_nanos(&self) -> u32 { self.nanos }
 
-    /// Checked duration addition. Computes `self + other`, returning `None`
+    /// Checked `Duration` addition. Computes `self + other`, returning [`None`]
     /// if overflow occurred.
     ///
+    /// [`None`]: ../../std/option/enum.Option.html#variant.None
+    ///
     /// # Examples
     ///
     /// Basic usage:
@@ -136,9 +183,11 @@ pub fn checked_add(self, rhs: Duration) -> Option<Duration> {
         }
     }
 
-    /// Checked duration subtraction. Computes `self + other`, returning `None`
+    /// Checked `Duration` subtraction. Computes `self - other`, returning [`None`]
     /// if the result would be negative or if underflow occurred.
     ///
+    /// [`None`]: ../../std/option/enum.Option.html#variant.None
+    ///
     /// # Examples
     ///
     /// Basic usage:
@@ -172,8 +221,10 @@ pub fn checked_sub(self, rhs: Duration) -> Option<Duration> {
         }
     }
 
-    /// Checked duration multiplication. Computes `self * other`, returning
-    /// `None` if underflow or overflow occurred.
+    /// Checked `Duration` multiplication. Computes `self * other`, returning
+    /// [`None`] if overflow occurred.
+    ///
+    /// [`None`]: ../../std/option/enum.Option.html#variant.None
     ///
     /// # Examples
     ///
@@ -207,8 +258,10 @@ pub fn checked_mul(self, rhs: u32) -> Option<Duration> {
         }
     }
 
-    /// Checked duration division. Computes `self / other`, returning `None`
-    /// if `other == 0` or the operation results in underflow or overflow.
+    /// Checked `Duration` division. Computes `self / other`, returning [`None`]
+    /// if `other == 0`.
+    ///
+    /// [`None`]: ../../std/option/enum.Option.html#variant.None
     ///
     /// # Examples
     ///
index 2a911aceb9d94e01a8be3187953b019271d6103d..fdd82225b974747990adb31c6a9d8067499011d2 100644 (file)
@@ -47,10 +47,14 @@ pub const fn with_empty_ctxt(name: Name) -> Ident {
         Ident { name: name, ctxt: SyntaxContext::empty() }
     }
 
-   /// Maps a string to an identifier with an empty syntax context.
-   pub fn from_str(s: &str) -> Ident {
-       Ident::with_empty_ctxt(Symbol::intern(s))
-   }
+    /// Maps a string to an identifier with an empty syntax context.
+    pub fn from_str(s: &str) -> Ident {
+        Ident::with_empty_ctxt(Symbol::intern(s))
+    }
+
+    pub fn unhygienize(&self) -> Ident {
+        Ident { name: self.name, ctxt: SyntaxContext::empty() }
+    }
 }
 
 impl fmt::Debug for Ident {
@@ -133,12 +137,7 @@ pub fn from_ident(s: Span, identifier: Ident) -> Path {
         Path {
             span: s,
             global: false,
-            segments: vec![
-                PathSegment {
-                    identifier: identifier,
-                    parameters: PathParameters::none()
-                }
-            ],
+            segments: vec![identifier.into()],
         }
     }
 }
@@ -156,7 +155,15 @@ pub struct PathSegment {
     /// this is more than just simple syntactic sugar; the use of
     /// parens affects the region binding rules, so we preserve the
     /// distinction.
-    pub parameters: PathParameters,
+    /// The `Option<P<..>>` wrapper is purely a size optimization;
+    /// `None` is used to represent both `Path` and `Path<>`.
+    pub parameters: Option<P<PathParameters>>,
+}
+
+impl From<Ident> for PathSegment {
+    fn from(id: Ident) -> Self {
+        PathSegment { identifier: id, parameters: None }
+    }
 }
 
 /// Parameters of a path segment.
@@ -170,79 +177,8 @@ pub enum PathParameters {
     Parenthesized(ParenthesizedParameterData),
 }
 
-impl PathParameters {
-    pub fn none() -> PathParameters {
-        PathParameters::AngleBracketed(AngleBracketedParameterData {
-            lifetimes: Vec::new(),
-            types: P::new(),
-            bindings: P::new(),
-        })
-    }
-
-    pub fn is_empty(&self) -> bool {
-        match *self {
-            PathParameters::AngleBracketed(ref data) => data.is_empty(),
-
-            // Even if the user supplied no types, something like
-            // `X()` is equivalent to `X<(),()>`.
-            PathParameters::Parenthesized(..) => false,
-        }
-    }
-
-    pub fn has_lifetimes(&self) -> bool {
-        match *self {
-            PathParameters::AngleBracketed(ref data) => !data.lifetimes.is_empty(),
-            PathParameters::Parenthesized(_) => false,
-        }
-    }
-
-    pub fn has_types(&self) -> bool {
-        match *self {
-            PathParameters::AngleBracketed(ref data) => !data.types.is_empty(),
-            PathParameters::Parenthesized(..) => true,
-        }
-    }
-
-    /// Returns the types that the user wrote. Note that these do not necessarily map to the type
-    /// parameters in the parenthesized case.
-    pub fn types(&self) -> Vec<&P<Ty>> {
-        match *self {
-            PathParameters::AngleBracketed(ref data) => {
-                data.types.iter().collect()
-            }
-            PathParameters::Parenthesized(ref data) => {
-                data.inputs.iter()
-                    .chain(data.output.iter())
-                    .collect()
-            }
-        }
-    }
-
-    pub fn lifetimes(&self) -> Vec<&Lifetime> {
-        match *self {
-            PathParameters::AngleBracketed(ref data) => {
-                data.lifetimes.iter().collect()
-            }
-            PathParameters::Parenthesized(_) => {
-                Vec::new()
-            }
-        }
-    }
-
-    pub fn bindings(&self) -> Vec<&TypeBinding> {
-        match *self {
-            PathParameters::AngleBracketed(ref data) => {
-                data.bindings.iter().collect()
-            }
-            PathParameters::Parenthesized(_) => {
-                Vec::new()
-            }
-        }
-    }
-}
-
 /// A path like `Foo<'a, T>`
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
+#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Default)]
 pub struct AngleBracketedParameterData {
     /// The lifetime parameters for this path segment.
     pub lifetimes: Vec<Lifetime>,
@@ -254,9 +190,10 @@ pub struct AngleBracketedParameterData {
     pub bindings: P<[TypeBinding]>,
 }
 
-impl AngleBracketedParameterData {
-    fn is_empty(&self) -> bool {
-        self.lifetimes.is_empty() && self.types.is_empty() && self.bindings.is_empty()
+impl Into<Option<P<PathParameters>>> for AngleBracketedParameterData {
+    fn into(self) -> Option<P<PathParameters>> {
+        let empty = self.lifetimes.is_empty() && self.types.is_empty() && self.bindings.is_empty();
+        if empty { None } else { Some(P(PathParameters::AngleBracketed(self))) }
     }
 }
 
@@ -1968,8 +1905,6 @@ pub struct MacroDef {
     pub attrs: Vec<Attribute>,
     pub id: NodeId,
     pub span: Span,
-    pub imported_from: Option<Ident>,
-    pub allow_internal_unstable: bool,
     pub body: Vec<TokenTree>,
 }
 
index 45c120e0b95ca44daa6fc7445707efd986e822f6..c31bcfbd86992ec7dce23a1647d15d6f9ada2559 100644 (file)
@@ -29,7 +29,6 @@
 use util::ThinVec;
 
 use std::cell::{RefCell, Cell};
-use std::collections::HashSet;
 
 thread_local! {
     static USED_ATTRS: RefCell<Vec<u64>> = RefCell::new(Vec::new());
@@ -372,16 +371,6 @@ pub fn mk_spanned_attr_outer(sp: Span, id: AttrId, item: MetaItem) -> Attribute
     }
 }
 
-pub fn mk_doc_attr_outer(id: AttrId, item: MetaItem, is_sugared_doc: bool) -> Attribute {
-    Attribute {
-        id: id,
-        style: ast::AttrStyle::Outer,
-        value: item,
-        is_sugared_doc: is_sugared_doc,
-        span: DUMMY_SP,
-    }
-}
-
 pub fn mk_sugared_doc_attr(id: AttrId, text: Symbol, lo: BytePos, hi: BytePos)
                            -> Attribute {
     let style = doc_comment_style(&text.as_str());
@@ -421,13 +410,6 @@ pub fn first_attr_value_str_by_name(attrs: &[Attribute], name: &str) -> Option<S
         .and_then(|at| at.value_str())
 }
 
-pub fn last_meta_item_value_str_by_name(items: &[MetaItem], name: &str) -> Option<Symbol> {
-    items.iter()
-         .rev()
-         .find(|mi| mi.check_name(name))
-         .and_then(|i| i.value_str())
-}
-
 /* Higher-level applications */
 
 pub fn find_crate_name(attrs: &[Attribute]) -> Option<Symbol> {
@@ -856,18 +838,6 @@ pub fn find_deprecation(diagnostic: &Handler, attrs: &[Attribute],
     find_deprecation_generic(diagnostic, attrs.iter(), item_sp)
 }
 
-pub fn require_unique_names(diagnostic: &Handler, metas: &[MetaItem]) {
-    let mut set = HashSet::new();
-    for meta in metas {
-        let name = meta.name();
-
-        if !set.insert(name.clone()) {
-            panic!(diagnostic.span_fatal(meta.span,
-                                         &format!("duplicate meta item `{}`", name)));
-        }
-    }
-}
-
 
 /// Parse #[repr(...)] forms.
 ///
index ddbca47429d1876298601836b0ed032e2d1ed1b7..8e63f73fdaa7a1f7c6df130338a472fdcbbf6fe8 100644 (file)
@@ -217,8 +217,7 @@ fn expand<'cx>(&self,
                    cx: &'cx mut ExtCtxt,
                    sp: Span,
                    ident: ast::Ident,
-                   token_tree: Vec<tokenstream::TokenTree>,
-                   attrs: Vec<ast::Attribute>)
+                   token_tree: Vec<tokenstream::TokenTree>)
                    -> Box<MacResult+'cx>;
 }
 
@@ -234,8 +233,7 @@ fn expand<'cx>(&self,
                    cx: &'cx mut ExtCtxt,
                    sp: Span,
                    ident: ast::Ident,
-                   token_tree: Vec<tokenstream::TokenTree>,
-                   _attrs: Vec<ast::Attribute>)
+                   token_tree: Vec<tokenstream::TokenTree>)
                    -> Box<MacResult+'cx>
     {
         (*self)(cx, sp, ident, token_tree)
@@ -520,7 +518,6 @@ pub trait Resolver {
     fn eliminate_crate_var(&mut self, item: P<ast::Item>) -> P<ast::Item>;
 
     fn visit_expansion(&mut self, mark: Mark, expansion: &Expansion);
-    fn add_macro(&mut self, scope: Mark, def: ast::MacroDef, export: bool);
     fn add_ext(&mut self, ident: ast::Ident, ext: Rc<SyntaxExtension>);
     fn add_expansions_at_stmt(&mut self, id: ast::NodeId, macros: Vec<Mark>);
 
@@ -544,7 +541,6 @@ fn get_module_scope(&mut self, _id: ast::NodeId) -> Mark { Mark::root() }
     fn eliminate_crate_var(&mut self, item: P<ast::Item>) -> P<ast::Item> { item }
 
     fn visit_expansion(&mut self, _invoc: Mark, _expansion: &Expansion) {}
-    fn add_macro(&mut self, _scope: Mark, _def: ast::MacroDef, _export: bool) {}
     fn add_ext(&mut self, _ident: ast::Ident, _ext: Rc<SyntaxExtension>) {}
     fn add_expansions_at_stmt(&mut self, _id: ast::NodeId, _macros: Vec<Mark>) {}
 
index 6c0d40b69d3c841170b9dc8a89db42e38758e795..c3dc64f91247bed799f59ed813dff72b423217f9 100644 (file)
@@ -322,21 +322,17 @@ fn path_all(&self,
                 bindings: Vec<ast::TypeBinding> )
                 -> ast::Path {
         let last_identifier = idents.pop().unwrap();
-        let mut segments: Vec<ast::PathSegment> = idents.into_iter()
-                                                      .map(|ident| {
-            ast::PathSegment {
-                identifier: ident,
-                parameters: ast::PathParameters::none(),
-            }
-        }).collect();
-        segments.push(ast::PathSegment {
-            identifier: last_identifier,
-            parameters: ast::PathParameters::AngleBracketed(ast::AngleBracketedParameterData {
+        let mut segments: Vec<ast::PathSegment> = idents.into_iter().map(Into::into).collect();
+        let parameters = if lifetimes.is_empty() && types.is_empty() && bindings.is_empty() {
+            None
+        } else {
+            Some(P(ast::PathParameters::AngleBracketed(ast::AngleBracketedParameterData {
                 lifetimes: lifetimes,
                 types: P::from_vec(types),
                 bindings: P::from_vec(bindings),
-            })
-        });
+            })))
+        };
+        segments.push(ast::PathSegment { identifier: last_identifier, parameters: parameters });
         ast::Path {
             span: sp,
             global: global,
@@ -367,13 +363,14 @@ fn qpath_all(&self,
                  bindings: Vec<ast::TypeBinding>)
                  -> (ast::QSelf, ast::Path) {
         let mut path = trait_path;
+        let parameters = ast::AngleBracketedParameterData {
+            lifetimes: lifetimes,
+            types: P::from_vec(types),
+            bindings: P::from_vec(bindings),
+        };
         path.segments.push(ast::PathSegment {
             identifier: ident,
-            parameters: ast::PathParameters::AngleBracketed(ast::AngleBracketedParameterData {
-                lifetimes: lifetimes,
-                types: P::from_vec(types),
-                bindings: P::from_vec(bindings),
-            })
+            parameters: Some(P(ast::PathParameters::AngleBracketed(parameters))),
         });
 
         (ast::QSelf {
index 19545e2e642b12fc6b25592e15a9d2e72f7eca0f..5d62175fbf23a7af4c44dbf9836ebb499102c086 100644 (file)
@@ -158,7 +158,6 @@ pub struct Invocation {
 
 pub enum InvocationKind {
     Bang {
-        attrs: Vec<ast::Attribute>,
         mac: ast::Mac,
         ident: Option<Ident>,
         span: Span,
@@ -276,7 +275,7 @@ fn expand(&mut self, expansion: Expansion) -> Expansion {
             if expansions.len() < depth {
                 expansions.push(Vec::new());
             }
-            expansions[depth - 1].push((mark.as_u32(), expansion));
+            expansions[depth - 1].push((mark, expansion));
             if !self.cx.ecfg.single_step {
                 invocations.extend(new_invocations.into_iter().rev());
             }
@@ -287,7 +286,7 @@ fn expand(&mut self, expansion: Expansion) -> Expansion {
         let mut placeholder_expander = PlaceholderExpander::new(self.cx, self.monotonic);
         while let Some(expansions) = expansions.pop() {
             for (mark, expansion) in expansions.into_iter().rev() {
-                placeholder_expander.add(ast::NodeId::from_u32(mark), expansion);
+                placeholder_expander.add(mark.as_placeholder_id(), expansion);
             }
         }
 
@@ -386,20 +385,12 @@ fn expand_attr_invoc(&mut self, invoc: Invocation, ext: Rc<SyntaxExtension>) ->
     /// Expand a macro invocation. Returns the result of expansion.
     fn expand_bang_invoc(&mut self, invoc: Invocation, ext: Rc<SyntaxExtension>) -> Expansion {
         let (mark, kind) = (invoc.expansion_data.mark, invoc.expansion_kind);
-        let (attrs, mac, ident, span) = match invoc.kind {
-            InvocationKind::Bang { attrs, mac, ident, span } => (attrs, mac, ident, span),
+        let (mac, ident, span) = match invoc.kind {
+            InvocationKind::Bang { mac, ident, span } => (mac, ident, span),
             _ => unreachable!(),
         };
         let Mac_ { path, tts, .. } = mac.node;
 
-        // Detect use of feature-gated or invalid attributes on macro invoations
-        // since they will not be detected after macro expansion.
-        for attr in attrs.iter() {
-            feature_gate::check_attribute(&attr, &self.cx.parse_sess,
-                                          &self.cx.parse_sess.codemap(),
-                                          &self.cx.ecfg.features.unwrap());
-        }
-
         let extname = path.segments.last().unwrap().identifier.name;
         let ident = ident.unwrap_or(keywords::Invalid.ident());
         let marked_tts = mark_tts(&tts, mark);
@@ -440,7 +431,7 @@ fn expand_bang_invoc(&mut self, invoc: Invocation, ext: Rc<SyntaxExtension>) ->
                     }
                 });
 
-                kind.make_from(expander.expand(self.cx, span, ident, marked_tts, attrs))
+                kind.make_from(expander.expand(self.cx, span, ident, marked_tts))
             }
 
             MultiDecorator(..) | MultiModifier(..) | SyntaxExtension::AttrProcMacro(..) => {
@@ -595,13 +586,11 @@ fn collect(&mut self, expansion_kind: ExpansionKind, kind: InvocationKind) -> Ex
                 ..self.cx.current_expansion.clone()
             },
         });
-        placeholder(expansion_kind, ast::NodeId::from_u32(mark.as_u32()))
+        placeholder(expansion_kind, mark.as_placeholder_id())
     }
 
-    fn collect_bang(
-        &mut self, mac: ast::Mac, attrs: Vec<ast::Attribute>, span: Span, kind: ExpansionKind,
-    ) -> Expansion {
-        self.collect(kind, InvocationKind::Bang { attrs: attrs, mac: mac, ident: None, span: span })
+    fn collect_bang(&mut self, mac: ast::Mac, span: Span, kind: ExpansionKind) -> Expansion {
+        self.collect(kind, InvocationKind::Bang { mac: mac, ident: None, span: span })
     }
 
     fn collect_attr(&mut self, attr: ast::Attribute, item: Annotatable, kind: ExpansionKind)
@@ -622,6 +611,16 @@ fn classify_item<T: HasAttrs>(&mut self, mut item: T) -> (T, Option<ast::Attribu
     fn configure<T: HasAttrs>(&mut self, node: T) -> Option<T> {
         self.cfg.configure(node)
     }
+
+    // Detect use of feature-gated or invalid attributes on macro invocations
+    // since they will not be detected after macro expansion.
+    fn check_attributes(&mut self, attrs: &[ast::Attribute]) {
+        let codemap = &self.cx.parse_sess.codemap();
+        let features = self.cx.ecfg.features.unwrap();
+        for attr in attrs.iter() {
+            feature_gate::check_attribute(&attr, &self.cx.parse_sess, codemap, features);
+        }
+    }
 }
 
 // These are pretty nasty. Ideally, we would keep the tokens around, linked from
@@ -660,7 +659,8 @@ fn fold_expr(&mut self, expr: P<ast::Expr>) -> P<ast::Expr> {
         expr.node = self.cfg.configure_expr_kind(expr.node);
 
         if let ast::ExprKind::Mac(mac) = expr.node {
-            self.collect_bang(mac, expr.attrs.into(), expr.span, ExpansionKind::Expr).make_expr()
+            self.check_attributes(&expr.attrs);
+            self.collect_bang(mac, expr.span, ExpansionKind::Expr).make_expr()
         } else {
             P(noop_fold_expr(expr, self))
         }
@@ -671,8 +671,8 @@ fn fold_opt_expr(&mut self, expr: P<ast::Expr>) -> Option<P<ast::Expr>> {
         expr.node = self.cfg.configure_expr_kind(expr.node);
 
         if let ast::ExprKind::Mac(mac) = expr.node {
-            self.collect_bang(mac, expr.attrs.into(), expr.span, ExpansionKind::OptExpr)
-                .make_opt_expr()
+            self.check_attributes(&expr.attrs);
+            self.collect_bang(mac, expr.span, ExpansionKind::OptExpr).make_opt_expr()
         } else {
             Some(P(noop_fold_expr(expr, self)))
         }
@@ -685,8 +685,7 @@ fn fold_pat(&mut self, pat: P<ast::Pat>) -> P<ast::Pat> {
         }
 
         pat.and_then(|pat| match pat.node {
-            PatKind::Mac(mac) =>
-                self.collect_bang(mac, Vec::new(), pat.span, ExpansionKind::Pat).make_pat(),
+            PatKind::Mac(mac) => self.collect_bang(mac, pat.span, ExpansionKind::Pat).make_pat(),
             _ => unreachable!(),
         })
     }
@@ -707,8 +706,8 @@ fn fold_stmt(&mut self, stmt: ast::Stmt) -> SmallVector<ast::Stmt> {
             }).collect()
         };
 
-        let mut placeholder =
-            self.collect_bang(mac, attrs.into(), stmt.span, ExpansionKind::Stmts).make_stmts();
+        self.check_attributes(&attrs);
+        let mut placeholder = self.collect_bang(mac, stmt.span, ExpansionKind::Stmts).make_stmts();
 
         // If this is a macro invocation with a semicolon, then apply that
         // semicolon to the final statement produced by expansion.
@@ -740,18 +739,21 @@ fn fold_item(&mut self, item: P<ast::Item>) -> SmallVector<P<ast::Item>> {
 
         match item.node {
             ast::ItemKind::Mac(..) => {
-                if match item.node {
-                    ItemKind::Mac(ref mac) => mac.node.path.segments.is_empty(),
-                    _ => unreachable!(),
-                } {
-                    return SmallVector::one(item);
-                }
+                self.check_attributes(&item.attrs);
+                let is_macro_def = if let ItemKind::Mac(ref mac) = item.node {
+                    mac.node.path.segments[0].identifier.name == "macro_rules"
+                } else {
+                    unreachable!()
+                };
 
-                item.and_then(|item| match item.node {
+                item.and_then(|mut item| match item.node {
+                    ItemKind::Mac(_) if is_macro_def => {
+                        item.id = Mark::fresh().as_placeholder_id();
+                        SmallVector::one(P(item))
+                    }
                     ItemKind::Mac(mac) => {
                         self.collect(ExpansionKind::Items, InvocationKind::Bang {
                             mac: mac,
-                            attrs: item.attrs,
                             ident: Some(item.ident),
                             span: item.span,
                         }).make_items()
@@ -823,7 +825,8 @@ fn fold_trait_item(&mut self, item: ast::TraitItem) -> SmallVector<ast::TraitIte
         match item.node {
             ast::TraitItemKind::Macro(mac) => {
                 let ast::TraitItem { attrs, span, .. } = item;
-                self.collect_bang(mac, attrs, span, ExpansionKind::TraitItems).make_trait_items()
+                self.check_attributes(&attrs);
+                self.collect_bang(mac, span, ExpansionKind::TraitItems).make_trait_items()
             }
             _ => fold::noop_fold_trait_item(item, self),
         }
@@ -841,7 +844,8 @@ fn fold_impl_item(&mut self, item: ast::ImplItem) -> SmallVector<ast::ImplItem>
         match item.node {
             ast::ImplItemKind::Macro(mac) => {
                 let ast::ImplItem { attrs, span, .. } = item;
-                self.collect_bang(mac, attrs, span, ExpansionKind::ImplItems).make_impl_items()
+                self.check_attributes(&attrs);
+                self.collect_bang(mac, span, ExpansionKind::ImplItems).make_impl_items()
             }
             _ => fold::noop_fold_impl_item(item, self),
         }
@@ -854,8 +858,7 @@ fn fold_ty(&mut self, ty: P<ast::Ty>) -> P<ast::Ty> {
         };
 
         match ty.node {
-            ast::TyKind::Mac(mac) =>
-                self.collect_bang(mac, Vec::new(), ty.span, ExpansionKind::Ty).make_ty(),
+            ast::TyKind::Mac(mac) => self.collect_bang(mac, ty.span, ExpansionKind::Ty).make_ty(),
             _ => unreachable!(),
         }
     }
index 0fd72277cca9f46015f5df1600e015b26365cede..2af5c2ea9995ef61f20ba390f2efffd5bf043065 100644 (file)
@@ -51,7 +51,11 @@ pub fn from_placeholder_id(id: NodeId) -> Self {
         Mark(id.as_u32())
     }
 
-    pub fn as_u32(&self) -> u32 {
+    pub fn as_placeholder_id(self) -> NodeId {
+        NodeId::from_u32(self.0)
+    }
+
+    pub fn as_u32(self) -> u32 {
         self.0
     }
 }
@@ -115,12 +119,12 @@ pub fn apply_mark(self, mark: Mark) -> SyntaxContext {
         })
     }
 
-   /// If `ident` is macro expanded, return the source ident from the macro definition
-   /// and the mark of the expansion that created the macro definition.
-   pub fn source(self) -> (Self /* source context */, Mark /* source macro */) {
-        let macro_def_ctxt = self.data().prev_ctxt.data();
-        (macro_def_ctxt.prev_ctxt, macro_def_ctxt.outer_mark)
-   }
+    /// If `ident` is macro expanded, return the source ident from the macro definition
+    /// and the mark of the expansion that created the macro definition.
+    pub fn source(self) -> (Self /* source context */, Mark /* source macro */) {
+         let macro_def_ctxt = self.data().prev_ctxt.data();
+         (macro_def_ctxt.prev_ctxt, macro_def_ctxt.outer_mark)
+    }
 }
 
 impl fmt::Debug for SyntaxContext {
index 4fe57a8345e94e707c71192c0f5f0f3bb8b06cbf..eb4b6144c8d28ad989d2044710ed2cda42b3f49f 100644 (file)
 use codemap::{DUMMY_SP, dummy_spanned};
 use ext::base::ExtCtxt;
 use ext::expand::{Expansion, ExpansionKind};
+use ext::hygiene::Mark;
 use fold::*;
 use ptr::P;
-use symbol::{Symbol, keywords};
+use symbol::keywords;
 use util::move_map::MoveMap;
 use util::small_vector::SmallVector;
 
@@ -68,10 +69,6 @@ fn mac_placeholder() -> ast::Mac {
     }
 }
 
-pub fn macro_scope_placeholder() -> Expansion {
-    placeholder(ExpansionKind::Items, ast::DUMMY_NODE_ID)
-}
-
 pub struct PlaceholderExpander<'a, 'b: 'a> {
     expansions: HashMap<ast::NodeId, Expansion>,
     cx: &'a mut ExtCtxt<'b>,
@@ -100,11 +97,12 @@ fn remove(&mut self, id: ast::NodeId) -> Expansion {
 impl<'a, 'b> Folder for PlaceholderExpander<'a, 'b> {
     fn fold_item(&mut self, item: P<ast::Item>) -> SmallVector<P<ast::Item>> {
         match item.node {
-            // Scope placeholder
-            ast::ItemKind::Mac(_) if item.id == ast::DUMMY_NODE_ID => SmallVector::one(item),
-            ast::ItemKind::Mac(_) => self.remove(item.id).make_items(),
-            _ => noop_fold_item(item, self),
+            ast::ItemKind::Mac(ref mac) if !mac.node.path.segments.is_empty() => {}
+            ast::ItemKind::Mac(_) => return self.remove(item.id).make_items(),
+            _ => {}
         }
+
+        noop_fold_item(item, self)
     }
 
     fn fold_trait_item(&mut self, item: ast::TraitItem) -> SmallVector<ast::TraitItem> {
@@ -172,10 +170,10 @@ fn fold_block(&mut self, block: P<ast::Block>) -> P<ast::Block> {
             block.stmts = block.stmts.move_flat_map(|mut stmt| {
                 remaining_stmts -= 1;
 
-                // Scope placeholder
+                // `macro_rules!` macro definition
                 if let ast::StmtKind::Item(ref item) = stmt.node {
-                    if let ast::ItemKind::Mac(..) = item.node {
-                        macros.push(item.ident.ctxt.data().outer_mark);
+                    if let ast::ItemKind::Mac(_) = item.node {
+                        macros.push(Mark::from_placeholder_id(item.id));
                         return None;
                     }
                 }
@@ -208,33 +206,13 @@ fn fold_block(&mut self, block: P<ast::Block>) -> P<ast::Block> {
     fn fold_mod(&mut self, module: ast::Mod) -> ast::Mod {
         let mut module = noop_fold_mod(module, self);
         module.items = module.items.move_flat_map(|item| match item.node {
-            ast::ItemKind::Mac(_) => None, // remove scope placeholders from modules
+            ast::ItemKind::Mac(_) if !self.cx.ecfg.keep_macs => None, // remove macro definitions
             _ => Some(item),
         });
         module
     }
-}
 
-pub fn reconstructed_macro_rules(def: &ast::MacroDef) -> Expansion {
-    Expansion::Items(SmallVector::one(P(ast::Item {
-        ident: def.ident,
-        attrs: def.attrs.clone(),
-        id: ast::DUMMY_NODE_ID,
-        node: ast::ItemKind::Mac(ast::Mac {
-            span: def.span,
-            node: ast::Mac_ {
-                path: ast::Path {
-                    span: DUMMY_SP,
-                    global: false,
-                    segments: vec![ast::PathSegment {
-                        identifier: ast::Ident::with_empty_ctxt(Symbol::intern("macro_rules")),
-                        parameters: ast::PathParameters::none(),
-                    }],
-                },
-                tts: def.body.clone(),
-            }
-        }),
-        vis: ast::Visibility::Inherited,
-        span: def.span,
-    })))
+    fn fold_mac(&mut self, mac: ast::Mac) -> ast::Mac {
+        mac
+    }
 }
index ca18e580ecdfbb7910d489d0eaa1a9c9f59e9eec..3abd24b50ba9a83baf3473b12d1b5cde2d996eb4 100644 (file)
 
 use {ast, attr};
 use syntax_pos::{Span, DUMMY_SP};
-use ext::base::{DummyResult, ExtCtxt, MacEager, MacResult, SyntaxExtension};
-use ext::base::{IdentMacroExpander, NormalTT, TTMacroExpander};
+use ext::base::{DummyResult, ExtCtxt, MacResult, SyntaxExtension};
+use ext::base::{NormalTT, TTMacroExpander};
 use ext::expand::{Expansion, ExpansionKind};
-use ext::placeholders;
 use ext::tt::macro_parser::{Success, Error, Failure};
 use ext::tt::macro_parser::{MatchedSeq, MatchedNonterminal};
 use ext::tt::macro_parser::{parse, parse_failure_msg};
@@ -151,38 +150,6 @@ fn generic_extension<'cx>(cx: &'cx ExtCtxt,
     cx.span_fatal(best_fail_spot.substitute_dummy(sp), &best_fail_msg);
 }
 
-pub struct MacroRulesExpander;
-impl IdentMacroExpander for MacroRulesExpander {
-    fn expand(&self,
-              cx: &mut ExtCtxt,
-              span: Span,
-              ident: ast::Ident,
-              tts: Vec<tokenstream::TokenTree>,
-              attrs: Vec<ast::Attribute>)
-              -> Box<MacResult> {
-        let export = attr::contains_name(&attrs, "macro_export");
-        let def = ast::MacroDef {
-            ident: ident,
-            id: ast::DUMMY_NODE_ID,
-            span: span,
-            imported_from: None,
-            body: tts,
-            allow_internal_unstable: attr::contains_name(&attrs, "allow_internal_unstable"),
-            attrs: attrs,
-        };
-
-        // If keep_macs is true, expands to a MacEager::items instead.
-        let result = if cx.ecfg.keep_macs {
-            MacEager::items(placeholders::reconstructed_macro_rules(&def).make_items())
-        } else {
-            MacEager::items(placeholders::macro_scope_placeholder().make_items())
-        };
-
-        cx.resolver.add_macro(cx.current_expansion.mark, def, export);
-        result
-    }
-}
-
 // Note that macro-by-example's input is also matched against a token tree:
 //                   $( $lhs:tt => $rhs:tt );+
 //
@@ -282,7 +249,7 @@ pub fn compile(sess: &ParseSess, def: &ast::MacroDef) -> SyntaxExtension {
         valid: valid,
     });
 
-    NormalTT(exp, Some(def.span), def.allow_internal_unstable)
+    NormalTT(exp, Some(def.span), attr::contains_name(&def.attrs, "allow_internal_unstable"))
 }
 
 fn check_lhs_nt_follows(sess: &ParseSess, lhs: &TokenTree) -> bool {
index 6af8efb2a195c6c3408a568b2fa0b8a8f7c04568..b3753e3e977e331cf424d382694f2bcd28ff0c34 100644 (file)
@@ -438,7 +438,7 @@ pub fn noop_fold_path<T: Folder>(Path {global, segments, span}: Path, fld: &mut
         global: global,
         segments: segments.move_map(|PathSegment {identifier, parameters}| PathSegment {
             identifier: fld.fold_ident(identifier),
-            parameters: fld.fold_path_parameters(parameters),
+            parameters: parameters.map(|ps| ps.map(|ps| fld.fold_path_parameters(ps))),
         }),
         span: fld.new_span(span)
     }
index c982205f0ecef8e8f135731803971224388d37f4..b9e6605639ead2c8ff0f8ee61cd0814c5df31738 100644 (file)
@@ -634,12 +634,7 @@ fn sp(a: u32, b: u32) -> Span {
                     node: ast::ExprKind::Path(None, ast::Path {
                         span: sp(0, 1),
                         global: false,
-                        segments: vec![
-                            ast::PathSegment {
-                                identifier: Ident::from_str("a"),
-                                parameters: ast::PathParameters::none(),
-                            }
-                        ],
+                        segments: vec![Ident::from_str("a").into()],
                     }),
                     span: sp(0, 1),
                     attrs: ThinVec::new(),
@@ -651,19 +646,10 @@ fn sp(a: u32, b: u32) -> Span {
                    P(ast::Expr {
                     id: ast::DUMMY_NODE_ID,
                     node: ast::ExprKind::Path(None, ast::Path {
-                            span: sp(0, 6),
-                            global: true,
-                            segments: vec![
-                                ast::PathSegment {
-                                    identifier: Ident::from_str("a"),
-                                    parameters: ast::PathParameters::none(),
-                                },
-                                ast::PathSegment {
-                                    identifier: Ident::from_str("b"),
-                                    parameters: ast::PathParameters::none(),
-                                }
-                            ]
-                        }),
+                        span: sp(0, 6),
+                        global: true,
+                        segments: vec![Ident::from_str("a").into(), Ident::from_str("b").into()],
+                    }),
                     span: sp(0, 6),
                     attrs: ThinVec::new(),
                    }))
@@ -772,12 +758,7 @@ fn string_to_tts_1() {
                         node:ast::ExprKind::Path(None, ast::Path{
                             span: sp(7, 8),
                             global: false,
-                            segments: vec![
-                                ast::PathSegment {
-                                    identifier: Ident::from_str("d"),
-                                    parameters: ast::PathParameters::none(),
-                                }
-                            ],
+                            segments: vec![Ident::from_str("d").into()],
                         }),
                         span:sp(7,8),
                         attrs: ThinVec::new(),
@@ -795,12 +776,7 @@ fn string_to_tts_1() {
                            node: ast::ExprKind::Path(None, ast::Path {
                                span:sp(0,1),
                                global:false,
-                               segments: vec![
-                                ast::PathSegment {
-                                    identifier: Ident::from_str("b"),
-                                    parameters: ast::PathParameters::none(),
-                                }
-                               ],
+                               segments: vec![Ident::from_str("b").into()],
                             }),
                            span: sp(0,1),
                            attrs: ThinVec::new()})),
@@ -842,12 +818,7 @@ fn parser_done(p: Parser){
                                                   node: ast::TyKind::Path(None, ast::Path{
                                         span:sp(10,13),
                                         global:false,
-                                        segments: vec![
-                                            ast::PathSegment {
-                                                identifier: Ident::from_str("i32"),
-                                                parameters: ast::PathParameters::none(),
-                                            }
-                                        ],
+                                        segments: vec![Ident::from_str("i32").into()],
                                         }),
                                         span:sp(10,13)
                                     }),
@@ -890,13 +861,7 @@ fn parser_done(p: Parser){
                                                       ast::Path{
                                                         span:sp(17,18),
                                                         global:false,
-                                                        segments: vec![
-                                                            ast::PathSegment {
-                                                                identifier: Ident::from_str("b"),
-                                                                parameters:
-                                                                ast::PathParameters::none(),
-                                                            }
-                                                        ],
+                                                        segments: vec![Ident::from_str("b").into()],
                                                       }),
                                                 span: sp(17,18),
                                                 attrs: ThinVec::new()})),
index a1d4ad9d629c9f973cfaafc84187c63deac0eff2..72462b74e686ca60b1f002f220738dd7e55b162f 100644 (file)
@@ -1705,12 +1705,11 @@ pub fn parse_path_segments_without_colons(&mut self) -> PResult<'a, Vec<ast::Pat
             // Parse types, optionally.
             let parameters = if self.eat_lt() {
                 let (lifetimes, types, bindings) = self.parse_generic_values_after_lt()?;
-
-                ast::PathParameters::AngleBracketed(ast::AngleBracketedParameterData {
+                ast::AngleBracketedParameterData {
                     lifetimes: lifetimes,
                     types: P::from_vec(types),
                     bindings: P::from_vec(bindings),
-                })
+                }.into()
             } else if self.eat(&token::OpenDelim(token::Paren)) {
                 let lo = self.prev_span.lo;
 
@@ -1727,18 +1726,17 @@ pub fn parse_path_segments_without_colons(&mut self) -> PResult<'a, Vec<ast::Pat
 
                 let hi = self.prev_span.hi;
 
-                ast::PathParameters::Parenthesized(ast::ParenthesizedParameterData {
+                Some(P(ast::PathParameters::Parenthesized(ast::ParenthesizedParameterData {
                     span: mk_sp(lo, hi),
                     inputs: inputs,
                     output: output_ty,
-                })
+                })))
             } else {
-                ast::PathParameters::none()
+                None
             };
 
             // Assemble and push the result.
-            segments.push(ast::PathSegment { identifier: identifier,
-                                             parameters: parameters });
+            segments.push(ast::PathSegment { identifier: identifier, parameters: parameters });
 
             // Continue only if we see a `::`
             if !self.eat(&token::ModSep) {
@@ -1757,10 +1755,7 @@ pub fn parse_path_segments_with_colons(&mut self) -> PResult<'a, Vec<ast::PathSe
 
             // If we do not see a `::`, stop.
             if !self.eat(&token::ModSep) {
-                segments.push(ast::PathSegment {
-                    identifier: identifier,
-                    parameters: ast::PathParameters::none()
-                });
+                segments.push(identifier.into());
                 return Ok(segments);
             }
 
@@ -1768,14 +1763,13 @@ pub fn parse_path_segments_with_colons(&mut self) -> PResult<'a, Vec<ast::PathSe
             if self.eat_lt() {
                 // Consumed `a::b::<`, go look for types
                 let (lifetimes, types, bindings) = self.parse_generic_values_after_lt()?;
-                let parameters = ast::AngleBracketedParameterData {
-                    lifetimes: lifetimes,
-                    types: P::from_vec(types),
-                    bindings: P::from_vec(bindings),
-                };
                 segments.push(ast::PathSegment {
                     identifier: identifier,
-                    parameters: ast::PathParameters::AngleBracketed(parameters),
+                    parameters: ast::AngleBracketedParameterData {
+                        lifetimes: lifetimes,
+                        types: P::from_vec(types),
+                        bindings: P::from_vec(bindings),
+                    }.into(),
                 });
 
                 // Consumed `a::b::<T,U>`, check for `::` before proceeding
@@ -1784,10 +1778,7 @@ pub fn parse_path_segments_with_colons(&mut self) -> PResult<'a, Vec<ast::PathSe
                 }
             } else {
                 // Consumed `a::`, go look for `b`
-                segments.push(ast::PathSegment {
-                    identifier: identifier,
-                    parameters: ast::PathParameters::none(),
-                });
+                segments.push(identifier.into());
             }
         }
     }
@@ -1802,10 +1793,7 @@ pub fn parse_path_segments_without_types(&mut self)
             let identifier = self.parse_path_segment_ident()?;
 
             // Assemble and push the result.
-            segments.push(ast::PathSegment {
-                identifier: identifier,
-                parameters: ast::PathParameters::none()
-            });
+            segments.push(identifier.into());
 
             // If we do not see a `::` or see `::{`/`::*`, stop.
             if !self.check(&token::ModSep) || self.is_import_coupler() {
index c28b9d00501b70fd6a989f27af86ad170873d3df..22e8391de93ed4910d9fbf988db6e3093392c844 100644 (file)
@@ -2349,7 +2349,9 @@ fn print_path(&mut self,
 
             try!(self.print_ident(segment.identifier));
 
-            try!(self.print_path_parameters(&segment.parameters, colons_before_params));
+            if let Some(ref parameters) = segment.parameters {
+                try!(self.print_path_parameters(parameters, colons_before_params))
+            }
         }
 
         Ok(())
@@ -2373,7 +2375,10 @@ fn print_qpath(&mut self,
         try!(word(&mut self.s, "::"));
         let item_segment = path.segments.last().unwrap();
         try!(self.print_ident(item_segment.identifier));
-        self.print_path_parameters(&item_segment.parameters, colons_before_params)
+        match item_segment.parameters {
+            Some(ref parameters) => self.print_path_parameters(parameters, colons_before_params),
+            None => Ok(()),
+        }
     }
 
     fn print_path_parameters(&mut self,
@@ -2381,10 +2386,6 @@ fn print_path_parameters(&mut self,
                              colons_before_params: bool)
                              -> io::Result<()>
     {
-        if parameters.is_empty() {
-            return Ok(());
-        }
-
         if colons_before_params {
             try!(word(&mut self.s, "::"))
         }
index 6a291ad9c408a372ed1dbd9b7af1b8c59f9a0335..4ad760a3cafe4194ca60be1ec28fb9e5c5c12168 100644 (file)
@@ -81,9 +81,8 @@ pub fn maybe_inject_crates_ref(sess: &ParseSess,
         vis: ast::Visibility::Inherited,
         node: ast::ItemKind::Use(P(codemap::dummy_spanned(ast::ViewPathGlob(ast::Path {
             global: false,
-            segments: vec![name, "prelude", "v1"].into_iter().map(|name| ast::PathSegment {
-                identifier: ast::Ident::from_str(name),
-                parameters: ast::PathParameters::none(),
+            segments: vec![name, "prelude", "v1"].into_iter().map(|name| {
+                ast::Ident::from_str(name).into()
             }).collect(),
             span: span,
         })))),
index fca89e265e4edcfa710694532e46cc8f3d162c48..7709d3bd1cf1ce27e5bcd1492ac54a34a7ad08b8 100644 (file)
@@ -580,10 +580,7 @@ fn path_node(ids: Vec<Ident>) -> ast::Path {
     ast::Path {
         span: DUMMY_SP,
         global: false,
-        segments: ids.into_iter().map(|identifier| ast::PathSegment {
-            identifier: identifier,
-            parameters: ast::PathParameters::none(),
-        }).collect()
+        segments: ids.into_iter().map(Into::into).collect(),
     }
 }
 
index 3e0353d532d88fb558cfb2cdd461bfc8ec6e89f5..ad29cb50a84c80221e308b2b381ed08bed08406e 100644 (file)
@@ -178,7 +178,6 @@ pub fn walk_crate<'a, V: Visitor<'a>>(visitor: &mut V, krate: &'a Crate) {
 
 pub fn walk_macro_def<'a, V: Visitor<'a>>(visitor: &mut V, macro_def: &'a MacroDef) {
     visitor.visit_ident(macro_def.span, macro_def.ident);
-    walk_opt_ident(visitor, macro_def.span, macro_def.imported_from);
     walk_list!(visitor, visit_attribute, &macro_def.attrs);
 }
 
@@ -384,7 +383,9 @@ pub fn walk_path_segment<'a, V: Visitor<'a>>(visitor: &mut V,
                                              path_span: Span,
                                              segment: &'a PathSegment) {
     visitor.visit_ident(path_span, segment.identifier);
-    visitor.visit_path_parameters(path_span, &segment.parameters);
+    if let Some(ref parameters) = segment.parameters {
+        visitor.visit_path_parameters(path_span, parameters);
+    }
 }
 
 pub fn walk_path_parameters<'a, V>(visitor: &mut V,
index b26e33eb384dc0017fc942a16ec9e62e0bf9e6c7..1381490efa194b3bd7a1e7850aa35c394bae9a30 100644 (file)
@@ -59,14 +59,10 @@ struct Result {
 
     impl Result {
         fn path(&self) -> ast::Path {
-            let segment = ast::PathSegment {
-                identifier: self.ident,
-                parameters: ast::PathParameters::none(),
-            };
             ast::Path {
                 span: self.span,
                 global: false,
-                segments: vec![segment],
+                segments: vec![self.ident.into()],
             }
         }
     }
index 66d6c0570ace70d4910c80257345353d6571841b..e31b29d5cc1b435270cc4cf9949b7825e0b639f7 100644 (file)
@@ -50,8 +50,7 @@
 
 use std::rc::Rc;
 use syntax::ast;
-use syntax::ext::base::{MacroExpanderFn, NormalTT, IdentTT, MultiModifier, NamedSyntaxExtension};
-use syntax::ext::tt::macro_rules::MacroRulesExpander;
+use syntax::ext::base::{MacroExpanderFn, NormalTT, MultiModifier, NamedSyntaxExtension};
 use syntax::symbol::Symbol;
 
 pub fn register_builtins(resolver: &mut syntax::ext::base::Resolver,
@@ -61,8 +60,6 @@ pub fn register_builtins(resolver: &mut syntax::ext::base::Resolver,
         resolver.add_ext(ast::Ident::with_empty_ctxt(name), Rc::new(ext));
     };
 
-    register(Symbol::intern("macro_rules"), IdentTT(Box::new(MacroRulesExpander), None, false));
-
     macro_rules! register {
         ($( $name:ident: $f:expr, )*) => { $(
             register(Symbol::intern(stringify!($name)),
index 4fbd70835dd2bc73ad9749505ee3a98d77f12241..187c56d7889ea52a27eb3d424a872f37e0e6558c 100644 (file)
@@ -13,4 +13,4 @@
 # released on `$date`
 
 rustc: beta-2016-12-16
-cargo: nightly-2016-11-16
+cargo: fbeea902d2c9a5be6d99cc35681565d8f7832592
index 95be48b5ff1b35ec80d820060d3c8c22c726a179..b2129902ef9c3bac73fa7389e3cee6d64784610b 100644 (file)
@@ -15,6 +15,6 @@
 
 extern crate libc as collections;
 //~^ ERROR E0259
-//~| NOTE `collections` was already imported
+//~| NOTE `collections` already imported
 
 fn main() {}
diff --git a/src/test/compile-fail/E0277-2.rs b/src/test/compile-fail/E0277-2.rs
new file mode 100644 (file)
index 0000000..211c0e6
--- /dev/null
@@ -0,0 +1,34 @@
+// 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.
+
+struct Foo {
+    bar: Bar
+}
+
+struct Bar {
+    baz: Baz
+}
+
+struct Baz {
+    x: *const u8
+}
+
+fn is_send<T: Send>() { }
+
+fn main() {
+    is_send::<Foo>();
+    //~^ ERROR the trait bound `*const u8: std::marker::Send` is not satisfied in `Foo`
+    //~| NOTE within `Foo`, the trait `std::marker::Send` is not implemented for `*const u8`
+    //~| NOTE: `*const u8` cannot be sent between threads safely
+    //~| NOTE: required because it appears within the type `Baz`
+    //~| NOTE: required because it appears within the type `Bar`
+    //~| NOTE: required because it appears within the type `Foo`
+    //~| NOTE: required by `is_send`
+}
index e4cb50cd3f25348deaa0d65df285e1ff5d600ef1..e31fea1e45863205e40132d17162e04a9fbe9e85 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use std::path::Path;
+
 trait Foo {
     fn bar(&self);
 }
@@ -16,6 +18,13 @@ fn some_func<T: Foo>(foo: T) {
     foo.bar();
 }
 
+fn f(p: Path) { }
+//~^ ERROR the trait bound `[u8]: std::marker::Sized` is not satisfied in `std::path::Path`
+//~| NOTE within `std::path::Path`, the trait `std::marker::Sized` is not implemented for `[u8]`
+//~| NOTE `[u8]` does not have a constant size known at compile-time
+//~| NOTE required because it appears within the type `std::path::Path`
+//~| NOTE all local variables must have a statically known size
+
 fn main() {
     some_func(5i32);
     //~^ ERROR the trait bound `i32: Foo` is not satisfied
index 853282ff014364786711170bdce00fadd7d1b3ab..e9df8868a1ed9d56a371b34802f629fda27d9c2c 100644 (file)
@@ -12,6 +12,6 @@ mod foo { pub mod foo {  } } //~ NOTE previous definition of `foo` here
 
 use foo::foo;
 //~^ ERROR a module named `foo` has already been defined in this module
-//~| was already imported
+//~| `foo` already defined
 
 fn main() {}
diff --git a/src/test/compile-fail/cast-rfc0401.rs b/src/test/compile-fail/cast-rfc0401.rs
deleted file mode 100644 (file)
index b98f464..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-// Copyright 2015 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.
-
-fn illegal_cast<U:?Sized,V:?Sized>(u: *const U) -> *const V
-{
-    u as *const V
-    //~^ ERROR casting
-    //~^^ NOTE vtable kinds
-}
-
-fn illegal_cast_2<U:?Sized>(u: *const U) -> *const str
-{
-    u as *const str
-    //~^ ERROR casting
-    //~^^ NOTE vtable kinds
-}
-
-trait Foo { fn foo(&self) {} }
-impl<T> Foo for T {}
-
-trait Bar { fn foo(&self) {} }
-impl<T> Bar for T {}
-
-enum E {
-    A, B
-}
-
-fn main()
-{
-    let f: f32 = 1.2;
-    let v = 0 as *const u8;
-    let fat_v : *const [u8] = unsafe { &*(0 as *const [u8; 1])};
-    let fat_sv : *const [i8] = unsafe { &*(0 as *const [i8; 1])};
-    let foo: &Foo = &f;
-
-    let _ = v as &u8; //~ ERROR non-scalar
-    let _ = v as E; //~ ERROR non-scalar
-    let _ = v as fn(); //~ ERROR non-scalar
-    let _ = v as (u32,); //~ ERROR non-scalar
-    let _ = Some(&v) as *const u8; //~ ERROR non-scalar
-
-    let _ = v as f32;
-    //~^ ERROR casting
-    let _ = main as f64;
-    //~^ ERROR casting
-    let _ = &v as usize;
-    //~^ ERROR casting
-    //~^^ HELP through a raw pointer first
-    let _ = f as *const u8;
-    //~^ ERROR casting
-    let _ = 3_i32 as bool;
-    //~^ ERROR cannot cast as `bool` [E0054]
-    //~| unsupported cast
-    //~| HELP compare with zero
-    let _ = E::A as bool;
-    //~^ ERROR cannot cast as `bool` [E0054]
-    //~| unsupported cast
-    //~| HELP compare with zero
-    let _ = 0x61u32 as char; //~ ERROR only `u8` can be cast
-
-    let _ = false as f32;
-    //~^ ERROR casting
-    //~^^ HELP through an integer first
-    let _ = E::A as f32;
-    //~^ ERROR casting
-    //~^^ HELP through an integer first
-    let _ = 'a' as f32;
-    //~^ ERROR casting
-    //~^^ HELP through an integer first
-
-    let _ = false as *const u8;
-    //~^ ERROR casting
-    let _ = E::A as *const u8;
-    //~^ ERROR casting
-    let _ = 'a' as *const u8;
-    //~^ ERROR casting
-
-    let _ = 42usize as *const [u8]; //~ ERROR casting
-    let _ = v as *const [u8]; //~ ERROR cannot cast
-    let _ = fat_v as *const Foo;
-    //~^ ERROR the trait bound `[u8]: std::marker::Sized` is not satisfied
-    //~| NOTE the trait `std::marker::Sized` is not implemented for `[u8]`
-    //~| NOTE `[u8]` does not have a constant size known at compile-time
-    //~| NOTE required for the cast to the object type `Foo`
-    let _ = foo as *const str; //~ ERROR casting
-    let _ = foo as *mut str; //~ ERROR casting
-    let _ = main as *mut str; //~ ERROR casting
-    let _ = &f as *mut f32; //~ ERROR casting
-    let _ = &f as *const f64; //~ ERROR casting
-    let _ = fat_sv as usize;
-    //~^ ERROR casting
-    //~^^ HELP through a thin pointer first
-
-    let a : *const str = "hello";
-    let _ = a as *const Foo;
-    //~^ ERROR the trait bound `str: std::marker::Sized` is not satisfied
-    //~| NOTE the trait `std::marker::Sized` is not implemented for `str`
-    //~| NOTE `str` does not have a constant size known at compile-time
-    //~| NOTE required for the cast to the object type `Foo`
-
-    // check no error cascade
-    let _ = main.f as *const u32; //~ no field `f` on type `fn() {main}`
-
-    let cf: *const Foo = &0;
-    let _ = cf as *const [u16];
-    //~^ ERROR casting
-    //~^^ NOTE vtable kinds
-    let _ = cf as *const Bar;
-    //~^ ERROR casting
-    //~^^ NOTE vtable kinds
-
-    vec![0.0].iter().map(|s| s as f32).collect::<Vec<f32>>();
-    //~^ ERROR casting `&{float}` as `f32` is invalid
-    //~| NOTE cannot cast `&{float}` as `f32`
-    //~| NOTE did you mean `*s`?
-}
index 2e2115b71103a733a1e626b1c8b7e426830569e1..88e804fb8aa0870df57fc4f6e25a2bb07effb47f 100644 (file)
 use self::A; //~ NOTE previous import of `A` here
 use self::B; //~ NOTE previous import of `B` here
 mod A {} //~ ERROR a module named `A` has already been imported in this module
-//~| `A` was already imported
+//~| `A` already imported
 pub mod B {} //~ ERROR a module named `B` has already been imported in this module
-//~| `B` was already imported
+//~| `B` already imported
 mod C {
     use C::D; //~ NOTE previous import of `D` here
     mod D {} //~ ERROR a module named `D` has already been imported in this module
-    //~| `D` was already imported
+    //~| `D` already imported
 }
 
 fn main() {}
index 188716c5e93f59eddd66f566389685c6f4f68dd9..26bb72b862f2ce888560f9a8cf28e013beeab465 100644 (file)
 use std::ops::Rem; //~ NOTE previous import
 
 type Add = bool; //~ ERROR a trait named `Add` has already been imported in this module
-//~| was already imported
+//~| `Add` already imported
 struct Sub { x: f32 } //~ ERROR a trait named `Sub` has already been imported in this module
-//~| was already imported
+//~| `Sub` already imported
 enum Mul { A, B } //~ ERROR a trait named `Mul` has already been imported in this module
-//~| was already imported
+//~| `Mul` already imported
 mod Div { } //~ ERROR a trait named `Div` has already been imported in this module
-//~| was already imported
+//~| `Div` already imported
 trait Rem {  } //~ ERROR a trait named `Rem` has already been imported in this module
-//~| was already imported
+//~| `Rem` already imported
 
 fn main() {}
index 5a068ce42142fd4854ab28d5b59e40e0a5ec26ad..2083d98e09d310a2da3c446d143f63272edf6d48 100644 (file)
@@ -13,6 +13,6 @@
 
 fn transmute() {}
 //~^ ERROR a value named `transmute` has already been imported in this module
-//~| was already imported
+//~| `transmute` already imported
 fn main() {
 }
index c438c17f51e3a61a53303f3eef45be12a4d96bb5..75c665b04a12325392ce0f5eb59bbec3cd113e0d 100644 (file)
@@ -10,6 +10,7 @@
 
 // ignore-android FIXME #17520
 // ignore-emscripten spawning processes is not supported
+// ignore-openbsd no support for libbacktrace without filename
 // compile-flags:-g
 
 use std::env;
diff --git a/src/test/ui/mismatched_types/cast-rfc0401.rs b/src/test/ui/mismatched_types/cast-rfc0401.rs
new file mode 100644 (file)
index 0000000..f72be0d
--- /dev/null
@@ -0,0 +1,82 @@
+// 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.
+
+fn illegal_cast<U:?Sized,V:?Sized>(u: *const U) -> *const V
+{
+    u as *const V
+}
+
+fn illegal_cast_2<U:?Sized>(u: *const U) -> *const str
+{
+    u as *const str
+}
+
+trait Foo { fn foo(&self) {} }
+impl<T> Foo for T {}
+
+trait Bar { fn foo(&self) {} }
+impl<T> Bar for T {}
+
+enum E {
+    A, B
+}
+
+fn main()
+{
+    let f: f32 = 1.2;
+    let v = 0 as *const u8;
+    let fat_v : *const [u8] = unsafe { &*(0 as *const [u8; 1])};
+    let fat_sv : *const [i8] = unsafe { &*(0 as *const [i8; 1])};
+    let foo: &Foo = &f;
+
+    let _ = v as &u8;
+    let _ = v as E;
+    let _ = v as fn();
+    let _ = v as (u32,);
+    let _ = Some(&v) as *const u8;
+
+    let _ = v as f32;
+    let _ = main as f64;
+    let _ = &v as usize;
+    let _ = f as *const u8;
+    let _ = 3_i32 as bool;
+    let _ = E::A as bool;
+    let _ = 0x61u32 as char;
+
+    let _ = false as f32;
+    let _ = E::A as f32;
+    let _ = 'a' as f32;
+
+    let _ = false as *const u8;
+    let _ = E::A as *const u8;
+    let _ = 'a' as *const u8;
+
+    let _ = 42usize as *const [u8];
+    let _ = v as *const [u8];
+    let _ = fat_v as *const Foo;
+    let _ = foo as *const str;
+    let _ = foo as *mut str;
+    let _ = main as *mut str;
+    let _ = &f as *mut f32;
+    let _ = &f as *const f64;
+    let _ = fat_sv as usize;
+
+    let a : *const str = "hello";
+    let _ = a as *const Foo;
+
+    // check no error cascade
+    let _ = main.f as *const u32;
+
+    let cf: *const Foo = &0;
+    let _ = cf as *const [u16];
+    let _ = cf as *const Bar;
+
+    vec![0.0].iter().map(|s| s as f32).collect::<Vec<f32>>();
+}
diff --git a/src/test/ui/mismatched_types/cast-rfc0401.stderr b/src/test/ui/mismatched_types/cast-rfc0401.stderr
new file mode 100644 (file)
index 0000000..7fd10f3
--- /dev/null
@@ -0,0 +1,240 @@
+error: casting `*const U` as `*const V` is invalid
+  --> $DIR/cast-rfc0401.rs:13:5
+   |
+13 |     u as *const V
+   |     ^^^^^^^^^^^^^
+   |
+   = note: vtable kinds may not match
+
+error: casting `*const U` as `*const str` is invalid
+  --> $DIR/cast-rfc0401.rs:18:5
+   |
+18 |     u as *const str
+   |     ^^^^^^^^^^^^^^^
+   |
+   = note: vtable kinds may not match
+
+error: no field `f` on type `fn() {main}`
+  --> $DIR/cast-rfc0401.rs:75:18
+   |
+75 |     let _ = main.f as *const u32;
+   |                  ^
+
+error: non-scalar cast: `*const u8` as `&u8`
+  --> $DIR/cast-rfc0401.rs:39:13
+   |
+39 |     let _ = v as &u8;
+   |             ^^^^^^^^
+
+error: non-scalar cast: `*const u8` as `E`
+  --> $DIR/cast-rfc0401.rs:40:13
+   |
+40 |     let _ = v as E;
+   |             ^^^^^^
+
+error: non-scalar cast: `*const u8` as `fn()`
+  --> $DIR/cast-rfc0401.rs:41:13
+   |
+41 |     let _ = v as fn();
+   |             ^^^^^^^^^
+
+error: non-scalar cast: `*const u8` as `(u32,)`
+  --> $DIR/cast-rfc0401.rs:42:13
+   |
+42 |     let _ = v as (u32,);
+   |             ^^^^^^^^^^^
+
+error: non-scalar cast: `std::option::Option<&*const u8>` as `*const u8`
+  --> $DIR/cast-rfc0401.rs:43:13
+   |
+43 |     let _ = Some(&v) as *const u8;
+   |             ^^^^^^^^^^^^^^^^^^^^^
+
+error: casting `*const u8` as `f32` is invalid
+  --> $DIR/cast-rfc0401.rs:45:13
+   |
+45 |     let _ = v as f32;
+   |             ^^^^^^^^
+
+error: casting `fn() {main}` as `f64` is invalid
+  --> $DIR/cast-rfc0401.rs:46:13
+   |
+46 |     let _ = main as f64;
+   |             ^^^^^^^^^^^
+
+error: casting `&*const u8` as `usize` is invalid
+  --> $DIR/cast-rfc0401.rs:47:13
+   |
+47 |     let _ = &v as usize;
+   |             ^^^^^^^^^^^
+   |
+   = help: cast through a raw pointer first
+
+error: casting `f32` as `*const u8` is invalid
+  --> $DIR/cast-rfc0401.rs:48:13
+   |
+48 |     let _ = f as *const u8;
+   |             ^^^^^^^^^^^^^^
+
+error[E0054]: cannot cast as `bool`
+  --> $DIR/cast-rfc0401.rs:49:13
+   |
+49 |     let _ = 3_i32 as bool;
+   |             ^^^^^^^^^^^^^ unsupported cast
+   |
+   = help: compare with zero instead
+
+error[E0054]: cannot cast as `bool`
+  --> $DIR/cast-rfc0401.rs:50:13
+   |
+50 |     let _ = E::A as bool;
+   |             ^^^^^^^^^^^^ unsupported cast
+   |
+   = help: compare with zero instead
+
+error: only `u8` can be cast as `char`, not `u32`
+  --> $DIR/cast-rfc0401.rs:51:13
+   |
+51 |     let _ = 0x61u32 as char;
+   |             ^^^^^^^^^^^^^^^
+
+error: casting `bool` as `f32` is invalid
+  --> $DIR/cast-rfc0401.rs:53:13
+   |
+53 |     let _ = false as f32;
+   |             ^^^^^^^^^^^^
+   |
+   = help: cast through an integer first
+
+error: casting `E` as `f32` is invalid
+  --> $DIR/cast-rfc0401.rs:54:13
+   |
+54 |     let _ = E::A as f32;
+   |             ^^^^^^^^^^^
+   |
+   = help: cast through an integer first
+
+error: casting `char` as `f32` is invalid
+  --> $DIR/cast-rfc0401.rs:55:13
+   |
+55 |     let _ = 'a' as f32;
+   |             ^^^^^^^^^^
+   |
+   = help: cast through an integer first
+
+error: casting `bool` as `*const u8` is invalid
+  --> $DIR/cast-rfc0401.rs:57:13
+   |
+57 |     let _ = false as *const u8;
+   |             ^^^^^^^^^^^^^^^^^^
+
+error: casting `E` as `*const u8` is invalid
+  --> $DIR/cast-rfc0401.rs:58:13
+   |
+58 |     let _ = E::A as *const u8;
+   |             ^^^^^^^^^^^^^^^^^
+
+error: casting `char` as `*const u8` is invalid
+  --> $DIR/cast-rfc0401.rs:59:13
+   |
+59 |     let _ = 'a' as *const u8;
+   |             ^^^^^^^^^^^^^^^^
+
+error: casting `usize` as `*const [u8]` is invalid
+  --> $DIR/cast-rfc0401.rs:61:13
+   |
+61 |     let _ = 42usize as *const [u8];
+   |             ^^^^^^^^^^^^^^^^^^^^^^
+
+error: cannot cast thin pointer `*const u8` to fat pointer `*const [u8]`
+  --> $DIR/cast-rfc0401.rs:62:13
+   |
+62 |     let _ = v as *const [u8];
+   |             ^^^^^^^^^^^^^^^^
+
+error: casting `&Foo` as `*const str` is invalid
+  --> $DIR/cast-rfc0401.rs:64:13
+   |
+64 |     let _ = foo as *const str;
+   |             ^^^^^^^^^^^^^^^^^
+
+error: casting `&Foo` as `*mut str` is invalid
+  --> $DIR/cast-rfc0401.rs:65:13
+   |
+65 |     let _ = foo as *mut str;
+   |             ^^^^^^^^^^^^^^^
+
+error: casting `fn() {main}` as `*mut str` is invalid
+  --> $DIR/cast-rfc0401.rs:66:13
+   |
+66 |     let _ = main as *mut str;
+   |             ^^^^^^^^^^^^^^^^
+
+error: casting `&f32` as `*mut f32` is invalid
+  --> $DIR/cast-rfc0401.rs:67:13
+   |
+67 |     let _ = &f as *mut f32;
+   |             ^^^^^^^^^^^^^^
+
+error: casting `&f32` as `*const f64` is invalid
+  --> $DIR/cast-rfc0401.rs:68:13
+   |
+68 |     let _ = &f as *const f64;
+   |             ^^^^^^^^^^^^^^^^
+
+error: casting `*const [i8]` as `usize` is invalid
+  --> $DIR/cast-rfc0401.rs:69:13
+   |
+69 |     let _ = fat_sv as usize;
+   |             ^^^^^^^^^^^^^^^
+   |
+   = help: cast through a thin pointer first
+
+error: casting `*const Foo` as `*const [u16]` is invalid
+  --> $DIR/cast-rfc0401.rs:78:13
+   |
+78 |     let _ = cf as *const [u16];
+   |             ^^^^^^^^^^^^^^^^^^
+   |
+   = note: vtable kinds may not match
+
+error: casting `*const Foo` as `*const Bar` is invalid
+  --> $DIR/cast-rfc0401.rs:79:13
+   |
+79 |     let _ = cf as *const Bar;
+   |             ^^^^^^^^^^^^^^^^
+   |
+   = note: vtable kinds may not match
+
+error[E0277]: the trait bound `[u8]: std::marker::Sized` is not satisfied
+  --> $DIR/cast-rfc0401.rs:63:13
+   |
+63 |     let _ = fat_v as *const Foo;
+   |             ^^^^^ the trait `std::marker::Sized` is not implemented for `[u8]`
+   |
+   = note: `[u8]` does not have a constant size known at compile-time
+   = note: required for the cast to the object type `Foo`
+
+error[E0277]: the trait bound `str: std::marker::Sized` is not satisfied
+  --> $DIR/cast-rfc0401.rs:72:13
+   |
+72 |     let _ = a as *const Foo;
+   |             ^ the trait `std::marker::Sized` is not implemented for `str`
+   |
+   = note: `str` does not have a constant size known at compile-time
+   = note: required for the cast to the object type `Foo`
+
+error: casting `&{float}` as `f32` is invalid
+  --> $DIR/cast-rfc0401.rs:81:30
+   |
+81 |     vec![0.0].iter().map(|s| s as f32).collect::<Vec<f32>>();
+   |                              ^^^^^^^^ cannot cast `&{float}` as `f32`
+   |
+help: did you mean `*s`?
+  --> $DIR/cast-rfc0401.rs:81:30
+   |
+81 |     vec![0.0].iter().map(|s| s as f32).collect::<Vec<f32>>();
+   |                              ^
+
+error: aborting due to 34 previous errors
+
index 227b695635dcec6c67ae13513a0114d09237759a..faf0a0eaa81ee5098e7d0ee18be607e4bec58085 100644 (file)
@@ -8,3 +8,4 @@ build = "build.rs"
 log = "0.3"
 env_logger = { version = "0.3.5", default-features = false }
 serialize = { path = "../../libserialize" }
+build_helper = { path = "../../build_helper" }
index 3cc14541fcdf2ad02b3b99f87d749422e7df9a65..9e2416fca81aeabdaf7de92140f0f0c592eac192 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+extern crate build_helper;
+
 use common::Config;
 use common::{CompileFail, ParseFail, Pretty, RunFail, RunPass, RunPassValgrind};
 use common::{Codegen, DebugInfoLldb, DebugInfoGdb, Rustdoc, CodegenUnits};
@@ -2108,7 +2110,7 @@ fn run_rmake_test(&self) {
         }
         self.create_dir_racy(&tmpdir);
 
-        let mut cmd = Command::new("make");
+        let mut cmd = Command::new(build_helper::make(&self.config.host));
         cmd.current_dir(&self.testpaths.file)
            .env("TARGET", &self.config.target)
            .env("PYTHON", &self.config.docck_python)
@@ -2294,7 +2296,18 @@ fn compare_mir_test_output(&self, test_name: &str, expected_content: &Vec<&str>)
                 };
             }
             if !found {
-                panic!("ran out of mir dump output to match against");
+                let normalize_all = dumped_string.lines()
+                                                 .map(nocomment_mir_line)
+                                                 .filter(|l| !l.is_empty())
+                                                 .collect::<Vec<_>>()
+                                                 .join("\n");
+                panic!("ran out of mir dump output to match against.\n\
+                        Did not find expected line: {:?}\n\
+                        Expected:\n{}\n\
+                        Actual:\n{}",
+                        expected_line,
+                        expected_content.join("\n"),
+                        normalize_all);
             }
         }
     }
@@ -2439,11 +2452,14 @@ enum TargetLocation {
 }
 
 fn normalize_mir_line(line: &str) -> String {
-    let no_comments = if let Some(idx) = line.find("//") {
+    nocomment_mir_line(line).replace(char::is_whitespace, "")
+}
+
+fn nocomment_mir_line(line: &str) -> &str {
+    if let Some(idx) = line.find("//") {
         let (l, _) = line.split_at(idx);
-        l
+        l.trim_right()
     } else {
         line
-    };
-    no_comments.replace(char::is_whitespace, "")
+    }
 }