]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #28651 - dotdash:exhaustive_match, r=eddyb
authorbors <bors@rust-lang.org>
Sun, 27 Sep 2015 05:29:39 +0000 (05:29 +0000)
committerbors <bors@rust-lang.org>
Sun, 27 Sep 2015 05:29:39 +0000 (05:29 +0000)
By putting an "unreachable" instruction into the default arm of a switch
instruction we can let LLVM know that the match is exhaustive, allowing
for better optimizations.

For example, this match:
```rust
pub enum Enum {
    One,
    Two,
    Three,
}

impl Enum {
    pub fn get_disc(self) -> u8 {
        match self {
            Enum::One => 0,
            Enum::Two => 1,
            Enum::Three => 2,
        }
    }
}
```

Currently compiles to this on x86_64:
```asm
  .cfi_startproc
  movzbl  %dil, %ecx
  cmpl  $1, %ecx
  setne %al
  testb %cl, %cl
  je  .LBB0_2
  incb  %al
  movb  %al, %dil
.LBB0_2:
  movb  %dil, %al
  retq
.Lfunc_end0:
```

But with this change we get:
```asm
  .cfi_startproc
  movb  %dil, %al
  retq
.Lfunc_end0:
```

160 files changed:
configure
mk/cfg/x86_64-rumprun-netbsd.mk [new file with mode: 0644]
src/compiletest/compiletest.rs
src/doc/README.md
src/doc/reference.md
src/doc/trpl/closures.md
src/doc/trpl/iterators.md
src/doc/trpl/lifetimes.md
src/doc/trpl/structs.md
src/grammar/verify.rs
src/liballoc/arc.rs
src/liballoc/boxed.rs
src/liballoc/boxed_test.rs
src/liballoc/heap.rs
src/liballoc/lib.rs
src/liballoc/raw_vec.rs
src/liballoc/rc.rs
src/libcollections/str.rs
src/libcollections/string.rs
src/libcollectionstest/str.rs
src/libcore/fmt/mod.rs
src/libcore/mem.rs
src/libcore/ops.rs
src/libcore/slice.rs
src/libcore/str/mod.rs
src/liblibc/lib.rs
src/librustc/metadata/creader.rs
src/librustc/metadata/encoder.rs
src/librustc/metadata/tydecode.rs
src/librustc/middle/cfg/construct.rs
src/librustc/middle/check_const.rs
src/librustc/middle/dataflow.rs
src/librustc/middle/entry.rs
src/librustc/middle/infer/error_reporting.rs
src/librustc/middle/intrinsicck.rs
src/librustc/middle/liveness.rs
src/librustc/middle/pat_util.rs
src/librustc/middle/resolve_lifetime.rs
src/librustc/middle/stability.rs
src/librustc/middle/traits/error_reporting.rs
src/librustc/middle/traits/mod.rs
src/librustc/middle/traits/object_safety.rs
src/librustc/session/config.rs
src/librustc/session/mod.rs
src/librustc_back/target/aarch64_apple_ios.rs
src/librustc_back/target/aarch64_linux_android.rs
src/librustc_back/target/aarch64_unknown_linux_gnu.rs
src/librustc_back/target/arm_linux_androideabi.rs
src/librustc_back/target/arm_unknown_linux_gnueabi.rs
src/librustc_back/target/arm_unknown_linux_gnueabihf.rs
src/librustc_back/target/armv7_apple_ios.rs
src/librustc_back/target/armv7s_apple_ios.rs
src/librustc_back/target/i386_apple_ios.rs
src/librustc_back/target/i686_apple_darwin.rs
src/librustc_back/target/i686_linux_android.rs
src/librustc_back/target/i686_pc_windows_gnu.rs
src/librustc_back/target/i686_pc_windows_msvc.rs
src/librustc_back/target/i686_unknown_dragonfly.rs
src/librustc_back/target/i686_unknown_freebsd.rs
src/librustc_back/target/i686_unknown_linux_gnu.rs
src/librustc_back/target/mips_unknown_linux_gnu.rs
src/librustc_back/target/mipsel_unknown_linux_gnu.rs
src/librustc_back/target/mod.rs
src/librustc_back/target/powerpc_unknown_linux_gnu.rs
src/librustc_back/target/x86_64_apple_darwin.rs
src/librustc_back/target/x86_64_apple_ios.rs
src/librustc_back/target/x86_64_pc_windows_gnu.rs
src/librustc_back/target/x86_64_pc_windows_msvc.rs
src/librustc_back/target/x86_64_rumprun_netbsd.rs [new file with mode: 0644]
src/librustc_back/target/x86_64_unknown_bitrig.rs
src/librustc_back/target/x86_64_unknown_dragonfly.rs
src/librustc_back/target/x86_64_unknown_freebsd.rs
src/librustc_back/target/x86_64_unknown_linux_gnu.rs
src/librustc_back/target/x86_64_unknown_linux_musl.rs
src/librustc_back/target/x86_64_unknown_netbsd.rs
src/librustc_back/target/x86_64_unknown_openbsd.rs
src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs
src/librustc_borrowck/borrowck/gather_loans/move_error.rs
src/librustc_driver/pretty.rs
src/librustc_front/fold.rs
src/librustc_front/hir.rs
src/librustc_front/print/pprust.rs
src/librustc_front/util.rs
src/librustc_lint/builtin.rs
src/librustc_lint/unused.rs
src/librustc_mir/build/matches/mod.rs
src/librustc_mir/hair.rs
src/librustc_mir/repr.rs
src/librustc_mir/tcx/expr.rs
src/librustc_mir/tcx/mod.rs
src/librustc_mir/tcx/pattern.rs
src/librustc_privacy/lib.rs
src/librustc_resolve/build_reduced_graph.rs
src/librustc_resolve/lib.rs
src/librustc_resolve/resolve_imports.rs
src/librustc_trans/back/linker.rs
src/librustc_trans/save/dump_csv.rs
src/librustc_trans/trans/_match.rs
src/librustc_trans/trans/base.rs
src/librustc_trans/trans/common.rs
src/librustc_trans/trans/consts.rs
src/librustc_trans/trans/controlflow.rs
src/librustc_trans/trans/debuginfo/create_scope_map.rs
src/librustc_trans/trans/debuginfo/metadata.rs
src/librustc_trans/trans/expr.rs
src/librustc_typeck/astconv.rs
src/librustc_typeck/check/_match.rs
src/librustc_typeck/check/mod.rs
src/librustc_typeck/check/wf.rs
src/librustc_typeck/check/wfcheck.rs
src/librustc_typeck/collect.rs
src/librustc_typeck/diagnostics.rs
src/librustdoc/clean/mod.rs
src/librustdoc/html/static/playpen.js
src/libstd/lib.rs
src/libstd/macros.rs
src/libstd/panicking.rs
src/libstd/sys/common/libunwind.rs
src/libstd/sys/common/unwind/mod.rs
src/libstd/sys/unix/stack_overflow.rs
src/libstd/sys/unix/thread.rs
src/libsyntax/ast.rs
src/libsyntax/ast_util.rs
src/libsyntax/codemap.rs
src/libsyntax/diagnostic.rs
src/libsyntax/diagnostics/plugin.rs
src/libsyntax/entry.rs
src/libsyntax/ext/base.rs
src/libsyntax/ext/build.rs
src/libsyntax/ext/expand.rs
src/libsyntax/ext/mtwt.rs
src/libsyntax/ext/quote.rs
src/libsyntax/ext/tt/macro_parser.rs
src/libsyntax/ext/tt/macro_rules.rs
src/libsyntax/ext/tt/transcribe.rs
src/libsyntax/feature_gate.rs
src/libsyntax/parse/attr.rs
src/libsyntax/parse/mod.rs
src/libsyntax/parse/parser.rs
src/libsyntax/parse/token.rs
src/libsyntax/print/pprust.rs
src/libsyntax/util/interner.rs
src/rustbook/build.rs
src/rustbook/help.rs
src/rustbook/javascript.rs [deleted file]
src/rustbook/main.rs
src/rustbook/static/rustbook.css
src/rustbook/static/rustbook.js
src/rustbook/subcommand.rs
src/test/auxiliary/lint_plugin_test.rs
src/test/auxiliary/msvc-data-only-lib.rs [new file with mode: 0644]
src/test/auxiliary/procedural_mbe_matching.rs
src/test/compile-fail/feature-gate-cfg-target-vendor.rs [new file with mode: 0644]
src/test/compile-fail/issue-28576.rs [new file with mode: 0644]
src/test/compile-fail/object-safety-issue-22040.rs
src/test/compile-fail/object-safety-supertrait-mentions-Self.rs
src/test/run-make/output-type-permutations/Makefile
src/test/run-pass/cfg-target-vendor.rs [new file with mode: 0644]
src/test/run-pass/issue-14919.rs
src/test/run-pass/msvc-data-only.rs [new file with mode: 0644]

index 1d95965150caea54b84466bbb6d6bb601645f8c0..fa2117dcc1d3d0de1ad757e1fdbda41361b36aeb 100755 (executable)
--- a/configure
+++ b/configure
@@ -1295,6 +1295,12 @@ $ pacman -R cmake && pacman -S mingw-w64-x86_64-cmake
             putvar CFG_MSVC_LIB_PATH_${bits}
             ;;
 
+        *-rumprun-netbsd)
+            step_msg "targeting rumprun-netbsd, disabling jemalloc"
+            CFG_DISABLE_JEMALLOC=1
+            putvar CFG_DISABLE_JEMALLOC
+            ;;
+
         *)
             ;;
     esac
diff --git a/mk/cfg/x86_64-rumprun-netbsd.mk b/mk/cfg/x86_64-rumprun-netbsd.mk
new file mode 100644 (file)
index 0000000..5894805
--- /dev/null
@@ -0,0 +1,24 @@
+# x86_64-rumprun-netbsd configuration
+CROSS_PREFIX_x86_64-rumprun-netbsd=x86_64-rumprun-netbsd-
+CC_x86_64-rumprun-netbsd=gcc
+CXX_x86_64-rumprun-netbsd=g++
+CPP_x86_64-rumprun-netbsd=gcc -E
+AR_x86_64-rumprun-netbsd=ar
+CFG_INSTALL_ONLY_RLIB_x86_64-rumprun-netbsd = 1
+CFG_LIB_NAME_x86_64-rumprun-netbsd=lib$(1).so
+CFG_STATIC_LIB_NAME_x86_64-rumprun-netbsd=lib$(1).a
+CFG_LIB_GLOB_x86_64-rumprun-netbsd=lib$(1)-*.so
+CFG_JEMALLOC_CFLAGS_x86_64-rumprun-netbsd := -m64
+CFG_GCCISH_CFLAGS_x86_64-rumprun-netbsd := -Wall -Werror -g -fPIC -m64
+CFG_GCCISH_CXXFLAGS_x86_64-rumprun-netbsd :=
+CFG_GCCISH_LINK_FLAGS_x86_64-rumprun-netbsd :=
+CFG_GCCISH_DEF_FLAG_x86_64-rumprun-netbsd :=
+CFG_LLC_FLAGS_x86_64-rumprun-netbsd :=
+CFG_INSTALL_NAME_x86_64-rumprun-netbsd =
+CFG_EXE_SUFFIX_x86_64-rumprun-netbsd =
+CFG_WINDOWSY_x86_64-rumprun-netbsd :=
+CFG_UNIXY_x86_64-rumprun-netbsd := 1
+CFG_LDPATH_x86_64-rumprun-netbsd :=
+CFG_RUN_x86_64-rumprun-netbsd=$(2)
+CFG_RUN_TARG_x86_64-rumprun-netbsd=$(call CFG_RUN_x86_64-rumprun-netbsd,,$(2))
+CFG_GNU_TRIPLE_x86_64-rumprun-netbsd := x86_64-rumprun-netbsd
index f508798a8b6ed0297a74f60d1903340651931602..0e928345d931f7ff28da2d4a04ba9d7378d18887 100644 (file)
@@ -348,7 +348,7 @@ fn extract_gdb_version(full_version_line: Option<String>) -> Option<String> {
           if !full_version_line.trim().is_empty() => {
             let full_version_line = full_version_line.trim();
 
-            // used to be a regex "(^|[^0-9])([0-9]\.[0-9])([^0-9]|$)"
+            // used to be a regex "(^|[^0-9])([0-9]\.[0-9]+)"
             for (pos, c) in full_version_line.char_indices() {
                 if !c.is_digit(10) { continue }
                 if pos + 2 >= full_version_line.len() { continue }
@@ -357,11 +357,12 @@ fn extract_gdb_version(full_version_line: Option<String>) -> Option<String> {
                 if pos > 0 && full_version_line.char_at_reverse(pos).is_digit(10) {
                     continue
                 }
-                if pos + 3 < full_version_line.len() &&
-                   full_version_line.char_at(pos + 3).is_digit(10) {
-                    continue
+                let mut end = pos + 3;
+                while end < full_version_line.len() &&
+                      full_version_line.char_at(end).is_digit(10) {
+                    end += 1;
                 }
-                return Some(full_version_line[pos..pos+3].to_owned());
+                return Some(full_version_line[pos..end].to_owned());
             }
             println!("Could not extract GDB version from line '{}'",
                      full_version_line);
index c09f28ae4f62d5cc0dd594505f39d0e50bec19ca..0882b073ea48c32109697ec28b4d65ffae767c4a 100644 (file)
@@ -2,9 +2,10 @@
 
 ## Building
 
-To generate all the docs, just run `make docs` from the root of the repository.
-This will convert the distributed Markdown docs to HTML and generate HTML doc
-for the 'std' and 'extra' libraries.
+To generate all the docs, follow the "Building Documentation" instructions in
+the README in the root of the repository. This will convert the distributed
+Markdown docs to HTML and generate HTML doc for the books, 'std' and 'extra'
+libraries.
 
 To generate HTML documentation from one source file/crate, do something like:
 
index cd24e33a232d895468456dbeefbb951dd4d7462a..b50e3af0fdd956b0be91a5fe937ecf6e741c9f30 100644 (file)
@@ -881,7 +881,7 @@ mod foo {
     }
 
     use foo::example::iter; // good: foo is at crate root
-//  use example::iter;      // bad:  core is not at the crate root
+//  use example::iter;      // bad:  example is not at the crate root
     use self::baz::foobaz;  // good: self refers to module 'foo'
     use foo::bar::foobar;   // good: foo is at crate root
 
@@ -2093,6 +2093,8 @@ The following configurations must be defined by the implementation:
 * `target_pointer_width = "..."` - Target pointer width in bits. This is set
   to `"32"` for targets with 32-bit pointers, and likewise set to `"64"` for
   64-bit pointers.
+* `target_vendor = "..."` - Vendor of the target, for example `apple`, `pc`, or
+  simply `"unknown"`.
 * `test` - Enabled when compiling the test harness (using the `--test` flag).
 * `unix` - See `target_family`.
 * `windows` - See `target_family`.
@@ -2269,7 +2271,7 @@ The currently implemented features of the reference compiler are:
 * `advanced_slice_patterns` - See the [match expressions](#match-expressions)
                               section for discussion; the exact semantics of
                               slice patterns are subject to change, so some types
-                             are still unstable.
+                              are still unstable.
 
 * `slice_patterns` - OK, actually, slice patterns are just scary and
                      completely unstable.
@@ -2290,6 +2292,9 @@ The currently implemented features of the reference compiler are:
 * `box_syntax` - Allows use of `box` expressions, the exact semantics of which
                  is subject to change.
 
+* `cfg_target_vendor` - Allows conditional compilation using the `target_vendor`
+                        matcher which is subject to change.
+
 * `concat_idents` - Allows use of the `concat_idents` macro, which is in many
                     ways insufficient for concatenating identifiers, and may be
                     removed entirely for something more wholesome.
index 161c4ce90b2408614e80601fb45de3be3f7569dd..983af4a0efe7fb9613a9def0feafc4b1b9f95a58 100644 (file)
@@ -411,8 +411,9 @@ fn factory() -> &(Fn(i32) -> i32) {
 ```
 
 Right. Because we have a reference, we need to give it a lifetime. But
-our `factory()` function takes no arguments, so elision doesn’t kick in
-here. What lifetime can we choose? `'static`:
+our `factory()` function takes no arguments, so
+[elision](lifetimes.html#lifetime-elision) doesn’t kick in here. Then what
+choices do we have? Try `'static`:
 
 ```rust,ignore
 fn factory() -> &'static (Fn(i32) -> i32) {
@@ -432,7 +433,7 @@ But we get another error:
 ```text
 error: mismatched types:
  expected `&'static core::ops::Fn(i32) -> i32`,
-    found `[closure <anon>:7:9: 7:20]`
+    found `[closure@<anon>:7:9: 7:20]`
 (expected &-ptr,
     found closure) [E0308]
          |x| x + num
@@ -441,21 +442,17 @@ error: mismatched types:
 ```
 
 This error is letting us know that we don’t have a `&'static Fn(i32) -> i32`,
-we have a `[closure <anon>:7:9: 7:20]`. Wait, what?
+we have a `[closure@<anon>:7:9: 7:20]`. Wait, what?
 
 Because each closure generates its own environment `struct` and implementation
 of `Fn` and friends, these types are anonymous. They exist just solely for
-this closure. So Rust shows them as `closure <anon>`, rather than some
+this closure. So Rust shows them as `closure@<anon>`, rather than some
 autogenerated name.
 
-But why doesn’t our closure implement `&'static Fn`? Well, as we discussed before,
-closures borrow their environment. And in this case, our environment is based
-on a stack-allocated `5`, the `num` variable binding. So the borrow has a lifetime
-of the stack frame. So if we returned this closure, the function call would be
-over, the stack frame would go away, and our closure is capturing an environment
-of garbage memory!
-
-So what to do? This _almost_ works:
+The error also points out that the return type is expected to be a reference,
+but what we are trying to return is not. Further, we cannot directly assign a
+`'static` lifetime to an object. So we'll take a different approach and return
+a "trait object" by `Box`ing up the `Fn`. This _almost_ works:
 
 ```rust,ignore
 fn factory() -> Box<Fn(i32) -> i32> {
@@ -471,7 +468,7 @@ assert_eq!(6, answer);
 # }
 ```
 
-We use a trait object, by `Box`ing up the `Fn`. There’s just one last problem:
+There’s just one last problem:
 
 ```text
 error: closure may outlive the current function, but it borrows `num`,
@@ -480,8 +477,12 @@ Box::new(|x| x + num)
          ^~~~~~~~~~~
 ```
 
-We still have a reference to the parent stack frame. With one last fix, we can
-make this work:
+Well, as we discussed before, closures borrow their environment. And in this
+case, our environment is based on a stack-allocated `5`, the `num` variable
+binding. So the borrow has a lifetime of the stack frame. So if we returned
+this closure, the function call would be over, the stack frame would go away,
+and our closure is capturing an environment of garbage memory! With one last
+fix, we can make this work:
 
 ```rust
 fn factory() -> Box<Fn(i32) -> i32> {
index 1c574f02091f8574f956557d3b67c7a2a4d30413..b52e0fefa57e2ab3904fb0259fb633775628b37c 100644 (file)
@@ -150,15 +150,16 @@ let greater_than_forty_two = (0..100)
                              .find(|x| *x > 42);
 
 match greater_than_forty_two {
-    Some(_) => println!("We got some numbers!"),
-    None => println!("No numbers found :("),
+    Some(_) => println!("Found a match!"),
+    None => println!("No match found :("),
 }
 ```
 
 `find` takes a closure, and works on a reference to each element of an
 iterator. This closure returns `true` if the element is the element we're
-looking for, and `false` otherwise. Because we might not find a matching
-element, `find` returns an `Option` rather than the element itself.
+looking for, and `false` otherwise. `find` returns the first element satisfying
+the specified predicate. Because we might not find a matching element, `find`
+returns an `Option` rather than the element itself.
 
 Another important consumer is `fold`. Here's what it looks like:
 
index 62270cb45b5e6c17b0de97d410626c5aa77fece0..fb2fc83e0626124ee4ccda190a12812c6f2817ad 100644 (file)
@@ -349,9 +349,9 @@ fn frob<'a, 'b>(s: &'a str, t: &'b str) -> &str; // Expanded: Output lifetime is
 fn get_mut(&mut self) -> &mut T; // elided
 fn get_mut<'a>(&'a mut self) -> &'a mut T; // expanded
 
-fn args<T:ToCStr>(&mut self, args: &[T]) -> &mut Command // elided
-fn args<'a, 'b, T:ToCStr>(&'a mut self, args: &'b [T]) -> &'a mut Command // expanded
+fn args<T:ToCStr>(&mut self, args: &[T]) -> &mut Command; // elided
+fn args<'a, 'b, T:ToCStr>(&'a mut self, args: &'b [T]) -> &'a mut Command; // expanded
 
 fn new(buf: &mut [u8]) -> BufWriter; // elided
-fn new<'a>(buf: &'a mut [u8]) -> BufWriter<'a> // expanded
+fn new<'a>(buf: &'a mut [u8]) -> BufWriter<'a>; // expanded
 ```
index 85b11d0b6b5eeb01b7002bf0a32d083e2b6eb6b3..b51ad8e087d22a995f550d2f15f79fc864cf17ba 100644 (file)
@@ -184,6 +184,8 @@ You can define a `struct` with no members at all:
 
 ```rust
 struct Electron;
+
+let x = Electron;
 ```
 
 Such a `struct` is called â€˜unit-like’ because it resembles the empty
index 6709479b2b5b2d2352a971c64d781182b7e2ec9f..b7714a7e3c5dd96ec94ec4c2e9e86f2310d2d247 100644 (file)
@@ -35,7 +35,7 @@
 
 fn parse_token_list(file: &str) -> HashMap<String, token::Token> {
     fn id() -> token::Token {
-        token::Ident(ast::Ident { name: Name(0), ctxt: 0, }, token::Plain)
+        token::Ident(ast::Ident::with_empty_ctxt(Name(0))), token::Plain)
     }
 
     let mut res = HashMap::new();
@@ -75,7 +75,7 @@ fn id() -> token::Token {
             "RPAREN"            => token::CloseDelim(token::Paren),
             "SLASH"             => token::BinOp(token::Slash),
             "COMMA"             => token::Comma,
-            "LIFETIME"          => token::Lifetime(ast::Ident { name: Name(0), ctxt: 0 }),
+            "LIFETIME"          => token::Lifetime(ast::Ident::with_empty_ctxt(Name(0))),
             "CARET"             => token::BinOp(token::Caret),
             "TILDE"             => token::Tilde,
             "IDENT"             => id(),
@@ -208,9 +208,9 @@ fn parse_antlr_token(s: &str, tokens: &HashMap<String, token::Token>, surrogate_
         token::Literal(token::ByteStr(..), n)    => token::Literal(token::ByteStr(nm), n),
         token::Literal(token::ByteStrRaw(..), n) => token::Literal(token::ByteStrRaw(fix(content),
                                                                                 count(content)), n),
-        token::Ident(..)           => token::Ident(ast::Ident { name: nm, ctxt: 0 },
+        token::Ident(..)           => token::Ident(ast::Ident::with_empty_ctxt(nm)),
                                                    token::ModName),
-        token::Lifetime(..)        => token::Lifetime(ast::Ident { name: nm, ctxt: 0 }),
+        token::Lifetime(..)        => token::Lifetime(ast::Ident::with_empty_ctxt(nm)),
         ref t => t.clone()
     };
 
index 78821403de0116cf2a5700cb1b2e6de1f2f391b3..ceca44fc1ac295f2b97ff269e2e73c778aef6e4f 100644 (file)
@@ -214,7 +214,9 @@ pub fn new(data: T) -> Arc<T> {
     #[stable(feature = "arc_unique", since = "1.4.0")]
     pub fn try_unwrap(this: Self) -> Result<T, Self> {
         // See `drop` for why all these atomics are like this
-        if this.inner().strong.compare_and_swap(1, 0, Release) != 1 { return Err(this) }
+        if this.inner().strong.compare_and_swap(1, 0, Release) != 1 {
+            return Err(this)
+        }
 
         atomic::fence(Acquire);
 
@@ -251,7 +253,9 @@ pub fn downgrade(this: &Self) -> Weak<T> {
             let cur = this.inner().weak.load(Relaxed);
 
             // check if the weak counter is currently "locked"; if so, spin.
-            if cur == usize::MAX { continue }
+            if cur == usize::MAX {
+                continue
+            }
 
             // NOTE: this code currently ignores the possibility of overflow
             // into usize::MAX; in general both Rc and Arc need to be adjusted
@@ -303,7 +307,9 @@ unsafe fn drop_slow(&mut self) {
 
         if self.inner().weak.fetch_sub(1, Release) == 1 {
             atomic::fence(Acquire);
-            deallocate(ptr as *mut u8, size_of_val(&*ptr), align_of_val(&*ptr))
+            deallocate(ptr as *mut u8,
+                       size_of_val(&*ptr),
+                       align_of_val(&*ptr))
         }
     }
 }
@@ -348,7 +354,9 @@ fn clone(&self) -> Arc<T> {
         // We abort because such a program is incredibly degenerate, and we
         // don't care to support it.
         if old_size > MAX_REFCOUNT {
-            unsafe { abort(); }
+            unsafe {
+                abort();
+            }
         }
 
         Arc { _ptr: self._ptr }
@@ -556,7 +564,9 @@ fn drop(&mut self) {
         // Because `fetch_sub` is already atomic, we do not need to synchronize
         // with other threads unless we are going to delete the object. This
         // same logic applies to the below `fetch_sub` to the `weak` count.
-        if self.inner().strong.fetch_sub(1, Release) != 1 { return }
+        if self.inner().strong.fetch_sub(1, Release) != 1 {
+            return
+        }
 
         // This fence is needed to prevent reordering of use of the data and
         // deletion of the data.  Because it is marked `Release`, the decreasing
@@ -578,7 +588,7 @@ fn drop(&mut self) {
         atomic::fence(Acquire);
 
         unsafe {
-            self.drop_slow()
+            self.drop_slow();
         }
     }
 }
@@ -613,11 +623,15 @@ pub fn upgrade(&self) -> Option<Arc<T>> {
             // "stale" read of 0 is fine), and any other value is
             // confirmed via the CAS below.
             let n = inner.strong.load(Relaxed);
-            if n == 0 { return None }
+            if n == 0 {
+                return None
+            }
 
             // Relaxed is valid for the same reason it is on Arc's Clone impl
             let old = inner.strong.compare_and_swap(n, n + 1, Relaxed);
-            if old == n { return Some(Arc { _ptr: self._ptr }) }
+            if old == n {
+                return Some(Arc { _ptr: self._ptr })
+            }
         }
     }
 
@@ -653,7 +667,9 @@ fn clone(&self) -> Weak<T> {
 
         // See comments in Arc::clone() for why we do this (for mem::forget).
         if old_size > MAX_REFCOUNT {
-            unsafe { abort(); }
+            unsafe {
+                abort();
+            }
         }
 
         return Weak { _ptr: self._ptr }
@@ -705,9 +721,11 @@ fn drop(&mut self) {
         // ref, which can only happen after the lock is released.
         if self.inner().weak.fetch_sub(1, Release) == 1 {
             atomic::fence(Acquire);
-            unsafe { deallocate(ptr as *mut u8,
-                                size_of_val(&*ptr),
-                                align_of_val(&*ptr)) }
+            unsafe {
+                deallocate(ptr as *mut u8,
+                           size_of_val(&*ptr),
+                           align_of_val(&*ptr))
+            }
         }
     }
 }
@@ -727,7 +745,9 @@ impl<T: ?Sized + PartialEq> PartialEq for Arc<T> {
     ///
     /// five == Arc::new(5);
     /// ```
-    fn eq(&self, other: &Arc<T>) -> bool { *(*self) == *(*other) }
+    fn eq(&self, other: &Arc<T>) -> bool {
+        *(*self) == *(*other)
+    }
 
     /// Inequality for two `Arc<T>`s.
     ///
@@ -742,7 +762,9 @@ fn eq(&self, other: &Arc<T>) -> bool { *(*self) == *(*other) }
     ///
     /// five != Arc::new(5);
     /// ```
-    fn ne(&self, other: &Arc<T>) -> bool { *(*self) != *(*other) }
+    fn ne(&self, other: &Arc<T>) -> bool {
+        *(*self) != *(*other)
+    }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: ?Sized + PartialOrd> PartialOrd for Arc<T> {
@@ -776,7 +798,9 @@ fn partial_cmp(&self, other: &Arc<T>) -> Option<Ordering> {
     ///
     /// five < Arc::new(5);
     /// ```
-    fn lt(&self, other: &Arc<T>) -> bool { *(*self) < *(*other) }
+    fn lt(&self, other: &Arc<T>) -> bool {
+        *(*self) < *(*other)
+    }
 
     /// 'Less-than or equal to' comparison for two `Arc<T>`s.
     ///
@@ -791,7 +815,9 @@ fn lt(&self, other: &Arc<T>) -> bool { *(*self) < *(*other) }
     ///
     /// five <= Arc::new(5);
     /// ```
-    fn le(&self, other: &Arc<T>) -> bool { *(*self) <= *(*other) }
+    fn le(&self, other: &Arc<T>) -> bool {
+        *(*self) <= *(*other)
+    }
 
     /// Greater-than comparison for two `Arc<T>`s.
     ///
@@ -806,7 +832,9 @@ fn le(&self, other: &Arc<T>) -> bool { *(*self) <= *(*other) }
     ///
     /// five > Arc::new(5);
     /// ```
-    fn gt(&self, other: &Arc<T>) -> bool { *(*self) > *(*other) }
+    fn gt(&self, other: &Arc<T>) -> bool {
+        *(*self) > *(*other)
+    }
 
     /// 'Greater-than or equal to' comparison for two `Arc<T>`s.
     ///
@@ -821,11 +849,15 @@ fn gt(&self, other: &Arc<T>) -> bool { *(*self) > *(*other) }
     ///
     /// five >= Arc::new(5);
     /// ```
-    fn ge(&self, other: &Arc<T>) -> bool { *(*self) >= *(*other) }
+    fn ge(&self, other: &Arc<T>) -> bool {
+        *(*self) >= *(*other)
+    }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: ?Sized + Ord> Ord for Arc<T> {
-    fn cmp(&self, other: &Arc<T>) -> Ordering { (**self).cmp(&**other) }
+    fn cmp(&self, other: &Arc<T>) -> Ordering {
+        (**self).cmp(&**other)
+    }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: ?Sized + Eq> Eq for Arc<T> {}
@@ -854,7 +886,9 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: Default> Default for Arc<T> {
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn default() -> Arc<T> { Arc::new(Default::default()) }
+    fn default() -> Arc<T> {
+        Arc::new(Default::default())
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -1015,7 +1049,7 @@ fn test_dead() {
     #[test]
     fn weak_self_cyclic() {
         struct Cycle {
-            x: Mutex<Option<Weak<Cycle>>>
+            x: Mutex<Option<Weak<Cycle>>>,
         }
 
         let a = Arc::new(Cycle { x: Mutex::new(None) });
@@ -1095,7 +1129,9 @@ fn show_arc() {
 
     // Make sure deriving works with Arc<T>
     #[derive(Eq, Ord, PartialEq, PartialOrd, Clone, Debug, Default)]
-    struct Foo { inner: Arc<i32> }
+    struct Foo {
+        inner: Arc<i32>,
+    }
 
     #[test]
     fn test_unsized() {
@@ -1108,5 +1144,7 @@ fn test_unsized() {
 }
 
 impl<T: ?Sized> borrow::Borrow<T> for Arc<T> {
-    fn borrow(&self) -> &T { &**self }
+    fn borrow(&self) -> &T {
+        &**self
+    }
 }
index 3239677fc0cc9af9f24be6d06fa5cd63ce1693dd..1529187da064c05550974edc92755fdb91ead193 100644 (file)
@@ -66,7 +66,7 @@
 use core::ops::{CoerceUnsized, Deref, DerefMut};
 use core::ops::{Placer, Boxed, Place, InPlace, BoxPlace};
 use core::ptr::{self, Unique};
-use core::raw::{TraitObject};
+use core::raw::TraitObject;
 
 /// A value that represents the heap. This is the default place that the `box`
 /// keyword allocates into when no place is supplied.
@@ -95,7 +95,9 @@
            reason = "may be renamed; uncertain about custom allocator design",
            issue = "27779")]
 #[derive(Copy, Clone)]
-pub struct ExchangeHeapSingleton { _force_singleton: () }
+pub struct ExchangeHeapSingleton {
+    _force_singleton: (),
+}
 
 /// A pointer type for heap allocation.
 ///
@@ -126,7 +128,7 @@ pub struct ExchangeHeapSingleton { _force_singleton: () }
 #[unstable(feature = "placement_in",
            reason = "placement box design is still being worked out.",
            issue = "27779")]
-pub struct IntermediateBox<T: ?Sized>{
+pub struct IntermediateBox<T: ?Sized> {
     ptr: *mut u8,
     size: usize,
     align: usize,
@@ -152,9 +154,7 @@ fn make_place<T>() -> IntermediateBox<T> {
     let p = if size == 0 {
         heap::EMPTY as *mut u8
     } else {
-        let p = unsafe {
-            heap::allocate(size, align)
-        };
+        let p = unsafe { heap::allocate(size, align) };
         if p.is_null() {
             panic!("Box make_place allocation failure.");
         }
@@ -165,18 +165,24 @@ fn make_place<T>() -> IntermediateBox<T> {
 }
 
 impl<T> BoxPlace<T> for IntermediateBox<T> {
-    fn make_place() -> IntermediateBox<T> { make_place() }
+    fn make_place() -> IntermediateBox<T> {
+        make_place()
+    }
 }
 
 impl<T> InPlace<T> for IntermediateBox<T> {
     type Owner = Box<T>;
-    unsafe fn finalize(self) -> Box<T> { finalize(self) }
+    unsafe fn finalize(self) -> Box<T> {
+        finalize(self)
+    }
 }
 
 impl<T> Boxed for Box<T> {
     type Data = T;
     type Place = IntermediateBox<T>;
-    unsafe fn finalize(b: IntermediateBox<T>) -> Box<T> { finalize(b) }
+    unsafe fn finalize(b: IntermediateBox<T>) -> Box<T> {
+        finalize(b)
+    }
 }
 
 impl<T> Placer<T> for ExchangeHeapSingleton {
@@ -190,9 +196,7 @@ fn make_place(self) -> IntermediateBox<T> {
 impl<T: ?Sized> Drop for IntermediateBox<T> {
     fn drop(&mut self) {
         if self.size > 0 {
-            unsafe {
-                heap::deallocate(self.ptr, self.size, self.align)
-            }
+            unsafe { heap::deallocate(self.ptr, self.size, self.align) }
         }
     }
 }
@@ -256,13 +260,17 @@ pub fn into_raw(b: Box<T>) -> *mut T {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: Default> Default for Box<T> {
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn default() -> Box<T> { box Default::default() }
+    fn default() -> Box<T> {
+        box Default::default()
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> Default for Box<[T]> {
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn default() -> Box<[T]> { Box::<[T; 0]>::new([]) }
+    fn default() -> Box<[T]> {
+        Box::<[T; 0]>::new([])
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -275,8 +283,11 @@ impl<T: Clone> Clone for Box<T> {
     /// let x = Box::new(5);
     /// let y = x.clone();
     /// ```
+    #[rustfmt_skip]
     #[inline]
-    fn clone(&self) -> Box<T> { box {(**self).clone()} }
+    fn clone(&self) -> Box<T> {
+        box { (**self).clone() }
+    }
     /// Copies `source`'s contents into `self` without creating a new allocation.
     ///
     /// # Examples
@@ -311,9 +322,13 @@ fn clone(&self) -> Self {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: ?Sized + PartialEq> PartialEq for Box<T> {
     #[inline]
-    fn eq(&self, other: &Box<T>) -> bool { PartialEq::eq(&**self, &**other) }
+    fn eq(&self, other: &Box<T>) -> bool {
+        PartialEq::eq(&**self, &**other)
+    }
     #[inline]
-    fn ne(&self, other: &Box<T>) -> bool { PartialEq::ne(&**self, &**other) }
+    fn ne(&self, other: &Box<T>) -> bool {
+        PartialEq::ne(&**self, &**other)
+    }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: ?Sized + PartialOrd> PartialOrd for Box<T> {
@@ -322,13 +337,21 @@ fn partial_cmp(&self, other: &Box<T>) -> Option<Ordering> {
         PartialOrd::partial_cmp(&**self, &**other)
     }
     #[inline]
-    fn lt(&self, other: &Box<T>) -> bool { PartialOrd::lt(&**self, &**other) }
+    fn lt(&self, other: &Box<T>) -> bool {
+        PartialOrd::lt(&**self, &**other)
+    }
     #[inline]
-    fn le(&self, other: &Box<T>) -> bool { PartialOrd::le(&**self, &**other) }
+    fn le(&self, other: &Box<T>) -> bool {
+        PartialOrd::le(&**self, &**other)
+    }
     #[inline]
-    fn ge(&self, other: &Box<T>) -> bool { PartialOrd::ge(&**self, &**other) }
+    fn ge(&self, other: &Box<T>) -> bool {
+        PartialOrd::ge(&**self, &**other)
+    }
     #[inline]
-    fn gt(&self, other: &Box<T>) -> bool { PartialOrd::gt(&**self, &**other) }
+    fn gt(&self, other: &Box<T>) -> bool {
+        PartialOrd::gt(&**self, &**other)
+    }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: ?Sized + Ord> Ord for Box<T> {
@@ -356,8 +379,7 @@ pub fn downcast<T: Any>(self) -> Result<Box<T>, Box<Any>> {
             unsafe {
                 // Get the raw representation of the trait object
                 let raw = Box::into_raw(self);
-                let to: TraitObject =
-                    mem::transmute::<*mut Any, TraitObject>(raw);
+                let to: TraitObject = mem::transmute::<*mut Any, TraitObject>(raw);
 
                 // Extract the data pointer
                 Ok(Box::from_raw(to.data as *mut T))
@@ -408,23 +430,33 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 impl<T: ?Sized> Deref for Box<T> {
     type Target = T;
 
-    fn deref(&self) -> &T { &**self }
+    fn deref(&self) -> &T {
+        &**self
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: ?Sized> DerefMut for Box<T> {
-    fn deref_mut(&mut self) -> &mut T { &mut **self }
+    fn deref_mut(&mut self) -> &mut T {
+        &mut **self
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<I: Iterator + ?Sized> Iterator for Box<I> {
     type Item = I::Item;
-    fn next(&mut self) -> Option<I::Item> { (**self).next() }
-    fn size_hint(&self) -> (usize, Option<usize>) { (**self).size_hint() }
+    fn next(&mut self) -> Option<I::Item> {
+        (**self).next()
+    }
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        (**self).size_hint()
+    }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<I: DoubleEndedIterator + ?Sized> DoubleEndedIterator for Box<I> {
-    fn next_back(&mut self) -> Option<I::Item> { (**self).next_back() }
+    fn next_back(&mut self) -> Option<I::Item> {
+        (**self).next_back()
+    }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<I: ExactSizeIterator + ?Sized> ExactSizeIterator for Box<I> {}
@@ -506,10 +538,7 @@ impl<T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<Box<U>> for Box<T> {}
 #[stable(feature = "box_slice_clone", since = "1.3.0")]
 impl<T: Clone> Clone for Box<[T]> {
     fn clone(&self) -> Self {
-        let mut new = BoxBuilder {
-            data: RawVec::with_capacity(self.len()),
-            len: 0
-        };
+        let mut new = BoxBuilder { data: RawVec::with_capacity(self.len()), len: 0 };
 
         let mut target = new.data.ptr();
 
@@ -555,9 +584,13 @@ fn drop(&mut self) {
 }
 
 impl<T: ?Sized> borrow::Borrow<T> for Box<T> {
-    fn borrow(&self) -> &T { &**self }
+    fn borrow(&self) -> &T {
+        &**self
+    }
 }
 
 impl<T: ?Sized> borrow::BorrowMut<T> for Box<T> {
-    fn borrow_mut(&mut self) -> &mut T { &mut **self }
+    fn borrow_mut(&mut self) -> &mut T {
+        &mut **self
+    }
 }
index 2ef23b26a56a739549562c57ef71f521dab72063..7f3dadcf24d230998fb6a7084365e672a603824e 100644 (file)
@@ -34,12 +34,16 @@ fn any_move() {
     let b = Box::new(Test) as Box<Any>;
 
     match a.downcast::<i32>() {
-        Ok(a) => { assert!(a == Box::new(8)); }
-        Err(..) => panic!()
+        Ok(a) => {
+            assert!(a == Box::new(8));
+        }
+        Err(..) => panic!(),
     }
     match b.downcast::<Test>() {
-        Ok(a) => { assert!(a == Box::new(Test)); }
-        Err(..) => panic!()
+        Ok(a) => {
+            assert!(a == Box::new(Test));
+        }
+        Err(..) => panic!(),
     }
 
     let a = Box::new(8) as Box<Any>;
@@ -70,7 +74,8 @@ fn test_show() {
 
 #[test]
 fn deref() {
-    fn homura<T: Deref<Target=i32>>(_: T) { }
+    fn homura<T: Deref<Target = i32>>(_: T) {
+    }
     homura(Box::new(765));
 }
 
index 10cb84d1da14d1b8c94259efd30ff4228f26c2e8..6961702cbc09d4c66766646b8a1ef4e4f803b834 100644 (file)
     #[allocator]
     fn __rust_allocate(size: usize, align: usize) -> *mut u8;
     fn __rust_deallocate(ptr: *mut u8, old_size: usize, align: usize);
-    fn __rust_reallocate(ptr: *mut u8, old_size: usize, size: usize,
-                         align: usize) -> *mut u8;
-    fn __rust_reallocate_inplace(ptr: *mut u8, old_size: usize, size: usize,
-                               align: usize) -> usize;
+    fn __rust_reallocate(ptr: *mut u8, old_size: usize, size: usize, align: usize) -> *mut u8;
+    fn __rust_reallocate_inplace(ptr: *mut u8,
+                                 old_size: usize,
+                                 size: usize,
+                                 align: usize)
+                                 -> usize;
     fn __rust_usable_size(size: usize, align: usize) -> usize;
 }
 
 #[inline(always)]
 fn check_size_and_alignment(size: usize, align: usize) {
     debug_assert!(size != 0);
-    debug_assert!(size <= isize::MAX as usize, "Tried to allocate too much: {} bytes", size);
-    debug_assert!(usize::is_power_of_two(align), "Invalid alignment of allocation: {}", align);
+    debug_assert!(size <= isize::MAX as usize,
+                  "Tried to allocate too much: {} bytes",
+                  size);
+    debug_assert!(usize::is_power_of_two(align),
+                  "Invalid alignment of allocation: {}",
+                  align);
 }
 
 // FIXME: #13996: mark the `allocate` and `reallocate` return value as `noalias`
@@ -84,8 +90,11 @@ pub unsafe fn reallocate(ptr: *mut u8, old_size: usize, size: usize, align: usiz
 /// create the allocation referenced by `ptr`. The `old_size` parameter may be
 /// any value in range_inclusive(requested_size, usable_size).
 #[inline]
-pub unsafe fn reallocate_inplace(ptr: *mut u8, old_size: usize, size: usize,
-                                 align: usize) -> usize {
+pub unsafe fn reallocate_inplace(ptr: *mut u8,
+                                 old_size: usize,
+                                 size: usize,
+                                 align: usize)
+                                 -> usize {
     check_size_and_alignment(size, align);
     __rust_reallocate_inplace(ptr, old_size, size, align)
 }
@@ -124,7 +133,9 @@ unsafe fn exchange_malloc(size: usize, align: usize) -> *mut u8 {
         EMPTY as *mut u8
     } else {
         let ptr = allocate(size, align);
-        if ptr.is_null() { ::oom() }
+        if ptr.is_null() {
+            ::oom()
+        }
         ptr
     }
 }
@@ -148,7 +159,9 @@ fn basic_reallocate_inplace_noop() {
         unsafe {
             let size = 4000;
             let ptr = heap::allocate(size, 8);
-            if ptr.is_null() { ::oom() }
+            if ptr.is_null() {
+                ::oom()
+            }
             let ret = heap::reallocate_inplace(ptr, size, size, 8);
             heap::deallocate(ptr, size, 8);
             assert_eq!(ret, heap::usable_size(size, 8));
index 66de5d7bea84eab0cacb0571ffd32dc1dcc17d55..98c729aaba43308639767b7a1de4b09be2fd3154 100644 (file)
 
 // Allow testing this library
 
-#[cfg(test)] #[macro_use] extern crate std;
-#[cfg(test)] #[macro_use] extern crate log;
+#[cfg(test)]
+#[macro_use]
+extern crate std;
+#[cfg(test)]
+#[macro_use]
+extern crate log;
 
 // Heaps provided for low-level allocation strategies
 
 #[cfg(not(test))]
 pub mod boxed;
 #[cfg(test)]
-mod boxed { pub use std::boxed::{Box, HEAP}; }
+mod boxed {
+    pub use std::boxed::{Box, HEAP};
+}
 #[cfg(test)]
 mod boxed_test;
 pub mod arc;
index 97acd0db52478348da758770ee7e4a4b4ddf39d7..dd2db6fab086dd8539a13763677d60e413cb5410 100644 (file)
@@ -58,7 +58,11 @@ impl<T> RawVec<T> {
     pub fn new() -> Self {
         unsafe {
             // !0 is usize::MAX. This branch should be stripped at compile time.
-            let cap = if mem::size_of::<T>() == 0 { !0 } else { 0 };
+            let cap = if mem::size_of::<T>() == 0 {
+                !0
+            } else {
+                0
+            };
 
             // heap::EMPTY doubles as "unallocated" and "zero-sized allocation"
             RawVec { ptr: Unique::new(heap::EMPTY as *mut T), cap: cap }
@@ -92,7 +96,9 @@ pub fn with_capacity(cap: usize) -> Self {
             } else {
                 let align = mem::align_of::<T>();
                 let ptr = heap::allocate(alloc_size, align);
-                if ptr.is_null() { oom() }
+                if ptr.is_null() {
+                    oom()
+                }
                 ptr
             };
 
@@ -133,7 +139,11 @@ pub fn ptr(&self) -> *mut T {
     ///
     /// This will always be `usize::MAX` if `T` is zero-sized.
     pub fn cap(&self) -> usize {
-        if mem::size_of::<T>() == 0 { !0 } else { self.cap }
+        if mem::size_of::<T>() == 0 {
+            !0
+        } else {
+            self.cap
+        }
     }
 
     /// Doubles the size of the type's backing allocation. This is common enough
@@ -190,7 +200,11 @@ pub fn double(&mut self) {
 
             let (new_cap, ptr) = if self.cap == 0 {
                 // skip to 4 because tiny Vec's are dumb; but not if that would cause overflow
-                let new_cap = if elem_size > (!0) / 8 { 1 } else { 4 };
+                let new_cap = if elem_size > (!0) / 8 {
+                    1
+                } else {
+                    4
+                };
                 let ptr = heap::allocate(new_cap * elem_size, align);
                 (new_cap, ptr)
             } else {
@@ -207,7 +221,9 @@ pub fn double(&mut self) {
             };
 
             // If allocate or reallocate fail, we'll get `null` back
-            if ptr.is_null() { oom() }
+            if ptr.is_null() {
+                oom()
+            }
 
             self.ptr = Unique::new(ptr as *mut _);
             self.cap = new_cap;
@@ -246,7 +262,9 @@ pub fn reserve_exact(&mut self, used_cap: usize, needed_extra_cap: usize) {
 
             // Don't actually need any more capacity.
             // Wrapping in case they gave a bad `used_cap`.
-            if self.cap().wrapping_sub(used_cap) >= needed_extra_cap { return; }
+            if self.cap().wrapping_sub(used_cap) >= needed_extra_cap {
+                return;
+            }
 
             // Nothing we can really do about these checks :(
             let new_cap = used_cap.checked_add(needed_extra_cap).expect("capacity overflow");
@@ -263,7 +281,9 @@ pub fn reserve_exact(&mut self, used_cap: usize, needed_extra_cap: usize) {
             };
 
             // If allocate or reallocate fail, we'll get `null` back
-            if ptr.is_null() { oom() }
+            if ptr.is_null() {
+                oom()
+            }
 
             self.ptr = Unique::new(ptr as *mut _);
             self.cap = new_cap;
@@ -326,7 +346,9 @@ pub fn reserve(&mut self, used_cap: usize, needed_extra_cap: usize) {
 
             // Don't actually need any more capacity.
             // Wrapping in case they give a bas `used_cap`
-            if self.cap().wrapping_sub(used_cap) >= needed_extra_cap { return; }
+            if self.cap().wrapping_sub(used_cap) >= needed_extra_cap {
+                return;
+            }
 
             // Nothing we can really do about these checks :(
             let new_cap = used_cap.checked_add(needed_extra_cap)
@@ -346,7 +368,9 @@ pub fn reserve(&mut self, used_cap: usize, needed_extra_cap: usize) {
             };
 
             // If allocate or reallocate fail, we'll get `null` back
-            if ptr.is_null() { oom() }
+            if ptr.is_null() {
+                oom()
+            }
 
             self.ptr = Unique::new(ptr as *mut _);
             self.cap = new_cap;
@@ -374,7 +398,8 @@ pub fn shrink_to_fit(&mut self, amount: usize) {
         }
 
         // This check is my waterloo; it's the only thing Vec wouldn't have to do.
-        assert!(self.cap >= amount, "Tried to shrink to a larger capacity");
+        assert!(self.cap >= amount,
+                "Tried to shrink to a larger capacity");
 
         if amount == 0 {
             mem::replace(self, RawVec::new());
@@ -386,7 +411,9 @@ pub fn shrink_to_fit(&mut self, amount: usize) {
                                            self.cap * elem_size,
                                            amount * elem_size,
                                            align);
-                if ptr.is_null() { oom() }
+                if ptr.is_null() {
+                    oom()
+                }
                 self.ptr = Unique::new(ptr as *mut _);
             }
             self.cap = amount;
@@ -446,6 +473,7 @@ fn drop(&mut self) {
 #[inline]
 fn alloc_guard(alloc_size: usize) {
     if core::usize::BITS < 64 {
-        assert!(alloc_size <= ::core::isize::MAX as usize, "capacity overflow");
+        assert!(alloc_size <= ::core::isize::MAX as usize,
+                "capacity overflow");
     }
 }
index 4fe474cef0a26e21a69fc69ebb126bed2e16d7f4..3507f123a6f153c3b060ff3f5b5a403e5c0d8775 100644 (file)
@@ -213,7 +213,7 @@ pub fn new(value: T) -> Rc<T> {
                 _ptr: NonZero::new(Box::into_raw(box RcBox {
                     strong: Cell::new(1),
                     weak: Cell::new(1),
-                    value: value
+                    value: value,
                 })),
             }
         }
@@ -290,13 +290,17 @@ pub fn downgrade(this: &Self) -> Weak<T> {
     #[inline]
     #[unstable(feature = "rc_counts", reason = "not clearly useful",
                issue = "28356")]
-    pub fn weak_count(this: &Self) -> usize { this.weak() - 1 }
+    pub fn weak_count(this: &Self) -> usize {
+        this.weak() - 1
+    }
 
     /// Get the number of strong references to this value.
     #[inline]
     #[unstable(feature = "rc_counts", reason = "not clearly useful",
                issue = "28356")]
-    pub fn strong_count(this: &Self) -> usize { this.strong() }
+    pub fn strong_count(this: &Self) -> usize {
+        this.strong()
+    }
 
     /// Returns true if there are no other `Rc` or `Weak<T>` values that share
     /// the same inner value.
@@ -451,7 +455,7 @@ fn drop(&mut self) {
         unsafe {
             let ptr = *self._ptr;
             if !(*(&ptr as *const _ as *const *const ())).is_null() &&
-                ptr as *const () as usize != mem::POST_DROP_USIZE {
+               ptr as *const () as usize != mem::POST_DROP_USIZE {
                 self.dec_strong();
                 if self.strong() == 0 {
                     // destroy the contained object
@@ -530,7 +534,9 @@ impl<T: ?Sized + PartialEq> PartialEq for Rc<T> {
     /// five == Rc::new(5);
     /// ```
     #[inline(always)]
-    fn eq(&self, other: &Rc<T>) -> bool { **self == **other }
+    fn eq(&self, other: &Rc<T>) -> bool {
+        **self == **other
+    }
 
     /// Inequality for two `Rc<T>`s.
     ///
@@ -546,7 +552,9 @@ fn eq(&self, other: &Rc<T>) -> bool { **self == **other }
     /// five != Rc::new(5);
     /// ```
     #[inline(always)]
-    fn ne(&self, other: &Rc<T>) -> bool { **self != **other }
+    fn ne(&self, other: &Rc<T>) -> bool {
+        **self != **other
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -586,7 +594,9 @@ fn partial_cmp(&self, other: &Rc<T>) -> Option<Ordering> {
     /// five < Rc::new(5);
     /// ```
     #[inline(always)]
-    fn lt(&self, other: &Rc<T>) -> bool { **self < **other }
+    fn lt(&self, other: &Rc<T>) -> bool {
+        **self < **other
+    }
 
     /// 'Less-than or equal to' comparison for two `Rc<T>`s.
     ///
@@ -602,7 +612,9 @@ fn lt(&self, other: &Rc<T>) -> bool { **self < **other }
     /// five <= Rc::new(5);
     /// ```
     #[inline(always)]
-    fn le(&self, other: &Rc<T>) -> bool { **self <= **other }
+    fn le(&self, other: &Rc<T>) -> bool {
+        **self <= **other
+    }
 
     /// Greater-than comparison for two `Rc<T>`s.
     ///
@@ -618,7 +630,9 @@ fn le(&self, other: &Rc<T>) -> bool { **self <= **other }
     /// five > Rc::new(5);
     /// ```
     #[inline(always)]
-    fn gt(&self, other: &Rc<T>) -> bool { **self > **other }
+    fn gt(&self, other: &Rc<T>) -> bool {
+        **self > **other
+    }
 
     /// 'Greater-than or equal to' comparison for two `Rc<T>`s.
     ///
@@ -634,7 +648,9 @@ fn gt(&self, other: &Rc<T>) -> bool { **self > **other }
     /// five >= Rc::new(5);
     /// ```
     #[inline(always)]
-    fn ge(&self, other: &Rc<T>) -> bool { **self >= **other }
+    fn ge(&self, other: &Rc<T>) -> bool {
+        **self >= **other
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -653,7 +669,9 @@ impl<T: ?Sized + Ord> Ord for Rc<T> {
     /// five.partial_cmp(&Rc::new(5));
     /// ```
     #[inline]
-    fn cmp(&self, other: &Rc<T>) -> Ordering { (**self).cmp(&**other) }
+    fn cmp(&self, other: &Rc<T>) -> Ordering {
+        (**self).cmp(&**other)
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -764,12 +782,13 @@ fn drop(&mut self) {
         unsafe {
             let ptr = *self._ptr;
             if !(*(&ptr as *const _ as *const *const ())).is_null() &&
-                ptr as *const () as usize != mem::POST_DROP_USIZE {
+               ptr as *const () as usize != mem::POST_DROP_USIZE {
                 self.dec_weak();
                 // the weak count starts at 1, and will only go to zero if all
                 // the strong pointers have disappeared.
                 if self.weak() == 0 {
-                    deallocate(ptr as *mut u8, size_of_val(&*ptr),
+                    deallocate(ptr as *mut u8,
+                               size_of_val(&*ptr),
                                align_of_val(&*ptr))
                 }
             }
@@ -821,7 +840,9 @@ trait RcBoxPtr<T: ?Sized> {
     fn inner(&self) -> &RcBox<T>;
 
     #[inline]
-    fn strong(&self) -> usize { self.inner().strong.get() }
+    fn strong(&self) -> usize {
+        self.inner().strong.get()
+    }
 
     #[inline]
     fn inc_strong(&self) {
@@ -829,10 +850,14 @@ fn inc_strong(&self) {
     }
 
     #[inline]
-    fn dec_strong(&self) { self.inner().strong.set(self.strong() - 1); }
+    fn dec_strong(&self) {
+        self.inner().strong.set(self.strong() - 1);
+    }
 
     #[inline]
-    fn weak(&self) -> usize { self.inner().weak.get() }
+    fn weak(&self) -> usize {
+        self.inner().weak.get()
+    }
 
     #[inline]
     fn inc_weak(&self) {
@@ -840,7 +865,9 @@ fn inc_weak(&self) {
     }
 
     #[inline]
-    fn dec_weak(&self) { self.inner().weak.set(self.weak() - 1); }
+    fn dec_weak(&self) {
+        self.inner().weak.set(self.weak() - 1);
+    }
 }
 
 impl<T: ?Sized> RcBoxPtr<T> for Rc<T> {
@@ -928,7 +955,7 @@ fn test_dead() {
     #[test]
     fn weak_self_cyclic() {
         struct Cycle {
-            x: RefCell<Option<Weak<Cycle>>>
+            x: RefCell<Option<Weak<Cycle>>>,
         }
 
         let a = Rc::new(Cycle { x: RefCell::new(None) });
@@ -1086,5 +1113,7 @@ fn test_unsized() {
 }
 
 impl<T: ?Sized> borrow::Borrow<T> for Rc<T> {
-    fn borrow(&self) -> &T { &**self }
+    fn borrow(&self) -> &T {
+        &**self
+    }
 }
index 2f74ab5026e9257073ea25a77ddf2f52be17182d..a3d38bdd1b31b3b5c667b6d9aa6c07beff484cdd 100644 (file)
@@ -1157,25 +1157,21 @@ pub fn rmatches<'a, P: Pattern<'a>>(&'a self, pat: P) -> RMatches<'a, P>
         core_str::StrExt::rmatches(self, pat)
     }
 
-    /// An iterator over the start and end indices of the disjoint matches
-    /// of a pattern within `self`.
+    /// An iterator over the disjoint matches of a pattern within `self` as well
+    /// as the index that the match starts at.
     ///
     /// For matches of `pat` within `self` that overlap, only the indices
-    /// corresponding to the first
-    /// match are returned.
+    /// corresponding to the first match are returned.
     ///
-    /// The pattern can be a simple `&str`, `char`, or a closure that
-    /// determines if a character matches.
-    /// Additional libraries might provide more complex patterns like
-    /// regular expressions.
+    /// The pattern can be a simple `&str`, `char`, or a closure that determines
+    /// if a character matches. Additional libraries might provide more complex
+    /// patterns like regular expressions.
     ///
     /// # Iterator behavior
     ///
     /// The returned iterator will be double ended if the pattern allows a
-    /// reverse search
-    /// and forward/reverse search yields the same elements. This is true for,
-    /// eg, `char` but not
-    /// for `&str`.
+    /// reverse search and forward/reverse search yields the same elements. This
+    /// is true for, eg, `char` but not for `&str`.
     ///
     /// If the pattern allows a reverse search but its results might differ
     /// from a forward search, `rmatch_indices()` can be used.
@@ -1185,42 +1181,36 @@ pub fn rmatches<'a, P: Pattern<'a>>(&'a self, pat: P) -> RMatches<'a, P>
     /// ```
     /// #![feature(str_match_indices)]
     ///
-    /// let v: Vec<(usize, usize)> = "abcXXXabcYYYabc".match_indices("abc").collect();
-    /// assert_eq!(v, [(0, 3), (6, 9), (12, 15)]);
+    /// let v: Vec<_> = "abcXXXabcYYYabc".match_indices("abc").collect();
+    /// assert_eq!(v, [(0, "abc"), (6, "abc"), (12, "abc")]);
     ///
-    /// let v: Vec<(usize, usize)> = "1abcabc2".match_indices("abc").collect();
-    /// assert_eq!(v, [(1, 4), (4, 7)]);
+    /// let v: Vec<_> = "1abcabc2".match_indices("abc").collect();
+    /// assert_eq!(v, [(1, "abc"), (4, "abc")]);
     ///
-    /// let v: Vec<(usize, usize)> = "ababa".match_indices("aba").collect();
-    /// assert_eq!(v, [(0, 3)]); // only the first `aba`
+    /// let v: Vec<_> = "ababa".match_indices("aba").collect();
+    /// assert_eq!(v, [(0, "aba")]); // only the first `aba`
     /// ```
     #[unstable(feature = "str_match_indices",
                reason = "might have its iterator type changed",
                issue = "27743")]
-    // NB: Right now MatchIndices yields `(usize, usize)`, but it would
-    // be more consistent with `matches` and `char_indices` to return `(usize, &str)`
     pub fn match_indices<'a, P: Pattern<'a>>(&'a self, pat: P) -> MatchIndices<'a, P> {
         core_str::StrExt::match_indices(self, pat)
     }
 
-    /// An iterator over the start and end indices of the disjoint matches of
-    /// a pattern within
-    /// `self`, yielded in reverse order.
+    /// An iterator over the disjoint matches of a pattern within `self`,
+    /// yielded in reverse order along with the index of the match.
     ///
     /// For matches of `pat` within `self` that overlap, only the indices
-    /// corresponding to the last
-    /// match are returned.
+    /// corresponding to the last match are returned.
     ///
-    /// The pattern can be a simple `&str`, `char`, or a closure that
-    /// determines if a character matches.
-    /// Additional libraries might provide more complex patterns like
-    /// regular expressions.
+    /// The pattern can be a simple `&str`, `char`, or a closure that determines
+    /// if a character matches. Additional libraries might provide more complex
+    /// patterns like regular expressions.
     ///
     /// # Iterator behavior
     ///
-    /// The returned iterator requires that the pattern supports a
-    /// reverse search,
-    /// and it will be double ended if a forward/reverse search yields
+    /// The returned iterator requires that the pattern supports a reverse
+    /// search, and it will be double ended if a forward/reverse search yields
     /// the same elements.
     ///
     /// For iterating from the front, `match_indices()` can be used.
@@ -1230,20 +1220,18 @@ pub fn match_indices<'a, P: Pattern<'a>>(&'a self, pat: P) -> MatchIndices<'a, P
     /// ```
     /// #![feature(str_match_indices)]
     ///
-    /// let v: Vec<(usize, usize)> = "abcXXXabcYYYabc".rmatch_indices("abc").collect();
-    /// assert_eq!(v, [(12, 15), (6, 9), (0, 3)]);
+    /// let v: Vec<_> = "abcXXXabcYYYabc".rmatch_indices("abc").collect();
+    /// assert_eq!(v, [(12, "abc"), (6, "abc"), (0, "abc")]);
     ///
-    /// let v: Vec<(usize, usize)> = "1abcabc2".rmatch_indices("abc").collect();
-    /// assert_eq!(v, [(4, 7), (1, 4)]);
+    /// let v: Vec<_> = "1abcabc2".rmatch_indices("abc").collect();
+    /// assert_eq!(v, [(4, "abc"), (1, "abc")]);
     ///
-    /// let v: Vec<(usize, usize)> = "ababa".rmatch_indices("aba").collect();
-    /// assert_eq!(v, [(2, 5)]); // only the last `aba`
+    /// let v: Vec<_> = "ababa".rmatch_indices("aba").collect();
+    /// assert_eq!(v, [(2, "aba")]); // only the last `aba`
     /// ```
     #[unstable(feature = "str_match_indices",
                reason = "might have its iterator type changed",
                issue = "27743")]
-    // NB: Right now RMatchIndices yields `(usize, usize)`, but it would
-    // be more consistent with `rmatches` and `char_indices` to return `(usize, &str)`
     pub fn rmatch_indices<'a, P: Pattern<'a>>(&'a self, pat: P) -> RMatchIndices<'a, P>
         where P::Searcher: ReverseSearcher<'a>
     {
@@ -1416,10 +1404,10 @@ pub fn parse<F: FromStr>(&self) -> Result<F, F::Err> {
     pub fn replace(&self, from: &str, to: &str) -> String {
         let mut result = String::new();
         let mut last_end = 0;
-        for (start, end) in self.match_indices(from) {
+        for (start, part) in self.match_indices(from) {
             result.push_str(unsafe { self.slice_unchecked(last_end, start) });
             result.push_str(to);
-            last_end = end;
+            last_end = start + part.len();
         }
         result.push_str(unsafe { self.slice_unchecked(last_end, self.len()) });
         result
index ba921fed68b1dc4e922c3cc7aa64f5153302c482..acbce825ecc3f71bb699605674f5a2b82ff07d7a 100644 (file)
@@ -1041,8 +1041,8 @@ fn deref_mut(&mut self) -> &mut str {
 #[unstable(feature = "str_parse_error", reason = "may want to be replaced with \
                                                   Void if it ever exists",
            issue = "27734")]
-#[derive(Copy, Clone, Debug, Eq, PartialEq)]
-pub struct ParseError(());
+#[derive(Copy)]
+pub enum ParseError {}
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl FromStr for String {
@@ -1053,6 +1053,26 @@ fn from_str(s: &str) -> Result<String, ParseError> {
     }
 }
 
+impl Clone for ParseError {
+    fn clone(&self) -> ParseError {
+        match *self {}
+    }
+}
+
+impl fmt::Debug for ParseError {
+    fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result {
+        match *self {}
+    }
+}
+
+impl PartialEq for ParseError {
+    fn eq(&self, _: &ParseError) -> bool {
+        match *self {}
+    }
+}
+
+impl Eq for ParseError {}
+
 /// A generic trait for converting a value to a string
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait ToString {
index 7b481f63991165d04e3e3a6357753f1a45ff6f57..b4555679e9c1bf351736263d3d5eb3153286c54e 100644 (file)
@@ -1047,7 +1047,7 @@ fn test_pattern_deref_forward() {
 fn test_empty_match_indices() {
     let data = "aä中!";
     let vec: Vec<_> = data.match_indices("").collect();
-    assert_eq!(vec, [(0, 0), (1, 1), (3, 3), (6, 6), (7, 7)]);
+    assert_eq!(vec, [(0, ""), (1, ""), (3, ""), (6, ""), (7, "")]);
 }
 
 #[test]
@@ -1477,7 +1477,7 @@ fn $name() {
 
 generate_iterator_test! {
     double_ended_match_indices {
-        ("a1b2c3", char::is_numeric) -> [(1, 2), (3, 4), (5, 6)];
+        ("a1b2c3", char::is_numeric) -> [(1, "1"), (3, "2"), (5, "3")];
     }
     with str::match_indices, str::rmatch_indices;
 }
index db7e6d3006f3f25f6bfb4a1a2fafb96edd76c089..8c596eb3e997b12910ab9c6a16f040dfffe3e5ba 100644 (file)
@@ -865,12 +865,12 @@ pub fn pad_integral(&mut self,
         let mut sign = None;
         if !is_positive {
             sign = Some('-'); width += 1;
-        } else if self.flags & (1 << (FlagV1::SignPlus as u32)) != 0 {
+        } else if self.sign_plus() {
             sign = Some('+'); width += 1;
         }
 
         let mut prefixed = false;
-        if self.flags & (1 << (FlagV1::Alternate as u32)) != 0 {
+        if self.alternate() {
             prefixed = true; width += prefix.char_len();
         }
 
@@ -900,7 +900,7 @@ pub fn pad_integral(&mut self,
             }
             // The sign and prefix goes before the padding if the fill character
             // is zero
-            Some(min) if self.flags & (1 << (FlagV1::SignAwareZeroPad as u32)) != 0 => {
+            Some(min) if self.sign_aware_zero_pad() => {
                 self.fill = '0';
                 try!(write_prefix(self));
                 self.with_padding(min - width, Alignment::Right, |f| {
@@ -1013,7 +1013,7 @@ fn pad_formatted_parts(&mut self, formatted: &flt2dec::Formatted) -> Result {
             let mut formatted = formatted.clone();
             let mut align = self.align;
             let old_fill = self.fill;
-            if self.flags & (1 << (FlagV1::SignAwareZeroPad as u32)) != 0 {
+            if self.sign_aware_zero_pad() {
                 // a sign always goes first
                 let sign = unsafe { str::from_utf8_unchecked(formatted.sign) };
                 try!(self.buf.write_str(sign));
@@ -1117,6 +1117,28 @@ pub fn width(&self) -> Option<usize> { self.width }
                issue = "27726")]
     pub fn precision(&self) -> Option<usize> { self.precision }
 
+    /// Determines if the `+` flag was specified.
+    #[unstable(feature = "fmt_flags", reason = "method was just created",
+               issue = "27726")]
+    pub fn sign_plus(&self) -> bool { self.flags & (1 << FlagV1::SignPlus as u32) != 0 }
+
+    /// Determines if the `-` flag was specified.
+    #[unstable(feature = "fmt_flags", reason = "method was just created",
+               issue = "27726")]
+    pub fn sign_minus(&self) -> bool { self.flags & (1 << FlagV1::SignMinus as u32) != 0 }
+
+    /// Determines if the `#` flag was specified.
+    #[unstable(feature = "fmt_flags", reason = "method was just created",
+               issue = "27726")]
+    pub fn alternate(&self) -> bool { self.flags & (1 << FlagV1::Alternate as u32) != 0 }
+
+    /// Determines if the `0` flag was specified.
+    #[unstable(feature = "fmt_flags", reason = "method was just created",
+               issue = "27726")]
+    pub fn sign_aware_zero_pad(&self) -> bool {
+        self.flags & (1 << FlagV1::SignAwareZeroPad as u32) != 0
+    }
+
     /// Creates a `DebugStruct` builder designed to assist with creation of
     /// `fmt::Debug` implementations for structs.
     ///
@@ -1361,7 +1383,7 @@ fn fmt(&self, f: &mut Formatter) -> Result {
         // it denotes whether to prefix with 0x. We use it to work out whether
         // or not to zero extend, and then unconditionally set it to get the
         // prefix.
-        if f.flags & 1 << (FlagV1::Alternate as u32) > 0 {
+        if f.alternate() {
             f.flags |= 1 << (FlagV1::SignAwareZeroPad as u32);
 
             if let None = f.width {
@@ -1410,7 +1432,7 @@ fn fmt(&self, f: &mut Formatter) -> Result {
 fn float_to_decimal_common<T>(fmt: &mut Formatter, num: &T, negative_zero: bool) -> Result
     where T: flt2dec::DecodableFloat
 {
-    let force_sign = fmt.flags & (1 << (FlagV1::SignPlus as u32)) != 0;
+    let force_sign = fmt.sign_plus();
     let sign = match (force_sign, negative_zero) {
         (false, false) => flt2dec::Sign::Minus,
         (false, true)  => flt2dec::Sign::MinusRaw,
@@ -1434,7 +1456,7 @@ fn float_to_decimal_common<T>(fmt: &mut Formatter, num: &T, negative_zero: bool)
 fn float_to_exponential_common<T>(fmt: &mut Formatter, num: &T, upper: bool) -> Result
     where T: flt2dec::DecodableFloat
 {
-    let force_sign = fmt.flags & (1 << (FlagV1::SignPlus as u32)) != 0;
+    let force_sign = fmt.sign_plus();
     let sign = match force_sign {
         false => flt2dec::Sign::Minus,
         true  => flt2dec::Sign::MinusPlus,
index 48d003c2cffbab672cced53cab0eff87b4fd0e58..193b8d6d620de46dcd17c85e5bc0d80e81fb5acf 100644 (file)
@@ -434,6 +434,11 @@ pub fn replace<T>(dest: &mut T, mut src: T) -> T {
 /// While this does call the argument's implementation of `Drop`, it will not
 /// release any borrows, as borrows are based on lexical scope.
 ///
+/// This effectively does nothing for
+/// [types which implement `Copy`](../../book/ownership.html#copy-types),
+/// e.g. integers. Such values are copied and _then_ moved into the function,
+/// so the value persists after this function call.
+///
 /// # Examples
 ///
 /// Basic usage:
@@ -486,6 +491,21 @@ pub fn replace<T>(dest: &mut T, mut src: T) -> T {
 /// let borrow = x.borrow();
 /// println!("{}", *borrow);
 /// ```
+///
+/// Integers and other types implementing `Copy` are unaffected by `drop()`
+///
+/// ```
+/// #[derive(Copy, Clone)]
+/// struct Foo(u8);
+///
+/// let x = 1;
+/// let y = Foo(2);
+/// drop(x); // a copy of `x` is moved and dropped
+/// drop(y); // a copy of `y` is moved and dropped
+///
+/// println!("x: {}, y: {}", x, y.0); // still available
+/// ```
+///
 #[inline]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn drop<T>(_x: T) { }
index 350ade22707caac1cafe384ea649ad6737bc624e..582c091091fb2ac800de643d52936b48bb97b7c4 100644 (file)
@@ -1628,7 +1628,7 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
 /// impl<T> Deref for DerefExample<T> {
 ///     type Target = T;
 ///
-///     fn deref<'a>(&'a self) -> &'a T {
+///     fn deref(&self) -> &T {
 ///         &self.value
 ///     }
 /// }
index 5518bacb019e880abf82222582875bfe8f66d516..a4ccc975d56bc871f41ebc77a35a852644177034 100644 (file)
@@ -1410,7 +1410,7 @@ impl<'a, T> ExactSizeIterator for ChunksMut<'a, T> {}
 // Free functions
 //
 
-/// Converts a pointer to A into a slice of length 1 (without copying).
+/// Converts a reference to A into a slice of length 1 (without copying).
 #[unstable(feature = "ref_slice", issue = "27774")]
 pub fn ref_slice<A>(s: &A) -> &[A] {
     unsafe {
@@ -1418,7 +1418,7 @@ pub fn ref_slice<A>(s: &A) -> &[A] {
     }
 }
 
-/// Converts a pointer to A into a slice of length 1 (without copying).
+/// Converts a reference to A into a slice of length 1 (without copying).
 #[unstable(feature = "ref_slice", issue = "27774")]
 pub fn mut_ref_slice<A>(s: &mut A) -> &mut [A] {
     unsafe {
index 69ebcb1ab7e14928ed96f3f24b43460a5d522343..3c7f1b3688398fd64f904fd55d620de37fbe9e65 100644 (file)
@@ -115,8 +115,8 @@ impl Utf8Error {
     /// Returns the index in the given string up to which valid UTF-8 was
     /// verified.
     ///
-    /// Starting at the index provided, but not necessarily at it precisely, an
-    /// invalid UTF-8 encoding sequence was found.
+    /// It is the maximum index such that `from_utf8(input[..index])`
+    /// would return `Some(_)`.
     #[unstable(feature = "utf8_error", reason = "method just added",
                issue = "27734")]
     pub fn valid_up_to(&self) -> usize { self.valid_up_to }
@@ -729,15 +729,19 @@ fn next_back(&mut self) -> Option<&'a str>
 
 impl<'a, P: Pattern<'a>> MatchIndicesInternal<'a, P> {
     #[inline]
-    fn next(&mut self) -> Option<(usize, usize)> {
-        self.0.next_match()
+    fn next(&mut self) -> Option<(usize, &'a str)> {
+        self.0.next_match().map(|(start, end)| unsafe {
+            (start, self.0.haystack().slice_unchecked(start, end))
+        })
     }
 
     #[inline]
-    fn next_back(&mut self) -> Option<(usize, usize)>
+    fn next_back(&mut self) -> Option<(usize, &'a str)>
         where P::Searcher: ReverseSearcher<'a>
     {
-        self.0.next_match_back()
+        self.0.next_match_back().map(|(start, end)| unsafe {
+            (start, self.0.haystack().slice_unchecked(start, end))
+        })
     }
 }
 
@@ -753,7 +757,7 @@ fn next_back(&mut self) -> Option<(usize, usize)>
                    reason = "type may be removed or have its iterator impl changed",
                    issue = "27743")]
     internal:
-        MatchIndicesInternal yielding ((usize, usize));
+        MatchIndicesInternal yielding ((usize, &'a str));
     delegate double ended;
 }
 
index 2ee69543c3cf3e34367f6079a1f1abb1bd518885..f75851506c279959b4a19a50ba3698e4bffbbbfd 100644 (file)
@@ -24,6 +24,7 @@
        html_playground_url = "https://play.rust-lang.org/",
        issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/")]
 #![cfg_attr(test, feature(test))]
+#![feature(cfg_target_vendor)]
 
 //! Bindings for the C standard library and other platform libraries
 //!
 
 // On NaCl, these libraries are static. Thus it would be a Bad Idea to link them
 // in when creating a test crate.
-#[cfg(not(any(windows, target_env = "musl", all(target_os = "nacl", test))))]
+#[cfg(not(any(windows,
+              target_env = "musl",
+              all(target_os = "nacl", test),
+              all(target_os = "netbsd", target_vendor = "rumprun"))))]
 #[link(name = "c")]
 #[link(name = "m")]
 extern {}
index 8a879815980361d2e99dcf2ce85f80f55f918877..9acd13f0a043906cc9e14e2e8a700705e00085e9 100644 (file)
@@ -482,7 +482,7 @@ pub fn read_exported_macros(&mut self, item: &ast::Item) -> Vec<ast::MacroDef> {
                 let span = mk_sp(lo, p.last_span.hi);
                 p.abort_if_errors();
                 macros.push(ast::MacroDef {
-                    ident: name.ident(),
+                    ident: ast::Ident::with_empty_ctxt(name),
                     attrs: attrs,
                     id: ast::DUMMY_NODE_ID,
                     span: span,
index b19c0f2ecc5d2f9f490aba6062fd189243102114..8addc06c8840db570a63db993846f2ecd619d9a8 100644 (file)
@@ -520,9 +520,9 @@ fn encode_info_for_mod(ecx: &EncodeContext,
         });
 
         if let hir::ItemImpl(..) = item.node {
-            let (ident, did) = (item.name, item.id);
+            let (name, did) = (item.name, item.id);
             debug!("(encoding info for module) ... encoding impl {} ({}/{})",
-                   ident,
+                   name,
                    did, ecx.tcx.map.node_to_string(did));
 
             rbml_w.wr_tagged_u64(tag_mod_impl, def_to_u64(DefId::local(did)));
index 7856890724cb65c7d01c1ca1e5be3a554f76b7d4..abc0429e7d29784ad21333cd194f8fe6d1fde7ca 100644 (file)
@@ -184,8 +184,8 @@ fn parse_bound_region(&mut self) -> ty::BoundRegion {
             }
             '[' => {
                 let def = self.parse_def(RegionParameter);
-                let ident = token::str_to_ident(&self.parse_str(']'));
-                ty::BrNamed(def, ident.name)
+                let name = token::intern(&self.parse_str(']'));
+                ty::BrNamed(def, name)
             }
             'f' => {
                 let id = self.parse_u32();
@@ -219,12 +219,12 @@ pub fn parse_region(&mut self) -> ty::Region {
                 assert_eq!(self.next(), '|');
                 let index = self.parse_u32();
                 assert_eq!(self.next(), '|');
-                let nm = token::str_to_ident(&self.parse_str(']'));
+                let name = token::intern(&self.parse_str(']'));
                 ty::ReEarlyBound(ty::EarlyBoundRegion {
                     param_id: node_id,
                     space: space,
                     index: index,
-                    name: nm.name
+                    name: name
                 })
             }
             'f' => {
@@ -598,7 +598,7 @@ fn parse_projection_predicate(&mut self) -> ty::ProjectionPredicate<'tcx> {
         ty::ProjectionPredicate {
             projection_ty: ty::ProjectionTy {
                 trait_ref: self.parse_trait_ref(),
-                item_name: token::str_to_ident(&self.parse_str('|')).name,
+                item_name: token::intern(&self.parse_str('|')),
             },
             ty: self.parse_ty(),
         }
index cc69d0789f82b4ccd8be52c6d003a221e946f7e9..3b04dc3fb9b1a91399919b2c20918a6c736f3574 100644 (file)
@@ -284,7 +284,7 @@ fn expr(&mut self, expr: &hir::Expr, pred: CFGIndex) -> CFGIndex {
             }
 
             hir::ExprBreak(label) => {
-                let loop_scope = self.find_scope(expr, label.map(|l| l.node));
+                let loop_scope = self.find_scope(expr, label.map(|l| l.node.name));
                 let b = self.add_ast_node(expr.id, &[pred]);
                 self.add_exiting_edge(expr, b,
                                       loop_scope, loop_scope.break_index);
@@ -292,7 +292,7 @@ fn expr(&mut self, expr: &hir::Expr, pred: CFGIndex) -> CFGIndex {
             }
 
             hir::ExprAgain(label) => {
-                let loop_scope = self.find_scope(expr, label.map(|l| l.node));
+                let loop_scope = self.find_scope(expr, label.map(|l| l.node.name));
                 let a = self.add_ast_node(expr.id, &[pred]);
                 self.add_exiting_edge(expr, a,
                                       loop_scope, loop_scope.continue_index);
@@ -585,7 +585,7 @@ fn add_returning_edge(&mut self,
 
     fn find_scope(&self,
                   expr: &hir::Expr,
-                  label: Option<ast::Ident>) -> LoopScope {
+                  label: Option<ast::Name>) -> LoopScope {
         if label.is_none() {
             return *self.loop_scopes.last().unwrap();
         }
index c6ff38d0f093d554211c07c1d91c02c9e88d0fcd..b5901762e30d7974cc06aa67ff35abf4afa80a22 100644 (file)
@@ -709,20 +709,26 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
             if !is_const {
                 v.add_qualif(ConstQualif::NOT_CONST);
                 if v.mode != Mode::Var {
+                    fn span_limited_call_error(tcx: &ty::ctxt, span: Span, s: &str) {
+                        span_err!(tcx.sess, span, E0015, "{}", s);
+                    }
+
                     // FIXME(#24111) Remove this check when const fn stabilizes
                     if let UnstableFeatures::Disallow = v.tcx.sess.opts.unstable_features {
-                        span_err!(v.tcx.sess, e.span, E0015,
-                                  "function calls in {}s are limited to \
-                                   struct and enum constructors", v.msg());
+                        span_limited_call_error(&v.tcx, e.span,
+                                                &format!("function calls in {}s are limited to \
+                                                          struct and enum constructors",
+                                                         v.msg()));
                         v.tcx.sess.span_note(e.span,
                                              "a limited form of compile-time function \
                                               evaluation is available on a nightly \
                                               compiler via `const fn`");
                     } else {
-                        span_err!(v.tcx.sess, e.span, E0015,
-                                  "function calls in {}s are limited to \
-                                   constant functions, \
-                                   struct and enum constructors", v.msg());
+                        span_limited_call_error(&v.tcx, e.span,
+                                                &format!("function calls in {}s are limited \
+                                                          to constant functions, \
+                                                          struct and enum constructors",
+                                                         v.msg()));
                     }
                 }
             }
index 132efc1ff88269eb3e5875faea0ced62478b9722..caedc811842a0757cfc1a82a23e877f75fb3e65c 100644 (file)
@@ -114,7 +114,7 @@ fn pre(&self,
            ps: &mut pprust::State,
            node: pprust::AnnNode) -> io::Result<()> {
         let id = match node {
-            pprust::NodeIdent(_) | pprust::NodeName(_) => 0,
+            pprust::NodeName(_) => 0,
             pprust::NodeExpr(expr) => expr.id,
             pprust::NodeBlock(blk) => blk.id,
             pprust::NodeItem(_) | pprust::NodeSubItem(_) => 0,
index 4b45aedd47640c9dfb69026e5a6572b0af792966..3cfcb52f9030fd6ac152e6f453639a202734b378 100644 (file)
@@ -85,7 +85,7 @@ fn entry_point_type(item: &Item, depth: usize) -> EntryPointType {
                 EntryPointType::Start
             } else if attr::contains_name(&item.attrs, "main") {
                 EntryPointType::MainAttr
-            } else if item.name == "main" {
+            } else if item.name.as_str() == "main" {
                 if depth == 1 {
                     // This is a top-level function so can be 'main'
                     EntryPointType::MainNamed
index fa2856e2f30c3793342c352359a24b5e09ce69ec..802b09a1a65e8394fea9503f912c468bda23cc14 100644 (file)
@@ -1015,12 +1015,12 @@ fn give_suggestion(&self, same_regions: &[SameRegions]) {
             },
             None => None
         };
-        let (fn_decl, generics, unsafety, constness, ident, expl_self, span)
+        let (fn_decl, generics, unsafety, constness, name, expl_self, span)
                                     = node_inner.expect("expect item fn");
         let rebuilder = Rebuilder::new(self.tcx, fn_decl, expl_self,
                                        generics, same_regions, &life_giver);
         let (fn_decl, expl_self, generics) = rebuilder.rebuild();
-        self.give_expl_lifetime_param(&fn_decl, unsafety, constness, ident,
+        self.give_expl_lifetime_param(&fn_decl, unsafety, constness, name,
                                       expl_self.as_ref(), &generics, span);
     }
 }
@@ -1127,7 +1127,7 @@ fn pick_lifetime(&self,
                 names.push(lt_name);
             }
             names.sort();
-            let name = token::str_to_ident(&names[0]).name;
+            let name = token::intern(&names[0]);
             return (name_to_dummy_lifetime(name), Kept);
         }
         return (self.life_giver.give_lifetime(), Fresh);
@@ -1938,8 +1938,7 @@ fn give_lifetime(&self) -> hir::Lifetime {
             let mut s = String::from("'");
             s.push_str(&num_to_string(self.counter.get()));
             if !self.taken.contains(&s) {
-                lifetime = name_to_dummy_lifetime(
-                                    token::str_to_ident(&s[..]).name);
+                lifetime = name_to_dummy_lifetime(token::intern(&s[..]));
                 self.generated.borrow_mut().push(lifetime);
                 break;
             }
index c042aea829b98ce92618eec9a29dfb4bf7fb71d8..b3e287f6d7d5d7cf13e39ac7194dbe006093d130 100644 (file)
@@ -55,7 +55,7 @@ fn def_id_is_transmute(&self, def_id: DefId) -> bool {
             ty::TyBareFn(_, ref bfty) => bfty.abi == RustIntrinsic,
             _ => return false
         };
-        intrinsic && self.tcx.item_name(def_id) == "transmute"
+        intrinsic && self.tcx.item_name(def_id).as_str() == "transmute"
     }
 
     fn check_transmute(&self, span: Span, from: Ty<'tcx>, to: Ty<'tcx>, id: ast::NodeId) {
index 71a2091cc1460b119703a93ccf536190a228459e..f3a3b5369511b6f39f1f1158538a223aca1b5a20 100644 (file)
@@ -383,7 +383,7 @@ fn visit_fn(ir: &mut IrMaps,
                                &*arg.pat,
                                |_bm, arg_id, _x, path1| {
             debug!("adding argument {}", arg_id);
-            let name = path1.node.name;
+            let name = path1.node;
             fn_maps.add_variable(Arg(arg_id, name));
         })
     };
@@ -416,7 +416,7 @@ fn visit_fn(ir: &mut IrMaps,
 fn visit_local(ir: &mut IrMaps, local: &hir::Local) {
     pat_util::pat_bindings(&ir.tcx.def_map, &*local.pat, |_, p_id, sp, path1| {
         debug!("adding local variable {}", p_id);
-        let name = path1.node.name;
+        let name = path1.node;
         ir.add_live_node_for_node(p_id, VarDefNode(sp));
         ir.add_variable(Local(LocalInfo {
           id: p_id,
@@ -431,7 +431,7 @@ fn visit_arm(ir: &mut IrMaps, arm: &hir::Arm) {
         pat_util::pat_bindings(&ir.tcx.def_map, &**pat, |bm, p_id, sp, path1| {
             debug!("adding local variable {} from match with bm {:?}",
                    p_id, bm);
-            let name = path1.node.name;
+            let name = path1.node;
             ir.add_live_node_for_node(p_id, VarDefNode(sp));
             ir.add_variable(Local(LocalInfo {
                 id: p_id,
@@ -688,7 +688,7 @@ fn write_vars<F>(&self,
     }
 
     fn find_loop_scope(&self,
-                       opt_label: Option<ast::Ident>,
+                       opt_label: Option<ast::Name>,
                        id: NodeId,
                        sp: Span)
                        -> NodeId {
@@ -1049,7 +1049,7 @@ fn propagate_through_expr(&mut self, expr: &Expr, succ: LiveNode)
 
           hir::ExprBreak(opt_label) => {
               // Find which label this break jumps to
-              let sc = self.find_loop_scope(opt_label.map(|l| l.node), expr.id, expr.span);
+              let sc = self.find_loop_scope(opt_label.map(|l| l.node.name), expr.id, expr.span);
 
               // Now that we know the label we're going to,
               // look it up in the break loop nodes table
@@ -1063,7 +1063,7 @@ fn propagate_through_expr(&mut self, expr: &Expr, succ: LiveNode)
 
           hir::ExprAgain(opt_label) => {
               // Find which label this expr continues to
-              let sc = self.find_loop_scope(opt_label.map(|l| l.node), expr.id, expr.span);
+              let sc = self.find_loop_scope(opt_label.map(|l| l.node.name), expr.id, expr.span);
 
               // Now that we know the label we're going to,
               // look it up in the continue loop nodes table
@@ -1553,8 +1553,8 @@ fn warn_about_unused_args(&self, decl: &hir::FnDecl, entry_ln: LiveNode) {
                                    |_bm, p_id, sp, path1| {
                 let var = self.variable(p_id, sp);
                 // Ignore unused self.
-                let ident = path1.node;
-                if ident.name != special_idents::self_.name {
+                let name = path1.node;
+                if name != special_idents::self_.name {
                     self.warn_about_unused(sp, p_id, entry_ln, var);
                 }
             })
index 6f55ddfdfd2017dc013a2c20a78d1c469c8aec19..0ffa5d7a5e338620849353c73df08bb178c75c08 100644 (file)
@@ -16,9 +16,9 @@
 use syntax::ast;
 use rustc_front::hir;
 use rustc_front::util::walk_pat;
-use syntax::codemap::{Span, Spanned, DUMMY_SP};
+use syntax::codemap::{respan, Span, Spanned, DUMMY_SP};
 
-pub type PatIdMap = FnvHashMap<ast::Ident, ast::NodeId>;
+pub type PatIdMap = FnvHashMap<ast::Name, ast::NodeId>;
 
 // This is used because same-named variables in alternative patterns need to
 // use the NodeId of their namesake in the first pattern.
@@ -109,12 +109,26 @@ pub fn pat_is_binding_or_wild(dm: &DefMap, pat: &hir::Pat) -> bool {
 /// Call `it` on every "binding" in a pattern, e.g., on `a` in
 /// `match foo() { Some(a) => (), None => () }`
 pub fn pat_bindings<I>(dm: &DefMap, pat: &hir::Pat, mut it: I) where
+    I: FnMut(hir::BindingMode, ast::NodeId, Span, &Spanned<ast::Name>),
+{
+    walk_pat(pat, |p| {
+        match p.node {
+          hir::PatIdent(binding_mode, ref pth, _) if pat_is_binding(dm, p) => {
+            it(binding_mode, p.id, p.span, &respan(pth.span, pth.node.name));
+          }
+          _ => {}
+        }
+        true
+    });
+}
+
+pub fn pat_bindings_hygienic<I>(dm: &DefMap, pat: &hir::Pat, mut it: I) where
     I: FnMut(hir::BindingMode, ast::NodeId, Span, &Spanned<ast::Ident>),
 {
     walk_pat(pat, |p| {
         match p.node {
           hir::PatIdent(binding_mode, ref pth, _) if pat_is_binding(dm, p) => {
-            it(binding_mode, p.id, p.span, pth);
+            it(binding_mode, p.id, p.span, &respan(pth.span, pth.node));
           }
           _ => {}
         }
@@ -182,10 +196,10 @@ pub fn pat_contains_bindings_or_wild(dm: &DefMap, pat: &hir::Pat) -> bool {
     contains_bindings
 }
 
-pub fn simple_identifier<'a>(pat: &'a hir::Pat) -> Option<&'a ast::Ident> {
+pub fn simple_name<'a>(pat: &'a hir::Pat) -> Option<ast::Name> {
     match pat.node {
         hir::PatIdent(hir::BindByValue(_), ref path1, None) => {
-            Some(&path1.node)
+            Some(path1.node.name)
         }
         _ => {
             None
@@ -197,7 +211,7 @@ pub fn def_to_path(tcx: &ty::ctxt, id: DefId) -> hir::Path {
     tcx.with_path(id, |path| hir::Path {
         global: false,
         segments: path.last().map(|elem| hir::PathSegment {
-            identifier: ast::Ident::new(elem.name()),
+            identifier: ast::Ident::with_empty_ctxt(elem.name()),
             parameters: hir::PathParameters::none(),
         }).into_iter().collect(),
         span: DUMMY_SP,
index c21999c2dbc322d0db4cafa700b2655ad4defe54..6fbdd90217658da22026411a8a14a6a95589dedb 100644 (file)
@@ -73,7 +73,7 @@ struct LifetimeContext<'a> {
     trait_ref_hack: bool,
 
     // List of labels in the function/method currently under analysis.
-    labels_in_fn: Vec<(ast::Ident, Span)>,
+    labels_in_fn: Vec<(ast::Name, Span)>,
 }
 
 enum ScopeChain<'a> {
@@ -381,7 +381,7 @@ fn extract_labels<'v, 'a>(ctxt: &mut LifetimeContext<'a>, b: &'v hir::Block) {
     struct GatherLabels<'a> {
         sess: &'a Session,
         scope: Scope<'a>,
-        labels_in_fn: &'a mut Vec<(ast::Ident, Span)>,
+        labels_in_fn: &'a mut Vec<(ast::Name, Span)>,
     }
 
     let mut gather = GatherLabels {
@@ -403,9 +403,9 @@ fn visit_expr(&mut self, ex: &'v hir::Expr) {
             if let Some(label) = expression_label(ex) {
                 for &(prior, prior_span) in &self.labels_in_fn[..] {
                     // FIXME (#24278): non-hygienic comparison
-                    if label.name == prior.name {
+                    if label == prior {
                         signal_shadowing_problem(self.sess,
-                                                 label.name,
+                                                 label,
                                                  original_label(prior_span),
                                                  shadower_label(ex.span));
                     }
@@ -426,17 +426,17 @@ fn visit_item(&mut self, _: &hir::Item) {
         }
     }
 
-    fn expression_label(ex: &hir::Expr) -> Option<ast::Ident> {
+    fn expression_label(ex: &hir::Expr) -> Option<ast::Name> {
         match ex.node {
             hir::ExprWhile(_, _, Some(label)) |
-            hir::ExprLoop(_, Some(label)) => Some(label),
+            hir::ExprLoop(_, Some(label)) => Some(label.name),
             _ => None,
         }
     }
 
     fn check_if_label_shadows_lifetime<'a>(sess: &'a Session,
                                            mut scope: Scope<'a>,
-                                           label: ast::Ident,
+                                           label: ast::Name,
                                            label_span: Span) {
         loop {
             match *scope {
@@ -447,10 +447,10 @@ fn check_if_label_shadows_lifetime<'a>(sess: &'a Session,
                 LateScope(lifetimes, s) => {
                     for lifetime_def in lifetimes {
                         // FIXME (#24278): non-hygienic comparison
-                        if label.name == lifetime_def.lifetime.name {
+                        if label == lifetime_def.lifetime.name {
                             signal_shadowing_problem(
                                 sess,
-                                label.name,
+                                label,
                                 original_lifetime(&lifetime_def.lifetime),
                                 shadower_label(label_span));
                             return;
@@ -703,7 +703,7 @@ fn check_lifetime_def_for_shadowing(&self,
     {
         for &(label, label_span) in &self.labels_in_fn {
             // FIXME (#24278): non-hygienic comparison
-            if lifetime.name == label.name {
+            if lifetime.name == label {
                 signal_shadowing_problem(self.sess,
                                          lifetime.name,
                                          original_label(label_span),
index bc83f42b90860d734f4bfb34bcb632407f86cd81..596686f32cbc33a8282fd8352e484f869af05ac5 100644 (file)
@@ -336,7 +336,7 @@ fn visit_item(&mut self, item: &hir::Item) {
         // When compiling with --test we don't enforce stability on the
         // compiler-generated test module, demarcated with `DUMMY_SP` plus the
         // name `__test`
-        if item.span == DUMMY_SP && item.name == "__test" { return }
+        if item.span == DUMMY_SP && item.name.as_str() == "__test" { return }
 
         check_item(self.tcx, item, true,
                    &mut |id, sp, stab| self.check(id, sp, stab));
index 5248cb7f30e97fed681dd1285ab9e6226529e882..25e6036e85ab47496685aa24c07d617ce99d3132 100644 (file)
@@ -248,9 +248,12 @@ pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
                     }
 
                     ty::Predicate::ObjectSafe(trait_def_id) => {
+                        let violations = object_safety_violations(
+                            infcx.tcx, trait_def_id);
                         report_object_safety_error(infcx.tcx,
                                                    obligation.cause.span,
                                                    trait_def_id,
+                                                   violations,
                                                    is_warning);
                         note_obligation_cause(infcx, obligation);
                     }
@@ -286,7 +289,9 @@ pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
         }
 
         TraitNotObjectSafe(did) => {
-            report_object_safety_error(infcx.tcx, obligation.cause.span, did, is_warning);
+            let violations = object_safety_violations(infcx.tcx, did);
+            report_object_safety_error(infcx.tcx, obligation.cause.span, did,
+                                       violations, is_warning);
             note_obligation_cause(infcx, obligation);
         }
     }
@@ -295,6 +300,7 @@ pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
 pub fn report_object_safety_error<'tcx>(tcx: &ty::ctxt<'tcx>,
                                         span: Span,
                                         trait_def_id: DefId,
+                                        violations: Vec<ObjectSafetyViolation>,
                                         is_warning: bool)
 {
     span_err_or_warn!(
@@ -302,7 +308,7 @@ pub fn report_object_safety_error<'tcx>(tcx: &ty::ctxt<'tcx>,
         "the trait `{}` cannot be made into an object",
         tcx.item_path_str(trait_def_id));
 
-    for violation in object_safety_violations(tcx, trait_def_id) {
+    for violation in violations {
         match violation {
             ObjectSafetyViolation::SizedSelf => {
                 tcx.sess.fileline_note(
index b0d4d92e8e1b28650dbeaf580e13d5a5ef7a7a7f..5dc6f9454a881505ffcf541822237f084ed02891 100644 (file)
@@ -37,6 +37,7 @@
 pub use self::project::normalize;
 pub use self::project::Normalized;
 pub use self::object_safety::is_object_safe;
+pub use self::object_safety::astconv_object_safety_violations;
 pub use self::object_safety::object_safety_violations;
 pub use self::object_safety::ObjectSafetyViolation;
 pub use self::object_safety::MethodViolationCode;
index 3a2602cd5b448d1940e5794241af13a022ebf082..1762233b0449a1634679ba05236ca60dd900c035 100644 (file)
@@ -76,6 +76,27 @@ pub fn is_object_safe<'tcx>(tcx: &ty::ctxt<'tcx>,
     result
 }
 
+/// Returns the object safety violations that affect
+/// astconv - currently, Self in supertraits. This is needed
+/// because `object_safety_violations` can't be used during
+/// type collection.
+pub fn astconv_object_safety_violations<'tcx>(tcx: &ty::ctxt<'tcx>,
+                                              trait_def_id: DefId)
+                                              -> Vec<ObjectSafetyViolation<'tcx>>
+{
+    let mut violations = vec![];
+
+    if supertraits_reference_self(tcx, trait_def_id) {
+        violations.push(ObjectSafetyViolation::SupertraitSelf);
+    }
+
+    debug!("object_safety_violations_for_trait(trait_def_id={:?}) = {:?}",
+           trait_def_id,
+           violations);
+
+    violations
+}
+
 pub fn object_safety_violations<'tcx>(tcx: &ty::ctxt<'tcx>,
                                       trait_def_id: DefId)
                                       -> Vec<ObjectSafetyViolation<'tcx>>
@@ -118,9 +139,9 @@ fn object_safety_violations_for_trait<'tcx>(tcx: &ty::ctxt<'tcx>,
     violations
 }
 
-fn supertraits_reference_self<'tcx>(tcx: &ty::ctxt<'tcx>,
-                                    trait_def_id: DefId)
-                                    -> bool
+pub fn supertraits_reference_self<'tcx>(tcx: &ty::ctxt<'tcx>,
+                                        trait_def_id: DefId)
+                                        -> bool
 {
     let trait_def = tcx.lookup_trait_def(trait_def_id);
     let trait_ref = trait_def.trait_ref.clone();
index 30f43baabba2fa57486f4c26376b2ddd59165cda..dcc4ca137ead99fd72bc3e09088e63cc9408af90 100644 (file)
@@ -617,6 +617,7 @@ pub fn default_configuration(sess: &Session) -> ast::CrateConfig {
     let wordsz = &sess.target.target.target_pointer_width;
     let os = &sess.target.target.target_os;
     let env = &sess.target.target.target_env;
+    let vendor = &sess.target.target.target_vendor;
 
     let fam = match sess.target.target.options.is_like_windows {
         true  => InternedString::new("windows"),
@@ -632,6 +633,7 @@ pub fn default_configuration(sess: &Session) -> ast::CrateConfig {
          mk(InternedString::new("target_endian"), intern(end)),
          mk(InternedString::new("target_pointer_width"), intern(wordsz)),
          mk(InternedString::new("target_env"), intern(env)),
+         mk(InternedString::new("target_vendor"), intern(vendor)),
     ];
     if sess.opts.debug_assertions {
         ret.push(attr::mk_word_item(InternedString::new("debug_assertions")));
index ff732ee7b9d80c60099da78a70c3c65adec28c11..9d1674b74d1fce197aeced5325f59a4c9b64cafd 100644 (file)
@@ -331,10 +331,10 @@ fn split_msg_into_multilines(msg: &str) -> Option<String> {
     let first = msg.match_indices("expected").filter(|s| {
         s.0 > 0 && (msg.char_at_reverse(s.0) == ' ' ||
                     msg.char_at_reverse(s.0) == '(')
-    }).map(|(a, b)| (a - 1, b));
+    }).map(|(a, b)| (a - 1, a + b.len()));
     let second = msg.match_indices("found").filter(|s| {
         msg.char_at_reverse(s.0) == ' '
-    }).map(|(a, b)| (a - 1, b));
+    }).map(|(a, b)| (a - 1, a + b.len()));
 
     let mut new_msg = String::new();
     let mut head = 0;
index e87cb43128d24fc1efffd5d53c16b3673fc91d95..e1242560e62c76b167568aaf797b7a45bd3d6500 100644 (file)
@@ -19,6 +19,7 @@ pub fn target() -> Target {
         arch: "aarch64".to_string(),
         target_os: "ios".to_string(),
         target_env: "".to_string(),
+        target_vendor: "apple".to_string(),
         options: TargetOptions {
             features: "+neon,+fp-armv8,+cyclone".to_string(),
             eliminate_frame_pointer: false,
index 8c350e8b28750ef3ec9f04682a257de05b715468..c6901a4cc4270942b16a7a194241732389cac70e 100644 (file)
@@ -18,6 +18,7 @@ pub fn target() -> Target {
         arch: "aarch64".to_string(),
         target_os: "android".to_string(),
         target_env: "".to_string(),
+        target_vendor: "unknown".to_string(),
         options: super::android_base::opts(),
     }
 }
index ed79caf486942158402e23ce2d47ce527b923ab8..51abab6609a86c52997e73b576723a21a4204833 100644 (file)
@@ -19,6 +19,7 @@ pub fn target() -> Target {
         target_env: "gnu".to_string(),
         arch: "aarch64".to_string(),
         target_os: "linux".to_string(),
+        target_vendor: "unknown".to_string(),
         options: base,
     }
 }
index 0770fe70e8a5780b69c6e28739fca356d9def1fa..732f1a353a8bd719c1f363e5fec3c02c9837765d 100644 (file)
@@ -21,6 +21,7 @@ pub fn target() -> Target {
         arch: "arm".to_string(),
         target_os: "android".to_string(),
         target_env: "gnu".to_string(),
+        target_vendor: "unknown".to_string(),
         options: base,
     }
 }
index 084f989277f317024220d1290a180deda2339d2d..7c35b43fd4b7544ea442bbed0273daffb491af97 100644 (file)
@@ -19,6 +19,7 @@ pub fn target() -> Target {
         arch: "arm".to_string(),
         target_os: "linux".to_string(),
         target_env: "gnueabi".to_string(),
+        target_vendor: "unknown".to_string(),
 
         options: TargetOptions {
             features: "+v6".to_string(),
index 08f1aa5ade848c6c9d6503c44d463b3b61f0a9db..a99ec45996c2e833c2b14505f4471581aa7b2532 100644 (file)
@@ -19,6 +19,7 @@ pub fn target() -> Target {
         arch: "arm".to_string(),
         target_os: "linux".to_string(),
         target_env: "gnueabihf".to_string(),
+        target_vendor: "unknown".to_string(),
 
         options: TargetOptions {
             features: "+v6,+vfp2".to_string(),
index a6d649ea162f93be4cab857075cf4af188055781..d30648002912e6831cf8bd4ff36f7e8bc33e8b95 100644 (file)
@@ -19,6 +19,7 @@ pub fn target() -> Target {
         arch: "arm".to_string(),
         target_os: "ios".to_string(),
         target_env: "".to_string(),
+        target_vendor: "apple".to_string(),
         options: TargetOptions {
             features: "+v7,+vfp3,+neon".to_string(),
             .. opts(Arch::Armv7)
index 264385512added148a0519249939a5bcfee2711e..66ec6efca0e6700a925f60a830b0631eab6cb549 100644 (file)
@@ -19,6 +19,7 @@ pub fn target() -> Target {
         arch: "arm".to_string(),
         target_os: "ios".to_string(),
         target_env: "".to_string(),
+        target_vendor: "apple".to_string(),
         options: TargetOptions {
             features: "+v7,+vfp4,+neon".to_string(),
             .. opts(Arch::Armv7s)
index d17aa915461df369a192a5bf13c88f303cea204a..52b5901192c657ae436d6bd9d46a2d86c1b9645d 100644 (file)
@@ -19,6 +19,7 @@ pub fn target() -> Target {
         arch: "x86".to_string(),
         target_os: "ios".to_string(),
         target_env: "".to_string(),
+        target_vendor: "apple".to_string(),
         options: opts(Arch::I386)
     }
 }
index 9fe15e76942863c7ada3bf69aa878905f8e3ccb2..98f4654ecab41ab9390d71e2443ed6b8dcf2e6c7 100644 (file)
@@ -22,6 +22,7 @@ pub fn target() -> Target {
         arch: "x86".to_string(),
         target_os: "macos".to_string(),
         target_env: "".to_string(),
+        target_vendor: "apple".to_string(),
         options: base,
     }
 }
index 708e7756b94bdda2b385b719f1ccf2f8068b3aa0..f548fdad3cbed9d81fd6f6a76007ea3d838ccccb 100644 (file)
@@ -21,6 +21,7 @@ pub fn target() -> Target {
         arch: "x86".to_string(),
         target_os: "android".to_string(),
         target_env: "gnu".to_string(),
+        target_vendor: "unknown".to_string(),
         options: base,
     }
 }
index ae1b4d450a58e93792f636f42e9ac966720a0308..c825f6043d27b3adf4fa7c40088eb283ec7acb3e 100644 (file)
@@ -30,6 +30,7 @@ pub fn target() -> Target {
         arch: "x86".to_string(),
         target_os: "windows".to_string(),
         target_env: "gnu".to_string(),
+        target_vendor: "pc".to_string(),
         options: options,
     }
 }
index d8c1c79b47fcd9ce727ac1b4be3aed94101631e2..96b2d37ab2088135a374386130487e12905b1533 100644 (file)
@@ -21,6 +21,7 @@ pub fn target() -> Target {
         arch: "x86".to_string(),
         target_os: "windows".to_string(),
         target_env: "msvc".to_string(),
+        target_vendor: "pc".to_string(),
         options: base,
     }
 }
index f2478e6d0dbfeb37cfe8765013a60a5aafc2d2c7..32a15b9f2d4d10c0ce3ab290a98ce1543197f17f 100644 (file)
@@ -22,6 +22,7 @@ pub fn target() -> Target {
         arch: "x86".to_string(),
         target_os: "dragonfly".to_string(),
         target_env: "".to_string(),
+        target_vendor: "unknown".to_string(),
         options: base,
     }
 }
index 6b2d9b5053c4ae6ebff10b62b0ecbd16981ef790..812ba11cd796b3ae39a7c8511c7f64f1aaaef2fc 100644 (file)
@@ -22,6 +22,7 @@ pub fn target() -> Target {
         arch: "x86".to_string(),
         target_os: "freebsd".to_string(),
         target_env: "".to_string(),
+        target_vendor: "unknown".to_string(),
         options: base,
     }
 }
index 074d5b2b9ed228d5be4995a2f78c5e0d55b77b18..ac2af0c64fd6ad2b1239860af8803b38f277022c 100644 (file)
@@ -22,6 +22,7 @@ pub fn target() -> Target {
         arch: "x86".to_string(),
         target_os: "linux".to_string(),
         target_env: "gnu".to_string(),
+        target_vendor: "unknown".to_string(),
         options: base,
     }
 }
index 3f3da6d6c9136aa86448c17ead7d1d761b37b021..357499c48ec7a5d9ae56c7b698b99aee5b4b3086 100644 (file)
@@ -18,6 +18,7 @@ pub fn target() -> Target {
         arch: "mips".to_string(),
         target_os: "linux".to_string(),
         target_env: "gnu".to_string(),
+        target_vendor: "unknown".to_string(),
         options: super::linux_base::opts()
     }
 }
index d7f286c8aa4085beda3357ee7c6cbb9b062a2785..3d0088add0d537d5d6703a7f920206e493bedf66 100644 (file)
@@ -18,6 +18,7 @@ pub fn target() -> Target {
         arch: "mips".to_string(),
         target_os: "linux".to_string(),
         target_env: "gnu".to_string(),
+        target_vendor: "unknown".to_string(),
 
         options: super::linux_base::opts()
     }
index e7c1c3fb258adad6a490e587295d0fbbc699beca..be404fc97ce080edb7b280138ae6602cae835c83 100644 (file)
@@ -77,6 +77,8 @@ pub struct Target {
     pub target_os: String,
     /// Environment name to use for conditional compilation.
     pub target_env: String,
+    /// Vendor name to use for conditional compilation.
+    pub target_vendor: String,
     /// Architecture to use for ABI considerations. Valid options: "x86", "x86_64", "arm",
     /// "aarch64", "mips", and "powerpc". "mips" includes "mipsel".
     pub arch: String,
@@ -260,14 +262,20 @@ pub fn from_json(obj: Json) -> Target {
             }
         };
 
+        let get_opt_field = |name: &str, default: &str| {
+            obj.find(name).and_then(|s| s.as_string())
+               .map(|s| s.to_string())
+               .unwrap_or(default.to_string())
+        };
+
         let mut base = Target {
             llvm_target: get_req_field("llvm-target"),
             target_endian: get_req_field("target-endian"),
             target_pointer_width: get_req_field("target-pointer-width"),
             arch: get_req_field("arch"),
             target_os: get_req_field("os"),
-            target_env: obj.find("env").and_then(|s| s.as_string())
-                           .map(|s| s.to_string()).unwrap_or(String::new()),
+            target_env: get_opt_field("env", ""),
+            target_vendor: get_opt_field("vendor", "unknown"),
             options: Default::default(),
         };
 
@@ -403,6 +411,7 @@ macro_rules! load_specific {
             x86_64_unknown_bitrig,
             x86_64_unknown_openbsd,
             x86_64_unknown_netbsd,
+            x86_64_rumprun_netbsd,
 
             x86_64_apple_darwin,
             i686_apple_darwin,
index 896824eba0e56b627bbb4ce14ae0caf6f745d11d..6664abf5458b715253ba2177079de42e9bcd6358 100644 (file)
@@ -21,6 +21,7 @@ pub fn target() -> Target {
         arch: "powerpc".to_string(),
         target_os: "linux".to_string(),
         target_env: "gnu".to_string(),
+        target_vendor: "unknown".to_string(),
         options: base,
     }
 }
index ef40c2f2006e1628086bdb2906f30d6748b6118b..3e19e1482909e2b85e317755c2b5f5e70e71f2f5 100644 (file)
@@ -23,6 +23,7 @@ pub fn target() -> Target {
         arch: "x86_64".to_string(),
         target_os: "macos".to_string(),
         target_env: "".to_string(),
+        target_vendor: "apple".to_string(),
         options: base,
     }
 }
index 7aca8c554dab63dd27c6d9b980dc1a1f3b464ceb..63234c0baee8cf14055b360dee9a57b81d1e0afb 100644 (file)
@@ -19,6 +19,7 @@ pub fn target() -> Target {
         arch: "x86_64".to_string(),
         target_os: "ios".to_string(),
         target_env: "".to_string(),
+        target_vendor: "apple".to_string(),
         options: opts(Arch::X86_64)
     }
 }
index aef1d7471b85b1d415f2d723dcb66bf11b2d2bf0..2bd363e46bb1cf7c711880ced70b8e8b44c514e2 100644 (file)
@@ -25,6 +25,7 @@ pub fn target() -> Target {
         arch: "x86_64".to_string(),
         target_os: "windows".to_string(),
         target_env: "gnu".to_string(),
+        target_vendor: "pc".to_string(),
         options: base,
     }
 }
index 85756db96061fc81f8b1fa227f33ab37e207c863..5030a1ff4483baaf84ccbb7c6b8af9c0ab8f505f 100644 (file)
@@ -22,6 +22,7 @@ pub fn target() -> Target {
         arch: "x86_64".to_string(),
         target_os: "windows".to_string(),
         target_env: "msvc".to_string(),
+        target_vendor: "pc".to_string(),
         options: base,
     }
 }
diff --git a/src/librustc_back/target/x86_64_rumprun_netbsd.rs b/src/librustc_back/target/x86_64_rumprun_netbsd.rs
new file mode 100644 (file)
index 0000000..d63ad53
--- /dev/null
@@ -0,0 +1,35 @@
+// Copyright 2014-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.
+
+use target::Target;
+
+pub fn target() -> Target {
+    let mut base = super::netbsd_base::opts();
+    base.pre_link_args.push("-m64".to_string());
+    base.linker = "x86_64-rumprun-netbsd-gcc".to_string();
+    base.ar = "x86_64-rumprun-netbsd-ar".to_string();
+
+    base.dynamic_linking = false;
+    base.has_rpath = false;
+    base.position_independent_executables = false;
+    base.disable_redzone = true;
+    base.no_default_libraries = false;
+
+    Target {
+        llvm_target: "x86_64-rumprun-netbsd".to_string(),
+        target_endian: "little".to_string(),
+        target_pointer_width: "64".to_string(),
+        arch: "x86_64".to_string(),
+        target_os: "netbsd".to_string(),
+        target_env: "".to_string(),
+        target_vendor: "rumprun".to_string(),
+        options: base,
+    }
+}
index 6ecf885aba38eff9cf1f1e9441001c32ccf3a3ca..04456b1b2714a495a786a7d3ac3270425cad6e7a 100644 (file)
@@ -21,6 +21,7 @@ pub fn target() -> Target {
         arch: "x86_64".to_string(),
         target_os: "bitrig".to_string(),
         target_env: "".to_string(),
+        target_vendor: "unknown".to_string(),
         options: base,
     }
 }
index f0e665967ec6f3fd2b77304ce1ec28f584b79543..62654176aa486738201c7b3b7fab3d0e62307d87 100644 (file)
@@ -22,6 +22,7 @@ pub fn target() -> Target {
         arch: "x86_64".to_string(),
         target_os: "dragonfly".to_string(),
         target_env: "".to_string(),
+        target_vendor: "unknown".to_string(),
         options: base,
     }
 }
index f742ebfde1d2c314fdf2e28e54c72d38e76f8613..888b7f58bffca9264418b961cfb6dcd5d56ab1c0 100644 (file)
@@ -22,6 +22,7 @@ pub fn target() -> Target {
         arch: "x86_64".to_string(),
         target_os: "freebsd".to_string(),
         target_env: "".to_string(),
+        target_vendor: "unknown".to_string(),
         options: base,
     }
 }
index 4749e481fd85534724ff1bba722cd73ffc9e557f..e3ccd9c4c7e7dd8ae7c9e68e316b64c3de6bdee9 100644 (file)
@@ -22,6 +22,7 @@ pub fn target() -> Target {
         arch: "x86_64".to_string(),
         target_os: "linux".to_string(),
         target_env: "gnu".to_string(),
+        target_vendor: "unknown".to_string(),
         options: base,
     }
 }
index c66192c28b13d7ce1ef2ddddd1f03dd891ba679c..a5ac78cd5b6081850a008bb98acbd5dd5cb4ad0b 100644 (file)
@@ -76,6 +76,7 @@ pub fn target() -> Target {
         arch: "x86_64".to_string(),
         target_os: "linux".to_string(),
         target_env: "musl".to_string(),
+        target_vendor: "unknown".to_string(),
         options: base,
     }
 }
index e13e58e3a186d163d22cc7a3dfc3c0491dad20c9..4101fabe73480eb518ed67387a298a7592105a5e 100644 (file)
@@ -21,6 +21,7 @@ pub fn target() -> Target {
         arch: "x86_64".to_string(),
         target_os: "netbsd".to_string(),
         target_env: "".to_string(),
+        target_vendor: "unknown".to_string(),
         options: base,
     }
 }
index a404db48b22bb38875769d86e8d82b675e46ccf8..07a1e137b4196b798c8fd50dd16ced5a3529e460 100644 (file)
@@ -21,6 +21,7 @@ pub fn target() -> Target {
         arch: "x86_64".to_string(),
         target_os: "openbsd".to_string(),
         target_env: "".to_string(),
+        target_vendor: "unknown".to_string(),
         options: base,
     }
 }
index 3515b53b00d31f6a1928f496c3c707b101a1afdd..83fac73b7f9dfd86b2232a7dd75fa457c59f13a7 100644 (file)
@@ -99,7 +99,7 @@ pub fn gather_move_from_pat<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
     let pat_span_path_opt = match move_pat.node {
         hir::PatIdent(_, ref path1, _) => {
             Some(MoveSpanAndPath{span: move_pat.span,
-                                 ident: path1.node})
+                                 name: path1.node.name})
         },
         _ => None,
     };
index bbcf51933422ea41b9036e6a5b8215f1c7f2abd6..59f914895ae59e34183a7a7622ccfe4a792d2a51 100644 (file)
@@ -15,7 +15,6 @@
 use std::cell::RefCell;
 use syntax::ast;
 use syntax::codemap;
-use rustc_front::print::pprust;
 use rustc_front::hir;
 
 pub struct MoveErrorCollector<'tcx> {
@@ -57,7 +56,7 @@ pub fn with_move_info(move_from: mc::cmt<'tcx>,
 #[derive(Clone)]
 pub struct MoveSpanAndPath {
     pub span: codemap::Span,
-    pub ident: ast::Ident
+    pub name: ast::Name,
 }
 
 pub struct GroupedMoveErrors<'tcx> {
@@ -73,7 +72,7 @@ fn report_move_errors<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
         let mut is_first_note = true;
         for move_to in &error.move_to_places {
             note_move_destination(bccx, move_to.span,
-                                  &move_to.ident, is_first_note);
+                                  move_to.name, is_first_note);
             is_first_note = false;
         }
     }
@@ -157,9 +156,8 @@ fn report_cannot_move_out_of<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
 
 fn note_move_destination(bccx: &BorrowckCtxt,
                          move_to_span: codemap::Span,
-                         pat_ident: &ast::Ident,
+                         pat_name: ast::Name,
                          is_first_note: bool) {
-    let pat_name = pprust::ident_to_string(pat_ident);
     if is_first_note {
         bccx.span_note(
             move_to_span,
index 75b57341d48dfcc88de5cec39806486c537666ac..f0fa1ff70c6f398dc55581fb712fa082cc60c3ac 100644 (file)
@@ -330,8 +330,7 @@ fn post(&self,
             s: &mut pprust_hir::State,
             node: pprust_hir::AnnNode) -> io::Result<()> {
         match node {
-            pprust_hir::NodeIdent(_) | pprust_hir::NodeName(_) => Ok(()),
-
+            pprust_hir::NodeName(_) => Ok(()),
             pprust_hir::NodeItem(item) => {
                 try!(pp::space(&mut s.s));
                 s.synth_comment(item.id.to_string())
@@ -381,7 +380,7 @@ fn post(&self,
                 try!(pp::space(&mut s.s));
                 // FIXME #16420: this doesn't display the connections
                 // between syntax contexts
-                s.synth_comment(format!("{}#{}", nm, ctxt))
+                s.synth_comment(format!("{}#{}", nm, ctxt.0))
             }
             pprust::NodeName(&ast::Name(nm)) => {
                 try!(pp::space(&mut s.s));
index c2ce7cd701d036756974dda81b6e17aa71b70238..7ae68894f1cb9c89c74efe61416e351a2b834856 100644 (file)
@@ -296,8 +296,8 @@ pub fn noop_fold_meta_items<T: Folder>(meta_items: Vec<P<MetaItem>>, fld: &mut T
 pub fn noop_fold_view_path<T: Folder>(view_path: P<ViewPath>, fld: &mut T) -> P<ViewPath> {
     view_path.map(|Spanned {node, span}| Spanned {
         node: match node {
-            ViewPathSimple(ident, path) => {
-                ViewPathSimple(ident, fld.fold_path(path))
+            ViewPathSimple(name, path) => {
+                ViewPathSimple(name, fld.fold_path(path))
             }
             ViewPathGlob(path) => {
                 ViewPathGlob(fld.fold_path(path))
@@ -520,11 +520,11 @@ pub fn noop_fold_explicit_self_underscore<T: Folder>(es: ExplicitSelf_, fld: &mu
                                                      -> ExplicitSelf_ {
     match es {
         SelfStatic | SelfValue(_) => es,
-        SelfRegion(lifetime, m, ident) => {
-            SelfRegion(fld.fold_opt_lifetime(lifetime), m, ident)
+        SelfRegion(lifetime, m, name) => {
+            SelfRegion(fld.fold_opt_lifetime(lifetime), m, name)
         }
-        SelfExplicit(typ, ident) => {
-            SelfExplicit(fld.fold_ty(typ), ident)
+        SelfExplicit(typ, name) => {
+            SelfExplicit(fld.fold_ty(typ), name)
         }
     }
 }
@@ -1111,10 +1111,10 @@ pub fn noop_fold_expr<T: Folder>(Expr {id, node, span}: Expr, folder: &mut T) ->
                           respan(folder.new_span(name.span),
                                  folder.fold_name(name.node)))
             }
-            ExprTupField(el, ident) => {
+            ExprTupField(el, index) => {
                 ExprTupField(folder.fold_expr(el),
-                             respan(folder.new_span(ident.span),
-                                    folder.fold_usize(ident.node)))
+                             respan(folder.new_span(index.span),
+                                    folder.fold_usize(index.node)))
             }
             ExprIndex(el, er) => {
                 ExprIndex(folder.fold_expr(el), folder.fold_expr(er))
index 077567893079287a12e8a2ca86ae747bd90adc84..49107edb9d3cd3c8953ca11421162f83cab7bd61 100644 (file)
@@ -629,7 +629,6 @@ pub enum Expr_ {
     ///
     /// `if expr { block } else { expr }`
     ExprIf(P<Expr>, P<Block>, Option<P<Expr>>),
-    // FIXME #6993: change to Option<Name> ... or not, if these are hygienic.
     /// A while loop, with an optional label
     ///
     /// `'label: while expr { block }`
@@ -637,7 +636,6 @@ pub enum Expr_ {
     /// Conditionless loop (can be exited with break, continue, or return)
     ///
     /// `'label: loop { block }`
-    // FIXME #6993: change to Option<Name> ... or not, if these are hygienic.
     ExprLoop(P<Block>, Option<Ident>),
     /// A `match` block, with a source that indicates whether or not it is
     /// the result of a desugaring, and if so, which kind.
index e9508009d9d0c712c24f9f0323546edef30c4dd8..36916967fcb3b9c3d4dbb41fb5b4c95cd9dd92fe 100644 (file)
@@ -30,7 +30,6 @@
 use std::io::{self, Write, Read};
 
 pub enum AnnNode<'a> {
-    NodeIdent(&'a ast::Ident),
     NodeName(&'a ast::Name),
     NodeBlock(&'a hir::Block),
     NodeItem(&'a hir::Item),
@@ -264,8 +263,8 @@ pub fn path_to_string(p: &hir::Path) -> String {
     to_string(|s| s.print_path(p, false, 0))
 }
 
-pub fn ident_to_string(id: &ast::Ident) -> String {
-    to_string(|s| s.print_ident(*id))
+pub fn name_to_string(name: ast::Name) -> String {
+    to_string(|s| s.print_name(name))
 }
 
 pub fn fun_to_string(decl: &hir::FnDecl,
@@ -1346,7 +1345,7 @@ pub fn print_expr(&mut self, expr: &hir::Expr) -> io::Result<()> {
             }
             hir::ExprWhile(ref test, ref blk, opt_ident) => {
                 if let Some(ident) = opt_ident {
-                    try!(self.print_ident(ident));
+                    try!(self.print_name(ident.name));
                     try!(self.word_space(":"));
                 }
                 try!(self.head("while"));
@@ -1356,7 +1355,7 @@ pub fn print_expr(&mut self, expr: &hir::Expr) -> io::Result<()> {
             }
             hir::ExprLoop(ref blk, opt_ident) => {
                 if let Some(ident) = opt_ident {
-                    try!(self.print_ident(ident));
+                    try!(self.print_name(ident.name));
                     try!(self.word_space(":"));
                 }
                 try!(self.head("loop"));
@@ -1461,7 +1460,7 @@ pub fn print_expr(&mut self, expr: &hir::Expr) -> io::Result<()> {
                 try!(word(&mut self.s, "break"));
                 try!(space(&mut self.s));
                 if let Some(ident) = opt_ident {
-                    try!(self.print_ident(ident.node));
+                    try!(self.print_name(ident.node.name));
                     try!(space(&mut self.s));
                 }
             }
@@ -1469,7 +1468,7 @@ pub fn print_expr(&mut self, expr: &hir::Expr) -> io::Result<()> {
                 try!(word(&mut self.s, "continue"));
                 try!(space(&mut self.s));
                 if let Some(ident) = opt_ident {
-                    try!(self.print_ident(ident.node));
+                    try!(self.print_name(ident.node.name));
                     try!(space(&mut self.s))
                 }
             }
@@ -1582,11 +1581,6 @@ pub fn print_decl(&mut self, decl: &hir::Decl) -> io::Result<()> {
         }
     }
 
-    pub fn print_ident(&mut self, ident: ast::Ident) -> io::Result<()> {
-        try!(word(&mut self.s, &ident.name.as_str()));
-        self.ann.post(self, NodeIdent(&ident))
-    }
-
     pub fn print_usize(&mut self, i: usize) -> io::Result<()> {
         word(&mut self.s, &i.to_string())
     }
@@ -1620,7 +1614,7 @@ fn print_path(&mut self,
                 try!(word(&mut self.s, "::"))
             }
 
-            try!(self.print_ident(segment.identifier));
+            try!(self.print_name(segment.identifier.name));
 
             try!(self.print_path_parameters(&segment.parameters, colons_before_params));
         }
@@ -1645,7 +1639,7 @@ fn print_qpath(&mut self,
         try!(word(&mut self.s, ">"));
         try!(word(&mut self.s, "::"));
         let item_segment = path.segments.last().unwrap();
-        try!(self.print_ident(item_segment.identifier));
+        try!(self.print_name(item_segment.identifier.name));
         self.print_path_parameters(&item_segment.parameters, colons_before_params)
     }
 
@@ -1741,7 +1735,7 @@ pub fn print_pat(&mut self, pat: &hir::Pat) -> io::Result<()> {
                         try!(self.word_nbsp("mut"));
                     }
                 }
-                try!(self.print_ident(path1.node));
+                try!(self.print_name(path1.node.name));
                 match *sub {
                     Some(ref p) => {
                         try!(word(&mut self.s, "@"));
@@ -2168,7 +2162,6 @@ pub fn print_view_path(&mut self, vp: &hir::ViewPath) -> io::Result<()> {
             hir::ViewPathSimple(name, ref path) => {
                 try!(self.print_path(path, false, 0));
 
-                // FIXME(#6993) can't compare identifiers directly here
                 if path.segments.last().unwrap().identifier.name != name {
                     try!(space(&mut self.s));
                     try!(self.word_space("as"));
@@ -2183,14 +2176,14 @@ pub fn print_view_path(&mut self, vp: &hir::ViewPath) -> io::Result<()> {
                 word(&mut self.s, "::*")
             }
 
-            hir::ViewPathList(ref path, ref idents) => {
+            hir::ViewPathList(ref path, ref segments) => {
                 if path.segments.is_empty() {
                     try!(word(&mut self.s, "{"));
                 } else {
                     try!(self.print_path(path, false, 0));
                     try!(word(&mut self.s, "::{"));
                 }
-                try!(self.commasep(Inconsistent, &idents[..], |s, w| {
+                try!(self.commasep(Inconsistent, &segments[..], |s, w| {
                     match w.node {
                         hir::PathListIdent { name, .. } => {
                             s.print_name(name)
@@ -2268,7 +2261,7 @@ pub fn print_ty_fn(&mut self,
                        abi: abi::Abi,
                        unsafety: hir::Unsafety,
                        decl: &hir::FnDecl,
-                       name: Option<ast::Ident>,
+                       name: Option<ast::Name>,
                        generics: &hir::Generics,
                        opt_explicit_self: Option<&hir::ExplicitSelf_>)
                        -> io::Result<()> {
@@ -2289,7 +2282,7 @@ pub fn print_ty_fn(&mut self,
                            unsafety,
                            hir::Constness::NotConst,
                            abi,
-                           name.map(|x| x.name),
+                           name,
                            &generics,
                            opt_explicit_self,
                            hir::Inherited));
index 4d1a34621d0efcf634cd480400453eb6cf01cffa..c2382a92ec723732b7b1e0bf66fcf24c90431379 100644 (file)
@@ -354,13 +354,13 @@ pub fn empty_generics() -> Generics {
 
 // convert a span and an identifier to the corresponding
 // 1-segment path
-pub fn ident_to_path(s: Span, identifier: Ident) -> Path {
+pub fn ident_to_path(s: Span, ident: Ident) -> Path {
     hir::Path {
         span: s,
         global: false,
         segments: vec!(
             hir::PathSegment {
-                identifier: identifier,
+                identifier: ident,
                 parameters: hir::AngleBracketedParameters(hir::AngleBracketedParameterData {
                     lifetimes: Vec::new(),
                     types: OwnedSlice::empty(),
index 111913adb8aa8f2655845d9ff3d31d194acf4734..d12cd082cab7e587de08c867ada749e4ac16c3a4 100644 (file)
@@ -761,9 +761,6 @@ fn get_lints(&self) -> LintArray {
 impl LateLintPass for UnconditionalRecursion {
     fn check_fn(&mut self, cx: &LateContext, fn_kind: FnKind, _: &hir::FnDecl,
                 blk: &hir::Block, sp: Span, id: ast::NodeId) {
-        type F = for<'tcx> fn(&ty::ctxt<'tcx>,
-                              ast::NodeId, ast::NodeId, ast::Ident, ast::NodeId) -> bool;
-
         let method = match fn_kind {
             FnKind::ItemFn(..) => None,
             FnKind::Method(..) => {
index f9f3e3a430811b57ec0b4ee654868b6745b6e8a4..dca4a81c56feb08e31b093a97baa2db7f68474f3 100644 (file)
@@ -47,10 +47,10 @@ fn check_unused_mut_pat(&self, cx: &LateContext, pats: &[P<hir::Pat>]) {
         let mut mutables = FnvHashMap();
         for p in pats {
             pat_util::pat_bindings(&cx.tcx.def_map, p, |mode, id, _, path1| {
-                let ident = path1.node;
+                let name = path1.node;
                 if let hir::BindByValue(hir::MutMutable) = mode {
-                    if !ident.name.as_str().starts_with("_") {
-                        match mutables.entry(ident.name.usize()) {
+                    if !name.as_str().starts_with("_") {
+                        match mutables.entry(name.0 as usize) {
                             Vacant(entry) => { entry.insert(vec![id]); },
                             Occupied(mut entry) => { entry.get_mut().push(id); },
                         }
index 7f0b3ee3b316bb13a13e4cd1d57cb0f83a2cae6f..2ff57a187123d8eb4d8e6f6e00c34f4821f3751c 100644 (file)
@@ -199,7 +199,7 @@ struct Candidate<H:Hair> {
 struct Binding<H:Hair> {
     span: H::Span,
     source: Lvalue<H>,
-    name: H::Ident,
+    name: H::Name,
     var_id: H::VarId,
     var_ty: H::Ty,
     mutability: Mutability,
@@ -376,7 +376,7 @@ fn bind_matched_candidate(&mut self,
     fn declare_binding(&mut self,
                        var_extent: H::CodeExtent,
                        mutability: Mutability,
-                       name: H::Ident,
+                       name: H::Name,
                        var_id: H::VarId,
                        var_ty: H::Ty,
                        span: H::Span)
index 823958fdab40dcfdfa30d929ded73c0da313e310..cb094ad49055f010bd83e9bfa9f08d96f0a6ffb9 100644 (file)
@@ -29,7 +29,6 @@ pub trait Hair: Sized+Debug+Clone+Eq+Hash { // (*)
     type DefId: Copy+Debug+Eq+Hash;                              // e.g., DefId
     type AdtDef: Copy+Debug+Eq+Hash;                             // e.g., AdtDef<'tcx>
     type Name: Copy+Debug+Eq+Hash;                               // e.g., ast::Name
-    type Ident: Copy+Debug+Eq+Hash;                              // e.g., ast::Ident
     type InternedString: Clone+Debug+Eq+Hash;                    // e.g., InternedString
     type Bytes: Clone+Debug+Eq+Hash;                             // e.g., Rc<Vec<u8>>
     type Span: Copy+Debug+Eq;                                    // e.g., syntax::codemap::Span
@@ -248,7 +247,7 @@ pub enum PatternKind<H:Hair> {
 
     // x, ref x, x @ P, etc
     Binding { mutability: Mutability,
-              name: H::Ident,
+              name: H::Name,
               mode: BindingMode<H>,
               var: H::VarId,
               ty: H::Ty,
index a54942144c5ec8494dc18b23eb0f0169a1e31241..a1b891ab090867ffe421ac2cb10c73e3561d15db 100644 (file)
@@ -113,7 +113,7 @@ pub enum BorrowKind {
 // decl, a let, etc.
 pub struct VarDecl<H:Hair> {
     pub mutability: Mutability,
-    pub name: H::Ident,
+    pub name: H::Name,
     pub ty: H::Ty,
 }
 
index 94e8b57a5879e620938c70f037deebdf277d6cb5..6c9713b003b64555d4eb345c6c901a354c95586d 100644 (file)
@@ -286,9 +286,9 @@ fn make_mirror(self, cx: &mut Cx<'a,'tcx>) -> Expr<Cx<'a,'tcx>> {
             hir::ExprField(ref source, name) =>
                 ExprKind::Field { lhs: source.to_ref(),
                                   name: Field::Named(name.node) },
-            hir::ExprTupField(ref source, ident) =>
+            hir::ExprTupField(ref source, index) =>
                 ExprKind::Field { lhs: source.to_ref(),
-                                  name: Field::Indexed(ident.node) },
+                                  name: Field::Indexed(index.node) },
             hir::ExprCast(ref source, _) =>
                 ExprKind::Cast { source: source.to_ref() },
             hir::ExprBox(ref value) =>
index 2e9eae0956d9693700a6245cb5913aff269dbb51..9c0ef55b3d83acf4f4e329ef426d4963b9b0c80e 100644 (file)
@@ -47,7 +47,6 @@ impl<'a,'tcx:'a> Hair for Cx<'a, 'tcx> {
     type DefId = DefId;
     type AdtDef = ty::AdtDef<'tcx>;
     type Name = ast::Name;
-    type Ident = ast::Ident;
     type InternedString = InternedString;
     type Bytes = Rc<Vec<u8>>;
     type Span = Span;
index aeca15cb43c36392ed746f5676a4d2d6f8a18f44..d80fbfa7fe89702a60b353a44207436893ba4625 100644 (file)
 #[derive(Clone, Debug)]
 pub struct PatNode<'tcx> {
     pat: &'tcx hir::Pat,
-    binding_map: Option<Rc<FnvHashMap<ast::Ident, ast::NodeId>>>
+    binding_map: Option<Rc<FnvHashMap<ast::Name, ast::NodeId>>>
 }
 
 impl<'tcx> PatNode<'tcx> {
     pub fn new(pat: &'tcx hir::Pat,
-               binding_map: Option<Rc<FnvHashMap<ast::Ident, ast::NodeId>>>)
+               binding_map: Option<Rc<FnvHashMap<ast::Name, ast::NodeId>>>)
                -> PatNode<'tcx> {
         PatNode {
             pat: pat,
@@ -220,7 +220,7 @@ fn make_mirror(self, cx: &mut Cx<'a,'tcx>) -> Pattern<Cx<'a,'tcx>> {
             {
                 let id = match self.binding_map {
                     None => self.pat.id,
-                    Some(ref map) => map[&ident.node],
+                    Some(ref map) => map[&ident.node.name],
                 };
                 let var_ty = cx.tcx.node_id_to_type(self.pat.id);
                 let region = match var_ty.sty {
@@ -240,7 +240,7 @@ fn make_mirror(self, cx: &mut Cx<'a,'tcx>) -> Pattern<Cx<'a,'tcx>> {
                 PatternKind::Binding {
                     mutability: mutability,
                     mode: mode,
-                    name: ident.node,
+                    name: ident.node.name,
                     var: id,
                     ty: var_ty,
                     subpattern: self.opt_pat_ref(sub),
index ce1b9663520fc31301d416b065ddd6201a684251..cf964107d16b38e201fb933e3d8418380efe356f 100644 (file)
@@ -392,7 +392,6 @@ enum PrivacyResult {
 
 enum FieldName {
     UnnamedField(usize), // index
-    // (Name, not Ident, because struct fields are not macro-hygienic)
     NamedField(ast::Name),
 }
 
index e3e1a26a6f6ebf9b55050967fc1b857c77c31eb9..8a15eabd61419700d60ec6d48a1741acf8ae0aa9 100644 (file)
@@ -281,14 +281,14 @@ fn build_reduced_graph_for_item(&mut self, item: &Item, parent: &Rc<Module>) ->
                     ViewPathSimple(_, ref full_path) => {
                         full_path.segments
                             .split_last().unwrap().1
-                            .iter().map(|ident| ident.identifier.name)
+                            .iter().map(|seg| seg.identifier.name)
                             .collect()
                     }
 
                     ViewPathGlob(ref module_ident_path) |
                     ViewPathList(ref module_ident_path, _) => {
                         module_ident_path.segments
-                            .iter().map(|ident| ident.identifier.name).collect()
+                            .iter().map(|seg| seg.identifier.name).collect()
                     }
                 };
 
index f3789c773fb2d01153b9489d701c6f70e8df8405..c61f75723c7bd937c13e7d8f0e3fc72ab3a2ca24 100644 (file)
@@ -57,7 +57,7 @@
 use rustc::metadata::decoder::{DefLike, DlDef, DlField, DlImpl};
 use rustc::middle::def::*;
 use rustc::middle::def_id::DefId;
-use rustc::middle::pat_util::pat_bindings;
+use rustc::middle::pat_util::pat_bindings_hygienic;
 use rustc::middle::privacy::*;
 use rustc::middle::subst::{ParamSpace, FnSpace, TypeSpace};
 use rustc::middle::ty::{Freevar, FreevarMap, TraitMap, GlobMap};
@@ -2559,7 +2559,7 @@ fn resolve_local(&mut self, local: &Local) {
     // user and one 'x' came from the macro.
     fn binding_mode_map(&mut self, pat: &Pat) -> BindingMap {
         let mut result = HashMap::new();
-        pat_bindings(&self.def_map, pat, |binding_mode, _id, sp, path1| {
+        pat_bindings_hygienic(&self.def_map, pat, |binding_mode, _id, sp, path1| {
             let name = mtwt::resolve(path1.node);
             result.insert(name, BindingInfo {
                 span: sp,
@@ -3710,7 +3710,7 @@ fn resolve_expr(&mut self, expr: &Expr) {
                                 false // Stop advancing
                             });
 
-                            if method_scope && special_names::self_ == path_name {
+                            if method_scope && special_names::self_.as_str() == &path_name[..] {
                                 resolve_error(
                                     self,
                                     expr.span,
index 3c2612a1348559f8fec49c96bc60eefddc00e832..99d7685f7c8f290dbd770a4685fdecdfb172f3f7 100644 (file)
@@ -537,7 +537,7 @@ fn resolve_single_import(&mut self,
                         fn get_binding(this: &mut Resolver,
                                        import_resolution: &ImportResolution,
                                        namespace: Namespace,
-                                       source: &Name)
+                                       source: Name)
                                     -> NamespaceResult {
 
                             // Import resolutions must be declared with "pub"
@@ -560,7 +560,7 @@ fn get_binding(this: &mut Resolver,
                                     let id = import_resolution.id(namespace);
                                     // track used imports and extern crates as well
                                     this.used_imports.insert((id, namespace));
-                                    this.record_import_use(id, *source);
+                                    this.record_import_use(id, source);
                                     match target_module.def_id.get() {
                                         Some(DefId{krate: kid, ..}) => {
                                             this.used_crates.insert(kid);
@@ -578,14 +578,14 @@ fn get_binding(this: &mut Resolver,
                             value_result = get_binding(self.resolver,
                                                        import_resolution,
                                                        ValueNS,
-                                                       &source);
+                                                       source);
                             value_used_reexport = import_resolution.is_public;
                         }
                         if type_result.is_unknown() {
                             type_result = get_binding(self.resolver,
                                                       import_resolution,
                                                       TypeNS,
-                                                      &source);
+                                                      source);
                             type_used_reexport = import_resolution.is_public;
                         }
 
@@ -793,10 +793,10 @@ fn resolve_glob_import(&mut self,
                     )));
         }
 
-        for (ident, target_import_resolution) in import_resolutions.iter() {
+        for (name, target_import_resolution) in import_resolutions.iter() {
             debug!("(resolving glob import) writing module resolution \
                     {} into `{}`",
-                   *ident,
+                   *name,
                    module_to_string(module_));
 
             if !target_import_resolution.is_public {
@@ -806,7 +806,7 @@ fn resolve_glob_import(&mut self,
 
             // Here we merge two import resolutions.
             let mut import_resolutions = module_.import_resolutions.borrow_mut();
-            match import_resolutions.get_mut(ident) {
+            match import_resolutions.get_mut(name) {
                 Some(dest_import_resolution) => {
                     // Merge the two import resolutions at a finer-grained
                     // level.
@@ -818,7 +818,7 @@ fn resolve_glob_import(&mut self,
                         Some(ref value_target) => {
                             self.check_for_conflicting_import(&dest_import_resolution,
                                                               import_directive.span,
-                                                              *ident,
+                                                              *name,
                                                               ValueNS);
                             dest_import_resolution.value_target = Some(value_target.clone());
                         }
@@ -830,7 +830,7 @@ fn resolve_glob_import(&mut self,
                         Some(ref type_target) => {
                             self.check_for_conflicting_import(&dest_import_resolution,
                                                               import_directive.span,
-                                                              *ident,
+                                                              *name,
                                                               TypeNS);
                             dest_import_resolution.type_target = Some(type_target.clone());
                         }
@@ -848,7 +848,7 @@ fn resolve_glob_import(&mut self,
             new_import_resolution.type_target =
                 target_import_resolution.type_target.clone();
 
-            import_resolutions.insert(*ident, new_import_resolution);
+            import_resolutions.insert(*name, new_import_resolution);
         }
 
         // Add all children from the containing module.
index d6c12f864c4f8f61b07522cc2e760e2e481808e6..79a91e4f41650c19eb0d60da487f3f6f1b1bcca1 100644 (file)
@@ -19,7 +19,6 @@
 use metadata::csearch;
 use middle::dependency_format::Linkage;
 use session::Session;
-use session::config::DebugInfoLevel::{NoDebugInfo, LimitedDebugInfo, FullDebugInfo};
 use session::config::CrateTypeDylib;
 use session::config;
 use syntax::ast;
@@ -281,17 +280,9 @@ fn optimize(&mut self) {
     }
 
     fn debuginfo(&mut self) {
-        match self.sess.opts.debuginfo {
-            NoDebugInfo => {
-                // Do nothing if debuginfo is disabled
-            },
-            LimitedDebugInfo |
-            FullDebugInfo    => {
-                // This will cause the Microsoft linker to generate a PDB file
-                // from the CodeView line tables in the object files.
-                self.cmd.arg("/DEBUG");
-            }
-        }
+        // This will cause the Microsoft linker to generate a PDB file
+        // from the CodeView line tables in the object files.
+        self.cmd.arg("/DEBUG");
     }
 
     fn whole_archives(&mut self) {
index 9f50e7a1e6d9ad040f828f96e1551f0f53a1acd4..f25429ee904693becb24f525214fa5686b6f7976 100644 (file)
@@ -444,7 +444,7 @@ fn process_static_or_const_item(&mut self, item: &ast::Item, typ: &ast::Ty, expr
 
     fn process_const(&mut self,
                      id: ast::NodeId,
-                     ident: &ast::Ident,
+                     name: ast::Name,
                      span: Span,
                      typ: &ast::Ty,
                      expr: &ast::Expr) {
@@ -456,7 +456,7 @@ fn process_const(&mut self,
         self.fmt.static_str(span,
                             sub_span,
                             id,
-                            &ident.name.as_str(),
+                            &name.as_str(),
                             &qualname,
                             &self.span.snippet(expr.span),
                             &ty_to_string(&*typ),
@@ -988,7 +988,7 @@ fn visit_generics(&mut self, generics: &ast::Generics) {
     fn visit_trait_item(&mut self, trait_item: &ast::TraitItem) {
         match trait_item.node {
             ast::ConstTraitItem(ref ty, Some(ref expr)) => {
-                self.process_const(trait_item.id, &trait_item.ident,
+                self.process_const(trait_item.id, trait_item.ident.name,
                                    trait_item.span, &*ty, &*expr);
             }
             ast::MethodTraitItem(ref sig, ref body) => {
@@ -1006,7 +1006,7 @@ fn visit_trait_item(&mut self, trait_item: &ast::TraitItem) {
     fn visit_impl_item(&mut self, impl_item: &ast::ImplItem) {
         match impl_item.node {
             ast::ConstImplItem(ref ty, ref expr) => {
-                self.process_const(impl_item.id, &impl_item.ident,
+                self.process_const(impl_item.id, impl_item.ident.name,
                                    impl_item.span, &ty, &expr);
             }
             ast::MethodImplItem(ref sig, ref body) => {
index 70940345e97d4af9927227f1281ea8f749d8fdf4..67bfe58089e85c9201277664e3642f42dc57db8a 100644 (file)
@@ -375,7 +375,7 @@ pub struct BindingInfo<'tcx> {
     pub ty: Ty<'tcx>,
 }
 
-type BindingsMap<'tcx> = FnvHashMap<ast::Ident, BindingInfo<'tcx>>;
+type BindingsMap<'tcx> = FnvHashMap<ast::Name, BindingInfo<'tcx>>;
 
 struct ArmData<'p, 'blk, 'tcx: 'blk> {
     bodycx: Block<'blk, 'tcx>,
@@ -390,7 +390,7 @@ struct ArmData<'p, 'blk, 'tcx: 'blk> {
 struct Match<'a, 'p: 'a, 'blk: 'a, 'tcx: 'blk> {
     pats: Vec<&'p hir::Pat>,
     data: &'a ArmData<'p, 'blk, 'tcx>,
-    bound_ptrs: Vec<(ast::Ident, ValueRef)>,
+    bound_ptrs: Vec<(ast::Name, ValueRef)>,
     // Thread along renamings done by the check_match::StaticInliner, so we can
     // map back to original NodeIds
     pat_renaming_map: Option<&'a FnvHashMap<(NodeId, Span), NodeId>>
@@ -464,7 +464,7 @@ fn expand_nested_bindings<'a, 'p, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
         loop {
             pat = match pat.node {
                 hir::PatIdent(_, ref path, Some(ref inner)) => {
-                    bound_ptrs.push((path.node, val.val));
+                    bound_ptrs.push((path.node.name, val.val));
                     &**inner
                 },
                 _ => break
@@ -505,7 +505,7 @@ fn enter_match<'a, 'b, 'p, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
             match this.node {
                 hir::PatIdent(_, ref path, None) => {
                     if pat_is_binding(dm, &*this) {
-                        bound_ptrs.push((path.node, val.val));
+                        bound_ptrs.push((path.node.name, val.val));
                     }
                 }
                 hir::PatVec(ref before, Some(ref slice), ref after) => {
@@ -513,7 +513,7 @@ fn enter_match<'a, 'b, 'p, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
                         let subslice_val = bind_subslice_pat(
                             bcx, this.id, val,
                             before.len(), after.len());
-                        bound_ptrs.push((path.node, subslice_val));
+                        bound_ptrs.push((path.node.name, subslice_val));
                     }
                 }
                 _ => {}
@@ -943,7 +943,7 @@ fn insert_lllocals<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
                                bindings_map: &BindingsMap<'tcx>,
                                cs: Option<cleanup::ScopeId>)
                                -> Block<'blk, 'tcx> {
-    for (&ident, &binding_info) in bindings_map {
+    for (&name, &binding_info) in bindings_map {
         let (llval, aliases_other_state) = match binding_info.trmode {
             // By value mut binding for a copy type: load from the ptr
             // into the matched value and copy to our alloca
@@ -1021,7 +1021,7 @@ fn insert_lllocals<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
 
         debug!("binding {} to {}", binding_info.id, bcx.val_to_string(llval));
         bcx.fcx.lllocals.borrow_mut().insert(binding_info.id, datum);
-        debuginfo::create_match_binding_metadata(bcx, ident.name, binding_info);
+        debuginfo::create_match_binding_metadata(bcx, name, binding_info);
     }
     bcx
 }
@@ -1514,8 +1514,7 @@ fn create_bindings_map<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, pat: &hir::Pat,
     let reassigned = is_discr_reassigned(bcx, discr, body);
     let mut bindings_map = FnvHashMap();
     pat_bindings(&tcx.def_map, &*pat, |bm, p_id, span, path1| {
-        let ident = path1.node;
-        let name = ident.name;
+        let name = path1.node;
         let variable_ty = node_id_type(bcx, p_id);
         let llvariable_ty = type_of::type_of(ccx, variable_ty);
         let tcx = bcx.tcx();
@@ -1547,7 +1546,7 @@ fn create_bindings_map<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, pat: &hir::Pat,
                 trmode = TrByRef;
             }
         };
-        bindings_map.insert(ident, BindingInfo {
+        bindings_map.insert(name, BindingInfo {
             llmatch: llmatch,
             trmode: trmode,
             id: p_id,
@@ -1660,7 +1659,7 @@ fn create_dummy_locals<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
         pat_bindings(&tcx.def_map, pat, |_, p_id, _, path1| {
             let scope = cleanup::var_scope(tcx, p_id);
             bcx = mk_binding_alloca(
-                bcx, p_id, path1.node.name, scope, (),
+                bcx, p_id, path1.node, scope, (),
                 "_match::store_local::create_dummy_locals",
                 |(), bcx, Datum { val: llval, ty, kind }| {
                     // Dummy-locals start out uninitialized, so set their
@@ -1697,11 +1696,11 @@ fn create_dummy_locals<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
             //
             // In such cases, the more general path is unsafe, because
             // it assumes it is matching against a valid value.
-            match simple_identifier(&*pat) {
-                Some(ident) => {
+            match simple_name(pat) {
+                Some(name) => {
                     let var_scope = cleanup::var_scope(tcx, local.id);
                     return mk_binding_alloca(
-                        bcx, pat.id, ident.name, var_scope, (),
+                        bcx, pat.id, name, var_scope, (),
                         "_match::store_local",
                         |(), bcx, Datum { val: v, .. }| expr::trans_into(bcx, &**init_expr,
                                                                          expr::SaveIn(v)));
index dd0c06c9142e60b62af197a1626dc032e21c294d..16247b254d9f35f60bfee583147e4732c292b883 100644 (file)
@@ -40,7 +40,7 @@
 use middle::def_id::{DefId, LOCAL_CRATE};
 use middle::lang_items::{LangItem, ExchangeMallocFnLangItem, StartFnLangItem};
 use middle::weak_lang_items;
-use middle::pat_util::simple_identifier;
+use middle::pat_util::simple_name;
 use middle::subst::Substs;
 use middle::ty::{self, Ty, HasTypeFlags};
 use rustc::front::map as hir_map;
@@ -1447,10 +1447,10 @@ pub fn create_datums_for_fn_args<'a, 'tcx>(mut bcx: Block<'a, 'tcx>,
         };
 
         let pat = &*args[i].pat;
-        bcx = if let Some(ident) = simple_identifier(&*pat) {
+        bcx = if let Some(name) = simple_name(pat) {
             // Generate nicer LLVM for the common case of fn a pattern
             // like `x: T`
-            set_value_name(arg_datum.val, &bcx.name(ident.name));
+            set_value_name(arg_datum.val, &bcx.name(name));
             bcx.fcx.lllocals.borrow_mut().insert(pat.id, arg_datum);
             bcx
         } else {
@@ -2570,20 +2570,6 @@ fn internalize_symbols(cx: &SharedCrateContext, reachable: &HashSet<&str>) {
     unsafe {
         let mut declared = HashSet::new();
 
-        let iter_globals = |llmod| {
-            ValueIter {
-                cur: llvm::LLVMGetFirstGlobal(llmod),
-                step: llvm::LLVMGetNextGlobal,
-            }
-        };
-
-        let iter_functions = |llmod| {
-            ValueIter {
-                cur: llvm::LLVMGetFirstFunction(llmod),
-                step: llvm::LLVMGetNextFunction,
-            }
-        };
-
         // Collect all external declarations in all compilation units.
         for ccx in cx.iter() {
             for val in iter_globals(ccx.llmod()).chain(iter_functions(ccx.llmod())) {
@@ -2623,28 +2609,73 @@ fn internalize_symbols(cx: &SharedCrateContext, reachable: &HashSet<&str>) {
             }
         }
     }
+}
+
+// Create a `__imp_<symbol> = &symbol` global for every public static `symbol`.
+// This is required to satisfy `dllimport` references to static data in .rlibs
+// when using MSVC linker.  We do this only for data, as linker can fix up
+// code references on its own.
+// See #26591, #27438
+fn create_imps(cx: &SharedCrateContext) {
+    unsafe {
+        for ccx in cx.iter() {
+            let exported: Vec<_> = iter_globals(ccx.llmod())
+                .filter(|&val| llvm::LLVMGetLinkage(val) == llvm::ExternalLinkage as c_uint &&
+                               llvm::LLVMIsDeclaration(val) == 0)
+                .collect();
+
+            let i8p_ty = Type::i8p(&ccx);
+            for val in exported {
+                let name = CStr::from_ptr(llvm::LLVMGetValueName(val));
+                let imp_name = String::from("__imp_") +
+                               str::from_utf8(name.to_bytes()).unwrap();
+                let imp_name = CString::new(imp_name).unwrap();
+                let imp = llvm::LLVMAddGlobal(ccx.llmod(), i8p_ty.to_ref(),
+                                              imp_name.as_ptr() as *const _);
+                llvm::LLVMSetInitializer(imp, llvm::LLVMConstBitCast(val, i8p_ty.to_ref()));
+                llvm::SetLinkage(imp, llvm::ExternalLinkage);
+            }
+        }
+    }
+}
+
+struct ValueIter {
+    cur: ValueRef,
+    step: unsafe extern "C" fn(ValueRef) -> ValueRef,
+}
 
+impl Iterator for ValueIter {
+    type Item = ValueRef;
 
-    struct ValueIter {
-        cur: ValueRef,
-        step: unsafe extern "C" fn(ValueRef) -> ValueRef,
+    fn next(&mut self) -> Option<ValueRef> {
+        let old = self.cur;
+        if !old.is_null() {
+            self.cur = unsafe {
+                let step: unsafe extern "C" fn(ValueRef) -> ValueRef =
+                    mem::transmute_copy(&self.step);
+                step(old)
+            };
+            Some(old)
+        } else {
+            None
+        }
     }
+}
 
-    impl Iterator for ValueIter {
-        type Item = ValueRef;
+fn iter_globals(llmod: llvm::ModuleRef) -> ValueIter {
+    unsafe {
+        ValueIter {
+            cur: llvm::LLVMGetFirstGlobal(llmod),
+            step: llvm::LLVMGetNextGlobal,
+        }
+    }
+}
 
-        fn next(&mut self) -> Option<ValueRef> {
-            let old = self.cur;
-            if !old.is_null() {
-                self.cur = unsafe {
-                    let step: unsafe extern "C" fn(ValueRef) -> ValueRef =
-                        mem::transmute_copy(&self.step);
-                    step(old)
-                };
-                Some(old)
-            } else {
-                None
-            }
+fn iter_functions(llmod: llvm::ModuleRef) -> ValueIter {
+    unsafe {
+        ValueIter {
+            cur: llvm::LLVMGetFirstFunction(llmod),
+            step: llvm::LLVMGetNextFunction,
         }
     }
 }
@@ -2824,6 +2855,11 @@ pub fn trans_crate(tcx: &ty::ctxt, analysis: ty::CrateAnalysis) -> CrateTranslat
                             &reachable_symbols.iter().map(|x| &x[..]).collect());
     }
 
+    if sess.target.target.options.is_like_msvc &&
+       sess.crate_types.borrow().iter().any(|ct| *ct == config::CrateTypeRlib) {
+        create_imps(&shared_ccx);
+    }
+
     let metadata_module = ModuleTranslation {
         llcx: shared_ccx.metadata_llcx(),
         llmod: shared_ccx.metadata_llmod(),
index ec34d0dd5925782f23ce2a8a47ebf37dadc84346..78f631371c093f980070834ec7acffef13dbe3cd 100644 (file)
@@ -168,7 +168,7 @@ pub fn return_type_is_void(ccx: &CrateContext, ty: Ty) -> bool {
 /// Generates a unique symbol based off the name given. This is used to create
 /// unique symbols for things like closures.
 pub fn gensym_name(name: &str) -> PathElem {
-    let num = token::gensym(name).usize();
+    let num = token::gensym(name).0;
     // use one colon which will get translated to a period by the mangler, and
     // we're guaranteed that `num` is globally unique for this crate.
     PathName(token::gensym(&format!("{}:{}", name, num)))
@@ -829,7 +829,7 @@ pub fn C_cstr(cx: &CrateContext, s: InternedString, null_terminated: bool) -> Va
                                                 !null_terminated as Bool);
 
         let gsym = token::gensym("str");
-        let sym = format!("str{}", gsym.usize());
+        let sym = format!("str{}", gsym.0);
         let g = declare::define_global(cx, &sym[..], val_ty(sc)).unwrap_or_else(||{
             cx.sess().bug(&format!("symbol `{}` is already defined", sym));
         });
index f8b8c41a034e6ac0c7b7bc5f5e997387ac1af093..5988f95aedf6c35c9c398ea0fefedc2447636f30 100644 (file)
@@ -116,7 +116,7 @@ fn addr_of_mut(ccx: &CrateContext,
         // FIXME: this totally needs a better name generation scheme, perhaps a simple global
         // counter? Also most other uses of gensym in trans.
         let gsym = token::gensym("_");
-        let name = format!("{}{}", kind, gsym.usize());
+        let name = format!("{}{}", kind, gsym.0);
         let gv = declare::define_global(ccx, &name[..], val_ty(cv)).unwrap_or_else(||{
             ccx.sess().bug(&format!("symbol `{}` is already defined", name));
         });
index 340eabf77daec4c57126f5378177a10885181211..875eb353cf7e349bf341289e045e6d7e662eb965 100644 (file)
@@ -305,7 +305,7 @@ pub fn trans_loop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 
 pub fn trans_break_cont<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                                     expr: &hir::Expr,
-                                    opt_label: Option<ast::Ident>,
+                                    opt_label: Option<ast::Name>,
                                     exit: usize)
                                     -> Block<'blk, 'tcx> {
     let _icx = push_ctxt("trans_break_cont");
@@ -338,14 +338,14 @@ pub fn trans_break_cont<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 
 pub fn trans_break<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                                expr: &hir::Expr,
-                               label_opt: Option<ast::Ident>)
+                               label_opt: Option<ast::Name>)
                                -> Block<'blk, 'tcx> {
     return trans_break_cont(bcx, expr, label_opt, cleanup::EXIT_BREAK);
 }
 
 pub fn trans_cont<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                               expr: &hir::Expr,
-                              label_opt: Option<ast::Ident>)
+                              label_opt: Option<ast::Name>)
                               -> Block<'blk, 'tcx> {
     return trans_break_cont(bcx, expr, label_opt, cleanup::EXIT_LOOP);
 }
index 313ff7cd37d6016e7d5799076bdd14dd9f374c5e..7597d5f92aec05b6128c5e7e4f82f600e31a4b0e 100644 (file)
@@ -49,7 +49,7 @@ pub fn create_scope_map(cx: &CrateContext,
     for arg in args {
         pat_util::pat_bindings(def_map, &*arg.pat, |_, node_id, _, path1| {
             scope_stack.push(ScopeStackEntry { scope_metadata: fn_metadata,
-                                               name: Some(path1.node.name) });
+                                               name: Some(path1.node) });
             scope_map.insert(node_id, fn_metadata);
         })
     }
index fa2c476f6133b120f94c9c96b94bd01eca8533c2..1d35b51a5f81c086ca98c354dc04b0138fefcd18 100644 (file)
@@ -1925,7 +1925,7 @@ pub fn create_local_var_metadata(bcx: Block, local: &hir::Local) {
     let def_map = &cx.tcx().def_map;
     let locals = bcx.fcx.lllocals.borrow();
 
-    pat_util::pat_bindings(def_map, &*local.pat, |_, node_id, span, var_ident| {
+    pat_util::pat_bindings(def_map, &*local.pat, |_, node_id, span, var_name| {
         let datum = match locals.get(&node_id) {
             Some(datum) => datum,
             None => {
@@ -1943,7 +1943,7 @@ pub fn create_local_var_metadata(bcx: Block, local: &hir::Local) {
         let scope_metadata = scope_metadata(bcx.fcx, node_id, span);
 
         declare_local(bcx,
-                      var_ident.node.name,
+                      var_name.node,
                       datum.ty,
                       scope_metadata,
                       VariableAccess::DirectVariable { alloca: datum.val },
@@ -2105,7 +2105,7 @@ pub fn create_argument_metadata(bcx: Block, arg: &hir::Arg) {
                          .fn_metadata;
     let locals = bcx.fcx.lllocals.borrow();
 
-    pat_util::pat_bindings(def_map, &*arg.pat, |_, node_id, span, var_ident| {
+    pat_util::pat_bindings(def_map, &*arg.pat, |_, node_id, span, var_name| {
         let datum = match locals.get(&node_id) {
             Some(v) => v,
             None => {
@@ -2132,7 +2132,7 @@ pub fn create_argument_metadata(bcx: Block, arg: &hir::Arg) {
         };
 
         declare_local(bcx,
-                      var_ident.node.name,
+                      var_name.node,
                       datum.ty,
                       scope_metadata,
                       VariableAccess::DirectVariable { alloca: datum.val },
index 35686ebaa9689f6ca0041a125242be343e7ddad9..722089e42f9be42aa9056af04e06e87e966e9599 100644 (file)
@@ -963,10 +963,10 @@ fn trans_rvalue_stmt_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 
     match expr.node {
         hir::ExprBreak(label_opt) => {
-            controlflow::trans_break(bcx, expr, label_opt.map(|l| l.node))
+            controlflow::trans_break(bcx, expr, label_opt.map(|l| l.node.name))
         }
         hir::ExprAgain(label_opt) => {
-            controlflow::trans_cont(bcx, expr, label_opt.map(|l| l.node))
+            controlflow::trans_cont(bcx, expr, label_opt.map(|l| l.node.name))
         }
         hir::ExprRet(ref ex) => {
             // Check to see if the return expression itself is reachable.
@@ -1114,7 +1114,7 @@ fn trans_rvalue_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
             // trans. Shudder.
             fn make_field(field_name: &str, expr: P<hir::Expr>) -> hir::Field {
                 hir::Field {
-                    name: codemap::dummy_spanned(token::str_to_ident(field_name).name),
+                    name: codemap::dummy_spanned(token::intern(field_name)),
                     expr: expr,
                     span: codemap::DUMMY_SP,
                 }
index 5be450ea27832586ff460775821178d076ae5352..7b2bbbcc4a92a24e4d854a8c0f3030848c0b24bf 100644 (file)
@@ -393,7 +393,7 @@ fn create_substs_for_ast_path<'tcx>(
     let tcx = this.tcx();
 
     debug!("create_substs_for_ast_path(decl_generics={:?}, self_ty={:?}, \
-           types_provided={:?}, region_substs={:?}",
+           types_provided={:?}, region_substs={:?})",
            decl_generics, self_ty, types_provided,
            region_substs);
 
@@ -474,6 +474,9 @@ fn create_substs_for_ast_path<'tcx>(
         }
     }
 
+    debug!("create_substs_for_ast_path(decl_generics={:?}, self_ty={:?}) -> {:?}",
+           decl_generics, self_ty, substs);
+
     substs
 }
 
@@ -741,6 +744,7 @@ fn ast_path_to_poly_trait_ref<'a,'tcx>(
     poly_projections: &mut Vec<ty::PolyProjectionPredicate<'tcx>>)
     -> ty::PolyTraitRef<'tcx>
 {
+    debug!("ast_path_to_poly_trait_ref(trait_segment={:?})", trait_segment);
     // The trait reference introduces a binding level here, so
     // we need to shift the `rscope`. It'd be nice if we could
     // do away with this rscope stuff and work this knowledge
@@ -774,6 +778,8 @@ fn ast_path_to_poly_trait_ref<'a,'tcx>(
         poly_projections.extend(converted_bindings);
     }
 
+    debug!("ast_path_to_poly_trait_ref(trait_segment={:?}, projections={:?}) -> {:?}",
+           trait_segment, poly_projections, poly_trait_ref);
     poly_trait_ref
 }
 
@@ -1103,7 +1109,18 @@ fn make_object_type<'tcx>(this: &AstConv<'tcx>,
         object.principal_trait_ref_with_self_ty(tcx, tcx.types.err);
 
     // ensure the super predicates and stop if we encountered an error
-    if this.ensure_super_predicates(span, object.principal_def_id()).is_err() {
+    if this.ensure_super_predicates(span, principal.def_id()).is_err() {
+        return tcx.types.err;
+    }
+
+    // check that there are no gross object safety violations,
+    // most importantly, that the supertraits don't contain Self,
+    // to avoid ICE-s.
+    let object_safety_violations =
+        traits::astconv_object_safety_violations(tcx, principal.def_id());
+    if !object_safety_violations.is_empty() {
+        traits::report_object_safety_error(
+            tcx, span, principal.def_id(), object_safety_violations, false);
         return tcx.types.err;
     }
 
index 136b3c4405d5b989e9221ba06e5129d6203ec156..546e337d746d992a7dcbcd743e9b45e19ecc7a21 100644 (file)
@@ -179,7 +179,7 @@ pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
 
             // if there are multiple arms, make sure they all agree on
             // what the type of the binding `x` ought to be
-            let canon_id = *pcx.map.get(&path.node).unwrap();
+            let canon_id = *pcx.map.get(&path.node.name).unwrap();
             if canon_id != pat.id {
                 let ct = fcx.local_ty(pat.span, canon_id);
                 demand::eqtype(fcx, pat.span, ct, typ);
index dec2e49272b48aa9f80cb6647876d8d57ea749d1..419fb7aea6c6e436bd44f5b2f91814d8d883511f 100644 (file)
@@ -682,7 +682,7 @@ pub fn check_struct(ccx: &CrateCtxt, id: ast::NodeId, span: Span) {
 }
 
 pub fn check_item_type<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) {
-    debug!("check_item_type(it.id={}, it.ident={})",
+    debug!("check_item_type(it.id={}, it.name={})",
            it.id,
            ccx.tcx.item_path_str(DefId::local(it.id)));
     let _indenter = indenter();
@@ -750,7 +750,7 @@ pub fn check_item_type<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) {
 }
 
 pub fn check_item_body<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) {
-    debug!("check_item_body(it.id={}, it.ident={})",
+    debug!("check_item_body(it.id={}, it.name={})",
            it.id,
            ccx.tcx.item_path_str(DefId::local(it.id)));
     let _indenter = indenter();
@@ -838,7 +838,7 @@ fn check_trait_on_unimplemented<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                         Position::ArgumentNamed(s) if s == "Self" => (),
                         // So is `{A}` if A is a type parameter
                         Position::ArgumentNamed(s) => match types.iter().find(|t| {
-                            t.name == s
+                            t.name.as_str() == s
                         }) {
                             Some(_) => (),
                             None => {
index 902ebcc3da87b7a1e77603fee4ee9fcf9bcdfc78..70983b89ed5c820af31228e032d26fc829e4ec27 100644 (file)
@@ -55,7 +55,7 @@ fn tcx(&self) -> &ty::ctxt<'tcx> {
     /// the types first.
     fn check_item_well_formed(&mut self, item: &hir::Item) {
         let ccx = self.ccx;
-        debug!("check_item_well_formed(it.id={}, it.ident={})",
+        debug!("check_item_well_formed(it.id={}, it.name={})",
                item.id,
                ccx.tcx.item_path_str(DefId::local(item.id)));
 
index 0e462b2a8525d8915ece80ae7c772f350154f47d..2c6879891b1c909929adfbfc562508dbb9d21966 100644 (file)
@@ -61,7 +61,7 @@ fn tcx(&self) -> &ty::ctxt<'tcx> {
     /// the types first.
     fn check_item_well_formed(&mut self, item: &hir::Item) {
         let ccx = self.ccx;
-        debug!("check_item_well_formed(it.id={}, it.ident={})",
+        debug!("check_item_well_formed(it.id={}, it.name={})",
                item.id,
                ccx.tcx.item_path_str(DefId::local(item.id)));
 
index cd3c630c7abb5d579b753b81ec6d8dd1760d4aaf..9e1b20258f07b05d68135178a1dda0dd246aac63 100644 (file)
@@ -699,12 +699,12 @@ fn convert_methods<'a,'tcx,'i,I>(ccx: &CrateCtxt<'a, 'tcx>,
            rcvr_ty_generics,
            rcvr_ty_predicates);
 
-    for (sig, id, ident, vis, _span) in methods {
+    for (sig, id, name, vis, _span) in methods {
         convert_method(ccx,
                        container,
                        sig,
                        id,
-                       ident,
+                       name,
                        vis,
                        untransformed_rcvr_ty,
                        rcvr_ty_generics,
index 3b08140612f25c4505f1bceba4a0657ae0b89110..30cb89cf0fde6f50eb358637962e9890c65c0d36 100644 (file)
@@ -3355,5 +3355,5 @@ struct i8x16(i8, i8, i8, i8, i8, i8, i8, i8,
     E0399, // trait items need to be implemented because the associated
            // type `{}` was overridden
     E0436, // functional record update requires a struct
-    E0513, // no type for local variable ..
+    E0513  // no type for local variable ..
 }
index 14d5ed2eb507de4b17df948358aeb9d1400bfffc..89020b011a955b4a2f727974dbcadc7e68d2196e 100644 (file)
@@ -1583,7 +1583,7 @@ fn clean(&self, cx: &DocContext) -> Type {
                 let mut trait_path = p.clone();
                 trait_path.segments.pop();
                 Type::QPath {
-                    name: p.segments.last().unwrap().identifier.clean(cx),
+                    name: p.segments.last().unwrap().identifier.name.clean(cx),
                     self_type: box qself.ty.clean(cx),
                     trait_: box resolve_type(cx, trait_path.clean(cx), self.id)
                 }
@@ -2044,7 +2044,7 @@ pub struct PathSegment {
 impl Clean<PathSegment> for hir::PathSegment {
     fn clean(&self, cx: &DocContext) -> PathSegment {
         PathSegment {
-            name: self.identifier.clean(cx),
+            name: self.identifier.name.clean(cx),
             params: self.parameters.clean(cx)
         }
     }
@@ -2064,12 +2064,6 @@ fn path_to_string(p: &hir::Path) -> String {
     s
 }
 
-impl Clean<String> for ast::Ident {
-    fn clean(&self, _: &DocContext) -> String {
-        self.to_string()
-    }
-}
-
 impl Clean<String> for ast::Name {
     fn clean(&self, _: &DocContext) -> String {
         self.to_string()
index ef8bdf5e2ce9738146d429b227f1c8a5b817777d..6b96a285992bb5cf9eeedae62e5b058fc90439e4 100644 (file)
@@ -12,6 +12,8 @@
 /*globals $: true, rootPath: true */
 
 document.addEventListener('DOMContentLoaded', function() {
+    'use strict';
+
     if (!window.playgroundUrl) {
         return;
     }
index c67a4182f54cbb32384b95c3c66b2b71affeb7ac..9129ffcc211820697a50c71db0cb105ed350a12f 100644 (file)
 #![feature(associated_consts)]
 #![feature(borrow_state)]
 #![feature(box_syntax)]
+#![feature(cfg_target_vendor)]
 #![feature(char_from_unchecked)]
 #![feature(char_internals)]
 #![feature(clone_from_slice)]
index a07d21add8db9c5fcb870d092f0c35a5f8383f69..a88ddb997f61d9aec982b5f35dd5791e7768e64e 100644 (file)
@@ -98,7 +98,7 @@ macro_rules! print {
     ($($arg:tt)*) => ($crate::io::_print(format_args!($($arg)*)));
 }
 
-/// Macro for printing to the standard output.
+/// Macro for printing to the standard output, with a newline.
 ///
 /// Use the `format!` syntax to write data to the standard output.
 /// See `std::fmt` for more information.
index 9715939d644aa5b61ff258c9c8edf0623c9b82f2..2b2af350c992cc874737ccfe547e65ef9f7ffc2b 100644 (file)
 use io::prelude::*;
 
 use any::Any;
+use cell::Cell;
 use cell::RefCell;
+use intrinsics;
 use sys::stdio::Stderr;
 use sys_common::backtrace;
 use sys_common::thread_info;
-use sys_common::unwind;
+use sys_common::util;
+
+thread_local! { pub static PANIC_COUNT: Cell<usize> = Cell::new(0) }
 
 thread_local! {
     pub static LOCAL_STDERR: RefCell<Option<Box<Write + Send>>> = {
@@ -24,7 +28,8 @@
     }
 }
 
-pub fn on_panic(obj: &(Any+Send), file: &'static str, line: u32) {
+fn log_panic(obj: &(Any+Send), file: &'static str, line: u32,
+             log_backtrace: bool) {
     let msg = match obj.downcast_ref::<&'static str>() {
         Some(s) => *s,
         None => match obj.downcast_ref::<String>() {
@@ -35,37 +40,59 @@ pub fn on_panic(obj: &(Any+Send), file: &'static str, line: u32) {
     let mut err = Stderr::new().ok();
     let thread = thread_info::current_thread();
     let name = thread.as_ref().and_then(|t| t.name()).unwrap_or("<unnamed>");
+
+    let write = |err: &mut ::io::Write| {
+        let _ = writeln!(err, "thread '{}' panicked at '{}', {}:{}",
+                         name, msg, file, line);
+        if log_backtrace {
+            let _ = backtrace::write(err);
+        }
+    };
+
     let prev = LOCAL_STDERR.with(|s| s.borrow_mut().take());
     match (prev, err.as_mut()) {
         (Some(mut stderr), _) => {
-            // FIXME: what to do when the thread printing panics?
-            let _ = writeln!(stderr,
-                             "thread '{}' panicked at '{}', {}:{}\n",
-                             name, msg, file, line);
-            if backtrace::log_enabled() {
-                let _ = backtrace::write(&mut *stderr);
-            }
+            write(&mut *stderr);
             let mut s = Some(stderr);
             LOCAL_STDERR.with(|slot| {
                 *slot.borrow_mut() = s.take();
             });
         }
-        (None, Some(ref mut err)) => {
-            let _ = writeln!(err, "thread '{}' panicked at '{}', {}:{}",
-                             name, msg, file, line);
-            if backtrace::log_enabled() {
-                let _ = backtrace::write(err);
-            }
-        }
+        (None, Some(ref mut err)) => { write(err) }
         _ => {}
     }
+}
 
-    // If this is a double panic, make sure that we printed a backtrace
-    // for this panic.
-    match err {
-        Some(ref mut err) if unwind::panicking() && !backtrace::log_enabled() => {
-            let _ = backtrace::write(err);
-        }
-        _ => {}
+pub fn on_panic(obj: &(Any+Send), file: &'static str, line: u32) {
+    let panics = PANIC_COUNT.with(|s| {
+        let count = s.get() + 1;
+        s.set(count);
+        count
+    });
+
+    // If this is the third nested call, on_panic triggered the last panic,
+    // otherwise the double-panic check would have aborted the process.
+    // Even if it is likely that on_panic was unable to log the backtrace,
+    // abort immediately to avoid infinite recursion, so that attaching a
+    // debugger provides a useable stacktrace.
+    if panics >= 3 {
+        util::dumb_print(format_args!("thread panicked while processing \
+                                       panic. aborting."));
+        unsafe { intrinsics::abort() }
+    }
+
+    // If this is a double panic, make sure that we print a backtrace
+    // for this panic. Otherwise only print it if logging is enabled.
+    let log_backtrace = panics >= 2 || backtrace::log_enabled();
+    log_panic(obj, file, line, log_backtrace);
+
+    if panics >= 2 {
+        // If a thread panics while it's already unwinding then we
+        // have limited options. Currently our preference is to
+        // just abort. In the future we may consider resuming
+        // unwinding or otherwise exiting the thread cleanly.
+        util::dumb_print(format_args!("thread panicked while panicking. \
+                                       aborting."));
+        unsafe { intrinsics::abort() }
     }
 }
index c6bffb0f733eeab4223110db1017b4cd39f51921..da7ebbf4ed39f57b0f67b44a0307c9f74f2c3575 100644 (file)
@@ -108,10 +108,18 @@ pub enum _Unwind_Context {}
 #[link(name = "unwind", kind = "static")]
 extern {}
 
-#[cfg(any(target_os = "android", target_os = "netbsd", target_os = "openbsd"))]
+#[cfg(any(target_os = "android", target_os = "openbsd"))]
 #[link(name = "gcc")]
 extern {}
 
+#[cfg(all(target_os = "netbsd", not(target_vendor = "rumprun")))]
+#[link(name = "gcc")]
+extern {}
+
+#[cfg(all(target_os = "netbsd", target_vendor = "rumprun"))]
+#[link(name = "unwind")]
+extern {}
+
 #[cfg(target_os = "dragonfly")]
 #[link(name = "gcc_pic")]
 extern {}
index 8148bb6b7b82e6de8d3457950868477516640537..c06d7886a757b088594cb017c4e37b3db9b7514f 100644 (file)
@@ -64,9 +64,8 @@
 
 use any::Any;
 use boxed;
-use cell::Cell;
 use cmp;
-use panicking;
+use panicking::{self,PANIC_COUNT};
 use fmt;
 use intrinsics;
 use mem;
@@ -92,8 +91,6 @@
 #[path = "gcc.rs"] #[doc(hidden)]
 pub mod imp;
 
-thread_local! { static PANICKING: Cell<bool> = Cell::new(false) }
-
 /// Invoke a closure, capturing the cause of panic if one occurs.
 ///
 /// This function will return `Ok(())` if the closure did not panic, and will
@@ -131,9 +128,9 @@ pub unsafe fn try<F: FnOnce()>(f: F) -> Result<(), Box<Any + Send>> {
     // care of exposing correctly.
     unsafe fn inner_try(f: fn(*mut u8), data: *mut u8)
                         -> Result<(), Box<Any + Send>> {
-        PANICKING.with(|s| {
+        PANIC_COUNT.with(|s| {
             let prev = s.get();
-            s.set(false);
+            s.set(0);
             let ep = intrinsics::try(f, data);
             s.set(prev);
             if ep.is_null() {
@@ -161,7 +158,7 @@ fn rust_try(f: extern fn(*mut u8),
 
 /// Determines whether the current thread is unwinding because of panic.
 pub fn panicking() -> bool {
-    PANICKING.with(|s| s.get())
+    PANIC_COUNT.with(|s| s.get() != 0)
 }
 
 // An uninlined, unmangled function upon which to slap yer breakpoints
@@ -234,17 +231,6 @@ fn begin_unwind_inner(msg: Box<Any + Send>,
     // First, invoke the default panic handler.
     panicking::on_panic(&*msg, file, line);
 
-    if panicking() {
-        // If a thread panics while it's already unwinding then we
-        // have limited options. Currently our preference is to
-        // just abort. In the future we may consider resuming
-        // unwinding or otherwise exiting the thread cleanly.
-        super::util::dumb_print(format_args!("thread panicked while panicking. \
-                                              aborting."));
-        unsafe { intrinsics::abort() }
-    }
-    PANICKING.with(|s| s.set(true));
-
     // Finally, perform the unwinding.
     rust_panic(msg);
 }
index 441313bc639935dd8046b8510eaa217611e5cc92..f5fd11b61b1e67efef59b9c50f31075b3fc8836a 100644 (file)
@@ -34,7 +34,7 @@ fn drop(&mut self) {
 #[cfg(any(target_os = "linux",
           target_os = "macos",
           target_os = "bitrig",
-          target_os = "netbsd",
+          all(target_os = "netbsd", not(target_vendor = "rumprun")),
           target_os = "openbsd"))]
 mod imp {
     use super::Handler;
@@ -143,7 +143,7 @@ pub unsafe fn drop_handler(handler: &mut Handler) {
 #[cfg(not(any(target_os = "linux",
               target_os = "macos",
               target_os = "bitrig",
-              target_os = "netbsd",
+              all(target_os = "netbsd", not(target_vendor = "rumprun")),
               target_os = "openbsd")))]
 mod imp {
     use ptr;
index 83e0a03a2341ee2b49630af6151371031509cc6b..50e01ecf9fa98161e541b4d663bcffef3a178276 100644 (file)
@@ -174,7 +174,7 @@ fn drop(&mut self) {
 #[cfg(all(not(target_os = "linux"),
           not(target_os = "macos"),
           not(target_os = "bitrig"),
-          not(target_os = "netbsd"),
+          not(all(target_os = "netbsd", not(target_vendor = "rumprun"))),
           not(target_os = "openbsd")))]
 pub mod guard {
     pub unsafe fn current() -> Option<usize> { None }
@@ -185,7 +185,7 @@ pub unsafe fn init() -> Option<usize> { None }
 #[cfg(any(target_os = "linux",
           target_os = "macos",
           target_os = "bitrig",
-          target_os = "netbsd",
+          all(target_os = "netbsd", not(target_vendor = "rumprun")),
           target_os = "openbsd"))]
 #[allow(unused_imports)]
 pub mod guard {
index db7d77e5454c25cf63b41a19aba0d621ba7731c7..75a976296489565aaa6e54e8f0c45c43deae4418 100644 (file)
 use std::rc::Rc;
 use serialize::{Encodable, Decodable, Encoder, Decoder};
 
-// FIXME #6993: in librustc, uses of "ident" should be replaced
-// by just "Name".
+/// A name is a part of an identifier, representing a string or gensym. It's
+/// the result of interning.
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
+pub struct Name(pub u32);
+
+/// A SyntaxContext represents a chain of macro-expandings
+/// and renamings. Each macro expansion corresponds to
+/// a fresh u32. This u32 is a reference to a table stored
+// in thread-local storage.
+// The special value EMPTY_CTXT is used to indicate an empty
+// syntax context.
+#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
+pub struct SyntaxContext(pub u32);
 
 /// An identifier contains a Name (index into the interner
 /// table) and a SyntaxContext to track renaming and
-/// macro expansion per Flatt et al., "Macros
-/// That Work Together"
-#[derive(Clone, Copy, Hash, PartialOrd, Eq, Ord)]
+/// macro expansion per Flatt et al., "Macros That Work Together"
+#[derive(Clone, Copy, Eq, Hash)]
 pub struct Ident {
     pub name: Name,
     pub ctxt: SyntaxContext
 }
 
-impl Ident {
-    /// Construct an identifier with the given name and an empty context:
-    pub fn new(name: Name) -> Ident { Ident {name: name, ctxt: EMPTY_CTXT}}
+impl Name {
+    pub fn as_str(self) -> token::InternedString {
+        token::InternedString::new_from_name(self)
+    }
 }
 
-impl fmt::Debug for Ident {
+impl fmt::Debug for Name {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f, "{}#{}", self.name, self.ctxt)
+        write!(f, "{}({})", self, self.0)
     }
 }
 
-impl fmt::Display for Ident {
+impl fmt::Display for Name {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        fmt::Display::fmt(&self.name, f)
+        fmt::Display::fmt(&self.as_str(), f)
     }
 }
 
-impl fmt::Debug for Name {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        let Name(nm) = *self;
-        write!(f, "{}({})", self, nm)
+impl Encodable for Name {
+    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
+        s.emit_str(&self.as_str())
     }
 }
 
-impl fmt::Display for Name {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        fmt::Display::fmt(&self.as_str(), f)
+impl Decodable for Name {
+    fn decode<D: Decoder>(d: &mut D) -> Result<Name, D::Error> {
+        Ok(token::intern(&try!(d.read_str())[..]))
+    }
+}
+
+pub const EMPTY_CTXT : SyntaxContext = SyntaxContext(0);
+
+impl Ident {
+    pub fn new(name: Name, ctxt: SyntaxContext) -> Ident {
+        Ident {name: name, ctxt: ctxt}
+    }
+    pub fn with_empty_ctxt(name: Name) -> Ident {
+        Ident {name: name, ctxt: EMPTY_CTXT}
     }
 }
 
@@ -119,74 +140,27 @@ fn eq(&self, other: &Ident) -> bool {
             // idents that have different contexts. You can't fix this without
             // knowing whether the comparison should be hygienic or non-hygienic.
             // if it should be non-hygienic (most things are), just compare the
-            // 'name' fields of the idents. Or, even better, replace the idents
-            // with Name's.
+            // 'name' fields of the idents.
             //
             // On the other hand, if the comparison does need to be hygienic,
             // one example and its non-hygienic counterpart would be:
             //      syntax::parse::token::Token::mtwt_eq
             //      syntax::ext::tt::macro_parser::token_name_eq
-            panic!("not allowed to compare these idents: {:?}, {:?}. \
-                   Probably related to issue \\#6993", self, other);
+            panic!("idents with different contexts are compared with operator `==`: \
+                {:?}, {:?}.", self, other);
         }
     }
 }
 
-/// A SyntaxContext represents a chain of macro-expandings
-/// and renamings. Each macro expansion corresponds to
-/// a fresh u32
-
-// I'm representing this syntax context as an index into
-// a table, in order to work around a compiler bug
-// that's causing unreleased memory to cause core dumps
-// and also perhaps to save some work in destructor checks.
-// the special uint '0' will be used to indicate an empty
-// syntax context.
-
-// this uint is a reference to a table stored in thread-local
-// storage.
-pub type SyntaxContext = u32;
-pub const EMPTY_CTXT : SyntaxContext = 0;
-pub const ILLEGAL_CTXT : SyntaxContext = 1;
-
-/// A name is a part of an identifier, representing a string or gensym. It's
-/// the result of interning.
-#[derive(Eq, Ord, PartialEq, PartialOrd, Hash, Clone, Copy)]
-pub struct Name(pub u32);
-
-impl<T: AsRef<str>> PartialEq<T> for Name {
-    fn eq(&self, other: &T) -> bool {
-        self.as_str() == other.as_ref()
-    }
-}
-
-impl Name {
-    pub fn as_str(&self) -> token::InternedString {
-        token::InternedString::new_from_name(*self)
-    }
-
-    pub fn usize(&self) -> usize {
-        let Name(nm) = *self;
-        nm as usize
-    }
-
-    pub fn ident(&self) -> Ident {
-        Ident { name: *self, ctxt: 0 }
-    }
-}
-
-/// A mark represents a unique id associated with a macro expansion
-pub type Mrk = u32;
-
-impl Encodable for Name {
-    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
-        s.emit_str(&self.as_str())
+impl fmt::Debug for Ident {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "{}#{}", self.name, self.ctxt.0)
     }
 }
 
-impl Decodable for Name {
-    fn decode<D: Decoder>(d: &mut D) -> Result<Name, D::Error> {
-        Ok(token::intern(&try!(d.read_str())[..]))
+impl fmt::Display for Ident {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        fmt::Display::fmt(&self.name, f)
     }
 }
 
@@ -202,8 +176,8 @@ fn decode<D: Decoder>(d: &mut D) -> Result<Ident, D::Error> {
     }
 }
 
-/// Function name (not all functions have names)
-pub type FnIdent = Option<Ident>;
+/// A mark represents a unique id associated with a macro expansion
+pub type Mrk = u32;
 
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)]
 pub struct Lifetime {
@@ -841,19 +815,16 @@ pub enum Expr_ {
     ///
     /// This is desugared to a `match` expression.
     ExprIfLet(P<Pat>, P<Expr>, P<Block>, Option<P<Expr>>),
-    // FIXME #6993: change to Option<Name> ... or not, if these are hygienic.
     /// A while loop, with an optional label
     ///
     /// `'label: while expr { block }`
     ExprWhile(P<Expr>, P<Block>, Option<Ident>),
-    // FIXME #6993: change to Option<Name> ... or not, if these are hygienic.
     /// A while-let loop, with an optional label
     ///
     /// `'label: while let pat = expr { block }`
     ///
     /// This is desugared to a combination of `loop` and `match` expressions.
     ExprWhileLet(P<Pat>, P<Expr>, P<Block>, Option<Ident>),
-    // FIXME #6993: change to Option<Name> ... or not, if these are hygienic.
     /// A for loop, with an optional label
     ///
     /// `'label: for pat in expr { block }`
@@ -863,7 +834,6 @@ pub enum Expr_ {
     /// Conditionless loop (can be exited with break, continue, or return)
     ///
     /// `'label: loop { block }`
-    // FIXME #6993: change to Option<Name> ... or not, if these are hygienic.
     ExprLoop(P<Block>, Option<Ident>),
     /// A `match` block, with a source that indicates whether or not it is
     /// the result of a desugaring, and if so, which kind.
@@ -1223,13 +1193,6 @@ pub struct MutTy {
     pub mutbl: Mutability,
 }
 
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub struct TypeField {
-    pub ident: Ident,
-    pub mt: MutTy,
-    pub span: Span,
-}
-
 /// Represents a method's signature in a trait declaration,
 /// or in an implementation.
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
index 545c69cafffed030977d2fe076b621137a0cee35..a7c496a0f7b9d164550ac5eee84414f73d1e821c 100644 (file)
@@ -576,21 +576,21 @@ mod tests {
     use ast::*;
     use super::*;
 
-    fn ident_to_segment(id : &Ident) -> PathSegment {
-        PathSegment {identifier: id.clone(),
+    fn ident_to_segment(idIdent) -> PathSegment {
+        PathSegment {identifier: id,
                      parameters: PathParameters::none()}
     }
 
     #[test] fn idents_name_eq_test() {
         assert!(segments_name_eq(
-            &[Ident{name:Name(3),ctxt:4}, Ident{name:Name(78),ctxt:82}]
-                .iter().map(ident_to_segment).collect::<Vec<PathSegment>>(),
-            &[Ident{name:Name(3),ctxt:104}, Ident{name:Name(78),ctxt:182}]
-                .iter().map(ident_to_segment).collect::<Vec<PathSegment>>()));
+            &[Ident::new(Name(3),SyntaxContext(4)), Ident::new(Name(78),SyntaxContext(82))]
+                .iter().cloned().map(ident_to_segment).collect::<Vec<PathSegment>>(),
+            &[Ident::new(Name(3),SyntaxContext(104)), Ident::new(Name(78),SyntaxContext(182))]
+                .iter().cloned().map(ident_to_segment).collect::<Vec<PathSegment>>()));
         assert!(!segments_name_eq(
-            &[Ident{name:Name(3),ctxt:4}, Ident{name:Name(78),ctxt:82}]
-                .iter().map(ident_to_segment).collect::<Vec<PathSegment>>(),
-            &[Ident{name:Name(3),ctxt:104}, Ident{name:Name(77),ctxt:182}]
-                .iter().map(ident_to_segment).collect::<Vec<PathSegment>>()));
+            &[Ident::new(Name(3),SyntaxContext(4)), Ident::new(Name(78),SyntaxContext(82))]
+                .iter().cloned().map(ident_to_segment).collect::<Vec<PathSegment>>(),
+            &[Ident::new(Name(3),SyntaxContext(104)), Ident::new(Name(77),SyntaxContext(182))]
+                .iter().cloned().map(ident_to_segment).collect::<Vec<PathSegment>>()));
     }
 }
index 56a15ce895cf24f7fddc0cfd75f6e4e273b3095e..1f8c726bf6880d4ab8c51ee30cc945b151331535 100644 (file)
@@ -1083,7 +1083,6 @@ pub struct MalformedCodemapPositions {
 #[cfg(test)]
 mod tests {
     use super::*;
-    use std::rc::Rc;
 
     #[test]
     fn t1 () {
index c177eb1f00bbd39fe7e994b67f79180f9ec998b5..6b4a5538501866b4aa8f613c6537d7d80f7bbb99 100644 (file)
@@ -842,7 +842,7 @@ pub fn expect<T, M>(diag: &SpanHandler, opt: Option<T>, msg: M) -> T where
 #[cfg(test)]
 mod test {
     use super::{EmitterWriter, Level};
-    use codemap::{mk_sp, CodeMap, BytePos};
+    use codemap::{mk_sp, CodeMap};
     use std::sync::{Arc, Mutex};
     use std::io::{self, Write};
     use std::str::from_utf8;
index 6c3bee3f48ed9c90fe71abd9a3fd236f9c950e90..a276765e2161692ab636ec3ea164ad443219b32e 100644 (file)
@@ -138,7 +138,7 @@ pub fn expand_register_diagnostic<'cx>(ecx: &'cx mut ExtCtxt,
             ));
         }
     });
-    let sym = Ident::new(token::gensym(&format!(
+    let sym = Ident::with_empty_ctxt(token::gensym(&format!(
         "__register_diagnostic_{}", code
     )));
     MacEager::items(SmallVector::many(vec![
index 2b4df3186de6bc99629189e254d616d51a308857..ddc4443a77c9d7aa290aeb0511613560de3d5179 100644 (file)
@@ -28,7 +28,7 @@ pub fn entry_point_type(item: &Item, depth: usize) -> EntryPointType {
                 EntryPointType::Start
             } else if attr::contains_name(&item.attrs, "main") {
                 EntryPointType::MainAttr
-            } else if item.ident.name == "main" {
+            } else if item.ident.name.as_str() == "main" {
                 if depth == 1 {
                     // This is a top-level function so can be 'main'
                     EntryPointType::MainNamed
index 775d47a8c0e087fc782e66479de426fd6a51bd84..aaaca8bd4d8e2229d922832ceddda8df0ed6d0fe 100644 (file)
@@ -646,7 +646,7 @@ pub fn expansion_cause(&self) -> Span {
         loop {
             if self.codemap().with_expn_info(expn_id, |info| {
                 info.map_or(None, |i| {
-                    if i.callee.name() == "include" {
+                    if i.callee.name().as_str() == "include" {
                         // Stop going up the backtrace once include! is encountered
                         return None;
                     }
@@ -899,9 +899,9 @@ fn find_escape_frame<'a>(&'a mut self) -> &'a mut MapChainFrame {
         unreachable!()
     }
 
-    pub fn find(&self, k: &Name) -> Option<Rc<SyntaxExtension>> {
+    pub fn find(&self, k: Name) -> Option<Rc<SyntaxExtension>> {
         for frame in self.chain.iter().rev() {
-            match frame.map.get(k) {
+            match frame.map.get(&k) {
                 Some(v) => return Some(v.clone()),
                 None => {}
             }
index f8beb0e36e2c34ee869ffd40694260b458bc0090..5b35b870c305a879d6664ad9c84f868fda071a93 100644 (file)
@@ -73,7 +73,6 @@ fn ty_ptr(&self, span: Span,
 
     fn ty_vars(&self, ty_params: &OwnedSlice<ast::TyParam>) -> Vec<P<ast::Ty>> ;
     fn ty_vars_global(&self, ty_params: &OwnedSlice<ast::TyParam>) -> Vec<P<ast::Ty>> ;
-    fn ty_field_imm(&self, span: Span, name: Ident, ty: P<ast::Ty>) -> ast::TypeField;
 
     fn typaram(&self,
                span: Span,
@@ -443,14 +442,6 @@ fn ty_option(&self, ty: P<ast::Ty>) -> P<ast::Ty> {
                           Vec::new()))
     }
 
-    fn ty_field_imm(&self, span: Span, name: Ident, ty: P<ast::Ty>) -> ast::TypeField {
-        ast::TypeField {
-            ident: name,
-            mt: ast::MutTy { ty: ty, mutbl: ast::MutImmutable },
-            span: span,
-        }
-    }
-
     fn ty_infer(&self, span: Span) -> P<ast::Ty> {
         self.ty(span, ast::TyInfer)
     }
index e14e48c022d1aee80be8a4b00538088b267398d7..6173630175a1b9f8c66606482c5c897b159d5f54 100644 (file)
@@ -524,7 +524,7 @@ fn expand_mac_invoc<T, F, G>(mac: ast::Mac,
         return None;
     }
     let extname = pth.segments[0].identifier.name;
-    match fld.cx.syntax_env.find(&extname) {
+    match fld.cx.syntax_env.find(extname) {
         None => {
             fld.cx.span_err(
                 pth.span,
@@ -593,7 +593,7 @@ fn expand_loop_block(loop_block: P<Block>,
                      fld: &mut MacroExpander) -> (P<Block>, Option<Ident>) {
     match opt_ident {
         Some(label) => {
-            let new_label = fresh_name(&label);
+            let new_label = fresh_name(label);
             let rename = (label, new_label);
 
             // The rename *must not* be added to the pending list of current
@@ -689,7 +689,7 @@ pub fn expand_item_mac(it: P<ast::Item>,
 
     let fm = fresh_mark();
     let items = {
-        let expanded = match fld.cx.syntax_env.find(&extname) {
+        let expanded = match fld.cx.syntax_env.find(extname) {
             None => {
                 fld.cx.span_err(path_span,
                                 &format!("macro undefined: '{}!'",
@@ -892,7 +892,7 @@ fn expand_non_macro_stmt(Spanned {node, span: stmt_span}: Stmt, fld: &mut MacroE
                     // generate fresh names, push them to a new pending list
                     let idents = pattern_bindings(&*expanded_pat);
                     let mut new_pending_renames =
-                        idents.iter().map(|ident| (*ident, fresh_name(ident))).collect();
+                        idents.iter().map(|ident| (*ident, fresh_name(*ident))).collect();
                     // rewrite the pattern using the new names (the old
                     // ones have already been applied):
                     let rewritten_pat = {
@@ -951,7 +951,7 @@ fn expand_arm(arm: ast::Arm, fld: &mut MacroExpander) -> ast::Arm {
     // all of the pats must have the same set of bindings, so use the
     // first one to extract them and generate new names:
     let idents = pattern_bindings(&*expanded_pats[0]);
-    let new_renames = idents.into_iter().map(|id| (id, fresh_name(&id))).collect();
+    let new_renames = idents.into_iter().map(|id| (id, fresh_name(id))).collect();
     // apply the renaming, but only to the PatIdents:
     let mut rename_pats_fld = PatIdentRenamer{renames:&new_renames};
     let rewritten_pats = expanded_pats.move_map(|pat| rename_pats_fld.fold_pat(pat));
@@ -1061,7 +1061,7 @@ fn expand_pat(p: P<ast::Pat>, fld: &mut MacroExpander) -> P<ast::Pat> {
             return DummyResult::raw_pat(span);
         }
         let extname = pth.segments[0].identifier.name;
-        let marked_after = match fld.cx.syntax_env.find(&extname) {
+        let marked_after = match fld.cx.syntax_env.find(extname) {
             None => {
                 fld.cx.span_err(pth.span,
                                 &format!("macro undefined: '{}!'",
@@ -1134,10 +1134,7 @@ pub struct IdentRenamer<'a> {
 
 impl<'a> Folder for IdentRenamer<'a> {
     fn fold_ident(&mut self, id: Ident) -> Ident {
-        Ident {
-            name: id.name,
-            ctxt: mtwt::apply_renames(self.renames, id.ctxt),
-        }
+        Ident::new(id.name, mtwt::apply_renames(self.renames, id.ctxt))
     }
     fn fold_mac(&mut self, mac: ast::Mac) -> ast::Mac {
         fold::noop_fold_mac(mac, self)
@@ -1161,8 +1158,8 @@ fn fold_pat(&mut self, pat: P<ast::Pat>) -> P<ast::Pat> {
 
         pat.map(|ast::Pat {id, node, span}| match node {
             ast::PatIdent(binding_mode, Spanned{span: sp, node: ident}, sub) => {
-                let new_ident = Ident{name: ident.name,
-                                      ctxt: mtwt::apply_renames(self.renames, ident.ctxt)};
+                let new_ident = Ident::new(ident.name,
+                                           mtwt::apply_renames(self.renames, ident.ctxt));
                 let new_node =
                     ast::PatIdent(binding_mode,
                                   Spanned{span: self.new_span(sp), node: new_ident},
@@ -1254,7 +1251,7 @@ fn $fn_name(attrs: &[ast::Attribute],
                     fld: &MacroExpander)
                      -> (Vec<ast::Attribute>, Vec<ast::Attribute>) {
             attrs.iter().cloned().partition(|attr| {
-                match fld.cx.syntax_env.find(&intern(&attr.name())) {
+                match fld.cx.syntax_env.find(intern(&attr.name())) {
                     Some(rc) => match *rc {
                         $variant(..) => true,
                         _ => false
@@ -1276,7 +1273,7 @@ fn expand_decorators(a: Annotatable,
 {
     for attr in a.attrs() {
         let mname = intern(&attr.name());
-        match fld.cx.syntax_env.find(&mname) {
+        match fld.cx.syntax_env.find(mname) {
             Some(rc) => match *rc {
                 MultiDecorator(ref dec) => {
                     attr::mark_used(&attr);
@@ -1327,7 +1324,7 @@ fn expand_item_multi_modifier(mut it: Annotatable,
     for attr in &modifiers {
         let mname = intern(&attr.name());
 
-        match fld.cx.syntax_env.find(&mname) {
+        match fld.cx.syntax_env.find(mname) {
             Some(rc) => match *rc {
                 MultiModifier(ref mac) => {
                     attr::mark_used(attr);
@@ -1407,7 +1404,7 @@ fn expand_and_rename_fn_decl_and_block(fn_decl: P<ast::FnDecl>, block: P<ast::Bl
     let expanded_decl = fld.fold_fn_decl(fn_decl);
     let idents = fn_decl_arg_bindings(&*expanded_decl);
     let renames =
-        idents.iter().map(|id : &ast::Ident| (*id,fresh_name(id))).collect();
+        idents.iter().map(|id| (*id,fresh_name(*id))).collect();
     // first, a renamer for the PatIdents, for the fn_decl:
     let mut rename_pat_fld = PatIdentRenamer{renames: &renames};
     let rewritten_fn_decl = rename_pat_fld.fold_fn_decl(expanded_decl);
@@ -1628,10 +1625,7 @@ struct Marker { mark: Mrk }
 
 impl Folder for Marker {
     fn fold_ident(&mut self, id: Ident) -> Ident {
-        ast::Ident {
-            name: id.name,
-            ctxt: mtwt::apply_mark(self.mark, id.ctxt)
-        }
+        ast::Ident::new(id.name, mtwt::apply_mark(self.mark, id.ctxt))
     }
     fn fold_mac(&mut self, Spanned {node, span}: ast::Mac) -> ast::Mac {
         Spanned {
@@ -2104,7 +2098,7 @@ fn fmt_in_macro_used_inside_module_macro() {
         // find the xx binding
         let bindings = crate_bindings(&cr);
         let cxbinds: Vec<&ast::Ident> =
-            bindings.iter().filter(|b| b.name == "xx").collect();
+            bindings.iter().filter(|b| b.name.as_str() == "xx").collect();
         let cxbinds: &[&ast::Ident] = &cxbinds[..];
         let cxbind = match (cxbinds.len(), cxbinds.get(0)) {
             (1, Some(b)) => *b,
@@ -2116,7 +2110,7 @@ fn fmt_in_macro_used_inside_module_macro() {
         // the xx binding should bind all of the xx varrefs:
         for (idx,v) in varrefs.iter().filter(|p| {
             p.segments.len() == 1
-            && p.segments[0].identifier.name == "xx"
+            && p.segments[0].identifier.name.as_str() == "xx"
         }).enumerate() {
             if mtwt::resolve(v.segments[0].identifier) != resolved_binding {
                 println!("uh oh, xx binding didn't match xx varref:");
index ce83b84efee805ac9d129d921a54b0e4296bbe3f..21b4c77b9f867283591338bd0199bcb81524b2fa 100644 (file)
@@ -35,7 +35,7 @@
 pub struct SCTable {
     table: RefCell<Vec<SyntaxContext_>>,
     mark_memo: RefCell<HashMap<(SyntaxContext,Mrk),SyntaxContext>>,
-    rename_memo: RefCell<HashMap<(SyntaxContext,Ident,Name),SyntaxContext>>,
+    rename_memo: RefCell<HashMap<(SyntaxContext,Name,SyntaxContext,Name),SyntaxContext>>,
 }
 
 #[derive(PartialEq, RustcEncodable, RustcDecodable, Hash, Debug, Copy, Clone)]
@@ -66,8 +66,9 @@ pub fn apply_mark(m: Mrk, ctxt: SyntaxContext) -> SyntaxContext {
 /// Extend a syntax context with a given mark and sctable (explicit memoization)
 fn apply_mark_internal(m: Mrk, ctxt: SyntaxContext, table: &SCTable) -> SyntaxContext {
     let key = (ctxt, m);
-    * table.mark_memo.borrow_mut().entry(key)
-        .or_insert_with(|| idx_push(&mut *table.table.borrow_mut(), Mark(m, ctxt)))
+    *table.mark_memo.borrow_mut().entry(key).or_insert_with(|| {
+        SyntaxContext(idx_push(&mut *table.table.borrow_mut(), Mark(m, ctxt)))
+    })
 }
 
 /// Extend a syntax context with a given rename
@@ -81,10 +82,11 @@ fn apply_rename_internal(id: Ident,
                        to: Name,
                        ctxt: SyntaxContext,
                        table: &SCTable) -> SyntaxContext {
-    let key = (ctxt, id, to);
+    let key = (ctxt, id.name, id.ctxt, to);
 
-    * table.rename_memo.borrow_mut().entry(key)
-        .or_insert_with(|| idx_push(&mut *table.table.borrow_mut(), Rename(id, to, ctxt)))
+    *table.rename_memo.borrow_mut().entry(key).or_insert_with(|| {
+            SyntaxContext(idx_push(&mut *table.table.borrow_mut(), Rename(id, to, ctxt)))
+    })
 }
 
 /// Apply a list of renamings to a context
@@ -185,20 +187,20 @@ fn resolve_internal(id: Ident,
     }
 
     let resolved = {
-        let result = (*table.table.borrow())[id.ctxt as usize];
+        let result = (*table.table.borrow())[id.ctxt.0 as usize];
         match result {
             EmptyCtxt => id.name,
             // ignore marks here:
             Mark(_,subctxt) =>
-                resolve_internal(Ident{name:id.name, ctxt: subctxt},
+                resolve_internal(Ident::new(id.name, subctxt),
                                  table, resolve_table),
             // do the rename if necessary:
             Rename(Ident{name, ctxt}, toname, subctxt) => {
                 let resolvedfrom =
-                    resolve_internal(Ident{name:name, ctxt:ctxt},
+                    resolve_internal(Ident::new(name, ctxt),
                                      table, resolve_table);
                 let resolvedthis =
-                    resolve_internal(Ident{name:id.name, ctxt:subctxt},
+                    resolve_internal(Ident::new(id.name, subctxt),
                                      table, resolve_table);
                 if (resolvedthis == resolvedfrom)
                     && (marksof_internal(ctxt, resolvedthis, table)
@@ -229,7 +231,7 @@ fn marksof_internal(ctxt: SyntaxContext,
     let mut result = Vec::new();
     let mut loopvar = ctxt;
     loop {
-        let table_entry = (*table.table.borrow())[loopvar as usize];
+        let table_entry = (*table.table.borrow())[loopvar.0 as usize];
         match table_entry {
             EmptyCtxt => {
                 return result;
@@ -256,7 +258,7 @@ fn marksof_internal(ctxt: SyntaxContext,
 /// FAILS when outside is not a mark.
 pub fn outer_mark(ctxt: SyntaxContext) -> Mrk {
     with_sctable(|sctable| {
-        match (*sctable.table.borrow())[ctxt as usize] {
+        match (*sctable.table.borrow())[ctxt.0 as usize] {
             Mark(mrk, _) => mrk,
             _ => panic!("can't retrieve outer mark when outside is not a mark")
         }
@@ -302,7 +304,7 @@ fn xorpush_test () {
     }
 
     fn id(n: u32, s: SyntaxContext) -> Ident {
-        Ident {name: Name(n), ctxt: s}
+        Ident::new(Name(n), s)
     }
 
     // because of the SCTable, I now need a tidy way of
@@ -328,7 +330,7 @@ fn refold_test_sc(mut sc: SyntaxContext, table : &SCTable) -> Vec<TestSC> {
         let mut result = Vec::new();
         loop {
             let table = table.table.borrow();
-            match (*table)[sc as usize] {
+            match (*table)[sc.0 as usize] {
                 EmptyCtxt => {return result;},
                 Mark(mrk,tail) => {
                     result.push(M(mrk));
@@ -349,15 +351,15 @@ fn refold_test_sc(mut sc: SyntaxContext, table : &SCTable) -> Vec<TestSC> {
     fn test_unfold_refold(){
         let mut t = new_sctable_internal();
 
-        let test_sc = vec!(M(3),R(id(101,0),Name(14)),M(9));
-        assert_eq!(unfold_test_sc(test_sc.clone(),EMPTY_CTXT,&mut t),4);
+        let test_sc = vec!(M(3),R(id(101,EMPTY_CTXT),Name(14)),M(9));
+        assert_eq!(unfold_test_sc(test_sc.clone(),EMPTY_CTXT,&mut t),SyntaxContext(4));
         {
             let table = t.table.borrow();
-            assert!((*table)[2] == Mark(9,0));
-            assert!((*table)[3] == Rename(id(101,0),Name(14),2));
-            assert!((*table)[4] == Mark(3,3));
+            assert!((*table)[2] == Mark(9,EMPTY_CTXT));
+            assert!((*table)[3] == Rename(id(101,EMPTY_CTXT),Name(14),SyntaxContext(2)));
+            assert!((*table)[4] == Mark(3,SyntaxContext(3)));
         }
-        assert_eq!(refold_test_sc(4,&t),test_sc);
+        assert_eq!(refold_test_sc(SyntaxContext(4),&t),test_sc);
     }
 
     // extend a syntax context with a sequence of marks given
@@ -371,11 +373,11 @@ fn unfold_marks(mrks: Vec<Mrk> , tail: SyntaxContext, table: &SCTable)
     #[test] fn unfold_marks_test() {
         let mut t = new_sctable_internal();
 
-        assert_eq!(unfold_marks(vec!(3,7),EMPTY_CTXT,&mut t),3);
+        assert_eq!(unfold_marks(vec!(3,7),EMPTY_CTXT,&mut t),SyntaxContext(3));
         {
             let table = t.table.borrow();
-            assert!((*table)[2] == Mark(7,0));
-            assert!((*table)[3] == Mark(3,2));
+            assert!((*table)[2] == Mark(7,EMPTY_CTXT));
+            assert!((*table)[3] == Mark(3,SyntaxContext(2)));
         }
     }
 
@@ -396,7 +398,7 @@ fn test_marksof () {
          assert_eq! (marksof_internal (ans, stopname,&t), [16]);}
         // rename where stop doesn't match:
         { let chain = vec!(M(9),
-                        R(id(name1.usize() as u32,
+                        R(id(name1.0,
                              apply_mark_internal (4, EMPTY_CTXT,&mut t)),
                           Name(100101102)),
                         M(14));
@@ -405,7 +407,7 @@ fn test_marksof () {
         // rename where stop does match
         { let name1sc = apply_mark_internal(4, EMPTY_CTXT, &mut t);
          let chain = vec!(M(9),
-                       R(id(name1.usize() as u32, name1sc),
+                       R(id(name1.0, name1sc),
                          stopname),
                        M(14));
          let ans = unfold_test_sc(chain,EMPTY_CTXT,&mut t);
@@ -474,10 +476,10 @@ fn mtwt_resolve_test(){
     #[test]
     fn hashing_tests () {
         let mut t = new_sctable_internal();
-        assert_eq!(apply_mark_internal(12,EMPTY_CTXT,&mut t),2);
-        assert_eq!(apply_mark_internal(13,EMPTY_CTXT,&mut t),3);
+        assert_eq!(apply_mark_internal(12,EMPTY_CTXT,&mut t),SyntaxContext(2));
+        assert_eq!(apply_mark_internal(13,EMPTY_CTXT,&mut t),SyntaxContext(3));
         // using the same one again should result in the same index:
-        assert_eq!(apply_mark_internal(12,EMPTY_CTXT,&mut t),2);
+        assert_eq!(apply_mark_internal(12,EMPTY_CTXT,&mut t),SyntaxContext(2));
         // I'm assuming that the rename table will behave the same....
     }
 
@@ -496,10 +498,10 @@ fn resolve_table_hashing_tests() {
 
     #[test]
     fn new_resolves_test() {
-        let renames = vec!((Ident{name:Name(23),ctxt:EMPTY_CTXT},Name(24)),
-                           (Ident{name:Name(29),ctxt:EMPTY_CTXT},Name(29)));
+        let renames = vec!((Ident::with_empty_ctxt(Name(23)),Name(24)),
+                           (Ident::with_empty_ctxt(Name(29)),Name(29)));
         let new_ctxt1 = apply_renames(&renames,EMPTY_CTXT);
-        assert_eq!(resolve(Ident{name:Name(23),ctxt:new_ctxt1}),Name(24));
-        assert_eq!(resolve(Ident{name:Name(29),ctxt:new_ctxt1}),Name(29));
+        assert_eq!(resolve(Ident::new(Name(23),new_ctxt1)),Name(24));
+        assert_eq!(resolve(Ident::new(Name(29),new_ctxt1)),Name(29));
     }
 }
index b8168297190562b611cc573559f11bcb511640d8..e9a5d9148241d3fdc70505dfd394bdc23eb5e339 100644 (file)
@@ -464,7 +464,7 @@ macro_rules! mk_lit {
         ($name: expr, $suffix: expr, $($args: expr),*) => {{
             let inner = cx.expr_call(sp, mk_token_path(cx, sp, $name), vec![$($args),*]);
             let suffix = match $suffix {
-                Some(name) => cx.expr_some(sp, mk_name(cx, sp, ast::Ident::new(name))),
+                Some(name) => cx.expr_some(sp, mk_name(cx, sp, ast::Ident::with_empty_ctxt(name))),
                 None => cx.expr_none(sp)
             };
             cx.expr_call(sp, mk_token_path(cx, sp, "Literal"), vec![inner, suffix])
@@ -489,31 +489,32 @@ macro_rules! mk_lit {
         }
 
         token::Literal(token::Byte(i), suf) => {
-            let e_byte = mk_name(cx, sp, i.ident());
+            let e_byte = mk_name(cx, sp, ast::Ident::with_empty_ctxt(i));
             return mk_lit!("Byte", suf, e_byte);
         }
 
         token::Literal(token::Char(i), suf) => {
-            let e_char = mk_name(cx, sp, i.ident());
+            let e_char = mk_name(cx, sp, ast::Ident::with_empty_ctxt(i));
             return mk_lit!("Char", suf, e_char);
         }
 
         token::Literal(token::Integer(i), suf) => {
-            let e_int = mk_name(cx, sp, i.ident());
+            let e_int = mk_name(cx, sp, ast::Ident::with_empty_ctxt(i));
             return mk_lit!("Integer", suf, e_int);
         }
 
         token::Literal(token::Float(fident), suf) => {
-            let e_fident = mk_name(cx, sp, fident.ident());
+            let e_fident = mk_name(cx, sp, ast::Ident::with_empty_ctxt(fident));
             return mk_lit!("Float", suf, e_fident);
         }
 
         token::Literal(token::Str_(ident), suf) => {
-            return mk_lit!("Str_", suf, mk_name(cx, sp, ident.ident()))
+            return mk_lit!("Str_", suf, mk_name(cx, sp, ast::Ident::with_empty_ctxt(ident)))
         }
 
         token::Literal(token::StrRaw(ident, n), suf) => {
-            return mk_lit!("StrRaw", suf, mk_name(cx, sp, ident.ident()), cx.expr_usize(sp, n))
+            return mk_lit!("StrRaw", suf, mk_name(cx, sp, ast::Ident::with_empty_ctxt(ident)),
+                           cx.expr_usize(sp, n))
         }
 
         token::Ident(ident, style) => {
@@ -535,7 +536,7 @@ macro_rules! mk_lit {
         token::DocComment(ident) => {
             return cx.expr_call(sp,
                                 mk_token_path(cx, sp, "DocComment"),
-                                vec!(mk_name(cx, sp, ident.ident())));
+                                vec!(mk_name(cx, sp, ast::Ident::with_empty_ctxt(ident))));
         }
 
         token::MatchNt(name, kind, namep, kindp) => {
index f6513cc3e255297d279dae08d18274302c62fb09..01fd4608ecb361cbd8e5de12de4f8e445dd39875 100644 (file)
@@ -79,7 +79,7 @@
 use self::TokenTreeOrTokenTreeVec::*;
 
 use ast;
-use ast::{TokenTree, Ident};
+use ast::{TokenTree, Name};
 use ast::{TtDelimited, TtSequence, TtToken};
 use codemap::{BytePos, mk_sp, Span};
 use codemap;
@@ -202,9 +202,9 @@ pub enum NamedMatch {
 }
 
 pub fn nameize(p_s: &ParseSess, ms: &[TokenTree], res: &[Rc<NamedMatch>])
-            -> HashMap<Ident, Rc<NamedMatch>> {
+            -> HashMap<Name, Rc<NamedMatch>> {
     fn n_rec(p_s: &ParseSess, m: &TokenTree, res: &[Rc<NamedMatch>],
-             ret_val: &mut HashMap<Ident, Rc<NamedMatch>>, idx: &mut usize) {
+             ret_val: &mut HashMap<Name, Rc<NamedMatch>>, idx: &mut usize) {
         match m {
             &TtSequence(_, ref seq) => {
                 for next_m in &seq.tts {
@@ -217,7 +217,7 @@ fn n_rec(p_s: &ParseSess, m: &TokenTree, res: &[Rc<NamedMatch>],
                 }
             }
             &TtToken(sp, MatchNt(bind_name, _, _, _)) => {
-                match ret_val.entry(bind_name) {
+                match ret_val.entry(bind_name.name) {
                     Vacant(spot) => {
                         spot.insert(res[*idx].clone());
                         *idx += 1;
@@ -246,7 +246,7 @@ pub enum ParseResult<T> {
     Error(codemap::Span, String)
 }
 
-pub type NamedParseResult = ParseResult<HashMap<Ident, Rc<NamedMatch>>>;
+pub type NamedParseResult = ParseResult<HashMap<Name, Rc<NamedMatch>>>;
 pub type PositionalParseResult = ParseResult<Vec<Rc<NamedMatch>>>;
 
 /// Perform a token equality check, ignoring syntax context (that is, an
index d728fa59bd1df3e02aa2047b5ea49d5ea367feeb..0a95f24a7210df8eb63c6ea86f913ccbc3036a8c 100644 (file)
@@ -282,7 +282,7 @@ pub fn compile<'cx>(cx: &'cx mut ExtCtxt,
     };
 
     // Extract the arguments:
-    let lhses = match **argument_map.get(&lhs_nm).unwrap() {
+    let lhses = match **argument_map.get(&lhs_nm.name).unwrap() {
         MatchedSeq(ref s, _) => /* FIXME (#2543) */ (*s).clone(),
         _ => cx.span_bug(def.span, "wrong-structured lhs")
     };
@@ -291,7 +291,7 @@ pub fn compile<'cx>(cx: &'cx mut ExtCtxt,
         check_lhs_nt_follows(cx, &**lhs, def.span);
     }
 
-    let rhses = match **argument_map.get(&rhs_nm).unwrap() {
+    let rhses = match **argument_map.get(&rhs_nm.name).unwrap() {
         MatchedSeq(ref s, _) => /* FIXME (#2543) */ (*s).clone(),
         _ => cx.span_bug(def.span, "wrong-structured rhs")
     };
@@ -510,14 +510,14 @@ fn is_in_follow(_: &ExtCtxt, tok: &Token, frag: &str) -> Result<bool, String> {
             "pat" => {
                 match *tok {
                     FatArrow | Comma | Eq => Ok(true),
-                    Ident(i, _) if i.name == "if" || i.name == "in" => Ok(true),
+                    Ident(i, _) if i.name.as_str() == "if" || i.name.as_str() == "in" => Ok(true),
                     _ => Ok(false)
                 }
             },
             "path" | "ty" => {
                 match *tok {
                     Comma | FatArrow | Colon | Eq | Gt | Semi => Ok(true),
-                    Ident(i, _) if i.name == "as" => Ok(true),
+                    Ident(i, _) if i.name.as_str() == "as" => Ok(true),
                     _ => Ok(false)
                 }
             },
index b07bd099638642d556fa3c461cf44428009106cb..d1e48eda4ffd2f46b774fe6c3e5e39dd022767df 100644 (file)
@@ -10,7 +10,7 @@
 use self::LockstepIterSize::*;
 
 use ast;
-use ast::{TokenTree, TtDelimited, TtToken, TtSequence, Ident};
+use ast::{TokenTree, TtDelimited, TtToken, TtSequence, Ident, Name};
 use codemap::{Span, DUMMY_SP};
 use diagnostic::SpanHandler;
 use ext::tt::macro_parser::{NamedMatch, MatchedSeq, MatchedNonterminal};
@@ -38,7 +38,7 @@ pub struct TtReader<'a> {
     /// the unzipped tree:
     stack: Vec<TtFrame>,
     /* for MBE-style macro transcription */
-    interpolations: HashMap<Ident, Rc<NamedMatch>>,
+    interpolations: HashMap<Name, Rc<NamedMatch>>,
     imported_from: Option<Ident>,
 
     // Some => return imported_from as the next token
@@ -56,7 +56,7 @@ pub struct TtReader<'a> {
 /// `src` contains no `TtSequence`s, `MatchNt`s or `SubstNt`s, `interp` can
 /// (and should) be None.
 pub fn new_tt_reader<'a>(sp_diag: &'a SpanHandler,
-                         interp: Option<HashMap<Ident, Rc<NamedMatch>>>,
+                         interp: Option<HashMap<Name, Rc<NamedMatch>>>,
                          imported_from: Option<Ident>,
                          src: Vec<ast::TokenTree>)
                          -> TtReader<'a> {
@@ -70,7 +70,7 @@ pub fn new_tt_reader<'a>(sp_diag: &'a SpanHandler,
 /// `src` contains no `TtSequence`s, `MatchNt`s or `SubstNt`s, `interp` can
 /// (and should) be None.
 pub fn new_tt_reader_with_doc_flag<'a>(sp_diag: &'a SpanHandler,
-                                       interp: Option<HashMap<Ident, Rc<NamedMatch>>>,
+                                       interp: Option<HashMap<Name, Rc<NamedMatch>>>,
                                        imported_from: Option<Ident>,
                                        src: Vec<ast::TokenTree>,
                                        desugar_doc_comments: bool)
@@ -117,7 +117,7 @@ fn lookup_cur_matched_by_matched(r: &TtReader, start: Rc<NamedMatch>) -> Rc<Name
 }
 
 fn lookup_cur_matched(r: &TtReader, name: Ident) -> Option<Rc<NamedMatch>> {
-    let matched_opt = r.interpolations.get(&name).cloned();
+    let matched_opt = r.interpolations.get(&name.name).cloned();
     matched_opt.map(|s| lookup_cur_matched_by_matched(r, s))
 }
 
index eaf964a3c64f1da1761ac37cfdd81b0a77594757..18c6d74d62ec25bd8be6e0dc99b5fce2f1634e4a 100644 (file)
@@ -35,7 +35,7 @@
 use diagnostic::SpanHandler;
 use visit;
 use visit::{FnKind, Visitor};
-use parse::token::{self, InternedString};
+use parse::token::InternedString;
 
 use std::ascii::AsciiExt;
 use std::cmp;
 
     // allow `#[omit_gdb_pretty_printer_section]`
     ("omit_gdb_pretty_printer_section", "1.5.0", None, Active),
+
+    // Allows cfg(target_vendor = "...").
+    ("cfg_target_vendor", "1.5.0", None, Active),
 ];
 // (changing above list without updating src/doc/reference.md makes @cmr sad)
 
@@ -377,6 +380,7 @@ fn f($x: &Features) -> bool {
 const GATED_CFGS: &'static [(&'static str, &'static str, fn(&Features) -> bool)] = &[
     // (name in cfg, feature, function to check if the feature is enabled)
     ("target_feature", "cfg_target_feature", cfg_fn!(|x| x.cfg_target_feature)),
+    ("target_vendor", "cfg_target_vendor", cfg_fn!(|x| x.cfg_target_vendor)),
 ];
 
 #[derive(Debug, Eq, PartialEq)]
@@ -471,6 +475,7 @@ pub struct Features {
     pub default_type_parameter_fallback: bool,
     pub type_macros: bool,
     pub cfg_target_feature: bool,
+    pub cfg_target_vendor: bool,
     pub augmented_assignments: bool,
 }
 
@@ -500,6 +505,7 @@ pub fn new() -> Features {
             default_type_parameter_fallback: false,
             type_macros: false,
             cfg_target_feature: false,
+            cfg_target_vendor: false,
             augmented_assignments: false,
         }
     }
@@ -667,7 +673,7 @@ struct MacroVisitor<'a> {
 impl<'a, 'v> Visitor<'v> for MacroVisitor<'a> {
     fn visit_mac(&mut self, mac: &ast::Mac) {
         let path = &mac.node.path;
-        let id = path.segments.last().unwrap().identifier;
+        let name = path.segments.last().unwrap().identifier.name.as_str();
 
         // Issue 22234: If you add a new case here, make sure to also
         // add code to catch the macro during or after expansion.
@@ -677,19 +683,19 @@ fn visit_mac(&mut self, mac: &ast::Mac) {
         // catch uses of these macros within conditionally-compiled
         // code, e.g. `#[cfg]`-guarded functions.
 
-        if id == token::str_to_ident("asm") {
+        if name == "asm" {
             self.context.gate_feature("asm", path.span, EXPLAIN_ASM);
         }
 
-        else if id == token::str_to_ident("log_syntax") {
+        else if name == "log_syntax" {
             self.context.gate_feature("log_syntax", path.span, EXPLAIN_LOG_SYNTAX);
         }
 
-        else if id == token::str_to_ident("trace_macros") {
+        else if name == "trace_macros" {
             self.context.gate_feature("trace_macros", path.span, EXPLAIN_TRACE_MACROS);
         }
 
-        else if id == token::str_to_ident("concat_idents") {
+        else if name == "concat_idents" {
             self.context.gate_feature("concat_idents", path.span, EXPLAIN_CONCAT_IDENTS);
         }
     }
@@ -1069,6 +1075,7 @@ fn check_crate_inner<F>(cm: &CodeMap, span_handler: &SpanHandler,
         default_type_parameter_fallback: cx.has_feature("default_type_parameter_fallback"),
         type_macros: cx.has_feature("type_macros"),
         cfg_target_feature: cx.has_feature("cfg_target_feature"),
+        cfg_target_vendor: cx.has_feature("cfg_target_vendor"),
         augmented_assignments: cx.has_feature("augmented_assignments"),
     }
 }
index 18588c59357b29c9d0e056474ee61caf3bf408cf..015cf60f0cfdb4c9b50cd99c1e7881f8a0c95fbf 100644 (file)
@@ -40,7 +40,7 @@ fn parse_outer_attributes(&mut self) -> Vec<ast::Attribute> {
               token::DocComment(s) => {
                 let attr = ::attr::mk_sugared_doc_attr(
                     attr::mk_attr_id(),
-                    self.id_to_interned_str(s.ident()),
+                    self.id_to_interned_str(ast::Ident::with_empty_ctxt(s)),
                     self.span.lo,
                     self.span.hi
                 );
@@ -137,9 +137,8 @@ fn parse_inner_attributes(&mut self) -> Vec<ast::Attribute> {
                 token::DocComment(s) => {
                     // we need to get the position of this token before we bump.
                     let Span { lo, hi, .. } = self.span;
-                    let attr = attr::mk_sugared_doc_attr(attr::mk_attr_id(),
-                                                         self.id_to_interned_str(s.ident()),
-                                                         lo, hi);
+                    let str = self.id_to_interned_str(ast::Ident::with_empty_ctxt(s));
+                    let attr = attr::mk_sugared_doc_attr(attr::mk_attr_id(), str, lo, hi);
                     if attr.node.style == ast::AttrInner {
                         attrs.push(attr);
                         panictry!(self.bump());
index 279c987fcba6567c5b69b6d0c7dfe9e4948aea00..5beec702f8cfb1ab08412bc32a898debab885e86 100644 (file)
@@ -744,8 +744,8 @@ fn string_to_tts_macro () {
                 Some(&ast::TtToken(_, token::Ident(name_zip, token::Plain))),
                 Some(&ast::TtDelimited(_, ref macro_delimed)),
             )
-            if name_macro_rules.name == "macro_rules"
-            && name_zip.name == "zip" => {
+            if name_macro_rules.name.as_str() == "macro_rules"
+            && name_zip.name.as_str() == "zip" => {
                 let tts = &macro_delimed.tts[..];
                 match (tts.len(), tts.get(0), tts.get(1), tts.get(2)) {
                     (
@@ -763,7 +763,7 @@ fn string_to_tts_macro () {
                                 Some(&ast::TtToken(_, token::Ident(ident, token::Plain))),
                             )
                             if first_delimed.delim == token::Paren
-                            && ident.name == "a" => {},
+                            && ident.name.as_str() == "a" => {},
                             _ => panic!("value 3: {:?}", **first_delimed),
                         }
                         let tts = &second_delimed.tts[..];
@@ -774,7 +774,7 @@ fn string_to_tts_macro () {
                                 Some(&ast::TtToken(_, token::Ident(ident, token::Plain))),
                             )
                             if second_delimed.delim == token::Paren
-                            && ident.name == "a" => {},
+                            && ident.name.as_str() == "a" => {},
                             _ => panic!("value 4: {:?}", **second_delimed),
                         }
                     },
index 60e0f2d32a43dfdc5520f18f3b68b889be920485..f47dfeb1d34679df56a14526ada66b747d4ea961 100644 (file)
@@ -4658,7 +4658,7 @@ fn parse_item_struct(&mut self) -> PResult<ItemInfo> {
             (fields, None)
         // Tuple-style struct definition with optional where-clause.
         } else if self.token == token::OpenDelim(token::Paren) {
-            let fields = try!(self.parse_tuple_struct_body(&class_name, &mut generics));
+            let fields = try!(self.parse_tuple_struct_body(class_name, &mut generics));
             (fields, Some(ast::DUMMY_NODE_ID))
         } else {
             let token_str = self.this_token_to_string();
@@ -4693,7 +4693,7 @@ pub fn parse_record_struct_body(&mut self) -> PResult<Vec<StructField>> {
     }
 
     pub fn parse_tuple_struct_body(&mut self,
-                                   class_name: &ast::Ident,
+                                   class_name: ast::Ident,
                                    generics: &mut ast::Generics)
                                    -> PResult<Vec<StructField>> {
         // This is the case where we find `struct Foo<T>(T) where T: Copy;`
@@ -5723,10 +5723,10 @@ pub fn parse_optional_str(&mut self)
                                                  Option<ast::Name>)>> {
         let ret = match self.token {
             token::Literal(token::Str_(s), suf) => {
-                (self.id_to_interned_str(s.ident()), ast::CookedStr, suf)
+                (self.id_to_interned_str(ast::Ident::with_empty_ctxt(s)), ast::CookedStr, suf)
             }
             token::Literal(token::StrRaw(s, n), suf) => {
-                (self.id_to_interned_str(s.ident()), ast::RawStr(n), suf)
+                (self.id_to_interned_str(ast::Ident::with_empty_ctxt(s)), ast::RawStr(n), suf)
             }
             _ => return Ok(None)
         };
index a392872f7535b18d089554bfb6ff607fda1793c0..ba24dc3c0a74ec155fbc4d870741374560da667d 100644 (file)
@@ -453,7 +453,7 @@ pub mod special_idents {
             #[allow(non_upper_case_globals)]
             pub const $si_static: ast::Ident = ast::Ident {
                 name: ast::Name($si_name),
-                ctxt: 0,
+                ctxt: ast::EMPTY_CTXT,
             };
          )*
     }
@@ -462,7 +462,7 @@ pub mod special_names {
         use ast;
         $(
             #[allow(non_upper_case_globals)]
-            pub const $si_static: ast::Name =  ast::Name($si_name);
+            pub const $si_static: ast::Name = ast::Name($si_name);
         )*
     }
 
@@ -729,19 +729,19 @@ pub fn gensym(s: &str) -> ast::Name {
 /// Maps a string to an identifier with an empty syntax context.
 #[inline]
 pub fn str_to_ident(s: &str) -> ast::Ident {
-    ast::Ident::new(intern(s))
+    ast::Ident::with_empty_ctxt(intern(s))
 }
 
 /// Maps a string to a gensym'ed identifier.
 #[inline]
 pub fn gensym_ident(s: &str) -> ast::Ident {
-    ast::Ident::new(gensym(s))
+    ast::Ident::with_empty_ctxt(gensym(s))
 }
 
 // create a fresh name that maps to the same string as the old one.
 // note that this guarantees that str_ptr_eq(ident_to_string(src),interner_get(fresh_name(src)));
 // that is, that the new name and the old one are connected to ptr_eq strings.
-pub fn fresh_name(src: &ast::Ident) -> ast::Name {
+pub fn fresh_name(src: ast::Ident) -> ast::Name {
     let interner = get_ident_interner();
     interner.gensym_copy(src.name)
     // following: debug version. Could work in final except that it's incompatible with
@@ -753,7 +753,7 @@ pub fn fresh_name(src: &ast::Ident) -> ast::Name {
 
 // create a fresh mark.
 pub fn fresh_mark() -> ast::Mrk {
-    gensym("mark").usize() as u32
+    gensym("mark").0
 }
 
 #[cfg(test)]
@@ -763,7 +763,7 @@ mod tests {
     use ext::mtwt;
 
     fn mark_ident(id : ast::Ident, m : ast::Mrk) -> ast::Ident {
-        ast::Ident { name: id.name, ctxt:mtwt::apply_mark(m, id.ctxt) }
+        ast::Ident::new(id.name, mtwt::apply_mark(m, id.ctxt))
     }
 
     #[test] fn mtwt_token_eq_test() {
index 6d3f036894f3657ac58ea34bf9106ae0c6ec37f2..49b6dbed27e8c2991fe8a9cad3b85cf55e385603 100644 (file)
@@ -297,7 +297,7 @@ pub fn token_to_string(tok: &Token) -> String {
             token::NtBlock(ref e)       => block_to_string(&**e),
             token::NtStmt(ref e)        => stmt_to_string(&**e),
             token::NtPat(ref e)         => pat_to_string(&**e),
-            token::NtIdent(ref e, _)    => ident_to_string(&**e),
+            token::NtIdent(ref e, _)    => ident_to_string(**e),
             token::NtTT(ref e)          => tt_to_string(&**e),
             token::NtArm(ref e)         => arm_to_string(&*e),
             token::NtImplItem(ref e)    => impl_item_to_string(&**e),
@@ -376,8 +376,8 @@ pub fn path_to_string(p: &ast::Path) -> String {
     to_string(|s| s.print_path(p, false, 0))
 }
 
-pub fn ident_to_string(id: &ast::Ident) -> String {
-    to_string(|s| s.print_ident(*id))
+pub fn ident_to_string(id: ast::Ident) -> String {
+    to_string(|s| s.print_ident(id))
 }
 
 pub fn fun_to_string(decl: &ast::FnDecl,
@@ -2857,7 +2857,6 @@ pub fn print_view_path(&mut self, vp: &ast::ViewPath) -> io::Result<()> {
             ast::ViewPathSimple(ident, ref path) => {
                 try!(self.print_path(path, false, 0));
 
-                // FIXME(#6993) can't compare identifiers directly here
                 if path.segments.last().unwrap().identifier.name !=
                         ident.name {
                     try!(space(&mut self.s));
index 7ae9e4646e516b32bee9972485f904b3f974d2d6..6e9c161293de27359ef5fb91e3a79ff1f93242e2 100644 (file)
@@ -69,7 +69,7 @@ pub fn gensym(&self, val: T) -> Name {
 
     pub fn get(&self, idx: Name) -> T {
         let vect = self.vect.borrow();
-        (*vect)[idx.usize()].clone()
+        (*vect)[idx.0 as usize].clone()
     }
 
     pub fn len(&self) -> usize {
@@ -196,13 +196,13 @@ pub fn gensym_copy(&self, idx : Name) -> Name {
         let new_idx = Name(self.len() as u32);
         // leave out of map to avoid colliding
         let mut vect = self.vect.borrow_mut();
-        let existing = (*vect)[idx.usize()].clone();
+        let existing = (*vect)[idx.0 as usize].clone();
         vect.push(existing);
         new_idx
     }
 
     pub fn get(&self, idx: Name) -> RcStr {
-        (*self.vect.borrow())[idx.usize()].clone()
+        (*self.vect.borrow())[idx.0 as usize].clone()
     }
 
     pub fn len(&self) -> usize {
index aca0db4e1adbefad9bb35145f8eaad1043042cbd..4b6d67d2d2620a68490a237eb3d700b0f0cfc1e0 100644 (file)
@@ -23,8 +23,6 @@
 use book;
 use book::{Book, BookItem};
 
-use javascript;
-
 use rustdoc;
 
 struct Build;
@@ -82,7 +80,7 @@ fn walk_item(item: &BookItem,
 }
 
 fn render(book: &Book, tgt: &Path) -> CliResult<()> {
-    let tmp = try!(TempDir::new("rust-book"));
+    let tmp = try!(TempDir::new("rustbook"));
 
     for (_section, item) in book.iter() {
         let out_path = match item.path.parent() {
@@ -113,26 +111,28 @@ fn render(book: &Book, tgt: &Path) -> CliResult<()> {
         // write the prelude to a temporary HTML file for rustdoc inclusion
         let prelude = tmp.path().join("prelude.html");
         {
-            let mut toc = BufWriter::new(try!(File::create(&prelude)));
-            try!(writeln!(&mut toc, r#"<div id="nav">
-                <button id="toggle-nav">
-                  <span class="sr-only">Toggle navigation</span>
-                  <span class="bar"></span>
-                  <span class="bar"></span>
-                  <span class="bar"></span>
-                </button>
-              </div>"#));
-            let _ = write_toc(book, &item, &mut toc);
-            try!(writeln!(&mut toc, "<div id='page-wrapper'>"));
-            try!(writeln!(&mut toc, "<div id='page'>"));
+            let mut buffer = BufWriter::new(try!(File::create(&prelude)));
+            try!(writeln!(&mut buffer, r#"
+                <div id="nav">
+                    <button id="toggle-nav">
+                        <span class="sr-only">Toggle navigation</span>
+                        <span class="bar"></span>
+                        <span class="bar"></span>
+                        <span class="bar"></span>
+                    </button>
+                </div>"#));
+            let _ = write_toc(book, &item, &mut buffer);
+            try!(writeln!(&mut buffer, "<div id='page-wrapper'>"));
+            try!(writeln!(&mut buffer, "<div id='page'>"));
         }
 
         // write the postlude to a temporary HTML file for rustdoc inclusion
         let postlude = tmp.path().join("postlude.html");
         {
-            let mut toc = BufWriter::new(try!(File::create(&postlude)));
-            try!(toc.write_all(javascript::JAVASCRIPT.as_bytes()));
-            try!(writeln!(&mut toc, "</div></div>"));
+            let mut buffer = BufWriter::new(try!(File::create(&postlude)));
+            try!(writeln!(&mut buffer, "<script src='rustbook.js'></script>"));
+            try!(writeln!(&mut buffer, "<script src='playpen.js'></script>"));
+            try!(writeln!(&mut buffer, "</div></div>"));
         }
 
         try!(fs::create_dir_all(&out_path));
@@ -144,7 +144,7 @@ fn render(book: &Book, tgt: &Path) -> CliResult<()> {
             format!("--html-before-content={}", prelude.display()),
             format!("--html-after-content={}", postlude.display()),
             format!("--markdown-playground-url=https://play.rust-lang.org"),
-            format!("--markdown-css={}", item.path_to_root.join("rust-book.css").display()),
+            format!("--markdown-css={}", item.path_to_root.join("rustbook.css").display()),
             "--markdown-no-toc".to_string(),
         ];
         let output_result = rustdoc::main_args(rustdoc_args);
@@ -199,10 +199,10 @@ fn execute(&mut self, term: &mut Term) -> CommandResult<()> {
         let css = include_bytes!("static/rustbook.css");
         let js = include_bytes!("static/rustbook.js");
 
-        let mut css_file = try!(File::create(tgt.join("rust-book.css")));
+        let mut css_file = try!(File::create(tgt.join("rustbook.css")));
         try!(css_file.write_all(css));
 
-        let mut js_file = try!(File::create(tgt.join("rust-book.js")));
+        let mut js_file = try!(File::create(tgt.join("rustbook.js")));
         try!(js_file.write_all(js));
 
 
index 995d2f2494a490b1845344aaa86886152a733bd9..c90c2b936092a4b643483d20b26d37851139d929 100644 (file)
@@ -36,7 +36,7 @@ fn execute(&mut self, _: &mut Term) -> CommandResult<()> {
 }
 
 pub fn usage() {
-    println!("Usage: rust-book <command> [<args>]");
+    println!("Usage: rustbook <command> [<args>]");
     println!("");
     println!("The <command> must be one of:");
     println!("  help    Print this message.");
diff --git a/src/rustbook/javascript.rs b/src/rustbook/javascript.rs
deleted file mode 100644 (file)
index beddc23..0000000
+++ /dev/null
@@ -1,16 +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.
-
-// The rust-book JavaScript in string form.
-
-pub static JAVASCRIPT: &'static str = r#"
-<script type="text/javascript" src="rust-book.js"></script>
-<script type="text/javascript" src="playpen.js"></script>
-"#;
index 17a34cdc611a2757e87d7be39e00f0ee8586f258..d23e868eeadd192fc649763d79810881f10164d0 100644 (file)
@@ -35,8 +35,6 @@
 mod serve;
 mod test;
 
-mod javascript;
-
 static EXIT_STATUS: AtomicIsize = ATOMIC_ISIZE_INIT;
 
 fn main() {
index 6b9e7aa58f247ce9122ed5ff897a1407957a6f30..3755338f427dfe7be722c7182164056883c6d8e1 100644 (file)
@@ -1,5 +1,5 @@
 /**
- * Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+ * Copyright 2013-2015 The Rust Project Developers. See the COPYRIGHT
  * file at the top-level directory of this distribution and at
  * http://rust-lang.org/COPYRIGHT.
  *
  * except according to those terms.
  */
 
-@import url("../rust.css");
+@import url('../rust.css');
 
 body {
-    max-width:none;
-    font: 16px/1.4 'Source Serif Pro', Georgia, Times, 'Times New Roman', serif;
-    line-height: 1.6;
+    max-width: none;
+    font: 16px/1.6 'Source Serif Pro', Georgia, Times, 'Times New Roman', serif;
     color: #333;
 }
 
@@ -28,68 +27,64 @@ h1, h2, h3, h4, h5, h6 {
 @media only screen {
     #toc {
         position: fixed;
-        left: 0px;
-        top: 0px;
-        bottom: 0px;
+        top: 0;
+        left: 0;
+        bottom: 0;
         width: 300px;
         overflow-y: auto;
-        border-right: 1px solid rgba(0, 0, 0, 0.07);
-        padding: 10px 10px;
+        border-right: 1px solid #e8e8e8;
+        padding: 0 15px;
         font-size: 14px;
-        box-sizing: border-box;
-        -webkit-overflow-scrolling: touch;
         background-color: #fafafa;
-        color: #364149;
+        -webkit-overflow-scrolling: touch;
     }
 
     #page-wrapper {
         position: absolute;
-        left: 310px;
-        right: 0px;
-        top: 0px;
-        box-sizing: border-box;
-        background: none repeat scroll 0% 0% #FFF;
+        top: 0;
+        left: 300px;
+        right: 0;
+        padding: 0 15px;
         -webkit-overflow-scrolling: touch;
     }
 }
 
 @media only print {
-    #toc, #nav, #menu-bar {
+    #toc, #nav {
         display: none;
     }
 }
 
-@media only screen and (max-width: 1060px) {
+@media only screen and (max-width: 1023px) {
     #toc {
         width: 100%;
-        margin-right: 0;
         top: 40px;
     }
+
     #page-wrapper {
         top: 40px;
-        left: 15px;
-        padding-right: 15px;
+        left: 0;
     }
+
     .mobile-hidden {
         display: none;
     }
 }
 
 #page {
-    margin-left: auto;
-    margin-right:auto;
+    margin: 0 auto;
     max-width: 750px;
     padding-bottom: 50px;
 }
 
 .chapter {
-    list-style: none outside none;
-    padding-left: 0px;
+    list-style: none;
+    padding-left: 0;
     line-height: 30px;
 }
 
 .section {
-    list-style: none outside none;
+    list-style: none;
     padding-left: 20px;
     line-height: 40px;
 }
@@ -105,28 +100,21 @@ h1, h2, h3, h4, h5, h6 {
     padding: 5px 0;
 }
 
-.chapter li a.active {
-    color: #008cff;
-}
-
+.chapter li a.active,
 .chapter li a:hover {
     color: #008cff;
     text-decoration: none;
 }
 
 #toggle-nav {
-    height: 20px;
-    width:  30px;
-    padding: 3px 3px 0 3px;
-}
-
-#toggle-nav {
+    cursor: pointer;
     margin-top: 5px;
     width: 30px;
     height: 30px;
-    background-color: #FFF;
+    background-color: #fff;
     border: 1px solid #666;
-    border-radius: 3px 3px 3px 3px;
+    border-radius: 3px;
+    padding: 3px 3px 0 3px;
 }
 
 .sr-only {
@@ -160,10 +148,6 @@ pre {
     border-radius: 3px;
 }
 
-.nav-previous-next {
-    margin-top: 60px;
-}
-
 .left {
     float: left;
 }
index fdefab2875926be6c7908f4377c71cbee5bbe7a0..d8ab15260edb47448d08f0290f1695979201ec29 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -8,66 +8,71 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+/*jslint browser: true, es5: true */
+/*globals $: true, rootPath: true */
 
-document.addEventListener("DOMContentLoaded", function(event) {
+document.addEventListener('DOMContentLoaded', function() {
+    'use strict';
 
-  document.getElementById("toggle-nav").onclick = toggleNav;
+    document.getElementById('toggle-nav').onclick = function(e) {
+        var toc = document.getElementById('toc');
+        var pagewrapper = document.getElementById('page-wrapper');
+        toggleClass(toc, 'mobile-hidden');
+        toggleClass(pagewrapper, 'mobile-hidden');
+    };
 
-  function toggleNav() {
-    var toc = document.getElementById("toc");
-    var pagewrapper = document.getElementById("page-wrapper");
-    toggleClass(toc, "mobile-hidden");
-    toggleClass(pagewrapper, "mobile-hidden");
-  }
+    function toggleClass(el, className) {
+        // from http://youmightnotneedjquery.com/
+        if (el.classList) {
+            el.classList.toggle(className);
+        } else {
+            var classes = el.className.split(' ');
+            var existingIndex = classes.indexOf(className);
 
-  function toggleClass(el, className) {
-     // from http://youmightnotneedjquery.com/
-     if (el.classList) {
-       el.classList.toggle(className);
-     } else {
-       var classes = el.className.split(' ');
-       var existingIndex = classes.indexOf(className);
+            if (existingIndex >= 0) {
+                classes.splice(existingIndex, 1);
+            } else {
+                classes.push(className);
+            }
 
-       if (existingIndex >= 0) {
-         classes.splice(existingIndex, 1);
-       } else {
-         classes.push(className);
-       }
-
-       el.className = classes.join(' ');
-     }
-  }
+            el.className = classes.join(' ');
+        }
+    }
 
-  // The below code is used to add prev and next navigation links to the bottom
-  // of each of the sections.
-  // It works by extracting the current page based on the url and iterates over
-  // the menu links until it finds the menu item for the current page. We then
-  // create a copy of the preceding and following menu links and add the
-  // correct css class and insert them into the bottom of the page.
-  var toc = document.getElementById('toc').getElementsByTagName('a');
-  var href = document.location.pathname.split('/').pop();
-  if (href === 'index.html' || href === '') {
-    href = 'README.html';
-  }
+    // The below code is used to add prev and next navigation links to the
+    // bottom of each of the sections.
+    // It works by extracting the current page based on the url and iterates
+    // over the menu links until it finds the menu item for the current page. We
+    // then create a copy of the preceding and following menu links and add the
+    // correct css class and insert them into the bottom of the page.
+    var toc = document.getElementById('toc').getElementsByTagName('a');
+    var href = document.location.pathname.split('/').pop();
 
-  for (var i = 0; i < toc.length; i++) {
-    if (toc[i].attributes.href.value.split('/').pop() === href) {
-      var nav = document.createElement('p');
-      if (i > 0) {
-        var prevNode = toc[i-1].cloneNode(true);
-        prevNode.className = 'left';
-        prevNode.setAttribute('rel', 'prev');
-        nav.appendChild(prevNode);
-      }
-      if (i < toc.length - 1) {
-        var nextNode = toc[i+1].cloneNode(true);
-        nextNode.className = 'right';
-        nextNode.setAttribute('rel', 'next');
-        nav.appendChild(nextNode);
-      }
-      document.getElementById('page').appendChild(nav);
-      break;
+    if (href === 'index.html' || href === '') {
+        href = 'README.html';
     }
-  }
 
+    for (var i = 0; i < toc.length; i++) {
+        if (toc[i].attributes.href.value.split('/').pop() === href) {
+            var nav = document.createElement('p');
+
+            if (i > 0) {
+                var prevNode = toc[i-1].cloneNode(true);
+                prevNode.className = 'left';
+                prevNode.setAttribute('rel', 'prev');
+                nav.appendChild(prevNode);
+            }
+
+            if (i < toc.length - 1) {
+                var nextNode = toc[i+1].cloneNode(true);
+                nextNode.className = 'right';
+                nextNode.setAttribute('rel', 'next');
+                nav.appendChild(nextNode);
+            }
+
+            document.getElementById('page').appendChild(nav);
+
+            break;
+        }
+    }
 });
index 5a8e1f695ae6e846a9addc9b9d9f795a415ef9ac..a66c2b4f3024dda9bc90bd6c194b876df9555d53 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-//! Common API for all rust-book subcommands.
+//! Common API for all rustbook subcommands.
 
 use error::CliResult;
 use error::CommandResult;
index 4f5e8d6e0874c1a9d77eb885b135e32e9dbae031..a0036745d90a432f3be9ea1d83780e5bf1a0e5e3 100644 (file)
@@ -35,7 +35,7 @@ fn get_lints(&self) -> LintArray {
 
 impl EarlyLintPass for Pass {
     fn check_item(&mut self, cx: &EarlyContext, it: &ast::Item) {
-        if it.ident.name == "lintme" {
+        if it.ident.name.as_str() == "lintme" {
             cx.span_lint(TEST_LINT, it.span, "item is named 'lintme'");
         }
     }
diff --git a/src/test/auxiliary/msvc-data-only-lib.rs b/src/test/auxiliary/msvc-data-only-lib.rs
new file mode 100644 (file)
index 0000000..71fb9a5
--- /dev/null
@@ -0,0 +1,15 @@
+// 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.
+
+// no-prefer-dynamic
+
+#![crate_type = "rlib"]
+
+pub static FOO: i32 = 42;
index 8c7ad2293e23db67cd051db94533e334486b6c07..296d1e431f4ca20dcd037189745db0c130cff6d0 100644 (file)
@@ -33,7 +33,7 @@ fn expand_mbe_matches(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree])
 
     let mac_expr = match TokenTree::parse(cx, &mbe_matcher[..], args) {
         Success(map) => {
-            match (&*map[&str_to_ident("matched")], &*map[&str_to_ident("pat")]) {
+            match (&*map[&str_to_ident("matched").name], &*map[&str_to_ident("pat").name]) {
                 (&MatchedNonterminal(NtExpr(ref matched_expr)),
                  &MatchedSeq(ref pats, seq_sp)) => {
                     let pats: Vec<P<Pat>> = pats.iter().map(|pat_nt|
diff --git a/src/test/compile-fail/feature-gate-cfg-target-vendor.rs b/src/test/compile-fail/feature-gate-cfg-target-vendor.rs
new file mode 100644 (file)
index 0000000..e68a84d
--- /dev/null
@@ -0,0 +1,21 @@
+// 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.
+
+#[cfg(target_vendor = "x")] //~ ERROR `cfg(target_vendor)` is experimental
+#[cfg_attr(target_vendor = "x", x)] //~ ERROR `cfg(target_vendor)` is experimental
+struct Foo(u64, u64);
+
+#[cfg(not(any(all(target_vendor = "x"))))] //~ ERROR `cfg(target_vendor)` is experimental
+fn foo() {}
+
+fn main() {
+    cfg!(target_vendor = "x");
+    //~^ ERROR `cfg(target_vendor)` is experimental and subject to change
+}
diff --git a/src/test/compile-fail/issue-28576.rs b/src/test/compile-fail/issue-28576.rs
new file mode 100644 (file)
index 0000000..bd71867
--- /dev/null
@@ -0,0 +1,22 @@
+// 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.
+
+pub trait Foo<RHS=Self> {
+    type Assoc;
+}
+
+pub trait Bar: Foo<Assoc=()> {
+    fn new(&self, b: &
+           Bar //~ ERROR the trait `Bar` cannot be made into an object
+              <Assoc=()>
+    );
+}
+
+fn main() {}
index de419a259a24cf4fc0efb6d21eb37bdc2af8c746..12407f06ca06cec43dcbbfbd3f61887ae969c327 100644 (file)
@@ -20,12 +20,12 @@ trait Expr: Debug + PartialEq {
 #[derive(Debug)]
 struct SExpr<'x> {
     elements: Vec<Box<Expr+ 'x>>,
+    //~^ ERROR E0038
 }
 
 impl<'x> PartialEq for SExpr<'x> {
     fn eq(&self, other:&SExpr<'x>) -> bool {
         println!("L1: {} L2: {}", self.elements.len(), other.elements.len());
-        //~^ ERROR E0038
         let result = self.elements.len() == other.elements.len();
 
         println!("Got compare {}", result);
@@ -44,8 +44,8 @@ fn print_element_count(&self) {
 }
 
 fn main() {
-    let a: Box<Expr> = Box::new(SExpr::new()); //~ ERROR E0038
-    let b: Box<Expr> = Box::new(SExpr::new()); //~ ERROR E0038
+    let a: Box<Expr> = Box::new(SExpr::new());
+    let b: Box<Expr> = Box::new(SExpr::new());
 
     // assert_eq!(a , b);
 }
index ba82635a4016e16a0b57c59ac7bec7e33017ab5d..0a79ec30e4b942445b96da9bc08f970a4b023f01 100644 (file)
@@ -23,9 +23,9 @@ fn make_bar<T:Bar<u32>>(t: &T) -> &Bar<u32> {
 }
 
 fn make_baz<T:Baz>(t: &T) -> &Baz {
+    //~^ ERROR E0038
+    //~| NOTE the trait cannot use `Self` as a type parameter in the supertrait listing
     t
-        //~^ ERROR E0038
-        //~| NOTE the trait cannot use `Self` as a type parameter in the supertrait listing
 }
 
 fn main() {
index e3c36b9c0b7017b96bfb3df9d5c8388b72697456..a785e916cf73379ba73d5c3a5756f9addb5b8aa7 100644 (file)
@@ -5,12 +5,13 @@ all:
        $(call REMOVE_RLIBS,bar)
        $(call REMOVE_DYLIBS,bar)
        rm $(TMPDIR)/libbar.a
-       rm -f $(TMPDIR)/bar.{exp,lib}
+       rm -f $(TMPDIR)/bar.{exp,lib,pdb}
        # Check that $(TMPDIR) is empty.
        [ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ]
 
        $(RUSTC) foo.rs --crate-type=bin
        rm $(TMPDIR)/$(call BIN,bar)
+       rm -f $(TMPDIR)/bar.pdb
        [ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ]
 
        $(RUSTC) foo.rs --emit=asm,llvm-ir,llvm-bc,obj,link
@@ -19,6 +20,7 @@ all:
        rm $(TMPDIR)/bar.s
        rm $(TMPDIR)/bar.o
        rm $(TMPDIR)/$(call BIN,bar)
+       rm -f $(TMPDIR)/bar.pdb
        [ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ]
 
        $(RUSTC) foo.rs --emit=asm -o $(TMPDIR)/foo
@@ -39,6 +41,7 @@ all:
 
        $(RUSTC) foo.rs --emit=link -o $(TMPDIR)/$(call BIN,foo)
        rm $(TMPDIR)/$(call BIN,foo)
+       rm -f $(TMPDIR)/foo.pdb
        [ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ]
 
        $(RUSTC) foo.rs --crate-type=rlib -o $(TMPDIR)/foo
@@ -47,7 +50,7 @@ all:
 
        $(RUSTC) foo.rs --crate-type=dylib -o $(TMPDIR)/$(call BIN,foo)
        rm $(TMPDIR)/$(call BIN,foo)
-       rm -f $(TMPDIR)/foo.{exp,lib}
+       rm -f $(TMPDIR)/foo.{exp,lib,pdb}
        [ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ]
 
        $(RUSTC) foo.rs --crate-type=staticlib -o $(TMPDIR)/foo
@@ -56,6 +59,7 @@ all:
 
        $(RUSTC) foo.rs --crate-type=bin -o $(TMPDIR)/$(call BIN,foo)
        rm $(TMPDIR)/$(call BIN,foo)
+       rm -f $(TMPDIR)/foo.pdb
        [ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ]
 
        $(RUSTC) foo.rs --emit=asm,llvm-ir,llvm-bc,obj,link --crate-type=staticlib
diff --git a/src/test/run-pass/cfg-target-vendor.rs b/src/test/run-pass/cfg-target-vendor.rs
new file mode 100644 (file)
index 0000000..787ae52
--- /dev/null
@@ -0,0 +1,19 @@
+// 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.
+
+#![feature(cfg_target_vendor)]
+
+#[cfg(target_vendor = "unknown")]
+pub fn main() {
+}
+
+#[cfg(not(target_vendor = "unknown"))]
+pub fn main() {
+}
index 371e926ab18d5f05062de87439c779215453e732..d3c9fe9161ccb52259606a86f63755e0e73f4c59 100644 (file)
@@ -59,5 +59,5 @@ fn match_indices<'a, M, T: IntoMatcher<'a, M>>(s: &'a str, from: T) -> MatchIndi
 fn main() {
     let s = "abcbdef";
     match_indices(s, |c: char| c == 'b')
-        .collect::<Vec<(usize, usize)>>();
+        .collect::<Vec<_>>();
 }
diff --git a/src/test/run-pass/msvc-data-only.rs b/src/test/run-pass/msvc-data-only.rs
new file mode 100644 (file)
index 0000000..ad6888c
--- /dev/null
@@ -0,0 +1,17 @@
+// 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.
+
+// aux-build:msvc-data-only-lib.rs
+
+extern crate msvc_data_only_lib;
+
+fn main() {
+    println!("The answer is {} !", msvc_data_only_lib::FOO);
+}