diff --git a/configure b/configure index efa836ca97646..20a5fa390f00b 100755 --- a/configure +++ b/configure @@ -863,11 +863,6 @@ then CFG_DISABLE_JEMALLOC=1 fi -if [ -z "$CFG_ENABLE_CLANG" -a -z "$CFG_GCC" ] -then - err "either clang or gcc is required" -fi - # OS X 10.9, gcc is actually clang. This can cause some confusion in the build # system, so if we find that gcc is clang, we should just use clang directly. if [ $CFG_OSTYPE = apple-darwin -a -z "$CFG_ENABLE_CLANG" ] diff --git a/man/rustc.1 b/man/rustc.1 index b15829db431df..0cb1c5dc32b8e 100644 --- a/man/rustc.1 +++ b/man/rustc.1 @@ -1,4 +1,4 @@ -.TH RUSTC "1" "March 2014" "rustc 0.13.0" "User Commands" +.TH RUSTC "1" "August 2015" "rustc 1.2.0" "User Commands" .SH NAME rustc \- The Rust compiler .SH SYNOPSIS @@ -160,7 +160,7 @@ If the value is 'help', then a list of available CPUs is printed. \fBtarget\-feature\fR='\fI+feature1\fR,\fI\-feature2\fR' A comma\[hy]separated list of features to enable or disable for the target. A preceding '+' enables a feature while a preceding '\-' disables it. -Available features can be discovered through \fItarget\-cpu=help\fR. +Available features can be discovered through \fIllc -mcpu=help\fR. .TP \fBpasses\fR=\fIval\fR A space\[hy]separated list of extra LLVM passes to run. diff --git a/man/rustdoc.1 b/man/rustdoc.1 index 1738354fb43d5..b710c2c3a2560 100644 --- a/man/rustdoc.1 +++ b/man/rustdoc.1 @@ -1,4 +1,4 @@ -.TH RUSTDOC "1" "March 2014" "rustdoc 0.13.0" "User Commands" +.TH RUSTDOC "1" "August 2015" "rustdoc 1.2.0" "User Commands" .SH NAME rustdoc \- generate documentation from Rust source code .SH SYNOPSIS diff --git a/mk/cfg/aarch64-linux-android.mk b/mk/cfg/aarch64-linux-android.mk index 9e0245e093d8a..d7a1405c3d0a8 100644 --- a/mk/cfg/aarch64-linux-android.mk +++ b/mk/cfg/aarch64-linux-android.mk @@ -1,7 +1,6 @@ # aarch64-linux-android configuration # CROSS_PREFIX_aarch64-linux-android- CC_aarch64-linux-android=$(CFG_ANDROID_CROSS_PATH)/bin/aarch64-linux-android-gcc -LINK_aarch64-linux-android=$(CFG_ANDROID_CROSS_PATH)/bin/aarch64-linux-android-gcc CXX_aarch64-linux-android=$(CFG_ANDROID_CROSS_PATH)/bin/aarch64-linux-android-g++ CPP_aarch64-linux-android=$(CFG_ANDROID_CROSS_PATH)/bin/aarch64-linux-android-gcc -E AR_aarch64-linux-android=$(CFG_ANDROID_CROSS_PATH)/bin/aarch64-linux-android-ar diff --git a/mk/cfg/aarch64-unknown-linux-gnu.mk b/mk/cfg/aarch64-unknown-linux-gnu.mk index 88d7700db820f..6637423e4951a 100644 --- a/mk/cfg/aarch64-unknown-linux-gnu.mk +++ b/mk/cfg/aarch64-unknown-linux-gnu.mk @@ -1,7 +1,6 @@ # aarch64-unknown-linux-gnu configuration CROSS_PREFIX_aarch64-unknown-linux-gnu=aarch64-linux-gnu- CC_aarch64-unknown-linux-gnu=gcc -LINK_aarch64-unknown-linux-gnu=gcc CXX_aarch64-unknown-linux-gnu=g++ CPP_aarch64-unknown-linux-gnu=gcc -E AR_aarch64-unknown-linux-gnu=ar diff --git a/mk/cfg/arm-linux-androideabi.mk b/mk/cfg/arm-linux-androideabi.mk index a66f70f6305ed..fdd38ba75fe58 100644 --- a/mk/cfg/arm-linux-androideabi.mk +++ b/mk/cfg/arm-linux-androideabi.mk @@ -1,5 +1,4 @@ # arm-linux-androideabi configuration -LINK_arm-linux-androideabi=$(CFG_ANDROID_CROSS_PATH)/bin/arm-linux-androideabi-gcc CC_arm-linux-androideabi=$(CFG_ANDROID_CROSS_PATH)/bin/arm-linux-androideabi-gcc CXX_arm-linux-androideabi=$(CFG_ANDROID_CROSS_PATH)/bin/arm-linux-androideabi-g++ CPP_arm-linux-androideabi=$(CFG_ANDROID_CROSS_PATH)/bin/arm-linux-androideabi-gcc -E diff --git a/mk/cfg/i686-apple-darwin.mk b/mk/cfg/i686-apple-darwin.mk index 25b692449aa29..7ebb492bb21fe 100644 --- a/mk/cfg/i686-apple-darwin.mk +++ b/mk/cfg/i686-apple-darwin.mk @@ -1,6 +1,5 @@ # i686-apple-darwin configuration CC_i686-apple-darwin=$(CC) -LINK_i686-apple-darwin=cc CXX_i686-apple-darwin=$(CXX) CPP_i686-apple-darwin=$(CPP) AR_i686-apple-darwin=$(AR) diff --git a/mk/cfg/i686-unknown-linux-gnu.mk b/mk/cfg/i686-unknown-linux-gnu.mk index 1c5de9a2c05e6..88c0907f63b2a 100644 --- a/mk/cfg/i686-unknown-linux-gnu.mk +++ b/mk/cfg/i686-unknown-linux-gnu.mk @@ -1,6 +1,5 @@ # i686-unknown-linux-gnu configuration CC_i686-unknown-linux-gnu=$(CC) -LINK_i686-unknown-linux-gnu=cc CXX_i686-unknown-linux-gnu=$(CXX) CPP_i686-unknown-linux-gnu=$(CPP) AR_i686-unknown-linux-gnu=$(AR) diff --git a/mk/cfg/x86_64-apple-darwin.mk b/mk/cfg/x86_64-apple-darwin.mk index 9d3361b7fc638..4c68d3dcf37b4 100644 --- a/mk/cfg/x86_64-apple-darwin.mk +++ b/mk/cfg/x86_64-apple-darwin.mk @@ -1,6 +1,5 @@ # x86_64-apple-darwin configuration CC_x86_64-apple-darwin=$(CC) -LINK_x86_64-apple-darwin=cc CXX_x86_64-apple-darwin=$(CXX) CPP_x86_64-apple-darwin=$(CPP) AR_x86_64-apple-darwin=$(AR) diff --git a/mk/cfg/x86_64-pc-windows-gnu.mk b/mk/cfg/x86_64-pc-windows-gnu.mk index 10aaf137e8b3a..4118ea26c072b 100644 --- a/mk/cfg/x86_64-pc-windows-gnu.mk +++ b/mk/cfg/x86_64-pc-windows-gnu.mk @@ -1,7 +1,6 @@ # x86_64-pc-windows-gnu configuration CROSS_PREFIX_x86_64-pc-windows-gnu=x86_64-w64-mingw32- CC_x86_64-pc-windows-gnu=gcc -LINK_x86_64-pc-windows-gnu=gcc CXX_x86_64-pc-windows-gnu=g++ CPP_x86_64-pc-windows-gnu=gcc -E AR_x86_64-pc-windows-gnu=ar diff --git a/mk/cfg/x86_64-unknown-linux-gnu.mk b/mk/cfg/x86_64-unknown-linux-gnu.mk index 1735d1eb3f798..044c687c9fc4c 100644 --- a/mk/cfg/x86_64-unknown-linux-gnu.mk +++ b/mk/cfg/x86_64-unknown-linux-gnu.mk @@ -1,6 +1,5 @@ # x86_64-unknown-linux-gnu configuration CC_x86_64-unknown-linux-gnu=$(CC) -LINK_x86_64-unknown-linux-gnu=cc CXX_x86_64-unknown-linux-gnu=$(CXX) CPP_x86_64-unknown-linux-gnu=$(CPP) AR_x86_64-unknown-linux-gnu=$(AR) diff --git a/mk/platform.mk b/mk/platform.mk index 26a6db1c5bd1a..8a5e58c46f676 100644 --- a/mk/platform.mk +++ b/mk/platform.mk @@ -120,6 +120,15 @@ endef $(foreach target,$(CFG_TARGET), \ $(eval $(call ADD_INSTALLED_OBJECTS,$(target)))) +define DEFINE_LINKER + ifndef LINK_$(1) + LINK_$(1) := $$(CC_$(1)) + endif +endef + +$(foreach target,$(CFG_TARGET), \ + $(eval $(call DEFINE_LINKER,$(target)))) + # The -Qunused-arguments sidesteps spurious warnings from clang define FILTER_FLAGS ifeq ($$(CFG_USING_CLANG),1) diff --git a/src/doc/complement-design-faq.md b/src/doc/complement-design-faq.md index e0a56a1a631d4..e887ed0cc5297 100644 --- a/src/doc/complement-design-faq.md +++ b/src/doc/complement-design-faq.md @@ -160,7 +160,7 @@ that all delimiters be balanced. ## `->` for function return type This is to make the language easier to parse for humans, especially in the face -of higher-order functions. `fn foo(f: fn(int): int, fn(T): U): U` is not +of higher-order functions. `fn foo(f: fn(i32): i32, fn(T): U): U` is not particularly easy to read. ## Why is `let` used to introduce variables? diff --git a/src/doc/reference.md b/src/doc/reference.md index 8d1b93ce3c8b9..f69f15200d085 100644 --- a/src/doc/reference.md +++ b/src/doc/reference.md @@ -1892,12 +1892,13 @@ interpreted: On `enum`s: -- `repr` - on C-like enums, this sets the underlying type used for - representation. Takes one argument, which is the primitive - type this enum should be represented for, or `C`, which specifies that it - should be the default `enum` size of the C ABI for that platform. Note that - enum representation in C is undefined, and this may be incorrect when the C - code is compiled with certain flags. +- `repr` - this sets the underlying type used for representation of the + discriminant. Takes one argument, which is the primitive type this enum + should be represented as, or `C`, which specifies that it should be the + default `enum` size of the C ABI for that platform. Note that enum + representation in C is implementation defined, and this may be incorrect when + the C code is compiled with certain flags. The representation attribute + inhibits elision of the enum discriminant in layout optimizations. On `struct`s: @@ -3255,8 +3256,8 @@ User-defined types have limited capabilities. The primitive types are the following: * The boolean type `bool` with values `true` and `false`. -* The machine types. -* The machine-dependent integer and floating-point types. +* The machine types (integer and floating-point). +* The machine-dependent integer types. #### Machine types diff --git a/src/doc/style/errors/ergonomics.md b/src/doc/style/errors/ergonomics.md index d2fcf27e93cdf..f2e23963e106c 100644 --- a/src/doc/style/errors/ergonomics.md +++ b/src/doc/style/errors/ergonomics.md @@ -14,8 +14,8 @@ use std::io::{File, Open, Write, IoError}; struct Info { name: String, - age: int, - rating: int + age: i32, + rating: i32 } fn write_info(info: &Info) -> Result<(), IoError> { @@ -36,8 +36,8 @@ use std::io::{File, Open, Write, IoError}; struct Info { name: String, - age: int, - rating: int + age: i32, + rating: i32 } fn write_info(info: &Info) -> Result<(), IoError> { @@ -63,4 +63,4 @@ for more details. ### The `Result`-`impl` pattern [FIXME] > **[FIXME]** Document the way that the `io` module uses trait impls -> on `IoResult` to painlessly propagate errors. +> on `std::io::Result` to painlessly propagate errors. diff --git a/src/doc/style/features/functions-and-methods/README.md b/src/doc/style/features/functions-and-methods/README.md index 2dcfc382d0baf..611cd564ccac7 100644 --- a/src/doc/style/features/functions-and-methods/README.md +++ b/src/doc/style/features/functions-and-methods/README.md @@ -20,6 +20,7 @@ for any operation that is clearly associated with a particular type. Methods have numerous advantages over functions: + * They do not need to be imported or qualified to be used: all you need is a value of the appropriate type. * Their invocation performs autoborrowing (including mutable borrows). diff --git a/src/doc/style/features/functions-and-methods/input.md b/src/doc/style/features/functions-and-methods/input.md index b0912ea0203dc..072021194c13e 100644 --- a/src/doc/style/features/functions-and-methods/input.md +++ b/src/doc/style/features/functions-and-methods/input.md @@ -57,15 +57,15 @@ it becomes. Prefer ```rust -fn foo>(c: T) { ... } +fn foo>(c: T) { ... } ``` over any of ```rust -fn foo(c: &[int]) { ... } -fn foo(c: &Vec) { ... } -fn foo(c: &SomeOtherCollection) { ... } +fn foo(c: &[i32]) { ... } +fn foo(c: &Vec) { ... } +fn foo(c: &SomeOtherCollection) { ... } ``` if the function only needs to iterate over the data. @@ -121,7 +121,7 @@ The primary exception: sometimes a function is meant to modify data that the caller already owns, for example to re-use a buffer: ```rust -fn read(&mut self, buf: &mut [u8]) -> IoResult +fn read(&mut self, buf: &mut [u8]) -> std::io::Result ``` (From the [Reader trait](http://static.rust-lang.org/doc/master/std/io/trait.Reader.html#tymethod.read).) @@ -159,7 +159,7 @@ fn foo(a: u8) { ... } Note that [`ascii::Ascii`](http://static.rust-lang.org/doc/master/std/ascii/struct.Ascii.html) is a _wrapper_ around `u8` that guarantees the highest bit is zero; see -[newtype patterns]() for more details on creating typesafe wrappers. +[newtype patterns](../types/newtype.md) for more details on creating typesafe wrappers. Static enforcement usually comes at little run-time cost: it pushes the costs to the boundaries (e.g. when a `u8` is first converted into an diff --git a/src/doc/style/features/functions-and-methods/output.md b/src/doc/style/features/functions-and-methods/output.md index a83e2b76bcb7f..3e43d1e416d76 100644 --- a/src/doc/style/features/functions-and-methods/output.md +++ b/src/doc/style/features/functions-and-methods/output.md @@ -19,7 +19,7 @@ Prefer ```rust struct SearchResult { found: bool, // item in container? - expected_index: uint // what would the item's index be? + expected_index: usize // what would the item's index be? } fn binary_search(&self, k: Key) -> SearchResult @@ -27,7 +27,7 @@ fn binary_search(&self, k: Key) -> SearchResult or ```rust -fn binary_search(&self, k: Key) -> (bool, uint) +fn binary_search(&self, k: Key) -> (bool, usize) ``` over diff --git a/src/doc/style/features/let.md b/src/doc/style/features/let.md index 87117a20d7a49..01dff3dcceaf1 100644 --- a/src/doc/style/features/let.md +++ b/src/doc/style/features/let.md @@ -5,7 +5,7 @@ Prefer ```rust -fn use_mutex(m: sync::mutex::Mutex) { +fn use_mutex(m: sync::mutex::Mutex) { let guard = m.lock(); do_work(guard); drop(guard); // unlock the lock @@ -16,7 +16,7 @@ fn use_mutex(m: sync::mutex::Mutex) { over ```rust -fn use_mutex(m: sync::mutex::Mutex) { +fn use_mutex(m: sync::mutex::Mutex) { do_work(m.lock()); // do other work } @@ -34,7 +34,7 @@ Prefer ```rust let foo = match bar { - Baz => 0, + Baz => 0, Quux => 1 }; ``` @@ -44,7 +44,7 @@ over ```rust let foo; match bar { - Baz => { + Baz => { foo = 0; } Quux => { @@ -61,8 +61,8 @@ conditional expression. Prefer ```rust -s.iter().map(|x| x * 2) - .collect::>() +let v = s.iter().map(|x| x * 2) + .collect::>(); ``` over diff --git a/src/doc/style/features/traits/reuse.md b/src/doc/style/features/traits/reuse.md index 6735023ae6800..61f8db87cde89 100644 --- a/src/doc/style/features/traits/reuse.md +++ b/src/doc/style/features/traits/reuse.md @@ -15,7 +15,7 @@ trait Printable { fn print(&self) { println!("{:?}", *self) } } -impl Printable for int {} +impl Printable for i32 {} impl Printable for String { fn print(&self) { println!("{}", *self) } diff --git a/src/doc/style/features/types/newtype.md b/src/doc/style/features/types/newtype.md index 60c17fc2a52e2..e69aa3b83bfa4 100644 --- a/src/doc/style/features/types/newtype.md +++ b/src/doc/style/features/types/newtype.md @@ -43,12 +43,12 @@ promises to the client. For example, consider a function `my_transform` that returns a compound iterator type `Enumerate>>`. We wish to hide this type from the -client, so that the client's view of the return type is roughly `Iterator<(uint, +client, so that the client's view of the return type is roughly `Iterator<(usize, T)>`. We can do so using the newtype pattern: ```rust struct MyTransformResult(Enumerate>>); -impl Iterator<(uint, T)> for MyTransformResult { ... } +impl Iterator<(usize, T)> for MyTransformResult { ... } fn my_transform>(iter: Iter) -> MyTransformResult { ... diff --git a/src/doc/style/ownership/builders.md b/src/doc/style/ownership/builders.md index 8f721a9767672..348be516e374d 100644 --- a/src/doc/style/ownership/builders.md +++ b/src/doc/style/ownership/builders.md @@ -16,7 +16,7 @@ If `T` is such a data structure, consider introducing a `T` _builder_: value. When possible, choose a better name: e.g. `Command` is the builder for `Process`. 2. The builder constructor should take as parameters only the data _required_ to - to make a `T`. + make a `T`. 3. The builder should offer a suite of convenient methods for configuration, including setting up compound inputs (like slices) incrementally. These methods should return `self` to allow chaining. @@ -75,7 +75,7 @@ impl Command { } /// Executes the command as a child process, which is returned. - pub fn spawn(&self) -> IoResult { + pub fn spawn(&self) -> std::io::Result { ... } } diff --git a/src/doc/style/style/features.md b/src/doc/style/style/features.md index f73517c2b9c3b..b5d0b484ccda5 100644 --- a/src/doc/style/style/features.md +++ b/src/doc/style/style/features.md @@ -3,7 +3,7 @@ Terminate `return` statements with semicolons: ``` rust -fn foo(bar: int) -> Option { +fn foo(bar: i32) -> Option { if some_condition() { return None; } diff --git a/src/doc/style/style/imports.md b/src/doc/style/style/imports.md index 207a3fd7f8d16..cf3fd4163a26e 100644 --- a/src/doc/style/style/imports.md +++ b/src/doc/style/style/imports.md @@ -44,7 +44,7 @@ For example: use option::Option; use mem; -let i: int = mem::transmute(Option(0)); +let i: isize = mem::transmute(Option(0)); ``` > **[FIXME]** Add rationale. diff --git a/src/doc/style/style/whitespace.md b/src/doc/style/style/whitespace.md index b21b280dff0d7..c28a723209563 100644 --- a/src/doc/style/style/whitespace.md +++ b/src/doc/style/style/whitespace.md @@ -10,7 +10,7 @@ ``` rust #[deprecated = "Use `bar` instead."] -fn foo(a: uint, b: uint) -> uint { +fn foo(a: usize, b: usize) -> usize { a + b } ``` diff --git a/src/doc/trpl/associated-types.md b/src/doc/trpl/associated-types.md index 55e2787cc2591..ec96880f12a95 100644 --- a/src/doc/trpl/associated-types.md +++ b/src/doc/trpl/associated-types.md @@ -43,7 +43,7 @@ trait Graph { Now, our clients can be abstract over a given `Graph`: ```rust,ignore -fn distance(graph: &G, start: &G::N, end: &G::N) -> uint { ... } +fn distance(graph: &G, start: &G::N, end: &G::N) -> usize { ... } ``` No need to deal with the `E`dge type here! diff --git a/src/doc/trpl/box-syntax-and-patterns.md b/src/doc/trpl/box-syntax-and-patterns.md index 1cf84bfd658c0..8d83b64d68313 100644 --- a/src/doc/trpl/box-syntax-and-patterns.md +++ b/src/doc/trpl/box-syntax-and-patterns.md @@ -58,7 +58,7 @@ fn main() { ``` The idea is that by passing around a box, you're only copying a pointer, rather -than the hundred `int`s that make up the `BigStruct`. +than the hundred `i32`s that make up the `BigStruct`. This is an antipattern in Rust. Instead, write this: diff --git a/src/doc/trpl/conditional-compilation.md b/src/doc/trpl/conditional-compilation.md index 73eb0101692af..a944b852d249f 100644 --- a/src/doc/trpl/conditional-compilation.md +++ b/src/doc/trpl/conditional-compilation.md @@ -34,7 +34,7 @@ These can nest arbitrarily: As for how to enable or disable these switches, if you’re using Cargo, they get set in the [`[features]` section][features] of your `Cargo.toml`: -[features]: http://doc.crates.io/manifest.html#the-[features]-section +[features]: http://doc.crates.io/manifest.html#the-%5Bfeatures%5D-section ```toml [features] diff --git a/src/doc/trpl/glossary.md b/src/doc/trpl/glossary.md index 9845fcbdcd173..c97da0e95b823 100644 --- a/src/doc/trpl/glossary.md +++ b/src/doc/trpl/glossary.md @@ -19,7 +19,7 @@ In the example above `x` and `y` have arity 2. `z` has arity 3. When a compiler is compiling your program, it does a number of different things. One of the things that it does is turn the text of your program into an -‘abstract syntax tree’, or‘AST’. This tree is a representation of the +‘abstract syntax tree’, or ‘AST’. This tree is a representation of the structure of your program. For example, `2 + 3` can be turned into a tree: ```text diff --git a/src/doc/trpl/lifetimes.md b/src/doc/trpl/lifetimes.md index 0039f90b82c35..04ae4c7ccf3cc 100644 --- a/src/doc/trpl/lifetimes.md +++ b/src/doc/trpl/lifetimes.md @@ -134,8 +134,8 @@ x: &'a i32, # } ``` -uses it. So why do we need a lifetime here? We need to ensure that any reference -to a `Foo` cannot outlive the reference to an `i32` it contains. +uses it. So why do we need a lifetime here? We need to ensure that any +reference to the contained `i32` does not outlive the containing `Foo`. ## Thinking in scopes diff --git a/src/doc/trpl/method-syntax.md b/src/doc/trpl/method-syntax.md index e5f490e15e13e..1f694f71a883f 100644 --- a/src/doc/trpl/method-syntax.md +++ b/src/doc/trpl/method-syntax.md @@ -4,7 +4,7 @@ Functions are great, but if you want to call a bunch of them on some data, it can be awkward. Consider this code: ```rust,ignore -baz(bar(foo))); +baz(bar(foo)); ``` We would read this left-to right, and so we see ‘baz bar foo’. But this isn’t the diff --git a/src/doc/trpl/references-and-borrowing.md b/src/doc/trpl/references-and-borrowing.md index bb5adac5ebfc1..b69db228f2724 100644 --- a/src/doc/trpl/references-and-borrowing.md +++ b/src/doc/trpl/references-and-borrowing.md @@ -206,7 +206,7 @@ fn main() { ^ ``` -In other words, the mutable borow is held through the rest of our example. What +In other words, the mutable borrow is held through the rest of our example. What we want is for the mutable borrow to end _before_ we try to call `println!` and make an immutable borrow. In Rust, borrowing is tied to the scope that the borrow is valid for. And our scopes look like this: diff --git a/src/doc/trpl/traits.md b/src/doc/trpl/traits.md index efa16f2942f06..2ef9e7ca22e60 100644 --- a/src/doc/trpl/traits.md +++ b/src/doc/trpl/traits.md @@ -146,7 +146,7 @@ print_area(5); We get a compile-time error: ```text -error: failed to find an implementation of trait main::HasArea for int +error: the trait `HasArea` is not implemented for the type `_` [E0277] ``` So far, we’ve only added trait implementations to structs, but you can @@ -285,7 +285,7 @@ fn bar(x: T, y: K) where T: Clone, K: Clone + Debug { fn main() { foo("Hello", "world"); - bar("Hello", "workd"); + bar("Hello", "world"); } ``` diff --git a/src/libcollections/binary_heap.rs b/src/libcollections/binary_heap.rs index af7112a5cb4e3..00e4002f82f4f 100644 --- a/src/libcollections/binary_heap.rs +++ b/src/libcollections/binary_heap.rs @@ -153,7 +153,7 @@ use core::prelude::*; use core::iter::{FromIterator}; -use core::mem::{zeroed, replace, swap}; +use core::mem::swap; use core::ptr; use slice; @@ -484,46 +484,42 @@ impl BinaryHeap { // The implementations of sift_up and sift_down use unsafe blocks in // order to move an element out of the vector (leaving behind a - // zeroed element), shift along the others and move it back into the - // vector over the junk element. This reduces the constant factor - // compared to using swaps, which involves twice as many moves. - fn sift_up(&mut self, start: usize, mut pos: usize) { + // hole), shift along the others and move the removed element back into the + // vector at the final location of the hole. + // The `Hole` type is used to represent this, and make sure + // the hole is filled back at the end of its scope, even on panic. + // Using a hole reduces the constant factor compared to using swaps, + // which involves twice as many moves. + fn sift_up(&mut self, start: usize, pos: usize) { unsafe { - let new = replace(&mut self.data[pos], zeroed()); + // Take out the value at `pos` and create a hole. + let mut hole = Hole::new(&mut self.data, pos); - while pos > start { - let parent = (pos - 1) >> 1; - - if new <= self.data[parent] { break; } - - let x = replace(&mut self.data[parent], zeroed()); - ptr::write(&mut self.data[pos], x); - pos = parent; + while hole.pos() > start { + let parent = (hole.pos() - 1) / 2; + if hole.removed() <= hole.get(parent) { break } + hole.move_to(parent); } - ptr::write(&mut self.data[pos], new); } } fn sift_down_range(&mut self, mut pos: usize, end: usize) { + let start = pos; unsafe { - let start = pos; - let new = replace(&mut self.data[pos], zeroed()); - + let mut hole = Hole::new(&mut self.data, pos); let mut child = 2 * pos + 1; while child < end { let right = child + 1; - if right < end && !(self.data[child] > self.data[right]) { + if right < end && !(hole.get(child) > hole.get(right)) { child = right; } - let x = replace(&mut self.data[child], zeroed()); - ptr::write(&mut self.data[pos], x); - pos = child; - child = 2 * pos + 1; + hole.move_to(child); + child = 2 * hole.pos() + 1; } - ptr::write(&mut self.data[pos], new); - self.sift_up(start, pos); + pos = hole.pos; } + self.sift_up(start, pos); } fn sift_down(&mut self, pos: usize) { @@ -554,6 +550,73 @@ impl BinaryHeap { pub fn clear(&mut self) { self.drain(); } } +/// Hole represents a hole in a slice i.e. an index without valid value +/// (because it was moved from or duplicated). +/// In drop, `Hole` will restore the slice by filling the hole +/// position with the value that was originally removed. +struct Hole<'a, T: 'a> { + data: &'a mut [T], + /// `elt` is always `Some` from new until drop. + elt: Option, + pos: usize, +} + +impl<'a, T> Hole<'a, T> { + /// Create a new Hole at index `pos`. + fn new(data: &'a mut [T], pos: usize) -> Self { + unsafe { + let elt = ptr::read(&data[pos]); + Hole { + data: data, + elt: Some(elt), + pos: pos, + } + } + } + + #[inline(always)] + fn pos(&self) -> usize { self.pos } + + /// Return a reference to the element removed + #[inline(always)] + fn removed(&self) -> &T { + self.elt.as_ref().unwrap() + } + + /// Return a reference to the element at `index`. + /// + /// Panics if the index is out of bounds. + /// + /// Unsafe because index must not equal pos. + #[inline(always)] + unsafe fn get(&self, index: usize) -> &T { + debug_assert!(index != self.pos); + &self.data[index] + } + + /// Move hole to new location + /// + /// Unsafe because index must not equal pos. + #[inline(always)] + unsafe fn move_to(&mut self, index: usize) { + debug_assert!(index != self.pos); + let index_ptr: *const _ = &self.data[index]; + let hole_ptr = &mut self.data[self.pos]; + ptr::copy_nonoverlapping(index_ptr, hole_ptr, 1); + self.pos = index; + } +} + +impl<'a, T> Drop for Hole<'a, T> { + fn drop(&mut self) { + // fill the hole again + unsafe { + let pos = self.pos; + ptr::write(&mut self.data[pos], self.elt.take().unwrap()); + } + } +} + /// `BinaryHeap` iterator. #[stable(feature = "rust1", since = "1.0.0")] pub struct Iter <'a, T: 'a> { diff --git a/src/libcollections/fmt.rs b/src/libcollections/fmt.rs index cb023bcb7a586..817a5baf3d1be 100644 --- a/src/libcollections/fmt.rs +++ b/src/libcollections/fmt.rs @@ -164,8 +164,8 @@ //! provides some helper methods. //! //! Additionally, the return value of this function is `fmt::Result` which is a -//! typedef to `Result<(), IoError>` (also known as `IoResult<()>`). Formatting -//! implementations should ensure that they return errors from `write!` +//! typedef to `Result<(), std::io::Error>` (also known as `std::io::Result<()>`). +//! Formatting implementations should ensure that they return errors from `write!` //! correctly (propagating errors upward). //! //! An example of implementing the formatting traits would look diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index 4d52eb8e8ae67..8dacfa53bc980 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -440,6 +440,8 @@ impl Vec { } /// Extracts a slice containing the entire vector. + /// + /// Equivalent to `&s[..]`. #[inline] #[unstable(feature = "convert", reason = "waiting on RFC revision")] @@ -447,7 +449,9 @@ impl Vec { self } - /// Deprecated: use `&mut s[..]` instead. + /// Extracts a mutable slice of the entire vector. + /// + /// Equivalent to `&mut s[..]`. #[inline] #[unstable(feature = "convert", reason = "waiting on RFC revision")] diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index c83421d3067cd..3eb1fa4a558ea 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -143,7 +143,7 @@ #![stable(feature = "rust1", since = "1.0.0")] use clone::Clone; -use cmp::PartialEq; +use cmp::{PartialEq, Eq}; use default::Default; use marker::{Copy, Send, Sync, Sized}; use ops::{Deref, DerefMut, Drop}; @@ -212,7 +212,7 @@ impl Cell { } } - /// Gets a reference to the underlying `UnsafeCell`. + /// Returns a reference to the underlying `UnsafeCell`. /// /// # Unsafety /// @@ -263,6 +263,9 @@ impl PartialEq for Cell { } } +#[stable(feature = "cell_eq", since = "1.2.0")] +impl Eq for Cell {} + /// A mutable memory location with dynamically checked borrow rules /// /// See the [module-level documentation](index.html) for more. @@ -273,7 +276,7 @@ pub struct RefCell { } /// An enumeration of values returned from the `state` method on a `RefCell`. -#[derive(Copy, Clone, PartialEq, Debug)] +#[derive(Copy, Clone, PartialEq, Eq, Debug)] #[unstable(feature = "std_misc")] pub enum BorrowState { /// The cell is currently being read, there is at least one active `borrow`. @@ -439,7 +442,7 @@ impl RefCell { } } - /// Gets a reference to the underlying `UnsafeCell`. + /// Returns a reference to the underlying `UnsafeCell`. /// /// This can be used to circumvent `RefCell`'s safety checks. /// @@ -479,6 +482,9 @@ impl PartialEq for RefCell { } } +#[stable(feature = "cell_eq", since = "1.2.0")] +impl Eq for RefCell {} + struct BorrowRef<'b> { _borrow: &'b Cell, } @@ -671,8 +677,8 @@ impl UnsafeCell { /// /// # Unsafety /// - /// This function is unsafe because there is no guarantee that this or other threads are - /// currently inspecting the inner value. + /// This function is unsafe because this thread or another thread may currently be + /// inspecting the inner value. /// /// # Examples /// diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index da873f76d1bdd..ee1cab4076dc5 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -269,6 +269,50 @@ impl<'a> Display for Arguments<'a> { /// Format trait for the `:?` format. Useful for debugging, all types /// should implement this. +/// +/// Generally speaking, you should just `derive` a `Debug` implementation. +/// +/// # Examples +/// +/// Deriving an implementation: +/// +/// ``` +/// #[derive(Debug)] +/// struct Point { +/// x: i32, +/// y: i32, +/// } +/// +/// let origin = Point { x: 0, y: 0 }; +/// +/// println!("The origin is: {:?}", origin); +/// ``` +/// +/// Manually implementing: +/// +/// ``` +/// use std::fmt; +/// +/// struct Point { +/// x: i32, +/// y: i32, +/// } +/// +/// impl fmt::Debug for Point { +/// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { +/// write!(f, "({}, {})", self.x, self.y) +/// } +/// } +/// +/// let origin = Point { x: 0, y: 0 }; +/// +/// println!("The origin is: {:?}", origin); +/// ``` +/// +/// There are a number of `debug_*` methods on `Formatter` to help you with manual +/// implementations, such as [`debug_struct`][debug_struct]. +/// +/// [debug_struct]: ../std/fmt/struct.Formatter.html#method.debug_struct #[stable(feature = "rust1", since = "1.0.0")] #[rustc_on_unimplemented = "`{Self}` cannot be formatted using `:?`; if it is \ defined in your crate, add `#[derive(Debug)]` or \ diff --git a/src/libcore/num/isize.rs b/src/libcore/num/isize.rs index 0fd0d90b12501..2cdfe03eafe7f 100644 --- a/src/libcore/num/isize.rs +++ b/src/libcore/num/isize.rs @@ -9,10 +9,6 @@ // except according to those terms. //! Operations and constants for pointer-sized signed integers (`isize` type) -//! -//! This type was recently added to replace `int`. The rollout of the -//! new type will gradually take place over the alpha cycle along with -//! the development of clearer conventions around integer types. #![stable(feature = "rust1", since = "1.0.0")] #![doc(primitive = "isize")] diff --git a/src/libcore/num/usize.rs b/src/libcore/num/usize.rs index 602ef4fe45e73..6fd23425e4d89 100644 --- a/src/libcore/num/usize.rs +++ b/src/libcore/num/usize.rs @@ -9,10 +9,6 @@ // except according to those terms. //! Operations and constants for pointer-sized unsigned integers (`usize` type) -//! -//! This type was recently added to replace `uint`. The rollout of the -//! new type will gradually take place over the alpha cycle along with -//! the development of clearer conventions around integer types. #![stable(feature = "rust1", since = "1.0.0")] #![doc(primitive = "usize")] diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index 9d459027bf5cd..a1fa1834ef467 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -218,9 +218,9 @@ Therefore, casting one of these non-constant pointers to an integer results in a non-constant integer which lead to this error. Example: ``` -const X: u32 = 50; -const Y: *const u32 = &X; -println!("{:?}", Y); +const X: u32 = 1; +const Y: usize = &X as *const u32 as usize; +println!("{}", Y); ``` "##, @@ -892,6 +892,8 @@ register_diagnostics! { E0316, // nested quantification of lifetimes E0370, // discriminant overflow E0378, // method calls limited to constant inherent methods - E0394 // cannot refer to other statics by value, use the address-of + E0394, // cannot refer to other statics by value, use the address-of // operator or a constant instead + E0395, // pointer comparison in const-expr + E0396 // pointer dereference in const-expr } diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index 42dcc9661ca2d..5eefb99b058f1 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -252,6 +252,13 @@ fn doc_type<'tcx>(doc: rbml::Doc, tcx: &ty::ctxt<'tcx>, cdata: Cmd) -> Ty<'tcx> |_, did| translate_def_id(cdata, did)) } +fn maybe_doc_type<'tcx>(doc: rbml::Doc, tcx: &ty::ctxt<'tcx>, cdata: Cmd) -> Option> { + reader::maybe_get_doc(doc, tag_items_data_item_type).map(|tp| { + parse_ty_data(tp.data, cdata.cnum, tp.start, tcx, + |_, did| translate_def_id(cdata, did)) + }) +} + fn doc_method_fty<'tcx>(doc: rbml::Doc, tcx: &ty::ctxt<'tcx>, cdata: Cmd) -> ty::BareFnTy<'tcx> { let tp = reader::get_doc(doc, tag_item_method_fty); @@ -875,24 +882,24 @@ pub fn get_impl_or_trait_item<'tcx>(intr: Rc, id: ast::NodeId, tcx: &ty::ctxt<'tcx>) -> ty::ImplOrTraitItem<'tcx> { - let method_doc = lookup_item(id, cdata.data()); + let item_doc = lookup_item(id, cdata.data()); - let def_id = item_def_id(method_doc, cdata); + let def_id = item_def_id(item_doc, cdata); - let container_id = item_require_parent_item(cdata, method_doc); + let container_id = item_require_parent_item(cdata, item_doc); let container_doc = lookup_item(container_id.node, cdata.data()); let container = match item_family(container_doc) { Trait => TraitContainer(container_id), _ => ImplContainer(container_id), }; - let name = item_name(&*intr, method_doc); - let vis = item_visibility(method_doc); + let name = item_name(&*intr, item_doc); + let vis = item_visibility(item_doc); - match item_sort(method_doc) { + match item_sort(item_doc) { Some('C') => { - let ty = doc_type(method_doc, tcx, cdata); - let default = get_provided_source(method_doc, cdata); + let ty = doc_type(item_doc, tcx, cdata); + let default = get_provided_source(item_doc, cdata); ty::ConstTraitItem(Rc::new(ty::AssociatedConst { name: name, ty: ty, @@ -903,11 +910,11 @@ pub fn get_impl_or_trait_item<'tcx>(intr: Rc, })) } Some('r') | Some('p') => { - let generics = doc_generics(method_doc, tcx, cdata, tag_method_ty_generics); - let predicates = doc_predicates(method_doc, tcx, cdata, tag_method_ty_generics); - let fty = doc_method_fty(method_doc, tcx, cdata); - let explicit_self = get_explicit_self(method_doc); - let provided_source = get_provided_source(method_doc, cdata); + let generics = doc_generics(item_doc, tcx, cdata, tag_method_ty_generics); + let predicates = doc_predicates(item_doc, tcx, cdata, tag_method_ty_generics); + let fty = doc_method_fty(item_doc, tcx, cdata); + let explicit_self = get_explicit_self(item_doc); + let provided_source = get_provided_source(item_doc, cdata); ty::MethodTraitItem(Rc::new(ty::Method::new(name, generics, @@ -920,8 +927,10 @@ pub fn get_impl_or_trait_item<'tcx>(intr: Rc, provided_source))) } Some('t') => { + let ty = maybe_doc_type(item_doc, tcx, cdata); ty::TypeTraitItem(Rc::new(ty::AssociatedType { name: name, + ty: ty, vis: vis, def_id: def_id, container: container, diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index 0908ffd249fe4..8eefb4d5011d2 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -894,12 +894,12 @@ fn encode_info_for_method<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, rbml_w.end_tag(); } -fn encode_info_for_associated_type(ecx: &EncodeContext, - rbml_w: &mut Encoder, - associated_type: &ty::AssociatedType, - impl_path: PathElems, - parent_id: NodeId, - impl_item_opt: Option<&ast::ImplItem>) { +fn encode_info_for_associated_type<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, + rbml_w: &mut Encoder, + associated_type: &ty::AssociatedType<'tcx>, + impl_path: PathElems, + parent_id: NodeId, + impl_item_opt: Option<&ast::ImplItem>) { debug!("encode_info_for_associated_type({:?},{:?})", associated_type.def_id, token::get_name(associated_type.name)); @@ -913,8 +913,6 @@ fn encode_info_for_associated_type(ecx: &EncodeContext, encode_parent_item(rbml_w, local_def(parent_id)); encode_item_sort(rbml_w, 't'); - encode_bounds_and_type_for_item(rbml_w, ecx, associated_type.def_id.local_id()); - let stab = stability::lookup(ecx.tcx, associated_type.def_id); encode_stability(rbml_w, stab); @@ -923,7 +921,14 @@ fn encode_info_for_associated_type(ecx: &EncodeContext, if let Some(ii) = impl_item_opt { encode_attributes(rbml_w, &ii.attrs); - encode_type(ecx, rbml_w, ty::node_id_to_type(ecx.tcx, ii.id)); + } else { + encode_predicates(rbml_w, ecx, + &ty::lookup_predicates(ecx.tcx, associated_type.def_id), + tag_item_generics); + } + + if let Some(ty) = associated_type.ty { + encode_type(ecx, rbml_w, ty); } rbml_w.end_tag(); diff --git a/src/librustc/middle/check_const.rs b/src/librustc/middle/check_const.rs index c54517e00173b..3e084f3eeb305 100644 --- a/src/librustc/middle/check_const.rs +++ b/src/librustc/middle/check_const.rs @@ -536,11 +536,32 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, "allocations are not allowed in {}s", v.msg()); } } - ast::ExprUnary(ast::UnDeref, ref ptr) => { - match ty::node_id_to_type(v.tcx, ptr.id).sty { + ast::ExprUnary(op, ref inner) => { + match ty::node_id_to_type(v.tcx, inner.id).sty { ty::ty_ptr(_) => { - // This shouldn't be allowed in constants at all. + assert!(op == ast::UnDeref); + + v.add_qualif(ConstQualif::NOT_CONST); + if v.mode != Mode::Var { + span_err!(v.tcx.sess, e.span, E0396, + "raw pointers cannot be dereferenced in {}s", v.msg()); + } + } + _ => {} + } + } + ast::ExprBinary(op, ref lhs, _) => { + match ty::node_id_to_type(v.tcx, lhs.id).sty { + ty::ty_ptr(_) => { + assert!(op.node == ast::BiEq || op.node == ast::BiNe || + op.node == ast::BiLe || op.node == ast::BiLt || + op.node == ast::BiGe || op.node == ast::BiGt); + v.add_qualif(ConstQualif::NOT_CONST); + if v.mode != Mode::Var { + span_err!(v.tcx.sess, e.span, E0395, + "raw pointers cannot be compared in {}s", v.msg()); + } } _ => {} } @@ -553,7 +574,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, v.add_qualif(ConstQualif::NOT_CONST); if v.mode != Mode::Var { span_err!(v.tcx.sess, e.span, E0018, - "can't cast a pointer to an integer in {}s", v.msg()); + "raw pointers cannot be cast to integers in {}s", v.msg()); } } _ => {} @@ -695,8 +716,6 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, } ast::ExprBlock(_) | - ast::ExprUnary(..) | - ast::ExprBinary(..) | ast::ExprIndex(..) | ast::ExprField(..) | ast::ExprTupField(..) | diff --git a/src/librustc/middle/traits/project.rs b/src/librustc/middle/traits/project.rs index f6bde80e29875..969f82cc5ae1b 100644 --- a/src/librustc/middle/traits/project.rs +++ b/src/librustc/middle/traits/project.rs @@ -857,37 +857,41 @@ fn confirm_impl_candidate<'cx,'tcx>( -> (Ty<'tcx>, Vec>) { // there don't seem to be nicer accessors to these: - let impl_items_map = selcx.tcx().impl_items.borrow(); let impl_or_trait_items_map = selcx.tcx().impl_or_trait_items.borrow(); - let impl_items = impl_items_map.get(&impl_vtable.impl_def_id).unwrap(); - let mut impl_ty = None; - for impl_item in impl_items { - let assoc_type = match *impl_or_trait_items_map.get(&impl_item.def_id()).unwrap() { - ty::TypeTraitItem(ref assoc_type) => assoc_type.clone(), - ty::ConstTraitItem(..) | ty::MethodTraitItem(..) => { continue; } - }; - - if assoc_type.name != obligation.predicate.item_name { - continue; + // Look for the associated type in the impl + for impl_item in &selcx.tcx().impl_items.borrow()[&impl_vtable.impl_def_id] { + if let ty::TypeTraitItem(ref assoc_ty) = impl_or_trait_items_map[&impl_item.def_id()] { + if assoc_ty.name == obligation.predicate.item_name { + return (assoc_ty.ty.unwrap().subst(selcx.tcx(), &impl_vtable.substs), + impl_vtable.nested.into_vec()); + } } - - let impl_poly_ty = ty::lookup_item_type(selcx.tcx(), assoc_type.def_id); - impl_ty = Some(impl_poly_ty.ty.subst(selcx.tcx(), &impl_vtable.substs)); - break; } - match impl_ty { - Some(ty) => (ty, impl_vtable.nested.into_vec()), - None => { - // This means that the impl is missing a - // definition for the associated type. This error - // ought to be reported by the type checker method - // `check_impl_items_against_trait`, so here we - // just return ty_err. - (selcx.tcx().types.err, vec!()) + // It is not in the impl - get the default from the trait. + let trait_ref = obligation.predicate.trait_ref; + for trait_item in ty::trait_items(selcx.tcx(), trait_ref.def_id).iter() { + if let &ty::TypeTraitItem(ref assoc_ty) = trait_item { + if assoc_ty.name == obligation.predicate.item_name { + if let Some(ty) = assoc_ty.ty { + return (ty.subst(selcx.tcx(), trait_ref.substs), + impl_vtable.nested.into_vec()); + } else { + // This means that the impl is missing a + // definition for the associated type. This error + // ought to be reported by the type checker method + // `check_impl_items_against_trait`, so here we + // just return ty_err. + return (selcx.tcx().types.err, vec!()); + } + } } } + + selcx.tcx().sess.span_bug(obligation.cause.span, + &format!("No associated type for {}", + trait_ref.repr(selcx.tcx()))); } impl<'tcx> Repr<'tcx> for ProjectionTyError<'tcx> { diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 2ccbb0c5c103e..a67a968ea2cf9 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -136,7 +136,7 @@ impl ImplOrTraitItemContainer { pub enum ImplOrTraitItem<'tcx> { ConstTraitItem(Rc>), MethodTraitItem(Rc>), - TypeTraitItem(Rc), + TypeTraitItem(Rc>), } impl<'tcx> ImplOrTraitItem<'tcx> { @@ -267,8 +267,9 @@ pub struct AssociatedConst<'tcx> { } #[derive(Clone, Copy, Debug)] -pub struct AssociatedType { +pub struct AssociatedType<'tcx> { pub name: ast::Name, + pub ty: Option>, pub vis: ast::Visibility, pub def_id: ast::DefId, pub container: ImplOrTraitItemContainer, diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index cf2911ab182ef..6f71def11886d 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -1077,7 +1077,7 @@ impl<'tcx> Repr<'tcx> for ty::AssociatedConst<'tcx> { } } -impl<'tcx> Repr<'tcx> for ty::AssociatedType { +impl<'tcx> Repr<'tcx> for ty::AssociatedType<'tcx> { fn repr(&self, tcx: &ctxt<'tcx>) -> String { format!("AssociatedType(name: {}, vis: {}, def_id: {})", self.name.repr(tcx), diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index 844a0a698677f..c416a9810eb0e 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -279,7 +279,7 @@ pub fn sanitize(s: &str) -> String { } pub fn mangle>(path: PI, - hash: Option<&str>) -> String { + hash: Option<&str>) -> String { // Follow C++ namespace-mangling style, see // http://en.wikipedia.org/wiki/Name_mangling for more info. // diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs index bd16e018bc465..5352c61d8c0ad 100644 --- a/src/librustc_trans/back/write.rs +++ b/src/librustc_trans/back/write.rs @@ -342,8 +342,8 @@ struct HandlerFreeVars<'a> { } unsafe extern "C" fn report_inline_asm<'a, 'b>(cgcx: &'a CodegenContext<'a>, - msg: &'b str, - cookie: c_uint) { + msg: &'b str, + cookie: c_uint) { use syntax::codemap::ExpnId; match cgcx.lto_ctxt { diff --git a/src/librustc_trans/save/dump_csv.rs b/src/librustc_trans/save/dump_csv.rs index 00a1f728b9b00..5c630533ec33d 100644 --- a/src/librustc_trans/save/dump_csv.rs +++ b/src/librustc_trans/save/dump_csv.rs @@ -508,7 +508,7 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> { self.process_formals(&decl.inputs, &fn_data.qualname); self.process_generic_params(ty_params, item.span, &fn_data.qualname, item.id); } else { - unreachable!(); + self.sess.span_bug(item.span, "expected FunctionData"); } for arg in &decl.inputs { @@ -538,7 +538,7 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> { &var_data.type_value, var_data.scope); } else { - unreachable!(); + self.sess.span_bug(item.span, "expected VariableData"); } self.visit_ty(&typ); @@ -768,22 +768,18 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> { } fn process_mod(&mut self, - item: &ast::Item, // The module in question, represented as an item. - m: &ast::Mod) { - let qualname = format!("::{}", self.analysis.ty_cx.map.path_to_string(item.id)); - - let cm = self.sess.codemap(); - let filename = cm.span_to_filename(m.inner); - - let sub_span = self.span.sub_span_after_keyword(item.span, keywords::Mod); - self.fmt.mod_str(item.span, - sub_span, - item.id, - &qualname[..], - self.cur_scope, - &filename[..]); - - self.nest(item.id, |v| visit::walk_mod(v, m)); + item: &ast::Item) { // The module in question, represented as an item. + let mod_data = self.save_ctxt.get_item_data(item); + if let super::Data::ModData(mod_data) = mod_data { + self.fmt.mod_str(item.span, + Some(mod_data.span), + mod_data.id, + &mod_data.qualname, + mod_data.scope, + &mod_data.filename); + } else { + self.sess.span_bug(item.span, "expected ModData"); + } } fn process_path(&mut self, @@ -1188,7 +1184,10 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DumpCsvVisitor<'l, 'tcx> { } ast::ItemTrait(_, ref generics, ref trait_refs, ref methods) => self.process_trait(item, generics, trait_refs, methods), - ast::ItemMod(ref m) => self.process_mod(item, m), + ast::ItemMod(ref m) => { + self.process_mod(item); + self.nest(item.id, |v| visit::walk_mod(v, m)); + } ast::ItemTy(ref ty, ref ty_params) => { let qualname = format!("::{}", self.analysis.ty_cx.map.path_to_string(item.id)); let value = ty_to_string(&**ty); @@ -1295,30 +1294,22 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DumpCsvVisitor<'l, 'tcx> { ast::ExprStruct(ref path, ref fields, ref base) => self.process_struct_lit(ex, path, fields, base), ast::ExprMethodCall(_, _, ref args) => self.process_method_call(ex, args), - ast::ExprField(ref sub_ex, ident) => { + ast::ExprField(ref sub_ex, _) => { if generated_code(sub_ex.span) { return } - self.visit_expr(&**sub_ex); - let ty = &ty::expr_ty_adjusted(&self.analysis.ty_cx, &**sub_ex).sty; - match *ty { - ty::ty_struct(def_id, _) => { - let fields = ty::lookup_struct_fields(&self.analysis.ty_cx, def_id); - for f in &fields { - if f.name == ident.node.name { - let sub_span = self.span.span_for_last_ident(ex.span); - self.fmt.ref_str(recorder::VarRef, - ex.span, - sub_span, - f.id, - self.cur_scope); - break; - } - } - } - _ => self.sess.span_bug(ex.span, - &format!("Expected struct type, found {:?}", ty)), + self.visit_expr(&sub_ex); + + let field_data = self.save_ctxt.get_expr_data(ex); + if let super::Data::VariableRefData(field_data) = field_data { + self.fmt.ref_str(recorder::VarRef, + ex.span, + Some(field_data.span), + field_data.ref_id, + field_data.scope); + } else { + self.sess.span_bug(ex.span, "expected VariableRefData"); } }, ast::ExprTupField(ref sub_ex, idx) => { diff --git a/src/librustc_trans/save/mod.rs b/src/librustc_trans/save/mod.rs index c5c4a75ef823b..27297d8aa8d94 100644 --- a/src/librustc_trans/save/mod.rs +++ b/src/librustc_trans/save/mod.rs @@ -49,6 +49,12 @@ pub enum Data { FunctionData(FunctionData), /// Data for local and global variables (consts and statics). VariableData(VariableData), + /// Data for modules. + ModData(ModData), + + /// Data for the use of some variable (e.g., the use of a local variable, which + /// will refere to that variables declaration). + VariableRefData(VariableRefData), } /// Data for all kinds of functions and methods. @@ -72,6 +78,26 @@ pub struct VariableData { pub type_value: String, } +/// Data for modules. +pub struct ModData { + pub id: NodeId, + pub name: String, + pub qualname: String, + pub span: Span, + pub scope: NodeId, + pub filename: String, +} + +/// Data for the use of some item (e.g., the use of a local variable, which +/// will refere to that variables declaration (by ref_id)). +pub struct VariableRefData { + pub name: String, + pub span: Span, + pub scope: NodeId, + pub ref_id: DefId, +} + + impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { pub fn new(sess: &'l Session, analysis: &'l ty::CrateAnalysis<'tcx>, @@ -97,7 +123,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { pub fn get_item_data(&self, item: &ast::Item) -> Data { match item.node { - ast::Item_::ItemFn(..) => { + ast::ItemFn(..) => { let name = self.analysis.ty_cx.map.path_to_string(item.id); let qualname = format!("::{}", name); let sub_span = self.span_utils.sub_span_after_keyword(item.span, keywords::Fn); @@ -146,6 +172,58 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { type_value: ty_to_string(&typ), }) } + ast::ItemMod(ref m) => { + let qualname = format!("::{}", self.analysis.ty_cx.map.path_to_string(item.id)); + + let cm = self.sess.codemap(); + let filename = cm.span_to_filename(m.inner); + + let sub_span = self.span_utils.sub_span_after_keyword(item.span, keywords::Mod); + + Data::ModData(ModData { + id: item.id, + name: get_ident(item.ident).to_string(), + qualname: qualname, + span: sub_span.unwrap(), + scope: self.analysis.ty_cx.map.get_parent(item.id), + filename: filename, + }) + } + _ => { + // FIXME + unimplemented!(); + } + } + } + + pub fn get_expr_data(&self, expr: &ast::Expr) -> Data { + match expr.node { + ast::ExprField(ref sub_ex, ident) => { + let ty = &ty::expr_ty_adjusted(&self.analysis.ty_cx, &sub_ex).sty; + match *ty { + ty::ty_struct(def_id, _) => { + let fields = ty::lookup_struct_fields(&self.analysis.ty_cx, def_id); + for f in &fields { + if f.name == ident.node.name { + let sub_span = self.span_utils.span_for_last_ident(expr.span); + return Data::VariableRefData(VariableRefData { + name: get_ident(ident.node).to_string(), + span: sub_span.unwrap(), + scope: self.analysis.ty_cx.map.get_parent(expr.id), + ref_id: f.id, + }); + } + } + + self.sess.span_bug(expr.span, + &format!("Couldn't find field {} on {:?}", + &get_ident(ident.node), + ty)) + } + _ => self.sess.span_bug(expr.span, + &format!("Expected struct type, found {:?}", ty)), + } + } _ => { // FIXME unimplemented!(); diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index af3d8894c74d1..e7e8140aab319 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1070,7 +1070,7 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, // Check for missing items from trait let provided_methods = ty::provided_trait_methods(tcx, impl_trait_ref.def_id); let associated_consts = ty::associated_consts(tcx, impl_trait_ref.def_id); - let mut missing_methods = Vec::new(); + let mut missing_items = Vec::new(); for trait_item in &*trait_items { match *trait_item { ty::ConstTraitItem(ref associated_const) => { @@ -1086,8 +1086,8 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, associated_consts.iter().any(|ac| ac.default.is_some() && ac.name == associated_const.name); if !is_implemented && !is_provided { - missing_methods.push(format!("`{}`", - token::get_name(associated_const.name))); + missing_items.push(format!("`{}`", + token::get_name(associated_const.name))); } } ty::MethodTraitItem(ref trait_method) => { @@ -1103,7 +1103,7 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, let is_provided = provided_methods.iter().any(|m| m.name == trait_method.name); if !is_implemented && !is_provided { - missing_methods.push(format!("`{}`", token::get_name(trait_method.name))); + missing_items.push(format!("`{}`", token::get_name(trait_method.name))); } } ty::TypeTraitItem(ref associated_type) => { @@ -1115,17 +1115,18 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, _ => false, } }); - if !is_implemented { - missing_methods.push(format!("`{}`", token::get_name(associated_type.name))); + let is_provided = associated_type.ty.is_some(); + if !is_implemented && !is_provided { + missing_items.push(format!("`{}`", token::get_name(associated_type.name))); } } } } - if !missing_methods.is_empty() { + if !missing_items.is_empty() { span_err!(tcx.sess, impl_span, E0046, "not all trait items implemented, missing: {}", - missing_methods.connect(", ")); + missing_items.connect(", ")); } } diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 42d1c122fba83..4ef17105923aa 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -717,15 +717,17 @@ fn convert_associated_const<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, .insert(local_def(id), ty::ConstTraitItem(associated_const)); } -fn as_refsociated_type<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, - container: ImplOrTraitItemContainer, - ident: ast::Ident, - id: ast::NodeId, - vis: ast::Visibility) +fn convert_associated_type<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, + container: ImplOrTraitItemContainer, + ident: ast::Ident, + id: ast::NodeId, + vis: ast::Visibility, + ty: Option>) { let associated_type = Rc::new(ty::AssociatedType { name: ident.name, vis: vis, + ty: ty, def_id: local_def(id), container: container }); @@ -878,18 +880,11 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) { "associated types are not allowed in inherent impls"); } - as_refsociated_type(ccx, ImplContainer(local_def(it.id)), - impl_item.ident, impl_item.id, impl_item.vis); - let typ = ccx.icx(&ty_predicates).to_ty(&ExplicitRscope, ty); - tcx.tcache.borrow_mut().insert(local_def(impl_item.id), - TypeScheme { - generics: ty::Generics::empty(), - ty: typ, - }); - tcx.predicates.borrow_mut().insert(local_def(impl_item.id), - ty::GenericPredicates::empty()); - write_ty_to_tcx(tcx, impl_item.id, typ); + + convert_associated_type(ccx, ImplContainer(local_def(it.id)), + impl_item.ident, impl_item.id, impl_item.vis, + Some(typ)); } } @@ -972,9 +967,14 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) { // Convert all the associated types. for trait_item in trait_items { match trait_item.node { - ast::TypeTraitItem(..) => { - as_refsociated_type(ccx, TraitContainer(local_def(it.id)), - trait_item.ident, trait_item.id, ast::Public); + ast::TypeTraitItem(_, ref opt_ty) => { + let typ = opt_ty.as_ref().map({ + |ty| ccx.icx(&trait_predicates).to_ty(&ExplicitRscope, &ty) + }); + + convert_associated_type(ccx, TraitContainer(local_def(it.id)), + trait_item.ident, trait_item.id, ast::Public, + typ); } _ => {} } @@ -2291,10 +2291,10 @@ fn enforce_impl_params_are_constrained<'tcx>(tcx: &ty::ctxt<'tcx>, let lifetimes_in_associated_types: HashSet<_> = impl_items.iter() - .filter_map(|item| match item.node { - ast::TypeImplItem(..) => Some(ty::node_id_to_type(tcx, item.id)), - ast::ConstImplItem(..) | ast::MethodImplItem(..) | - ast::MacImplItem(..) => None, + .map(|item| ty::impl_or_trait_item(tcx, local_def(item.id))) + .filter_map(|item| match item { + ty::TypeTraitItem(ref assoc_ty) => assoc_ty.ty, + ty::ConstTraitItem(..) | ty::MethodTraitItem(..) => None }) .flat_map(|ty| ctp::parameters_for_type(ty).into_iter()) .filter_map(|p| match p { diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index de978971bbe61..cd8d7b416d239 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -362,11 +362,13 @@ pub fn build_impl(cx: &DocContext, } ty::TypeTraitItem(ref assoc_ty) => { let did = assoc_ty.def_id; - let type_scheme = ty::lookup_item_type(tcx, did); - let predicates = ty::lookup_predicates(tcx, did); + let type_scheme = ty::TypeScheme { + ty: assoc_ty.ty.unwrap(), + generics: ty::Generics::empty() + }; // Not sure the choice of ParamSpace actually matters here, // because an associated type won't have generics on the LHS - let typedef = (type_scheme, predicates, + let typedef = (type_scheme, ty::GenericPredicates::empty(), subst::ParamSpace::TypeSpace).clean(cx); Some(clean::Item { name: Some(assoc_ty.name.clean(cx)), diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index e366caf92f773..0be8570f90483 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2737,43 +2737,40 @@ impl<'tcx> Clean for ty::AssociatedConst<'tcx> { } } -impl Clean for ty::AssociatedType { +impl<'tcx> Clean for ty::AssociatedType<'tcx> { fn clean(&self, cx: &DocContext) -> Item { - // When loading a cross-crate associated type, the bounds for this type - // are actually located on the trait/impl itself, so we need to load - // all of the generics from there and then look for bounds that are - // applied to this associated type in question. - let predicates = ty::lookup_predicates(cx.tcx(), self.container.id()); - let generics = match self.container { - ty::TraitContainer(did) => { - let def = ty::lookup_trait_def(cx.tcx(), did); - (&def.generics, &predicates, subst::TypeSpace).clean(cx) - } - ty::ImplContainer(did) => { - let ty = ty::lookup_item_type(cx.tcx(), did); - (&ty.generics, &predicates, subst::TypeSpace).clean(cx) - } - }; let my_name = self.name.clean(cx); - let mut bounds = generics.where_predicates.iter().filter_map(|pred| { - let (name, self_type, trait_, bounds) = match *pred { - WherePredicate::BoundPredicate { - ty: QPath { ref name, ref self_type, ref trait_ }, - ref bounds - } => (name, self_type, trait_, bounds), - _ => return None, - }; - if *name != my_name { return None } - match **trait_ { - ResolvedPath { did, .. } if did == self.container.id() => {} - _ => return None, - } - match **self_type { - Generic(ref s) if *s == "Self" => {} - _ => return None, - } - Some(bounds) - }).flat_map(|i| i.iter().cloned()).collect::>(); + + let mut bounds = if let ty::TraitContainer(did) = self.container { + // When loading a cross-crate associated type, the bounds for this type + // are actually located on the trait/impl itself, so we need to load + // all of the generics from there and then look for bounds that are + // applied to this associated type in question. + let def = ty::lookup_trait_def(cx.tcx(), did); + let predicates = ty::lookup_predicates(cx.tcx(), did); + let generics = (&def.generics, &predicates, subst::TypeSpace).clean(cx); + generics.where_predicates.iter().filter_map(|pred| { + let (name, self_type, trait_, bounds) = match *pred { + WherePredicate::BoundPredicate { + ty: QPath { ref name, ref self_type, ref trait_ }, + ref bounds + } => (name, self_type, trait_, bounds), + _ => return None, + }; + if *name != my_name { return None } + match **trait_ { + ResolvedPath { did, .. } if did == self.container.id() => {} + _ => return None, + } + match **self_type { + Generic(ref s) if *s == "Self" => {} + _ => return None, + } + Some(bounds) + }).flat_map(|i| i.iter().cloned()).collect::>() + } else { + vec![] + }; // Our Sized/?Sized bound didn't get handled when creating the generics // because we didn't actually get our whole set of bounds until just now @@ -2789,7 +2786,7 @@ impl Clean for ty::AssociatedType { source: DUMMY_SP.clean(cx), name: Some(self.name.clean(cx)), attrs: inline::load_attrs(cx, cx.tcx(), self.def_id), - inner: AssociatedTypeItem(bounds, None), + inner: AssociatedTypeItem(bounds, self.ty.clean(cx)), visibility: self.vis.clean(cx), def_id: self.def_id, stability: stability::lookup(cx.tcx(), self.def_id).clean(cx), diff --git a/src/libstd/env.rs b/src/libstd/env.rs index 0b9c659ea2e5b..379c925b5750e 100644 --- a/src/libstd/env.rs +++ b/src/libstd/env.rs @@ -598,40 +598,94 @@ pub fn page_size() -> usize { pub mod consts { /// A string describing the architecture of the CPU that this is currently /// in use. + /// + /// Some possible values: + /// + /// - x86 + /// - x86_64 + /// - arm + /// - aarch64 + /// - mips + /// - mipsel + /// - powerpc #[stable(feature = "env", since = "1.0.0")] pub const ARCH: &'static str = super::arch::ARCH; /// The family of the operating system. In this case, `unix`. + /// + /// Some possible values: + /// + /// - unix + /// - windows #[stable(feature = "env", since = "1.0.0")] pub const FAMILY: &'static str = super::os::FAMILY; /// A string describing the specific operating system in use: in this /// case, `linux`. + /// + /// Some possible values: + /// + /// - linux + /// - macos + /// - ios + /// - freebsd + /// - dragonfly + /// - bitrig + /// - openbsd + /// - android + /// - windows #[stable(feature = "env", since = "1.0.0")] pub const OS: &'static str = super::os::OS; /// Specifies the filename prefix used for shared libraries on this /// platform: in this case, `lib`. + /// + /// Some possible values: + /// + /// - lib + /// - `""` (an empty string) #[stable(feature = "env", since = "1.0.0")] pub const DLL_PREFIX: &'static str = super::os::DLL_PREFIX; /// Specifies the filename suffix used for shared libraries on this /// platform: in this case, `.so`. + /// + /// Some possible values: + /// + /// - .so + /// - .dylib + /// - .dll #[stable(feature = "env", since = "1.0.0")] pub const DLL_SUFFIX: &'static str = super::os::DLL_SUFFIX; /// Specifies the file extension used for shared libraries on this /// platform that goes after the dot: in this case, `so`. + /// + /// Some possible values: + /// + /// - .so + /// - .dylib + /// - .dll #[stable(feature = "env", since = "1.0.0")] pub const DLL_EXTENSION: &'static str = super::os::DLL_EXTENSION; /// Specifies the filename suffix used for executable binaries on this /// platform: in this case, the empty string. + /// + /// Some possible values: + /// + /// - exe + /// - `""` (an empty string) #[stable(feature = "env", since = "1.0.0")] pub const EXE_SUFFIX: &'static str = super::os::EXE_SUFFIX; /// Specifies the file extension, if any, used for executable binaries /// on this platform: in this case, the empty string. + /// + /// Some possible values: + /// + /// - exe + /// - `""` (an empty string) #[stable(feature = "env", since = "1.0.0")] pub const EXE_EXTENSION: &'static str = super::os::EXE_EXTENSION; diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs index 31b427d3fa768..b60a84da81ddf 100644 --- a/src/libstd/fs.rs +++ b/src/libstd/fs.rs @@ -844,6 +844,8 @@ pub fn symlink_metadata>(path: P) -> io::Result { /// Rename a file or directory to a new name. /// +/// This will not work if the new name is on a different mount point. +/// /// # Errors /// /// This function will return an error if the provided `from` doesn't exist, if diff --git a/src/libstd/num/isize.rs b/src/libstd/num/isize.rs index 7fb2cd81ababf..aa89f858f6f63 100644 --- a/src/libstd/num/isize.rs +++ b/src/libstd/num/isize.rs @@ -9,10 +9,6 @@ // except according to those terms. //! Operations and constants for pointer-sized signed integers (`isize` type) -//! -//! This type was recently added to replace `int`. The rollout of the -//! new type will gradually take place over the alpha cycle along with -//! the development of clearer conventions around integer types. #![stable(feature = "rust1", since = "1.0.0")] #![doc(primitive = "isize")] diff --git a/src/libstd/num/usize.rs b/src/libstd/num/usize.rs index 19964c306a79b..b54d8ae96c5cf 100644 --- a/src/libstd/num/usize.rs +++ b/src/libstd/num/usize.rs @@ -9,10 +9,6 @@ // except according to those terms. //! Operations and constants for pointer-sized unsigned integers (`usize` type) -//! -//! This type was recently added to replace `uint`. The rollout of the -//! new type will gradually take place over the alpha cycle along with -//! the development of clearer conventions around integer types. #![stable(feature = "rust1", since = "1.0.0")] #![doc(primitive = "usize")] diff --git a/src/libstd/rand/mod.rs b/src/libstd/rand/mod.rs index e11a5818966fa..b806afc5951d8 100644 --- a/src/libstd/rand/mod.rs +++ b/src/libstd/rand/mod.rs @@ -95,7 +95,7 @@ impl StdRng { /// appropriate. /// /// Reading the randomness from the OS may fail, and any error is - /// propagated via the `IoResult` return value. + /// propagated via the `io::Result` return value. pub fn new() -> io::Result { OsRng::new().map(|mut r| StdRng { rng: r.gen() }) } diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index 575f29b3bc97f..da86e727c6874 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -740,7 +740,7 @@ fn should_sort_failures_before_printing_them() { fn use_color(opts: &TestOpts) -> bool { match opts.color { - AutoColor => get_concurrency() == 1 && stdout_isatty(), + AutoColor => !opts.nocapture && stdout_isatty(), AlwaysColor => true, NeverColor => false, } diff --git a/src/test/compile-fail/asm-src-loc-codegen-units.rs b/src/test/compile-fail/asm-src-loc-codegen-units.rs index 5ebcdb20b1952..79f0c436759b3 100644 --- a/src/test/compile-fail/asm-src-loc-codegen-units.rs +++ b/src/test/compile-fail/asm-src-loc-codegen-units.rs @@ -8,7 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. // -// ignore-stage1 (#20184) +// WONTFIX(#20184) Needs landing pads (not present in stage1) or the compiler hangs. +// ignore-stage1 // compile-flags: -C codegen-units=2 // error-pattern: build without -C codegen-units for more exact errors diff --git a/src/test/compile-fail/const-deref-ptr.rs b/src/test/compile-fail/const-deref-ptr.rs new file mode 100644 index 0000000000000..fa15f3e87c694 --- /dev/null +++ b/src/test/compile-fail/const-deref-ptr.rs @@ -0,0 +1,16 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Check that you can't dereference raw pointers in constants. + +fn main() { + static C: u64 = unsafe {*(0xdeadbeef as *const u64)}; //~ ERROR E0396 + println!("{}", C); +} diff --git a/src/test/compile-fail/issue-17458.rs b/src/test/compile-fail/issue-17458.rs index a3a9e17cb3c06..f5b7a0c13b728 100644 --- a/src/test/compile-fail/issue-17458.rs +++ b/src/test/compile-fail/issue-17458.rs @@ -9,7 +9,7 @@ // except according to those terms. static X: usize = 0 as *const usize as usize; -//~^ ERROR: can't cast a pointer to an integer in statics +//~^ ERROR: raw pointers cannot be cast to integers in statics fn main() { assert_eq!(X, 0); diff --git a/src/test/compile-fail/issue-22673.rs b/src/test/compile-fail/issue-22673.rs index 6983d1f0706a0..442e6bcda5a09 100644 --- a/src/test/compile-fail/issue-22673.rs +++ b/src/test/compile-fail/issue-22673.rs @@ -10,7 +10,7 @@ trait Expr : PartialEq { //~^ ERROR: unsupported cyclic reference between types/traits detected - type Item = Expr; + type Item; } fn main() {} diff --git a/src/test/compile-fail/issue-23073.rs b/src/test/compile-fail/issue-23073.rs new file mode 100644 index 0000000000000..1286ba873be5a --- /dev/null +++ b/src/test/compile-fail/issue-23073.rs @@ -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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +trait Foo { type T; } +trait Bar { + type Foo: Foo; + type FooT = <::Foo>::T; //~ ERROR ambiguous associated type +} + +fn main() {} diff --git a/src/test/compile-fail/issue-25826.rs b/src/test/compile-fail/issue-25826.rs new file mode 100644 index 0000000000000..00e1279d58a0e --- /dev/null +++ b/src/test/compile-fail/issue-25826.rs @@ -0,0 +1,16 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn id(t: T) -> T { t } +fn main() { + const A: bool = id:: as *const () < id:: as *const (); + //~^ ERROR raw pointers cannot be compared in constants [E0395] + println!("{}", A); +} diff --git a/src/test/run-pass/binary-heap-panic-safe.rs b/src/test/run-pass/binary-heap-panic-safe.rs new file mode 100644 index 0000000000000..4888a8b84fc42 --- /dev/null +++ b/src/test/run-pass/binary-heap-panic-safe.rs @@ -0,0 +1,108 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(std_misc, collections, catch_panic, rand)] + +use std::__rand::{thread_rng, Rng}; +use std::thread; + +use std::collections::BinaryHeap; +use std::cmp; +use std::sync::Arc; +use std::sync::Mutex; +use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering}; + +static DROP_COUNTER: AtomicUsize = ATOMIC_USIZE_INIT; + +// old binaryheap failed this test +// +// Integrity means that all elements are present after a comparison panics, +// even if the order may not be correct. +// +// Destructors must be called exactly once per element. +fn test_integrity() { + #[derive(Eq, PartialEq, Ord, Clone, Debug)] + struct PanicOrd(T, bool); + + impl Drop for PanicOrd { + fn drop(&mut self) { + // update global drop count + DROP_COUNTER.fetch_add(1, Ordering::SeqCst); + } + } + + impl PartialOrd for PanicOrd { + fn partial_cmp(&self, other: &Self) -> Option { + if self.1 || other.1 { + panic!("Panicking comparison"); + } + self.0.partial_cmp(&other.0) + } + } + let mut rng = thread_rng(); + const DATASZ: usize = 32; + const NTEST: usize = 10; + + // don't use 0 in the data -- we want to catch the zeroed-out case. + let data = (1..DATASZ + 1).collect::>(); + + // since it's a fuzzy test, run several tries. + for _ in 0..NTEST { + for i in 1..DATASZ + 1 { + DROP_COUNTER.store(0, Ordering::SeqCst); + + let mut panic_ords: Vec<_> = data.iter() + .filter(|&&x| x != i) + .map(|&x| PanicOrd(x, false)) + .collect(); + let panic_item = PanicOrd(i, true); + + // heapify the sane items + rng.shuffle(&mut panic_ords); + let heap = Arc::new(Mutex::new(BinaryHeap::from_vec(panic_ords))); + let inner_data; + + { + let heap_ref = heap.clone(); + + + // push the panicking item to the heap and catch the panic + let thread_result = thread::catch_panic(move || { + heap.lock().unwrap().push(panic_item); + }); + assert!(thread_result.is_err()); + + // Assert no elements were dropped + let drops = DROP_COUNTER.load(Ordering::SeqCst); + //assert!(drops == 0, "Must not drop items. drops={}", drops); + + { + // now fetch the binary heap's data vector + let mutex_guard = match heap_ref.lock() { + Ok(x) => x, + Err(poison) => poison.into_inner(), + }; + inner_data = mutex_guard.clone().into_vec(); + } + } + let drops = DROP_COUNTER.load(Ordering::SeqCst); + assert_eq!(drops, DATASZ); + + let mut data_sorted = inner_data.into_iter().map(|p| p.0).collect::>(); + data_sorted.sort(); + assert_eq!(data_sorted, data); + } + } +} + +fn main() { + test_integrity(); +} + diff --git a/src/test/run-pass/default-associated-types.rs b/src/test/run-pass/default-associated-types.rs new file mode 100644 index 0000000000000..b3def429b9b8c --- /dev/null +++ b/src/test/run-pass/default-associated-types.rs @@ -0,0 +1,30 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +trait Foo { + type Out = T; + fn foo(&self) -> Self::Out; +} + +impl Foo for () { + fn foo(&self) -> u32 { + 4u32 + } +} + +impl Foo for bool { + type Out = (); + fn foo(&self) {} +} + +fn main() { + assert_eq!(<() as Foo>::foo(&()), 4u32); + assert_eq!(>::foo(&true), ()); +} diff --git a/src/test/run-pass/enum-discrim-manual-sizing-2.rs b/src/test/run-pass/enum-discrim-manual-sizing-2.rs new file mode 100644 index 0000000000000..0470a9e19d580 --- /dev/null +++ b/src/test/run-pass/enum-discrim-manual-sizing-2.rs @@ -0,0 +1,107 @@ +// Copyright 2013 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test that explicit discriminant sizing inhibits the non-nullable pointer +// optimization in enum layout. + +use std::mem::size_of; + +#[repr(i8)] +enum Ei8 { + _None, + _Some(T), +} + +#[repr(u8)] +enum Eu8 { + _None, + _Some(T), +} + +#[repr(i16)] +enum Ei16 { + _None, + _Some(T), +} + +#[repr(u16)] +enum Eu16 { + _None, + _Some(T), +} + +#[repr(i32)] +enum Ei32 { + _None, + _Some(T), +} + +#[repr(u32)] +enum Eu32 { + _None, + _Some(T), +} + +#[repr(i64)] +enum Ei64 { + _None, + _Some(T), +} + +#[repr(u64)] +enum Eu64 { + _None, + _Some(T), +} + +#[repr(isize)] +enum Eint { + _None, + _Some(T), +} + +#[repr(usize)] +enum Euint { + _None, + _Some(T), +} + +#[repr(C)] +enum EC { + _None, + _Some(T), +} + +pub fn main() { + assert_eq!(size_of::>(), 1); + assert_eq!(size_of::>(), 1); + assert_eq!(size_of::>(), 2); + assert_eq!(size_of::>(), 2); + assert_eq!(size_of::>(), 4); + assert_eq!(size_of::>(), 4); + assert_eq!(size_of::>(), 8); + assert_eq!(size_of::>(), 8); + assert_eq!(size_of::>(), size_of::()); + assert_eq!(size_of::>(), size_of::()); + + let ptrsize = size_of::<&i32>(); + assert!(size_of::>() > ptrsize); + assert!(size_of::>() > ptrsize); + assert!(size_of::>() > ptrsize); + assert!(size_of::>() > ptrsize); + assert!(size_of::>() > ptrsize); + assert!(size_of::>() > ptrsize); + assert!(size_of::>() > ptrsize); + assert!(size_of::>() > ptrsize); + assert!(size_of::>() > ptrsize); + assert!(size_of::>() > ptrsize); + + assert!(size_of::>() > ptrsize); +} diff --git a/src/test/run-pass/issue-25339.rs b/src/test/run-pass/issue-25339.rs new file mode 100644 index 0000000000000..af172000fdb1a --- /dev/null +++ b/src/test/run-pass/issue-25339.rs @@ -0,0 +1,36 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::marker::PhantomData; + +pub trait Routing { + type Output; + fn resolve(&self, input: I); +} + +pub trait ToRouting { + type Input; + type Routing : ?Sized = Routing; + fn to_routing(self) -> Self::Routing; +} + +pub struct Mount> { + action: R, + _marker: PhantomData +} + +impl> Mount { + pub fn create>(mount: &str, input: T) { + input.to_routing(); + } +} + +fn main() { +} diff --git a/src/test/run-pass/macro-with-braces-in-expr-position.rs b/src/test/run-pass/macro-with-braces-in-expr-position.rs index 4881a5ab647ec..326d1cafe6c78 100644 --- a/src/test/run-pass/macro-with-braces-in-expr-position.rs +++ b/src/test/run-pass/macro-with-braces-in-expr-position.rs @@ -8,15 +8,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(std_misc)] - use std::thread; macro_rules! expr { ($e: expr) => { $e } } macro_rules! spawn { ($($code: tt)*) => { - expr!(thread::spawn(move|| {$($code)*})) + expr!(thread::spawn(move|| {$($code)*}).join()) } }