]> git.lizzy.rs Git - rust.git/commitdiff
auto merge of #17157 : nikomatsakis/rust/occurs-check, r=pcwalton
authorbors <bors@rust-lang.org>
Thu, 11 Sep 2014 12:20:43 +0000 (12:20 +0000)
committerbors <bors@rust-lang.org>
Thu, 11 Sep 2014 12:20:43 +0000 (12:20 +0000)
Avoid ever constructing cyclic types in the first place, rather than detecting them in resolve. This simplifies logic elsewhere in the compiler, in particular on the trait reform branch.

r? @pnkfelix or @pcwalton

cc #5527

125 files changed:
README.md
configure
mk/dist.mk
mk/docs.mk
mk/reconfig.mk
src/doc/guide-strings.md
src/doc/guide.md
src/doc/rust.md
src/doc/tutorial.md
src/etc/copy-runtime-deps.py
src/etc/licenseck.py
src/etc/pkg/rust.iss
src/etc/snapshot.py
src/jemalloc
src/liballoc/heap.rs
src/libarena/lib.rs
src/libcollections/slice.rs
src/libcore/fmt/mod.rs
src/libcore/fmt/rt.rs
src/libcore/iter.rs
src/libcore/ops.rs
src/libcoretest/any.rs
src/libcoretest/fmt/mod.rs
src/libcoretest/iter.rs
src/libcoretest/option.rs
src/libcoretest/result.rs
src/libdebug/repr.rs
src/libgraphviz/lib.rs
src/libgreen/sched.rs
src/libnative/io/file_unix.rs
src/libnative/io/mod.rs
src/libnative/io/net.rs
src/libnum/bigint.rs
src/librbml/lib.rs
src/librlibc/lib.rs
src/librustc/front/feature_gate.rs
src/librustc/front/show_span.rs
src/librustc/front/test.rs
src/librustc/lib.rs
src/librustc/lint/builtin.rs
src/librustc/middle/astencode.rs
src/librustc/middle/borrowck/mod.rs
src/librustc/middle/cfg/construct.rs
src/librustc/middle/check_const.rs
src/librustc/middle/check_static.rs
src/librustc/middle/const_eval.rs
src/librustc/middle/dead.rs
src/librustc/middle/expr_use_visitor.rs
src/librustc/middle/kind.rs
src/librustc/middle/liveness.rs
src/librustc/middle/mem_categorization.rs
src/librustc/middle/privacy.rs
src/librustc/middle/region.rs
src/librustc/middle/resolve.rs
src/librustc/middle/save/mod.rs
src/librustc/middle/trans/consts.rs
src/librustc/middle/trans/debuginfo.rs
src/librustc/middle/trans/expr.rs
src/librustc/middle/trans/tvec.rs
src/librustc/middle/ty.rs
src/librustc/middle/typeck/check/mod.rs
src/librustc/middle/typeck/check/regionck.rs
src/librustc/middle/typeck/collect.rs
src/librustc_back/svh.rs
src/librustdoc/html/markdown.rs
src/librustrt/c_str.rs
src/librustrt/task.rs
src/libserialize/json.rs
src/libsync/spsc_queue.rs
src/libsyntax/ast.rs
src/libsyntax/ext/build.rs
src/libsyntax/ext/format.rs
src/libsyntax/ext/quote.rs
src/libsyntax/fold.rs
src/libsyntax/parse/obsolete.rs
src/libsyntax/parse/parser.rs
src/libsyntax/print/pprust.rs
src/libsyntax/visit.rs
src/libuuid/lib.rs
src/test/bench/shootout-chameneos-redux.rs
src/test/bench/shootout-nbody.rs
src/test/bench/shootout-reverse-complement.rs
src/test/compile-fail/borrow-tuple-fields.rs [new file with mode: 0644]
src/test/compile-fail/borrowck-for-loop-head-linkage.rs [new file with mode: 0644]
src/test/compile-fail/borrowck-move-out-of-vec-tail.rs
src/test/compile-fail/borrowck-vec-pattern-element-loan.rs
src/test/compile-fail/borrowck-vec-pattern-loan-from-mut.rs
src/test/compile-fail/borrowck-vec-pattern-move-tail.rs
src/test/compile-fail/borrowck-vec-pattern-nesting.rs
src/test/compile-fail/borrowck-vec-pattern-tail-element-loan.rs
src/test/compile-fail/feature-gate-advanced-slice-features.rs [new file with mode: 0644]
src/test/compile-fail/generic-lifetime-trait-impl.rs [new file with mode: 0644]
src/test/compile-fail/issue-12369.rs
src/test/compile-fail/issue-12567.rs
src/test/compile-fail/lint-type-overflow.rs
src/test/compile-fail/match-vec-invalid.rs
src/test/compile-fail/match-vec-unreachable.rs
src/test/compile-fail/move-out-of-tuple-field.rs [new file with mode: 0644]
src/test/compile-fail/non-exhaustive-match.rs
src/test/compile-fail/non-exhaustive-pattern-witness.rs
src/test/compile-fail/tuple-index-not-tuple.rs [new file with mode: 0644]
src/test/compile-fail/tuple-index-out-of-bounds.rs [new file with mode: 0644]
src/test/compile-fail/unsized3.rs
src/test/compile-fail/vec-matching-obsolete-syntax.rs [new file with mode: 0644]
src/test/pretty/issue-4264.pp
src/test/run-pass-fulldeps/issue-16992.rs [new file with mode: 0644]
src/test/run-pass/borrow-tuple-fields.rs [new file with mode: 0644]
src/test/run-pass/borrowck-trait-lifetime.rs [new file with mode: 0644]
src/test/run-pass/empty-allocation-non-null.rs
src/test/run-pass/for-loop-does-not-borrow-iterators.rs [deleted file]
src/test/run-pass/ignore-all-the-things.rs
src/test/run-pass/issue-15080.rs
src/test/run-pass/issue-15104.rs
src/test/run-pass/issue-17074.rs [new file with mode: 0644]
src/test/run-pass/issue-7784.rs
src/test/run-pass/match-vec-alternatives.rs
src/test/run-pass/tuple-index-fat-types.rs [new file with mode: 0644]
src/test/run-pass/tuple-index.rs [new file with mode: 0644]
src/test/run-pass/unboxed-closures-unique-type-id.rs [new file with mode: 0644]
src/test/run-pass/unsized.rs
src/test/run-pass/vec-matching-fixed.rs
src/test/run-pass/vec-matching-fold.rs
src/test/run-pass/vec-matching-legal-tail-element-borrow.rs
src/test/run-pass/vec-matching.rs
src/test/run-pass/vec-tail-matching.rs

index e919f3329fe2a4725976b4147cd4790455dec204..097a2aeb6e49077f5b2e2cbc09e5840623b79b7c 100644 (file)
--- a/README.md
+++ b/README.md
@@ -101,6 +101,18 @@ There is a lot more documentation in the [wiki].
 
 [wiki]: https://github.com/rust-lang/rust/wiki
 
+## Getting help and getting involved
+
+The Rust community congregates in a few places:
+
+* [StackOverflow] - Get help here.
+* [/r/rust] - General discussion.
+* [discuss.rust-lang.org] - For development of the Rust language itself.
+
+[StackOverflow]: http://stackoverflow.com/questions/tagged/rust
+[/r/rust]: http://reddit.com/r/rust
+[discuss.rust-lang.org]: http://discuss.rust-lang.org/
+
 ## License
 
 Rust is primarily distributed under the terms of both the MIT license
index 1d6c387caa7c669811a7fa936bd4dd3b2840728d..6cdbfadf637984824963c5f46b779810d7462178 100755 (executable)
--- a/configure
+++ b/configure
@@ -707,7 +707,7 @@ then
             | cut -d ' ' -f 2)
 
         case $CFG_CLANG_VERSION in
-            (3.0svn | 3.0 | 3.1* | 3.2* | 3.3* | 3.4* | 3.5* )
+            (3.0svn | 3.0 | 3.1* | 3.2* | 3.3* | 3.4* | 3.5* | 3.6*)
             step_msg "found ok version of CLANG: $CFG_CLANG_VERSION"
             if [ -z "$CC" ]
             then
index 99fad94bf76ab95911b8581cf07f41e1be1b0662..4d86af37171b41561ff9e7ecfcb41afcf26ce701 100644 (file)
@@ -112,7 +112,7 @@ distcheck-tar-src: dist-tar-src
 
 ifdef CFG_ISCC
 
-PKG_EXE = dist/$(PKG_NAME)-install.exe
+PKG_EXE = dist/$(PKG_NAME)-$(CFG_BUILD).exe
 
 %.iss: $(S)src/etc/pkg/%.iss
        cp $< $@
@@ -123,7 +123,7 @@ PKG_EXE = dist/$(PKG_NAME)-install.exe
 $(PKG_EXE): rust.iss modpath.iss upgrade.iss LICENSE.txt rust-logo.ico \
             $(CSREQ3_T_$(CFG_BUILD)_H_$(CFG_BUILD)) \
             dist-prepare-win
-       $(CFG_PYTHON) $(S)src/etc/copy-runtime-deps.py tmp/dist/win/bin
+       $(CFG_PYTHON) $(S)src/etc/copy-runtime-deps.py tmp/dist/win/bin $(CFG_BUILD)
        @$(call E, ISCC: $@)
        $(Q)"$(CFG_ISCC)" $<
 
index 8a0c17de27aa0a3e92841a6098d1907bb2fa23f9..db0de4bde5b8a20df66618aaa4c3ca3435cf2dfb 100644 (file)
@@ -76,21 +76,22 @@ endif
 
 # Check for the various external utilities for the EPUB/PDF docs:
 
-ifeq ($(CFG_PDFLATEX),)
-  $(info cfg: no pdflatex found, deferring to xelatex)
+ifeq ($(CFG_LUALATEX),)
+  $(info cfg: no lualatex found, deferring to xelatex)
   ifeq ($(CFG_XELATEX),)
-    $(info cfg: no xelatex found, deferring to lualatex)
-    ifeq ($(CFG_LUALATEX),)
-      $(info cfg: no lualatex found, disabling LaTeX docs)
+    $(info cfg: no xelatex found, deferring to pdflatex)
+    ifeq ($(CFG_PDFLATEX),)
+      $(info cfg: no pdflatex found, disabling LaTeX docs)
       NO_PDF_DOCS = 1
        else
-      CFG_LATEX := $(CFG_LUALATEX)
+      CFG_LATEX := $(CFG_PDFLATEX)
     endif
   else
     CFG_LATEX := $(CFG_XELATEX)
+    XELATEX = 1
   endif
 else
-  CFG_LATEX := $(CFG_PDFLATEX)
+  CFG_LATEX := $(CFG_LUALATEX)
 endif
 
 
@@ -187,12 +188,25 @@ doc/$(1).tex: $$(D)/$(1).md doc/footer.tex doc/version.tex | doc/
 ifneq ($(NO_PDF_DOCS),1)
 ifeq ($$(SHOULD_BUILD_PDF_DOC_$(1)),1)
 DOC_TARGETS += doc/$(1).pdf
+ifneq ($(XELATEX),1)
 doc/$(1).pdf: doc/$(1).tex
        @$$(call E, latex compiler: $$@)
        $$(Q)$$(CFG_LATEX) \
        -interaction=batchmode \
        -output-directory=doc \
        $$<
+else
+# The version of xelatex on the snap bots seemingly ingores -output-directory
+# So we'll output to . and move to the doc directory manually.
+# This will leave some intermediate files in the build directory.
+doc/$(1).pdf: doc/$(1).tex
+       @$$(call E, latex compiler: $$@)
+       $$(Q)$$(CFG_LATEX) \
+       -interaction=batchmode \
+       -output-directory=. \
+       $$<
+       $$(Q)mv ./$(1).pdf $$@
+endif # XELATEX
 endif # SHOULD_BUILD_PDF_DOCS_$(1)
 endif # NO_PDF_DOCS
 
index 8b88fee0ad3d9a009478d5efe83be173195f8dd8..fc8237d32bb3e1442f3563b7ce5658739971696c 100644 (file)
@@ -15,7 +15,11 @@ rwildcard=$(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2) \
 
 ifndef CFG_DISABLE_MANAGE_SUBMODULES
 # This is a pretty expensive operation but I don't see any way to avoid it
-NEED_GIT_RECONFIG=$(shell cd "$(CFG_SRC_DIR)" && "$(CFG_GIT)" submodule status | grep -c '^\(+\|-\)')
+# NB: This only looks for '+' status (wrong commit checked out), not '-' status
+# (nothing checked out at all).  `./configure --{llvm,jemalloc,libuv}-root`
+# will explicitly deinitialize the corresponding submodules, and we don't
+# want to force constant rebuilds in that case.
+NEED_GIT_RECONFIG=$(shell cd "$(CFG_SRC_DIR)" && "$(CFG_GIT)" submodule status | grep -c '^+')
 else
 NEED_GIT_RECONFIG=0
 endif
index 6c6d6e36899353d76d1ed5784ff3a52b36ff4b6f..a49132ec8be9498dcd55bdc6243d2693ff882abf 100644 (file)
@@ -92,9 +92,33 @@ fn foo(s: String) {
 ```
 
 If you have good reason. It's not polite to hold on to ownership you don't
-need, and it can make your lifetimes more complex. Furthermore, you can pass
-either kind of string into `foo` by using `.as_slice()` on any `String` you
-need to pass in, so the `&str` version is more flexible.
+need, and it can make your lifetimes more complex.
+
+## Generic functions
+
+To write a function that's generic over types of strings, use [the `Str`
+trait](http://doc.rust-lang.org/std/str/trait.Str.html):
+
+```{rust}
+fn some_string_length<T: Str>(x: T) -> uint {
+        x.as_slice().len()
+}
+
+fn main() {
+    let s = "Hello, world";
+
+    println!("{}", some_string_length(s));
+
+    let s = "Hello, world".to_string();
+
+    println!("{}", some_string_length(s));
+}
+```
+
+Both of these lines will print `12`. 
+
+The only method that the `Str` trait has is `as_slice()`, which gives you
+access to a `&str` value from the underlying string.
 
 ## Comparisons
 
@@ -121,6 +145,65 @@ fn compare(string: String) {
 Converting a `String` to a `&str` is cheap, but converting the `&str` to a
 `String` involves an allocation.
 
+## Indexing strings
+
+You may be tempted to try to access a certain character of a `String`, like
+this:
+
+```{rust,ignore}
+let s = "hello".to_string();
+
+println!("{}", s[0]);
+```
+
+This does not compile. This is on purpose. In the world of UTF-8, direct
+indexing is basically never what you want to do. The reason is that each
+character can be a variable number of bytes. This means that you have to iterate
+through the characters anyway, which is a O(n) operation. 
+
+To iterate over a string, use the `graphemes()` method on `&str`:
+
+```{rust}
+let s = "αἰθήρ";
+
+for l in s.graphemes(true) {
+    println!("{}", l);
+}
+```
+
+Note that `l` has the type `&str` here, since a single grapheme can consist of
+multiple codepoints, so a `char` wouldn't be appropriate.
+
+This will print out each character in turn, as you'd expect: first "α", then
+"ἰ", etc. You can see that this is different than just the individual bytes.
+Here's a version that prints out each byte:
+
+```{rust}
+let s = "αἰθήρ";
+
+for l in s.bytes() {
+    println!("{}", l);
+}
+```
+
+This will print:
+
+```{notrust,ignore}
+206
+177
+225
+188
+176
+206
+184
+206
+174
+207
+129
+```
+
+Many more bytes than graphemes!
+
 # Other Documentation
 
 * [the `&str` API documentation](/std/str/index.html)
index e4bb3ae6ba6715171a95efd821fd52ea0407d4d2..ec5e544fa75298a6845e5ec9c185781e4dae965e 100644 (file)
@@ -150,7 +150,7 @@ in your file name, use an underscore. `hello_world.rs` versus `goodbye.rs`.
 
 Now that you've got your file open, type this in:
 
-```
+```{rust}
 fn main() {
     println!("Hello, world!");
 }
@@ -166,7 +166,7 @@ Hello, world!
 
 Success! Let's go over what just happened in detail.
 
-```
+```{rust}
 fn main() {
 
 }
@@ -186,7 +186,7 @@ declaration, with one space in between.
 
 Next up is this line:
 
-```
+```{rust}
     println!("Hello, world!");
 ```
 
@@ -520,10 +520,8 @@ error: aborting due to previous error
 Could not compile `hello_world`.
 ```
 
-Rust will not let us use a value that has not been initialized. So why let us
-declare a binding without initializing it? You'd think our first example would
-have errored. Well, Rust is smarter than that. Before we get to that, let's talk
-about this stuff we've added to `println!`.
+Rust will not let us use a value that has not been initialized. Next, let's
+talk about this stuff we've added to `println!`.
 
 If you include two curly braces (`{}`, some call them moustaches...) in your
 string to print, Rust will interpret this as a request to interpolate some sort
@@ -538,12 +536,6 @@ format in a more detailed manner, there are a [wide number of options
 available](std/fmt/index.html). For now, we'll just stick to the default:
 integers aren't very complicated to print.
 
-So, we've cleared up all of the confusion around bindings, with one exception:
-why does Rust let us declare a variable binding without an initial value if we
-must initialize the binding before we use it? And how does it know that we have
-or have not initialized the binding? For that, we need to learn our next
-concept: `if`.
-
 # If
 
 Rust's take on `if` is not particularly complex, but it's much more like the
@@ -570,7 +562,7 @@ the block is executed. If it's `false`, then it is not.
 
 If you want something to happen in the `false` case, use an `else`:
 
-```
+```{rust}
 let x = 5i;
 
 if x == 5i {
@@ -583,7 +575,7 @@ if x == 5i {
 This is all pretty standard. However, you can also do this:
 
 
-```
+```{rust}
 let x = 5i;
 
 let y = if x == 5i {
@@ -595,7 +587,7 @@ let y = if x == 5i {
 
 Which we can (and probably should) write like this:
 
-```
+```{rust}
 let x = 5i;
 
 let y = if x == 5i { 10i } else { 15i };
@@ -652,7 +644,7 @@ every line of Rust code you see.
 What is this exception that makes us say 'almost?' You saw it already, in this
 code:
 
-```
+```{rust}
 let x = 5i;
 
 let y: int = if x == 5i { 10i } else { 15i };
@@ -998,7 +990,7 @@ notation: `origin.x`.
 The values in structs are immutable, like other bindings in Rust. However, you
 can use `mut` to make them mutable:
 
-```rust
+```{rust}
 struct Point {
     x: int,
     y: int,
@@ -1022,7 +1014,7 @@ called a **tuple struct**. Tuple structs do have a name, but their fields
 don't:
 
 
-```
+```{rust}
 struct Color(int, int, int);
 struct Point(int, int, int);
 ```
@@ -1037,7 +1029,7 @@ let origin = Point(0, 0, 0);
 It is almost always better to use a struct than a tuple struct. We would write
 `Color` and `Point` like this instead:
 
-```rust
+```{rust}
 struct Color {
     red: int,
     blue: int,
@@ -1058,7 +1050,7 @@ There _is_ one case when a tuple struct is very useful, though, and that's a
 tuple struct with only one element. We call this a 'newtype,' because it lets
 you create a new type that's a synonym for another one:
 
-```
+```{rust}
 struct Inches(int);
 
 let length = Inches(10);
@@ -1175,7 +1167,7 @@ what's the solution?
 Rust has a keyword, `match`, that allows you to replace complicated `if`/`else`
 groupings with something more powerful. Check it out:
 
-```rust
+```{rust}
 let x = 5i;
 
 match x {
@@ -1416,7 +1408,7 @@ We now loop forever with `loop`, and use `break` to break out early.
 `continue` is similar, but instead of ending the loop, goes to the next
 iteration: This will only print the odd numbers:
 
-```
+```{rust}
 for x in range(0i, 10i) {
     if x % 2 == 0 { continue; }
 
@@ -4131,7 +4123,7 @@ the ability to use this **method call syntax** via the `impl` keyword.
 
 Here's how it works:
 
-```
+```{rust}
 struct Circle {
     x: f64,
     y: f64,
@@ -4170,7 +4162,7 @@ multiplications later, and we have our area.
 You can also define methods that do not take a `self` parameter. Here's a
 pattern that's very common in Rust code:
 
-```
+```{rust}
 struct Circle {
     x: f64,
     y: f64,
index 86776d50e7951464314781cb6298ed97e5d2040b..fb2407e5163818560aa1bb7d0afc0101da42ebf0 100644 (file)
@@ -2555,6 +2555,8 @@ The currently implemented features of the reference compiler are:
                         which is considered wildly unsafe and will be
                         obsoleted by language improvements.
 
+* `tuple_indexing` - Allows use of tuple indexing (expressions like `expr.0`)
+
 If a feature is promoted to a language feature, then all existing programs will
 start to receive compilation warnings about #[feature] directives which enabled
 the new feature (because the directive is no longer necessary). However, if
@@ -3290,17 +3292,19 @@ between `_` and `..` is that the pattern `C(_)` is only type-correct if `C` has
 exactly one argument, while the pattern `C(..)` is type-correct for any enum
 variant `C`, regardless of how many arguments `C` has.
 
-Used inside a vector pattern, `..` stands for any number of elements. This
-wildcard can be used at most once for a given vector, which implies that it
-cannot be used to specifically match elements that are at an unknown distance
-from both ends of a vector, like `[.., 42, ..]`. If followed by a variable name,
-it will bind the corresponding slice to the variable. Example:
+Used inside a vector pattern, `..` stands for any number of elements, when the
+`advanced_slice_patterns` feature gate is turned on. This wildcard can be used
+at most once for a given vector, which implies that it cannot be used to
+specifically match elements that are at an unknown distance from both ends of a
+vector, like `[.., 42, ..]`.  If followed by a variable name, it will bind the
+corresponding slice to the variable.  Example:
 
 ~~~~
+# #![feature(advanced_slice_patterns)]
 fn is_symmetric(list: &[uint]) -> bool {
     match list {
         [] | [_]                   => true,
-        [x, ..inside, y] if x == y => is_symmetric(inside),
+        [x, inside.., y] if x == y => is_symmetric(inside),
         _                          => false
     }
 }
index 0db25c4090ebc669b8ef432db83ba51c74674bf3..0e5a624b273336953726d98ac298e62ed0fef6e2 100644 (file)
@@ -1707,7 +1707,7 @@ let score = match numbers {
     [] => 0,
     [a] => a * 10,
     [a, b] => a * 6 + b * 4,
-    [a, b, c, ..rest] => a * 5 + b * 3 + c * 2 + rest.len() as int
+    [a, b, c, rest..] => a * 5 + b * 3 + c * 2 + rest.len() as int
 };
 ~~~~
 
index 8aab3f18bdad016c0734809cb4bee4d5873dbe8f..fd829cd0ab70f93227099db1396e8c8975a8a935 100644 (file)
@@ -12,8 +12,8 @@
 
 import snapshot, sys, os, shutil
 
-def copy_runtime_deps(dest_dir):
-    for path in snapshot.get_winnt_runtime_deps():
+def copy_runtime_deps(dest_dir, triple):
+    for path in snapshot.get_winnt_runtime_deps(snapshot.get_platform(triple)):
         shutil.copy(path, dest_dir)
 
     lic_dest = os.path.join(dest_dir, "third-party")
@@ -21,4 +21,4 @@ def copy_runtime_deps(dest_dir):
         shutil.rmtree(lic_dest) # copytree() won't overwrite existing files
     shutil.copytree(os.path.join(os.path.dirname(__file__), "third-party"), lic_dest)
 
-copy_runtime_deps(sys.argv[1])
+copy_runtime_deps(sys.argv[1], sys.argv[2])
index de0d5c18766ad2673068e04a05e7b41dabe94699..328a2ff6c9408704ff5dca0950bd22edf80e5368 100644 (file)
@@ -43,12 +43,15 @@ exceptions = [
     "libsync/mpmc_bounded_queue.rs", # BSD
     "libsync/mpsc_intrusive.rs", # BSD
     "test/bench/shootout-binarytrees.rs", # BSD
+    "test/bench/shootout-chameneos-redux.rs", # BSD
     "test/bench/shootout-fannkuch-redux.rs", # BSD
     "test/bench/shootout-k-nucleotide.rs", # BSD
     "test/bench/shootout-mandelbrot.rs", # BSD
     "test/bench/shootout-meteor.rs", # BSD
+    "test/bench/shootout-nbody.rs", # BSD
     "test/bench/shootout-pidigits.rs", # BSD
     "test/bench/shootout-regex-dna.rs", # BSD
+    "test/bench/shootout-reverse-complement.rs", # BSD
     "test/bench/shootout-threadring.rs", # BSD
 ]
 
index 053fe34952c954ae4163744c8e848694f8e388c3..08c28c4399bdd343b27a906f146144c8c71383cd 100644 (file)
@@ -1,6 +1,7 @@
 #define CFG_VERSION_WIN GetEnv("CFG_VERSION_WIN")
 #define CFG_RELEASE GetEnv("CFG_RELEASE")
 #define CFG_PACKAGE_NAME GetEnv("CFG_PACKAGE_NAME")
+#define CFG_BUILD GetEnv("CFG_BUILD")
 
 [Setup]
 
@@ -20,7 +21,7 @@ DisableStartupPrompt=true
 
 OutputDir=.\dist\
 SourceDir=.\
-OutputBaseFilename={#CFG_PACKAGE_NAME}-install
+OutputBaseFilename={#CFG_PACKAGE_NAME}-{#CFG_BUILD}
 DefaultDirName={pf32}\Rust
 
 Compression=lzma2/ultra
index 82302da17b85082d016f23dbd13700d5ff160a11..24255c0cc5df2c706d3a935f0aceda06d83b9159 100644 (file)
@@ -39,8 +39,10 @@ snapshot_files = {
     "freebsd": ["bin/rustc"],
     }
 
-winnt_runtime_deps = ["libgcc_s_dw2-1.dll",
-                      "libstdc++-6.dll"]
+winnt_runtime_deps_32 = ["libgcc_s_dw2-1.dll",
+                         "libstdc++-6.dll"]
+winnt_runtime_deps_64 = ["libgcc_s_seh-1.dll",
+                         "libstdc++-6.dll"]
 
 def parse_line(n, line):
   global snapshotfile
@@ -146,10 +148,14 @@ def hash_file(x):
     return scrub(h.hexdigest())
 
 # Returns a list of paths of Rust's system runtime dependencies
-def get_winnt_runtime_deps():
+def get_winnt_runtime_deps(platform):
+    if platform == "winnt-x86_64":
+      deps = winnt_runtime_deps_64
+    else:
+      deps = winnt_runtime_deps_32
     runtime_deps = []
-    path_dirs = os.environ["PATH"].split(';')
-    for name in winnt_runtime_deps:
+    path_dirs = os.environ["PATH"].split(os.pathsep)
+    for name in deps:
       for dir in path_dirs:
         matches = glob.glob(os.path.join(dir, name))
         if matches:
@@ -189,7 +195,7 @@ def make_snapshot(stage, triple):
                         "Please make a clean build." % "\n  ".join(matches))
 
     if kernel=="winnt":
-      for path in get_winnt_runtime_deps():
+      for path in get_winnt_runtime_deps(platform):
         tar.add(path, "rust-stage0/bin/" + os.path.basename(path))
       tar.add(os.path.join(os.path.dirname(__file__), "third-party"),
               "rust-stage0/bin/third-party")
index 024c67ad651e1a3ca228936c4cfb13a37329baf2..aae04170ccbfeea620502106b581c3c216cd132a 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 024c67ad651e1a3ca228936c4cfb13a37329baf2
+Subproject commit aae04170ccbfeea620502106b581c3c216cd132a
index c72a77702afff4ea2bfa636528374b3b40907b70..c7bc1bb973330f87653d7d06c734f97bf90b4d5f 100644 (file)
@@ -12,7 +12,6 @@
 // FIXME: #13996: mark the `allocate` and `reallocate` return value as `noalias`
 //                and `nonnull`
 
-use core::ptr::RawPtr;
 #[cfg(not(test))] use core::raw;
 #[cfg(stage0, not(test))] use util;
 
@@ -70,11 +69,6 @@ pub unsafe fn reallocate_inplace(ptr: *mut u8, size: uint, align: uint,
 /// the value returned by `usable_size` for the requested size.
 #[inline]
 pub unsafe fn deallocate(ptr: *mut u8, size: uint, align: uint) {
-    // FIXME(14395) This is only required for DST ~[T], it should be removed once
-    // we fix that representation to not use null pointers.
-    if ptr.is_null() {
-        return;
-    }
     imp::deallocate(ptr, size, align)
 }
 
@@ -149,12 +143,24 @@ unsafe fn closure_exchange_malloc(drop_glue: fn(*mut u8), size: uint,
     alloc as *mut u8
 }
 
+// The minimum alignment guaranteed by the architecture. This value is used to
+// add fast paths for low alignment values. In practice, the alignment is a
+// constant at the call site and the branch will be optimized out.
+#[cfg(target_arch = "arm")]
+#[cfg(target_arch = "mips")]
+#[cfg(target_arch = "mipsel")]
+static MIN_ALIGN: uint = 8;
+#[cfg(target_arch = "x86")]
+#[cfg(target_arch = "x86_64")]
+static MIN_ALIGN: uint = 16;
+
 #[cfg(jemalloc)]
 mod imp {
     use core::option::{None, Option};
     use core::ptr::{RawPtr, mut_null, null};
     use core::num::Int;
     use libc::{c_char, c_int, c_void, size_t};
+    use super::MIN_ALIGN;
 
     #[link(name = "jemalloc", kind = "static")]
     #[cfg(not(test))]
@@ -166,7 +172,10 @@ fn je_rallocx(ptr: *mut c_void, size: size_t,
                       flags: c_int) -> *mut c_void;
         fn je_xallocx(ptr: *mut c_void, size: size_t, extra: size_t,
                       flags: c_int) -> size_t;
+        #[cfg(stage0)]
         fn je_dallocx(ptr: *mut c_void, flags: c_int);
+        #[cfg(not(stage0))]
+        fn je_sdallocx(ptr: *mut c_void, size: size_t, flags: c_int);
         fn je_nallocx(size: size_t, flags: c_int) -> size_t;
         fn je_malloc_stats_print(write_cb: Option<extern "C" fn(cbopaque: *mut c_void,
                                                                 *const c_char)>,
@@ -183,9 +192,15 @@ fn je_malloc_stats_print(write_cb: Option<extern "C" fn(cbopaque: *mut c_void,
     #[inline(always)]
     fn mallocx_align(a: uint) -> c_int { a.trailing_zeros() as c_int }
 
+    #[inline(always)]
+    fn align_to_flags(align: uint) -> c_int {
+        if align <= MIN_ALIGN { 0 } else { mallocx_align(align) }
+    }
+
     #[inline]
     pub unsafe fn allocate(size: uint, align: uint) -> *mut u8 {
-        let ptr = je_mallocx(size as size_t, mallocx_align(align)) as *mut u8;
+        let flags = align_to_flags(align);
+        let ptr = je_mallocx(size as size_t, flags) as *mut u8;
         if ptr.is_null() {
             ::oom()
         }
@@ -195,8 +210,8 @@ pub unsafe fn allocate(size: uint, align: uint) -> *mut u8 {
     #[inline]
     pub unsafe fn reallocate(ptr: *mut u8, size: uint, align: uint,
                              _old_size: uint) -> *mut u8 {
-        let ptr = je_rallocx(ptr as *mut c_void, size as size_t,
-                             mallocx_align(align)) as *mut u8;
+        let flags = align_to_flags(align);
+        let ptr = je_rallocx(ptr as *mut c_void, size as size_t, flags) as *mut u8;
         if ptr.is_null() {
             ::oom()
         }
@@ -206,18 +221,28 @@ pub unsafe fn reallocate(ptr: *mut u8, size: uint, align: uint,
     #[inline]
     pub unsafe fn reallocate_inplace(ptr: *mut u8, size: uint, align: uint,
                                      _old_size: uint) -> bool {
-        je_xallocx(ptr as *mut c_void, size as size_t, 0,
-                   mallocx_align(align)) == size as size_t
+        let flags = align_to_flags(align);
+        je_xallocx(ptr as *mut c_void, size as size_t, 0, flags) == size as size_t
     }
 
     #[inline]
+    #[cfg(stage0)]
     pub unsafe fn deallocate(ptr: *mut u8, _size: uint, align: uint) {
-        je_dallocx(ptr as *mut c_void, mallocx_align(align))
+        let flags = align_to_flags(align);
+        je_dallocx(ptr as *mut c_void, flags)
+    }
+
+    #[inline]
+    #[cfg(not(stage0))]
+    pub unsafe fn deallocate(ptr: *mut u8, size: uint, align: uint) {
+        let flags = align_to_flags(align);
+        je_sdallocx(ptr as *mut c_void, size as size_t, flags)
     }
 
     #[inline]
     pub fn usable_size(size: uint, align: uint) -> uint {
-        unsafe { je_nallocx(size as size_t, mallocx_align(align)) as uint }
+        let flags = align_to_flags(align);
+        unsafe { je_nallocx(size as size_t, flags) as uint }
     }
 
     pub fn stats_print() {
@@ -234,6 +259,7 @@ mod imp {
     use core::ptr;
     use libc;
     use libc_heap;
+    use super::MIN_ALIGN;
 
     extern {
         fn posix_memalign(memptr: *mut *mut libc::c_void,
@@ -243,16 +269,7 @@ fn posix_memalign(memptr: *mut *mut libc::c_void,
 
     #[inline]
     pub unsafe fn allocate(size: uint, align: uint) -> *mut u8 {
-        // The posix_memalign manpage states
-        //
-        //      alignment [...] must be a power of and a multiple of
-        //      sizeof(void *)
-        //
-        // The `align` parameter to this function is the *minimum* alignment for
-        // a block of memory, so we special case everything under `*uint` to
-        // just pass it to malloc, which is guaranteed to align to at least the
-        // size of `*uint`.
-        if align < mem::size_of::<uint>() {
+        if align <= MIN_ALIGN {
             libc_heap::malloc_raw(size)
         } else {
             let mut out = 0 as *mut libc::c_void;
@@ -269,10 +286,14 @@ pub unsafe fn allocate(size: uint, align: uint) -> *mut u8 {
     #[inline]
     pub unsafe fn reallocate(ptr: *mut u8, size: uint, align: uint,
                              old_size: uint) -> *mut u8 {
-        let new_ptr = allocate(size, align);
-        ptr::copy_memory(new_ptr, ptr as *const u8, cmp::min(size, old_size));
-        deallocate(ptr, old_size, align);
-        return new_ptr;
+        if align <= MIN_ALIGN {
+            libc_heap::realloc_raw(ptr, size)
+        } else {
+            let new_ptr = allocate(size, align);
+            ptr::copy_memory(new_ptr, ptr as *const u8, cmp::min(size, old_size));
+            deallocate(ptr, old_size, align);
+            new_ptr
+        }
     }
 
     #[inline]
@@ -291,14 +312,16 @@ pub fn usable_size(size: uint, _align: uint) -> uint {
         size
     }
 
-    pub fn stats_print() {
-    }
+    pub fn stats_print() {}
 }
 
 #[cfg(not(jemalloc), windows)]
 mod imp {
     use libc::{c_void, size_t};
+    use libc;
+    use libc_heap;
     use core::ptr::RawPtr;
+    use super::MIN_ALIGN;
 
     extern {
         fn _aligned_malloc(size: size_t, align: size_t) -> *mut c_void;
@@ -309,22 +332,30 @@ fn _aligned_realloc(block: *mut c_void, size: size_t,
 
     #[inline]
     pub unsafe fn allocate(size: uint, align: uint) -> *mut u8 {
-        let ptr = _aligned_malloc(size as size_t, align as size_t);
-        if ptr.is_null() {
-            ::oom();
+        if align <= MIN_ALIGN {
+            libc_heap::malloc_raw(size)
+        } else {
+            let ptr = _aligned_malloc(size as size_t, align as size_t);
+            if ptr.is_null() {
+                ::oom();
+            }
+            ptr as *mut u8
         }
-        ptr as *mut u8
     }
 
     #[inline]
     pub unsafe fn reallocate(ptr: *mut u8, size: uint, align: uint,
                              _old_size: uint) -> *mut u8 {
-        let ptr = _aligned_realloc(ptr as *mut c_void, size as size_t,
-                                   align as size_t);
-        if ptr.is_null() {
-            ::oom();
+        if align <= MIN_ALIGN {
+            libc_heap::realloc_raw(ptr, size)
+        } else {
+            let ptr = _aligned_realloc(ptr as *mut c_void, size as size_t,
+                                       align as size_t);
+            if ptr.is_null() {
+                ::oom();
+            }
+            ptr as *mut u8
         }
-        ptr as *mut u8
     }
 
     #[inline]
@@ -334,8 +365,12 @@ pub unsafe fn reallocate_inplace(_ptr: *mut u8, _size: uint, _align: uint,
     }
 
     #[inline]
-    pub unsafe fn deallocate(ptr: *mut u8, _size: uint, _align: uint) {
-        _aligned_free(ptr as *mut c_void)
+    pub unsafe fn deallocate(ptr: *mut u8, _size: uint, align: uint) {
+        if align <= MIN_ALIGN {
+            libc::free(ptr as *mut libc::c_void)
+        } else {
+            _aligned_free(ptr as *mut c_void)
+        }
     }
 
     #[inline]
index e91898548533c0a98034a97488af0f92153e1006..ee3fd6ad0eb0db0f5a909c3b41ed799bc9a929f6 100644 (file)
@@ -509,6 +509,7 @@ mod tests {
     use self::test::Bencher;
     use super::{Arena, TypedArena};
 
+    #[allow(dead_code)]
     struct Point {
         x: int,
         y: int,
@@ -564,6 +565,7 @@ pub fn bench_copy_old_arena(b: &mut Bencher) {
         })
     }
 
+    #[allow(dead_code)]
     struct Noncopy {
         string: String,
         array: Vec<int>,
index 2418fabfff1d87f53ff0f06cd7a135620bd7a323..36edd913de2f83367e452bf7023499926619bb9c 100644 (file)
@@ -864,6 +864,7 @@ fn test_tail_empty() {
     }
 
     #[test]
+    #[allow(deprecated)]
     fn test_tailn() {
         let mut a = vec![11i, 12, 13];
         let b: &[int] = &[11, 12, 13];
@@ -875,6 +876,7 @@ fn test_tailn() {
 
     #[test]
     #[should_fail]
+    #[allow(deprecated)]
     fn test_tailn_empty() {
         let a: Vec<int> = vec![];
         a.tailn(2);
@@ -909,6 +911,7 @@ fn test_initn() {
 
     #[test]
     #[should_fail]
+    #[allow(deprecated)]
     fn test_initn_empty() {
         let a: Vec<int> = vec![];
         a.as_slice().initn(2);
@@ -1466,6 +1469,7 @@ fn test_shift() {
     }
 
     #[test]
+    #[allow(deprecated)]
     fn test_unshift() {
         let mut x = vec![1i, 2, 3];
         x.unshift(0);
@@ -2079,6 +2083,7 @@ fn test_ends_with() {
     }
 
     #[test]
+    #[allow(deprecated)]
     fn test_shift_ref() {
         let mut x: &[int] = [1, 2, 3, 4, 5];
         let h = x.shift_ref();
@@ -2092,6 +2097,7 @@ fn test_shift_ref() {
     }
 
     #[test]
+    #[allow(deprecated)]
     fn test_pop_ref() {
         let mut x: &[int] = [1, 2, 3, 4, 5];
         let h = x.pop_ref();
@@ -2171,6 +2177,7 @@ fn test_mut_chunks_0() {
     }
 
     #[test]
+    #[allow(deprecated)]
     fn test_mut_shift_ref() {
         let mut x: &mut [int] = [1, 2, 3, 4, 5];
         let h = x.mut_shift_ref();
@@ -2184,6 +2191,7 @@ fn test_mut_shift_ref() {
     }
 
     #[test]
+    #[allow(deprecated)]
     fn test_mut_pop_ref() {
         let mut x: &mut [int] = [1, 2, 3, 4, 5];
         let h = x.mut_pop_ref();
@@ -2441,7 +2449,7 @@ fn sort_sorted(b: &mut Bencher) {
         b.iter(|| {
             v.sort();
         });
-        b.bytes = (v.len() * mem::size_of_val(v.get(0))) as u64;
+        b.bytes = (v.len() * mem::size_of_val(&v[0])) as u64;
     }
 
     type BigSortable = (u64,u64,u64,u64);
@@ -2485,6 +2493,6 @@ fn sort_big_sorted(b: &mut Bencher) {
         b.iter(|| {
             v.sort();
         });
-        b.bytes = (v.len() * mem::size_of_val(v.get(0))) as u64;
+        b.bytes = (v.len() * mem::size_of_val(&v[0])) as u64;
     }
 }
index 7c4494358b1bf8055d281e981f9cd04cfa24f217..be75bfec32c86dd9fb172a5e42ce8dbbee0c39fd 100644 (file)
@@ -113,6 +113,33 @@ impl<'a> Arguments<'a> {
     /// Arguments structure. The compiler inserts an `unsafe` block to call this,
     /// which is valid because the compiler performs all necessary validation to
     /// ensure that the resulting call to format/write would be safe.
+    #[cfg(not(stage0))]
+    #[doc(hidden)] #[inline]
+    pub unsafe fn new<'a>(pieces: &'static [&'static str],
+                          args: &'a [Argument<'a>]) -> Arguments<'a> {
+        Arguments {
+            pieces: mem::transmute(pieces),
+            fmt: None,
+            args: args
+        }
+    }
+
+    /// This function is used to specify nonstandard formatting parameters.
+    /// The `pieces` array must be at least as long as `fmt` to construct
+    /// a valid Arguments structure.
+    #[cfg(not(stage0))]
+    #[doc(hidden)] #[inline]
+    pub unsafe fn with_placeholders<'a>(pieces: &'static [&'static str],
+                                        fmt: &'static [rt::Argument<'static>],
+                                        args: &'a [Argument<'a>]) -> Arguments<'a> {
+        Arguments {
+            pieces: mem::transmute(pieces),
+            fmt: Some(mem::transmute(fmt)),
+            args: args
+        }
+    }
+
+    #[cfg(stage0)]
     #[doc(hidden)] #[inline]
     pub unsafe fn new<'a>(fmt: &'static [rt::Piece<'static>],
                           args: &'a [Argument<'a>]) -> Arguments<'a> {
@@ -129,6 +156,20 @@ pub unsafe fn new<'a>(fmt: &'static [rt::Piece<'static>],
 /// and pass it to a function or closure, passed as the first argument. The
 /// macro validates the format string at compile-time so usage of the `write`
 /// and `format` functions can be safely performed.
+#[cfg(not(stage0))]
+pub struct Arguments<'a> {
+    // Format string pieces to print.
+    pieces: &'a [&'a str],
+
+    // Placeholder specs, or `None` if all specs are default (as in "{}{}").
+    fmt: Option<&'a [rt::Argument<'a>]>,
+
+    // Dynamic arguments for interpolation, to be interleaved with string
+    // pieces. (Every argument is preceded by a string piece.)
+    args: &'a [Argument<'a>],
+}
+
+#[cfg(stage0)] #[doc(hidden)]
 pub struct Arguments<'a> {
     fmt: &'a [rt::Piece<'a>],
     args: &'a [Argument<'a>],
@@ -255,6 +296,18 @@ pub fn $name<T: $trait_>(x: &T, fmt: &mut Formatter) -> Result {
     secret_upper_exp, UpperExp;
 }
 
+#[cfg(not(stage0))]
+static DEFAULT_ARGUMENT: rt::Argument<'static> = rt::Argument {
+    position: rt::ArgumentNext,
+    format: rt::FormatSpec {
+        fill: ' ',
+        align: rt::AlignUnknown,
+        flags: 0,
+        precision: rt::CountImplied,
+        width: rt::CountImplied,
+    }
+};
+
 /// The `write` function takes an output stream, a precompiled format string,
 /// and a list of arguments. The arguments will be formatted according to the
 /// specified format string into the output stream provided.
@@ -263,6 +316,51 @@ pub fn $name<T: $trait_>(x: &T, fmt: &mut Formatter) -> Result {
 ///
 ///   * output - the buffer to write output to
 ///   * args - the precompiled arguments generated by `format_args!`
+#[cfg(not(stage0))]
+pub fn write(output: &mut FormatWriter, args: &Arguments) -> Result {
+    let mut formatter = Formatter {
+        flags: 0,
+        width: None,
+        precision: None,
+        buf: output,
+        align: rt::AlignUnknown,
+        fill: ' ',
+        args: args.args,
+        curarg: args.args.iter(),
+    };
+
+    let mut pieces = args.pieces.iter();
+
+    match args.fmt {
+        None => {
+            // We can use default formatting parameters for all arguments.
+            for _ in range(0, args.args.len()) {
+                try!(formatter.buf.write(pieces.next().unwrap().as_bytes()));
+                try!(formatter.run(&DEFAULT_ARGUMENT));
+            }
+        }
+        Some(fmt) => {
+            // Every spec has a corresponding argument that is preceded by
+            // a string piece.
+            for (arg, piece) in fmt.iter().zip(pieces.by_ref()) {
+                try!(formatter.buf.write(piece.as_bytes()));
+                try!(formatter.run(arg));
+            }
+        }
+    }
+
+    // There can be only one trailing string piece left.
+    match pieces.next() {
+        Some(piece) => {
+            try!(formatter.buf.write(piece.as_bytes()));
+        }
+        None => {}
+    }
+
+    Ok(())
+}
+
+#[cfg(stage0)] #[doc(hidden)]
 pub fn write(output: &mut FormatWriter, args: &Arguments) -> Result {
     let mut formatter = Formatter {
         flags: 0,
@@ -285,7 +383,26 @@ impl<'a> Formatter<'a> {
     // First up is the collection of functions used to execute a format string
     // at runtime. This consumes all of the compile-time statics generated by
     // the format! syntax extension.
+    #[cfg(not(stage0))]
+    fn run(&mut self, arg: &rt::Argument) -> Result {
+        // Fill in the format parameters into the formatter
+        self.fill = arg.format.fill;
+        self.align = arg.format.align;
+        self.flags = arg.format.flags;
+        self.width = self.getcount(&arg.format.width);
+        self.precision = self.getcount(&arg.format.precision);
+
+        // Extract the correct argument
+        let value = match arg.position {
+            rt::ArgumentNext => { *self.curarg.next().unwrap() }
+            rt::ArgumentIs(i) => self.args[i],
+        };
+
+        // Then actually do some printing
+        (value.formatter)(value.value, self)
+    }
 
+    #[cfg(stage0)] #[doc(hidden)]
     fn run(&mut self, piece: &rt::Piece) -> Result {
         match *piece {
             rt::String(s) => self.buf.write(s.as_bytes()),
index 1f5449130ecf34b94b0787154cc7a9acf6a44299..59fbde88d8be3ad9e1979e250334e0ba8c44b4c0 100644 (file)
@@ -14,7 +14,7 @@
 //! These definitions are similar to their `ct` equivalents, but differ in that
 //! these can be statically allocated and are slightly optimized for the runtime
 
-
+#[cfg(stage0)]
 #[doc(hidden)]
 pub enum Piece<'a> {
     String(&'a str),
index da7f026aed4f5fd33c4fd03dc76724efd66f3700..89b2f9cc853b8cdc881f365ccc5bf4447aa5e731 100644 (file)
@@ -2185,7 +2185,7 @@ fn idx(&mut self, _: uint) -> Option<A> { Some(self.element.clone()) }
 /// Creates a new iterator that produces an infinite sequence of
 /// repeated applications of the given function `f`.
 #[allow(visible_private_types)]
-pub fn iterate<'a, T: Clone>(f: |T|: 'a -> T, seed: T) -> Iterate<'a, T> {
+pub fn iterate<'a, T: Clone>(seed: T, f: |T|: 'a -> T) -> Iterate<'a, T> {
     Unfold::new((f, Some(seed), true), |st| {
         let &(ref mut f, ref mut val, ref mut first) = st;
         if *first {
index 836285bc3135ad8e0bbd1dac18695439d2b89a5b..94febf0363594d543ba05658d2a154e67c3273ac 100644 (file)
@@ -55,6 +55,8 @@
  *
  */
 
+use kinds::Sized;
+
 /**
  *
  * The `Drop` trait is used to run some code when a value goes out of scope. This
@@ -700,7 +702,7 @@ pub trait IndexMut<Index,Result> {
  * ```
  */
 #[lang="deref"]
-pub trait Deref<Result> {
+pub trait Deref<Sized? Result> {
     /// The method called to dereference a value
     fn deref<'a>(&'a self) -> &'a Result;
 }
@@ -740,7 +742,7 @@ pub trait Deref<Result> {
  * ```
  */
 #[lang="deref_mut"]
-pub trait DerefMut<Result>: Deref<Result> {
+pub trait DerefMut<Sized? Result>: Deref<Result> {
     /// The method called to mutably dereference a value
     fn deref_mut<'a>(&'a mut self) -> &'a mut Result;
 }
index fae4a26cd3863ff555969cf6c1b8c88b52c42c4b..9656a6caba08c845d5037d32138609e8a7b16eb7 100644 (file)
@@ -51,22 +51,22 @@ fn any_owning() {
 }
 
 #[test]
-fn any_as_ref() {
+fn any_downcast_ref() {
     let a = &5u as &Any;
 
-    match a.as_ref::<uint>() {
+    match a.downcast_ref::<uint>() {
         Some(&5) => {}
         x => fail!("Unexpected value {}", x)
     }
 
-    match a.as_ref::<Test>() {
+    match a.downcast_ref::<Test>() {
         None => {}
         x => fail!("Unexpected value {}", x)
     }
 }
 
 #[test]
-fn any_as_mut() {
+fn any_downcast_mut() {
     let mut a = 5u;
     let mut b = box 7u;
 
@@ -74,7 +74,7 @@ fn any_as_mut() {
     let tmp: &mut uint = &mut *b;
     let b_r = tmp as &mut Any;
 
-    match a_r.as_mut::<uint>() {
+    match a_r.downcast_mut::<uint>() {
         Some(x) => {
             assert_eq!(*x, 5u);
             *x = 612;
@@ -82,7 +82,7 @@ fn any_as_mut() {
         x => fail!("Unexpected value {}", x)
     }
 
-    match b_r.as_mut::<uint>() {
+    match b_r.downcast_mut::<uint>() {
         Some(x) => {
             assert_eq!(*x, 7u);
             *x = 413;
@@ -90,22 +90,22 @@ fn any_as_mut() {
         x => fail!("Unexpected value {}", x)
     }
 
-    match a_r.as_mut::<Test>() {
+    match a_r.downcast_mut::<Test>() {
         None => (),
         x => fail!("Unexpected value {}", x)
     }
 
-    match b_r.as_mut::<Test>() {
+    match b_r.downcast_mut::<Test>() {
         None => (),
         x => fail!("Unexpected value {}", x)
     }
 
-    match a_r.as_mut::<uint>() {
+    match a_r.downcast_mut::<uint>() {
         Some(&612) => {}
         x => fail!("Unexpected value {}", x)
     }
 
-    match b_r.as_mut::<uint>() {
+    match b_r.downcast_mut::<uint>() {
         Some(&413) => {}
         x => fail!("Unexpected value {}", x)
     }
@@ -121,11 +121,11 @@ fn any_fixed_vec() {
 
 
 #[bench]
-fn bench_as_ref(b: &mut Bencher) {
+fn bench_downcast_ref(b: &mut Bencher) {
     b.iter(|| {
         let mut x = 0i;
         let mut y = &mut x as &mut Any;
         test::black_box(&mut y);
-        test::black_box(y.as_ref::<int>() == Some(&0));
+        test::black_box(y.downcast_ref::<int>() == Some(&0));
     });
 }
index 9fc09b3124ef381864c131bbe8710639faa65ed4..3f2208e6c2dadedaac61638a8912838f95f01caf 100644 (file)
@@ -9,3 +9,10 @@
 // except according to those terms.
 
 mod num;
+
+#[test]
+fn test_format_flags() {
+    // No residual flags left by pointer formatting
+    let p = "".as_ptr();
+    assert_eq!(format!("{:p} {:x}", p, 16u), format!("{:p} 10", p));
+}
index 99ac7cfed027f744708c0f69a404710170d2a70b..9b703a18caee9f4e26bbcab7dda168e7f88b1cd8 100644 (file)
@@ -839,7 +839,7 @@ fn test_min_max_result() {
 
 #[test]
 fn test_iterate() {
-    let mut it = iterate(|x| x * 2, 1u);
+    let mut it = iterate(1u, |x| x * 2);
     assert_eq!(it.next(), Some(1u));
     assert_eq!(it.next(), Some(2u));
     assert_eq!(it.next(), Some(4u));
index 2dad9fc3a22c42def94cc7973600ae2fcfecb0d2..6e5bf6e8f2dac572958afc8e9d2b9d774ee00eaf 100644 (file)
@@ -131,6 +131,7 @@ fn test_or_else() {
 }
 
 #[test]
+#[allow(deprecated)]
 fn test_option_while_some() {
     let mut i = 0i;
     Some(10i).while_some(|j| {
@@ -184,6 +185,7 @@ fn test_unwrap_or_else() {
 }
 
 #[test]
+#[allow(deprecated)]
 fn test_filtered() {
     let some_stuff = Some(42i);
     let modified_stuff = some_stuff.filtered(|&x| {x < 10});
@@ -256,6 +258,7 @@ fn test_mutate() {
 }
 
 #[test]
+#[allow(deprecated)]
 fn test_collect() {
     let v: Option<Vec<int>> = collect(range(0i, 0)
                                       .map(|_| Some(0i)));
index 7c7e0a542cd8729ac7c5298b34ba37cfc035983c..dbc393967d3e583688d71c10e9263988d939e11f 100644 (file)
@@ -69,6 +69,7 @@ pub fn test_impl_map_err() {
 }
 
 #[test]
+#[allow(deprecated)]
 fn test_collect() {
     let v: Result<Vec<int>, ()> = collect(range(0i, 0).map(|_| Ok::<int, ()>(0)));
     assert!(v == Ok(vec![]));
index 1f66d0352da59d8c639287c1072baff0431fb95b..7fe6f2dbf67d2bbb399275b038bdbcb7d6ccf414 100644 (file)
@@ -568,6 +568,7 @@ pub fn repr_to_string<T>(t: &T) -> String {
 }
 
 #[cfg(test)]
+#[allow(dead_code)]
 struct P {a: int, b: f64}
 
 #[test]
index d8325e05cdf4ccc03c6965493446b44d2ffbce2f..ea298f5e05f71ecfa97d8a7cb44c50f8b55cdd0c 100644 (file)
@@ -632,9 +632,9 @@ fn node_id(&'a self, n: &Node) -> Id<'a> {
             id_name(n)
         }
         fn node_label(&'a self, n: &Node) -> LabelText<'a> {
-            match self.node_labels.get(*n) {
-                &Some(ref l) => LabelStr(str::Slice(l.as_slice())),
-                &None        => LabelStr(id_name(n).name()),
+            match self.node_labels[*n] {
+                Some(ref l) => LabelStr(str::Slice(l.as_slice())),
+                None        => LabelStr(id_name(n).name()),
             }
         }
         fn edge_label(&'a self, e: & &'a Edge) -> LabelText<'a> {
index 084a66fdddf154c26f2daef852910273fe7fbbb8..1075466d099f977de7375898b1e13298814f4d9e 100644 (file)
@@ -1414,6 +1414,7 @@ fn start_closure_dtor() {
         // Regression test that the `start` task entrypoint can
         // contain dtors that use task resources
         run(proc() {
+            #[allow(dead_code)]
             struct S { field: () }
 
             impl Drop for S {
index 136652f3ebfc9e1e0cbc555b13ac812c67d8b3f9..bc1d877dc547bc24370bb1ba0376334e84c64a7b 100644 (file)
 //! Blocking posix-based file I/O
 
 use alloc::arc::Arc;
-use libc::{c_int, c_void};
-use libc;
+use libc::{mod, c_int, c_void};
 use std::c_str::CString;
 use std::mem;
-use std::rt::rtio;
-use std::rt::rtio::IoResult;
+use std::rt::rtio::{mod, IoResult};
 
 use io::{retry, keep_going};
 use io::util;
@@ -55,7 +53,7 @@ pub fn inner_read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
         let ret = retry(|| unsafe {
             libc::read(self.fd(),
                        buf.as_mut_ptr() as *mut libc::c_void,
-                       buf.len() as libc::size_t) as libc::c_int
+                       buf.len() as libc::size_t)
         });
         if ret == 0 {
             Err(util::eof())
@@ -93,7 +91,7 @@ fn pread(&mut self, buf: &mut [u8], offset: u64) -> IoResult<int> {
         match retry(|| unsafe {
             libc::pread(self.fd(), buf.as_ptr() as *mut _,
                         buf.len() as libc::size_t,
-                        offset as libc::off_t) as libc::c_int
+                        offset as libc::off_t)
         }) {
             -1 => Err(super::last_error()),
             n => Ok(n as int)
@@ -103,7 +101,7 @@ fn pwrite(&mut self, buf: &[u8], offset: u64) -> IoResult<()> {
         super::mkerr_libc(retry(|| unsafe {
             libc::pwrite(self.fd(), buf.as_ptr() as *const _,
                          buf.len() as libc::size_t, offset as libc::off_t)
-        } as c_int))
+        }))
     }
     fn seek(&mut self, pos: i64, whence: rtio::SeekStyle) -> IoResult<u64> {
         let whence = match whence {
index 276194feaf0e39ce0a2de99a610ed7828ec50f77..7881e088388ca44a4bdde284ab9b000eaa1c4653 100644 (file)
 
 #![allow(non_snake_case)]
 
-use libc::c_int;
-use libc;
+use libc::{mod, c_int};
 use std::c_str::CString;
 use std::os;
-use std::rt::rtio;
-use std::rt::rtio::{IoResult, IoError};
+use std::rt::rtio::{mod, IoResult, IoError};
+use std::num;
 
 // Local re-exports
 pub use self::file::FileDesc;
@@ -97,8 +96,8 @@ fn last_error() -> IoError {
 }
 
 // unix has nonzero values as errors
-fn mkerr_libc(ret: libc::c_int) -> IoResult<()> {
-    if ret != 0 {
+fn mkerr_libc <Int: num::Zero>(ret: Int) -> IoResult<()> {
+    if !ret.is_zero() {
         Err(last_error())
     } else {
         Ok(())
@@ -117,39 +116,33 @@ fn mkerr_winbool(ret: libc::c_int) -> IoResult<()> {
 
 #[cfg(windows)]
 #[inline]
-fn retry(f: || -> libc::c_int) -> libc::c_int {
-    loop {
-        match f() {
-            -1 if os::errno() as int == libc::WSAEINTR as int => {}
-            n => return n,
-        }
-    }
-}
+fn retry<I> (f: || -> I) -> I { f() } // PR rust-lang/rust/#17020
 
 #[cfg(unix)]
 #[inline]
-fn retry(f: || -> libc::c_int) -> libc::c_int {
+fn retry<I: PartialEq + num::One + Neg<I>> (f: || -> I) -> I {
+    let minus_one = -num::one::<I>();
     loop {
-        match f() {
-            -1 if os::errno() as int == libc::EINTR as int => {}
-            n => return n,
-        }
+        let n = f();
+        if n == minus_one && os::errno() == libc::EINTR as int { }
+        else { return n }
     }
 }
 
+
 fn keep_going(data: &[u8], f: |*const u8, uint| -> i64) -> i64 {
     let origamt = data.len();
     let mut data = data.as_ptr();
     let mut amt = origamt;
     while amt > 0 {
-        let ret = retry(|| f(data, amt) as libc::c_int);
+        let ret = retry(|| f(data, amt));
         if ret == 0 {
             break
         } else if ret != -1 {
             amt -= ret as uint;
             data = unsafe { data.offset(ret as int) };
         } else {
-            return ret as i64;
+            return ret;
         }
     }
     return (origamt - amt) as i64;
index 1a7a8da391a4a3a01a39be5e1e3f0b1ba7f6f054..ba951cdef26b92272ffd13449660e5470f805b4e 100644 (file)
@@ -13,8 +13,7 @@
 use std::mem;
 use std::ptr;
 use std::rt::mutex;
-use std::rt::rtio;
-use std::rt::rtio::{IoResult, IoError};
+use std::rt::rtio::{mod, IoResult, IoError};
 use std::sync::atomic;
 
 use super::{retry, keep_going};
@@ -988,9 +987,7 @@ pub fn write<T>(fd: sock_t,
                 write(false, inner, len)
             });
         } else {
-            ret = retry(|| {
-                write(false, buf.as_ptr(), buf.len()) as libc::c_int
-            }) as i64;
+            ret = retry(|| { write(false, buf.as_ptr(), buf.len()) });
             if ret > 0 { written = ret as uint; }
         }
     }
@@ -1017,7 +1014,7 @@ pub fn write<T>(fd: sock_t,
             let _guard = lock();
             let ptr = buf.slice_from(written).as_ptr();
             let len = buf.len() - written;
-            match retry(|| write(deadline.is_some(), ptr, len) as libc::c_int) {
+            match retry(|| write(deadline.is_some(), ptr, len)) {
                 -1 if util::wouldblock() => {}
                 -1 => return Err(os::last_error()),
                 n => { written += n as uint; }
index 39e21cfc48664fdcdea445ebc041b960c2e2fefe..c97f9513fc34a66ac61bc19b43f290d87f1be98f 100644 (file)
@@ -1978,10 +1978,10 @@ fn test_div_rem() {
     #[test]
     fn test_checked_add() {
         for elm in sum_triples.iter() {
-            let (aVec, bVec, cVec) = *elm;
-            let a = BigUint::from_slice(aVec);
-            let b = BigUint::from_slice(bVec);
-            let c = BigUint::from_slice(cVec);
+            let (a_vec, b_vec, c_vec) = *elm;
+            let a = BigUint::from_slice(a_vec);
+            let b = BigUint::from_slice(b_vec);
+            let c = BigUint::from_slice(c_vec);
 
             assert!(a.checked_add(&b).unwrap() == c);
             assert!(b.checked_add(&a).unwrap() == c);
@@ -1991,10 +1991,10 @@ fn test_checked_add() {
     #[test]
     fn test_checked_sub() {
         for elm in sum_triples.iter() {
-            let (aVec, bVec, cVec) = *elm;
-            let a = BigUint::from_slice(aVec);
-            let b = BigUint::from_slice(bVec);
-            let c = BigUint::from_slice(cVec);
+            let (a_vec, b_vec, c_vec) = *elm;
+            let a = BigUint::from_slice(a_vec);
+            let b = BigUint::from_slice(b_vec);
+            let c = BigUint::from_slice(c_vec);
 
             assert!(c.checked_sub(&a).unwrap() == b);
             assert!(c.checked_sub(&b).unwrap() == a);
@@ -2011,21 +2011,21 @@ fn test_checked_sub() {
     #[test]
     fn test_checked_mul() {
         for elm in mul_triples.iter() {
-            let (aVec, bVec, cVec) = *elm;
-            let a = BigUint::from_slice(aVec);
-            let b = BigUint::from_slice(bVec);
-            let c = BigUint::from_slice(cVec);
+            let (a_vec, b_vec, c_vec) = *elm;
+            let a = BigUint::from_slice(a_vec);
+            let b = BigUint::from_slice(b_vec);
+            let c = BigUint::from_slice(c_vec);
 
             assert!(a.checked_mul(&b).unwrap() == c);
             assert!(b.checked_mul(&a).unwrap() == c);
         }
 
         for elm in div_rem_quadruples.iter() {
-            let (aVec, bVec, cVec, dVec) = *elm;
-            let a = BigUint::from_slice(aVec);
-            let b = BigUint::from_slice(bVec);
-            let c = BigUint::from_slice(cVec);
-            let d = BigUint::from_slice(dVec);
+            let (a_vec, b_vec, c_vec, d_vec) = *elm;
+            let a = BigUint::from_slice(a_vec);
+            let b = BigUint::from_slice(b_vec);
+            let c = BigUint::from_slice(c_vec);
+            let d = BigUint::from_slice(d_vec);
 
             assert!(a == b.checked_mul(&c).unwrap() + d);
             assert!(a == c.checked_mul(&b).unwrap() + d);
@@ -2035,10 +2035,10 @@ fn test_checked_mul() {
     #[test]
     fn test_checked_div() {
         for elm in mul_triples.iter() {
-            let (aVec, bVec, cVec) = *elm;
-            let a = BigUint::from_slice(aVec);
-            let b = BigUint::from_slice(bVec);
-            let c = BigUint::from_slice(cVec);
+            let (a_vec, b_vec, c_vec) = *elm;
+            let a = BigUint::from_slice(a_vec);
+            let b = BigUint::from_slice(b_vec);
+            let c = BigUint::from_slice(c_vec);
 
             if !a.is_zero() {
                 assert!(c.checked_div(&a).unwrap() == b);
@@ -2651,10 +2651,10 @@ fn check(a: &BigInt, b: &BigInt, q: &BigInt, r: &BigInt) {
     #[test]
     fn test_checked_add() {
         for elm in sum_triples.iter() {
-            let (aVec, bVec, cVec) = *elm;
-            let a = BigInt::from_slice(Plus, aVec);
-            let b = BigInt::from_slice(Plus, bVec);
-            let c = BigInt::from_slice(Plus, cVec);
+            let (a_vec, b_vec, c_vec) = *elm;
+            let a = BigInt::from_slice(Plus, a_vec);
+            let b = BigInt::from_slice(Plus, b_vec);
+            let c = BigInt::from_slice(Plus, c_vec);
 
             assert!(a.checked_add(&b).unwrap() == c);
             assert!(b.checked_add(&a).unwrap() == c);
@@ -2670,10 +2670,10 @@ fn test_checked_add() {
     #[test]
     fn test_checked_sub() {
         for elm in sum_triples.iter() {
-            let (aVec, bVec, cVec) = *elm;
-            let a = BigInt::from_slice(Plus, aVec);
-            let b = BigInt::from_slice(Plus, bVec);
-            let c = BigInt::from_slice(Plus, cVec);
+            let (a_vec, b_vec, c_vec) = *elm;
+            let a = BigInt::from_slice(Plus, a_vec);
+            let b = BigInt::from_slice(Plus, b_vec);
+            let c = BigInt::from_slice(Plus, c_vec);
 
             assert!(c.checked_sub(&a).unwrap() == b);
             assert!(c.checked_sub(&b).unwrap() == a);
@@ -2689,10 +2689,10 @@ fn test_checked_sub() {
     #[test]
     fn test_checked_mul() {
         for elm in mul_triples.iter() {
-            let (aVec, bVec, cVec) = *elm;
-            let a = BigInt::from_slice(Plus, aVec);
-            let b = BigInt::from_slice(Plus, bVec);
-            let c = BigInt::from_slice(Plus, cVec);
+            let (a_vec, b_vec, c_vec) = *elm;
+            let a = BigInt::from_slice(Plus, a_vec);
+            let b = BigInt::from_slice(Plus, b_vec);
+            let c = BigInt::from_slice(Plus, c_vec);
 
             assert!(a.checked_mul(&b).unwrap() == c);
             assert!(b.checked_mul(&a).unwrap() == c);
@@ -2702,11 +2702,11 @@ fn test_checked_mul() {
         }
 
         for elm in div_rem_quadruples.iter() {
-            let (aVec, bVec, cVec, dVec) = *elm;
-            let a = BigInt::from_slice(Plus, aVec);
-            let b = BigInt::from_slice(Plus, bVec);
-            let c = BigInt::from_slice(Plus, cVec);
-            let d = BigInt::from_slice(Plus, dVec);
+            let (a_vec, b_vec, c_vec, d_vec) = *elm;
+            let a = BigInt::from_slice(Plus, a_vec);
+            let b = BigInt::from_slice(Plus, b_vec);
+            let c = BigInt::from_slice(Plus, c_vec);
+            let d = BigInt::from_slice(Plus, d_vec);
 
             assert!(a == b.checked_mul(&c).unwrap() + d);
             assert!(a == c.checked_mul(&b).unwrap() + d);
@@ -2715,10 +2715,10 @@ fn test_checked_mul() {
     #[test]
     fn test_checked_div() {
         for elm in mul_triples.iter() {
-            let (aVec, bVec, cVec) = *elm;
-            let a = BigInt::from_slice(Plus, aVec);
-            let b = BigInt::from_slice(Plus, bVec);
-            let c = BigInt::from_slice(Plus, cVec);
+            let (a_vec, b_vec, c_vec) = *elm;
+            let a = BigInt::from_slice(Plus, a_vec);
+            let b = BigInt::from_slice(Plus, b_vec);
+            let c = BigInt::from_slice(Plus, c_vec);
 
             if !a.is_zero() {
                 assert!(c.checked_div(&a).unwrap() == b);
index 933f2b223e9ecb09faae9e9d3a24d38e3693f3e4..6171a9946b6085702a0328a00074b91c0bdf0660 100644 (file)
@@ -1047,10 +1047,7 @@ mod tests {
 
     use serialize::{Encodable, Decodable};
 
-    use std::io::{IoError, IoResult, SeekStyle};
-    use std::io;
     use std::option::{None, Option, Some};
-    use std::slice;
 
     #[test]
     fn test_vuint_at() {
index d51d5a0aef2e1694d01d664230ac462c3720d62a..2ab7a6c52fac3283faebd2f2528f225cdb127fbf 100644 (file)
 
 #[cfg(test)]
 mod test {
-    use core::option::{Some, None};
-    use core::iter::Iterator;
     use core::collections::Collection;
     use core::str::StrSlice;
     use core::slice::{MutableSlice, ImmutableSlice};
index 2305434726599d0d4968f8c12d14be30a8e1cdde..225fc28cd6d9888b8a2ff022f6e4566a9b4509ee 100644 (file)
@@ -69,6 +69,8 @@
     ("rustc_diagnostic_macros", Active),
     ("unboxed_closures", Active),
     ("import_shadowing", Active),
+    ("advanced_slice_patterns", Active),
+    ("tuple_indexing", Active),
 
     // if you change this list without updating src/doc/rust.md, cmr will be sad
 
@@ -337,6 +339,11 @@ fn visit_expr(&mut self, e: &ast::Expr, _: ()) {
                                   "unboxed closures are a work-in-progress \
                                    feature with known bugs");
             }
+            ast::ExprTupField(..) => {
+                self.gate_feature("tuple_indexing",
+                                  e.span,
+                                  "tuple indexing is experimental");
+            }
             _ => {}
         }
         visit::walk_expr(self, e, ());
@@ -364,6 +371,20 @@ fn visit_attribute(&mut self, attr: &ast::Attribute, _: ()) {
         }
     }
 
+    fn visit_pat(&mut self, pattern: &ast::Pat, (): ()) {
+        match pattern.node {
+            ast::PatVec(_, Some(_), ref last) if !last.is_empty() => {
+                self.gate_feature("advanced_slice_patterns",
+                                  pattern.span,
+                                  "multiple-element slice matches anywhere \
+                                   but at the end of a slice (e.g. \
+                                   `[0, ..xs, 0]` are experimental")
+            }
+            _ => {}
+        }
+        visit::walk_pat(self, pattern, ())
+    }
+
     fn visit_fn(&mut self,
                 fn_kind: &visit::FnKind,
                 fn_decl: &ast::FnDecl,
index 36db4e422c11d2bc679e490d5102f5e615d7696d..1a59b3603de58b53a8102b6cad6a4bf572ca8060 100644 (file)
@@ -28,6 +28,10 @@ fn visit_expr(&mut self, e: &ast::Expr, _: ()) {
         self.sess.span_note(e.span, "expression");
         visit::walk_expr(self, e, ());
     }
+
+    fn visit_mac(&mut self, macro: &ast::Mac, e: ()) {
+        visit::walk_mac(self, macro, e);
+    }
 }
 
 pub fn run(sess: &Session, krate: &ast::Crate) {
index 13f6243fb7ba715c517346f9a7a2b7f2343daab2..63e93d266c7703a9f9f96464725d1cffba339e7d 100644 (file)
@@ -96,7 +96,7 @@ fn fold_crate(&mut self, c: ast::Crate) -> ast::Crate {
 
         // Add a special __test module to the crate that will contain code
         // generated for the test harness
-        let (mod_, reexport) = mk_test_module(&self.cx, &self.cx.reexport_test_harness_main);
+        let (mod_, reexport) = mk_test_module(&mut self.cx);
         folded.module.items.push(mod_);
         match reexport {
             Some(re) => folded.module.view_items.push(re),
@@ -378,8 +378,7 @@ fn mk_std(cx: &TestCtxt) -> ast::ViewItem {
     }
 }
 
-fn mk_test_module(cx: &TestCtxt, reexport_test_harness_main: &Option<InternedString>)
-                  -> (Gc<ast::Item>, Option<ast::ViewItem>) {
+fn mk_test_module(cx: &mut TestCtxt) -> (Gc<ast::Item>, Option<ast::ViewItem>) {
     // Link to test crate
     let view_items = vec!(mk_std(cx));
 
@@ -388,7 +387,7 @@ fn mk_test_module(cx: &TestCtxt, reexport_test_harness_main: &Option<InternedStr
 
     // The synthesized main function which will call the console test runner
     // with our list of tests
-    let mainfn = (quote_item!(&cx.ext_cx,
+    let mainfn = (quote_item!(&mut cx.ext_cx,
         pub fn main() {
             #![main]
             use std::slice::Slice;
@@ -412,7 +411,7 @@ pub fn main() {
         vis: ast::Public,
         span: DUMMY_SP,
     };
-    let reexport = reexport_test_harness_main.as_ref().map(|s| {
+    let reexport = cx.reexport_test_harness_main.as_ref().map(|s| {
         // building `use <ident> = __test::main`
         let reexport_ident = token::str_to_ident(s.get());
 
index 75a48fdd596ea7dc821a4edc711585154c6ba838..ce262bf449a159dc1ccabceb1e24c660d8bdb006 100644 (file)
@@ -42,8 +42,8 @@
 extern crate getopts;
 extern crate graphviz;
 extern crate libc;
-extern crate "rustc_llvm" as llvm;
-extern crate "rustc_back" as rustc_back;
+extern crate rustc_llvm;
+extern crate rustc_back;
 extern crate serialize;
 extern crate rbml;
 extern crate time;
@@ -53,6 +53,8 @@
 #[cfg(test)]
 extern crate test;
 
+pub use rustc_llvm as llvm;
+
 mod diagnostics;
 
 pub mod back {
index c3c4cf51f577540ed5dd0763a427c424377c1140..138947e8a873b5cdbf754e24d628f0e4bb711a30 100644 (file)
@@ -172,33 +172,24 @@ fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
             ast::ExprLit(lit) => {
                 match ty::get(ty::expr_ty(cx.tcx, e)).sty {
                     ty::ty_int(t) => {
-                        let int_type = if t == ast::TyI {
-                            cx.sess().targ_cfg.int_type
-                        } else { t };
-                        let (min, max) = int_ty_range(int_type);
-                        let mut lit_val: i64 = match lit.node {
+                        match lit.node {
                             ast::LitInt(v, ast::SignedIntLit(_, ast::Plus)) |
                             ast::LitInt(v, ast::UnsuffixedIntLit(ast::Plus)) => {
-                                if v > i64::MAX as u64{
+                                let int_type = if t == ast::TyI {
+                                    cx.sess().targ_cfg.int_type
+                                } else { t };
+                                let (min, max) = int_ty_range(int_type);
+                                let negative = self.negated_expr_id == e.id;
+
+                                if (negative && v > (min.abs() as u64)) ||
+                                   (!negative && v > (max.abs() as u64)) {
                                     cx.span_lint(TYPE_OVERFLOW, e.span,
                                                  "literal out of range for its type");
                                     return;
                                 }
-                                v as i64
-                            }
-                            ast::LitInt(v, ast::SignedIntLit(_, ast::Minus)) |
-                            ast::LitInt(v, ast::UnsuffixedIntLit(ast::Minus)) => {
-                                -(v as i64)
                             }
                             _ => fail!()
                         };
-                        if self.negated_expr_id == e.id {
-                            lit_val *= -1;
-                        }
-                        if lit_val < min || lit_val > max {
-                            cx.span_lint(TYPE_OVERFLOW, e.span,
-                                         "literal out of range for its type");
-                        }
                     },
                     ty::ty_uint(t) => {
                         let uint_type = if t == ast::TyU {
@@ -1065,6 +1056,7 @@ fn contains_exterior_struct_lit(value: &ast::Expr) -> bool {
                 ast::ExprUnary(_, ref x) |
                 ast::ExprCast(ref x, _) |
                 ast::ExprField(ref x, _, _) |
+                ast::ExprTupField(ref x, _, _) |
                 ast::ExprIndex(ref x, _) => {
                     // &X { y: 1 }, X { y: 1 }.y
                     contains_exterior_struct_lit(&**x)
index 0e64be3d0b70bbfa347a6f3364a4ed99baa2378d..b7597b50b4906b76e2c20763087381c1f798712f 100644 (file)
@@ -1951,7 +1951,7 @@ fn roundtrip(in_item: Option<Gc<ast::Item>>) {
 #[test]
 fn test_basic() {
     let cx = mk_ctxt();
-    roundtrip(quote_item!(cx,
+    roundtrip(quote_item!(&cx,
         fn foo() {}
     ));
 }
@@ -1959,7 +1959,7 @@ fn foo() {}
 #[test]
 fn test_smalltalk() {
     let cx = mk_ctxt();
-    roundtrip(quote_item!(cx,
+    roundtrip(quote_item!(&cx,
         fn foo() -> int { 3 + 4 } // first smalltalk program ever executed.
     ));
 }
@@ -1968,7 +1968,7 @@ fn foo() -> int { 3 + 4 } // first smalltalk program ever executed.
 #[test]
 fn test_more() {
     let cx = mk_ctxt();
-    roundtrip(quote_item!(cx,
+    roundtrip(quote_item!(&cx,
         fn foo(x: uint, y: uint) -> uint {
             let z = x + y;
             return z;
@@ -1987,7 +1987,7 @@ fn eq_int(a: int, b: int) -> bool { a == b }
     ).unwrap();
     let item_in = e::IIItemRef(&*item);
     let item_out = simplify_ast(item_in);
-    let item_exp = ast::IIItem(quote_item!(cx,
+    let item_exp = ast::IIItem(quote_item!(&cx,
         fn new_int_alist<B>() -> alist<int, B> {
             return alist {eq_fn: eq_int, data: Vec::new()};
         }
index f4d3678271c0ded7c8d6c26a980f60b9ce947688..5969e7e0c42d5a8a286035d370be9d324e5e04fa 100644 (file)
@@ -807,7 +807,7 @@ pub fn append_loan_path_to_string(&self,
                         out.push_str(token::get_name(fname).get());
                     }
                     mc::PositionalField(idx) => {
-                        out.push_char('#'); // invent a notation here
+                        out.push_char('.');
                         out.push_str(idx.to_string().as_slice());
                     }
                 }
index ec414b858187aae059be33986fa1f50f468abe1f..6e9b27655af79a1b9e4c59f507872f593b1e7169 100644 (file)
@@ -467,7 +467,8 @@ fn expr(&mut self, expr: Gc<ast::Expr>, pred: CFGIndex) -> CFGIndex {
             ast::ExprCast(e, _) |
             ast::ExprUnary(_, e) |
             ast::ExprParen(e) |
-            ast::ExprField(e, _, _) => {
+            ast::ExprField(e, _, _) |
+            ast::ExprTupField(e, _, _) => {
                 self.straightline(expr, pred, [e])
             }
 
index 3c8db8d048076cae439776cbb65957c76a6692da..a9a3d94ded897a0ce2bede4f0738b6260b582725 100644 (file)
@@ -173,6 +173,7 @@ fn check_expr(v: &mut CheckCrateVisitor, e: &Expr, is_const: bool) {
           ExprAddrOf(MutImmutable, _) |
           ExprParen(..) |
           ExprField(..) |
+          ExprTupField(..) |
           ExprIndex(..) |
           ExprTup(..) |
           ExprRepeat(..) |
index 7b00bb4589c71e8983c2aaaea38d992b8d655d44..ca58b4b6e60a40d8f498880c7b4c24d5d48b7e2a 100644 (file)
@@ -106,7 +106,7 @@ fn visit_expr(&mut self, e: &ast::Expr, is_const: bool) {
         }
 
         match e.node {
-            ast::ExprField(..) | ast::ExprVec(..) |
+            ast::ExprField(..) | ast::ExprTupField(..) | ast::ExprVec(..) |
             ast::ExprBlock(..) | ast::ExprTup(..)  => {
                 visit::walk_expr(self, e, is_const);
             }
index e853b5961ec4fa4b2ef60246efa8764d33d07ed1..2b4b6756f9f859ce046b06e4084a5461423f2f2f 100644 (file)
@@ -225,6 +225,8 @@ fn classify(&mut self, e: &Expr) -> constness {
 
             ast::ExprField(ref base, _, _) => self.classify(&**base),
 
+            ast::ExprTupField(ref base, _, _) => self.classify(&**base),
+
             ast::ExprIndex(ref base, ref idx) =>
                 join(self.classify(&**base), self.classify(&**idx)),
 
@@ -500,42 +502,44 @@ fn fromb(b: bool) -> Result<const_val, String> { Ok(const_int(b as i64)) }
                                         "target type not found for const cast")
                 });
 
-        let base = eval_const_expr_partial(tcx, &**base);
-        match base {
-            Err(_) => base,
-            Ok(val) => {
-                match ty::get(ety).sty {
-                    ty::ty_float(_) => {
-                        match val {
-                            const_bool(b) => Ok(const_float(b as f64)),
-                            const_uint(u) => Ok(const_float(u as f64)),
-                            const_int(i) => Ok(const_float(i as f64)),
-                            const_float(f) => Ok(const_float(f)),
-                            _ => Err("can't cast this type to float".to_string()),
-                        }
-                    }
-                    ty::ty_uint(_) => {
-                        match val {
-                            const_bool(b) => Ok(const_uint(b as u64)),
-                            const_uint(u) => Ok(const_uint(u)),
-                            const_int(i) => Ok(const_uint(i as u64)),
-                            const_float(f) => Ok(const_uint(f as u64)),
-                            _ => Err("can't cast this type to uint".to_string()),
-                        }
-                    }
-                    ty::ty_int(_) => {
-                        match val {
-                            const_bool(b) => Ok(const_int(b as i64)),
-                            const_uint(u) => Ok(const_int(u as i64)),
-                            const_int(i) => Ok(const_int(i)),
-                            const_float(f) => Ok(const_int(f as i64)),
-                            _ => Err("can't cast this type to int".to_string()),
-                        }
+        macro_rules! define_casts(
+            ($val:ident, {
+                $($ty_pat:pat => (
+                    $intermediate_ty:ty,
+                    $const_type:ident,
+                    $target_ty:ty
+                )),*
+            }) => (match ty::get(ety).sty {
+                $($ty_pat => {
+                    match $val {
+                        const_bool(b) => Ok($const_type(b as $intermediate_ty as $target_ty)),
+                        const_uint(u) => Ok($const_type(u as $intermediate_ty as $target_ty)),
+                        const_int(i) => Ok($const_type(i as $intermediate_ty as $target_ty)),
+                        const_float(f) => Ok($const_type(f as $intermediate_ty as $target_ty)),
+                        _ => Err(concat!(
+                            "can't cast this type to ", stringify!($const_type)
+                        ).to_string())
                     }
-                    _ => Err("can't cast this type".to_string())
-                }
-            }
-        }
+                },)*
+                _ => Err("can't cast this type".to_string())
+            })
+        )
+
+        eval_const_expr_partial(tcx, &**base)
+            .and_then(|val| define_casts!(val, {
+                ty::ty_int(ast::TyI) => (int, const_int, i64),
+                ty::ty_int(ast::TyI8) => (i8, const_int, i64),
+                ty::ty_int(ast::TyI16) => (i16, const_int, i64),
+                ty::ty_int(ast::TyI32) => (i32, const_int, i64),
+                ty::ty_int(ast::TyI64) => (i64, const_int, i64),
+                ty::ty_uint(ast::TyU) => (uint, const_uint, u64),
+                ty::ty_uint(ast::TyU8) => (u8, const_uint, u64),
+                ty::ty_uint(ast::TyU16) => (u16, const_uint, u64),
+                ty::ty_uint(ast::TyU32) => (u32, const_uint, u64),
+                ty::ty_uint(ast::TyU64) => (u64, const_uint, u64),
+                ty::ty_float(ast::TyF32) => (f32, const_float, f64),
+                ty::ty_float(ast::TyF64) => (f64, const_float, f64)
+            }))
       }
       ExprPath(_) => {
           match lookup_const(tcx, e) {
index b7cddd0c23f964876451b05e06c22b815d9070af..f275c818716599a9fee9ad6577c3ed8aea074299 100644 (file)
@@ -145,6 +145,17 @@ fn handle_field_access(&mut self, lhs: &ast::Expr, name: &ast::Ident) {
         }
     }
 
+    fn handle_tup_field_access(&mut self, lhs: &ast::Expr, idx: uint) {
+        match ty::get(ty::expr_ty_adjusted(self.tcx, lhs)).sty {
+            ty::ty_struct(id, _) => {
+                let fields = ty::lookup_struct_fields(self.tcx, id);
+                let field_id = fields[idx].id;
+                self.live_symbols.insert(field_id.node);
+            },
+            _ => ()
+        }
+    }
+
     fn handle_field_pattern_match(&mut self, lhs: &ast::Pat, pats: &[ast::FieldPat]) {
         let id = match self.tcx.def_map.borrow().get(&lhs.id) {
             &def::DefVariant(_, id, _) => id,
@@ -255,6 +266,9 @@ fn visit_expr(&mut self, expr: &ast::Expr, ctxt: MarkSymbolVisitorContext) {
             ast::ExprField(ref lhs, ref ident, _) => {
                 self.handle_field_access(&**lhs, &ident.node);
             }
+            ast::ExprTupField(ref lhs, idx, _) => {
+                self.handle_tup_field_access(&**lhs, idx.node);
+            }
             _ => ()
         }
 
index 207620b182907b9229985313f9a998bdf3ea29f4..d2362b7e9429b3291801da7dc058878e8ce63275 100644 (file)
@@ -324,6 +324,10 @@ pub fn walk_expr(&mut self, expr: &ast::Expr) {
                 self.select_from_expr(&**base);
             }
 
+            ast::ExprTupField(ref base, _, _) => {         // base.<n>
+                self.select_from_expr(&**base);
+            }
+
             ast::ExprIndex(ref lhs, ref rhs) => {           // lhs[rhs]
                 if !self.walk_overloaded_operator(expr, &**lhs, [rhs.clone()]) {
                     self.select_from_expr(&**lhs);
index e556c5a59c224696dcb3540358084453a8c0e4d0..e8b0afa98c2d0487c78f0f2d54ae4e0f5a723adb 100644 (file)
@@ -199,6 +199,15 @@ fn check_item(cx: &mut Context, item: &Item) {
                                     cx,
                                     item.span,
                                     &*trait_ref);
+
+                                let trait_def = ty::lookup_trait_def(cx.tcx, trait_ref.def_id);
+                                for (ty, type_param_def) in trait_ref.substs.types
+                                                                  .iter()
+                                                                  .zip(trait_def.generics
+                                                                                .types
+                                                                                .iter()) {
+                                    check_typaram_bounds(cx, item.span, *ty, type_param_def);
+                                }
                             }
                         }
                     }
index 26aa51b909944cff987fa77254b257d98d59f700..84fc8ff2c38cae28d24d06b6887f1e6afd08c9f9 100644 (file)
@@ -511,7 +511,7 @@ fn visit_expr(ir: &mut IrMaps, expr: &Expr) {
       }
 
       // otherwise, live nodes are not required:
-      ExprIndex(..) | ExprField(..) | ExprVec(..) |
+      ExprIndex(..) | ExprField(..) | ExprTupField(..) | ExprVec(..) |
       ExprCall(..) | ExprMethodCall(..) | ExprTup(..) |
       ExprBinary(..) | ExprAddrOf(..) |
       ExprCast(..) | ExprUnary(..) | ExprBreak(_) |
@@ -965,6 +965,10 @@ fn propagate_through_expr(&mut self, expr: &Expr, succ: LiveNode)
               self.propagate_through_expr(&**e, succ)
           }
 
+          ExprTupField(ref e, _, _) => {
+              self.propagate_through_expr(&**e, succ)
+          }
+
           ExprFnBlock(_, _, ref blk) |
           ExprProc(_, ref blk) |
           ExprUnboxedFn(_, _, _, ref blk) => {
@@ -1271,6 +1275,7 @@ fn propagate_through_lvalue_components(&mut self,
         match expr.node {
             ExprPath(_) => succ,
             ExprField(ref e, _, _) => self.propagate_through_expr(&**e, succ),
+            ExprTupField(ref e, _, _) => self.propagate_through_expr(&**e, succ),
             _ => self.propagate_through_expr(expr, succ)
         }
     }
@@ -1445,7 +1450,7 @@ fn check_expr(this: &mut Liveness, expr: &Expr) {
       // no correctness conditions related to liveness
       ExprCall(..) | ExprMethodCall(..) | ExprIf(..) | ExprMatch(..) |
       ExprWhile(..) | ExprLoop(..) | ExprIndex(..) | ExprField(..) |
-      ExprVec(..) | ExprTup(..) | ExprBinary(..) |
+      ExprTupField(..) | ExprVec(..) | ExprTup(..) | ExprBinary(..) |
       ExprCast(..) | ExprUnary(..) | ExprRet(..) | ExprBreak(..) |
       ExprAgain(..) | ExprLit(_) | ExprBlock(..) |
       ExprMac(..) | ExprAddrOf(..) | ExprStruct(..) | ExprRepeat(..) |
index abed04c8f33acf7cf90f98d4dc151af9521822b2..0d3dd8f91d9672128e5f9dee0b4ec8a821dd6fdf 100644 (file)
@@ -465,6 +465,11 @@ pub fn cat_expr_unadjusted(&self, expr: &ast::Expr) -> McResult<cmt> {
             Ok(self.cat_field(expr, base_cmt, f_name.node, expr_ty))
           }
 
+          ast::ExprTupField(ref base, idx, _) => {
+            let base_cmt = if_ok!(self.cat_expr(&**base));
+            Ok(self.cat_tup_field(expr, base_cmt, idx.node, expr_ty))
+          }
+
           ast::ExprIndex(ref base, _) => {
             let method_call = typeck::MethodCall::expr(expr.id());
             match self.typer.node_method_ty(method_call) {
@@ -737,6 +742,21 @@ pub fn cat_field<N:ast_node>(&self,
         })
     }
 
+    pub fn cat_tup_field<N:ast_node>(&self,
+                                     node: &N,
+                                     base_cmt: cmt,
+                                     f_idx: uint,
+                                     f_ty: ty::t)
+                                     -> cmt {
+        Rc::new(cmt_ {
+            id: node.id(),
+            span: node.span(),
+            mutbl: base_cmt.mutbl.inherit(),
+            cat: cat_interior(base_cmt, InteriorField(PositionalField(f_idx))),
+            ty: f_ty
+        })
+    }
+
     pub fn cat_deref_obj<N:ast_node>(&self, node: &N, base_cmt: cmt) -> cmt {
         self.cat_deref_common(node, base_cmt, 0, ty::mk_nil(), false)
     }
index 6017444267a4f2b7583962b05c162e0b60ebfab6..cdb7d114af90306c792fd289eea0574c2d46a1bf 100644 (file)
@@ -819,6 +819,14 @@ fn visit_expr(&mut self, expr: &ast::Expr, _: ()) {
                     _ => {}
                 }
             }
+            ast::ExprTupField(ref base, idx, _) => {
+                match ty::get(ty::expr_ty_adjusted(self.tcx, &**base)).sty {
+                    ty::ty_struct(id, _) => {
+                        self.check_field(expr.span, id, UnnamedField(idx.node));
+                    }
+                    _ => {}
+                }
+            }
             ast::ExprMethodCall(ident, _, _) => {
                 let method_call = MethodCall::expr(expr.id);
                 match self.tcx.method_map.borrow().find(&method_call) {
index 21bfcfeec70b51603e6f32ab31fb03a7051dfaf0..0db3864a06bb8fefeb48ac74da23014b0670da5e 100644 (file)
@@ -779,6 +779,7 @@ fn record_rvalue_scope<'a>(visitor: &mut RegionResolutionVisitor,
                 ast::ExprAddrOf(_, ref subexpr) |
                 ast::ExprUnary(ast::UnDeref, ref subexpr) |
                 ast::ExprField(ref subexpr, _, _) |
+                ast::ExprTupField(ref subexpr, _, _) |
                 ast::ExprIndex(ref subexpr, _) |
                 ast::ExprParen(ref subexpr) => {
                     let subexpr: &'a Gc<Expr> = subexpr; // FIXME(#11586)
index 0c8697d31f3c98dd2023d1013d9578b96344b004..854b8b9ba77112337d729054f7676badf65ef1e3 100644 (file)
@@ -1549,18 +1549,13 @@ fn build_reduced_graph_for_view_item(&mut self, view_item: &ViewItem,
                             PathListMod { .. } => Some(item.span),
                             _ => None
                         }).collect::<Vec<Span>>();
-                        match mod_spans.as_slice() {
-                            [first, second, ..other] => {
-                                self.resolve_error(first,
-                                    "`mod` import can only appear once in the list");
-                                self.session.span_note(second,
-                                        "another `mod` import appears here");
-                                for &other_span in other.iter() {
-                                    self.session.span_note(other_span,
-                                        "another `mod` import appears here");
-                                }
-                            },
-                            [_] | [] => ()
+                        if mod_spans.len() > 1 {
+                            self.resolve_error(mod_spans[0],
+                                "`mod` import can only appear once in the list");
+                            for other_span in mod_spans.iter().skip(1) {
+                                self.session.span_note(*other_span,
+                                    "another `mod` import appears here");
+                            }
                         }
 
                         for source_item in source_items.iter() {
@@ -3936,6 +3931,7 @@ fn resolve_item(&mut self, item: &Item) {
                                                                item.id,
                                                                ItemRibKind),
                                              |this| {
+                    this.resolve_type_parameters(&generics.ty_params);
                     visit::walk_item(this, item, ());
                 });
             }
index 7c7960e0918f46fb1213cc39b77ddb792258e4d4..7350413643c8da460fb03b10e250c2b47f7fff9b 100644 (file)
@@ -1314,6 +1314,34 @@ fn visit_expr(&mut self, ex: &ast::Expr, e: DxrVisitorEnv) {
                                             "Expected struct type, but not ty_struct"),
                 }
             },
+            ast::ExprTupField(sub_ex, idx, _) => {
+                if generated_code(sub_ex.span) {
+                    return
+                }
+
+                self.visit_expr(&*sub_ex, e);
+
+                let t = ty::expr_ty_adjusted(&self.analysis.ty_cx, &*sub_ex);
+                let t_box = ty::get(t);
+                match t_box.sty {
+                    ty::ty_struct(def_id, _) => {
+                        let fields = ty::lookup_struct_fields(&self.analysis.ty_cx, def_id);
+                        for (i, f) in fields.iter().enumerate() {
+                            if i == idx.node {
+                                let sub_span = self.span.span_for_last_ident(ex.span);
+                                self.fmt.ref_str(recorder::VarRef,
+                                                 ex.span,
+                                                 sub_span,
+                                                 f.id,
+                                                 e.cur_scope);
+                                break;
+                            }
+                        }
+                    },
+                    _ => self.sess.span_bug(ex.span,
+                                            "Expected struct type, but not ty_struct"),
+                }
+            },
             ast::ExprFnBlock(_, decl, body) => {
                 if generated_code(body.span) {
                     return
index bd5132ea4273660ea8f128ecb07e76b8c1957b5d..8f6a3864b37ea12a1e9af93148faa35692877107 100644 (file)
@@ -440,6 +440,13 @@ fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr,
                   (adt::const_get_field(cx, &*brepr, bv, discr, ix), inlineable)
               })
           }
+          ast::ExprTupField(ref base, idx, _) => {
+              let (bv, inlineable, bt) = const_expr(cx, &**base, is_local);
+              let brepr = adt::represent_type(cx, bt);
+              expr::with_field_tys(cx.tcx(), bt, None, |discr, _| {
+                  (adt::const_get_field(cx, &*brepr, bv, discr, idx.node), inlineable)
+              })
+          }
 
           ast::ExprIndex(ref base, ref index) => {
               let (bv, inlineable, bt) = const_expr(cx, &**base, is_local);
index b640f9ef5af11dfb5cb6640666de6bd6824e1fc7..e1c7ef4d50f0a45b4791f29cffcb03622664ada9 100644 (file)
@@ -3457,6 +3457,7 @@ fn walk_expr(cx: &CrateContext,
             ast::ExprCast(ref sub_exp, _)     |
             ast::ExprAddrOf(_, ref sub_exp)  |
             ast::ExprField(ref sub_exp, _, _) |
+            ast::ExprTupField(ref sub_exp, _, _) |
             ast::ExprParen(ref sub_exp) =>
                 walk_expr(cx, &**sub_exp, scope_stack, scope_map),
 
index 0421aef45ef9c4617d866f1e1f99c1889ebd62c7..bfcf4a11bc207bdf630d33457a317426dc529cc8 100644 (file)
@@ -62,7 +62,7 @@
 use middle::trans::inline;
 use middle::trans::tvec;
 use middle::trans::type_of;
-use middle::ty::struct_fields;
+use middle::ty::{struct_fields, tup_fields};
 use middle::ty::{AutoDerefRef, AutoAddEnv, AutoUnsafe};
 use middle::ty::{AutoPtr};
 use middle::ty;
@@ -412,29 +412,11 @@ fn unsize_unique_vec<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
         let vec_ty = ty::mk_uniq(tcx, ty::mk_vec(tcx, unit_ty, None));
         let scratch = rvalue_scratch_datum(bcx, vec_ty, "__unsize_unique");
 
-        if len == 0 {
-            Store(bcx,
-                  C_null(type_of::type_of(bcx.ccx(), unit_ty).ptr_to()),
-                  get_dataptr(bcx, scratch.val));
-        } else {
-            // Box<[(), ..n]> will not allocate, but ~[()] expects an
-            // allocation of n bytes, so we must allocate here (yuck).
-            let llty = type_of::type_of(bcx.ccx(), unit_ty);
-            if llsize_of_alloc(bcx.ccx(), llty) == 0 {
-                let ptr_unit_ty = type_of::type_of(bcx.ccx(), unit_ty).ptr_to();
-                let align = C_uint(bcx.ccx(), 8);
-                let alloc_result = malloc_raw_dyn(bcx, ptr_unit_ty, vec_ty, ll_len, align);
-                bcx = alloc_result.bcx;
-                let base = get_dataptr(bcx, scratch.val);
-                Store(bcx, alloc_result.val, base);
-            } else {
-                let base = get_dataptr(bcx, scratch.val);
-                let base = PointerCast(bcx,
-                                       base,
-                                       type_of::type_of(bcx.ccx(), datum_ty).ptr_to());
-                bcx = lval.store_to(bcx, base);
-            }
-        }
+        let base = get_dataptr(bcx, scratch.val);
+        let base = PointerCast(bcx,
+                               base,
+                               type_of::type_of(bcx.ccx(), datum_ty).ptr_to());
+        bcx = lval.store_to(bcx, base);
 
         Store(bcx, ll_len, get_len(bcx, scratch.val));
         DatumBlock::new(bcx, scratch.to_expr_datum())
@@ -593,6 +575,9 @@ fn trans_datum_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
         ast::ExprField(ref base, ident, _) => {
             trans_rec_field(bcx, &**base, ident.node)
         }
+        ast::ExprTupField(ref base, idx, _) => {
+            trans_rec_tup_field(bcx, &**base, idx.node)
+        }
         ast::ExprIndex(ref base, ref idx) => {
             trans_index(bcx, expr, &**base, &**idx, MethodCall::expr(expr.id))
         }
@@ -666,12 +651,10 @@ fn trans_datum_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     }
 }
 
-fn trans_rec_field<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
-                               base: &ast::Expr,
-                               field: ast::Ident)
-                               -> DatumBlock<'blk, 'tcx, Expr> {
-    //! Translates `base.field`.
-
+fn trans_field<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
+                           base: &ast::Expr,
+                           get_idx: |&'blk ty::ctxt<'tcx>, &[ty::field]| -> uint)
+                           -> DatumBlock<'blk, 'tcx, Expr> {
     let mut bcx = bcx;
     let _icx = push_ctxt("trans_rec_field");
 
@@ -679,7 +662,7 @@ fn trans_rec_field<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     let bare_ty = ty::unopen_type(base_datum.ty);
     let repr = adt::represent_type(bcx.ccx(), bare_ty);
     with_field_tys(bcx.tcx(), bare_ty, None, |discr, field_tys| {
-        let ix = ty::field_idx_strict(bcx.tcx(), field.name, field_tys);
+        let ix = get_idx(bcx.tcx(), field_tys);
         let d = base_datum.get_element(
             bcx,
             field_tys[ix].mt.ty,
@@ -697,6 +680,23 @@ fn trans_rec_field<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 
         }
     })
+
+}
+
+/// Translates `base.field`.
+fn trans_rec_field<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
+                               base: &ast::Expr,
+                               field: ast::Ident)
+                               -> DatumBlock<'blk, 'tcx, Expr> {
+    trans_field(bcx, base, |tcx, field_tys| ty::field_idx_strict(tcx, field.name, field_tys))
+}
+
+/// Translates `base.<idx>`.
+fn trans_rec_tup_field<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
+                                   base: &ast::Expr,
+                                   idx: uint)
+                                   -> DatumBlock<'blk, 'tcx, Expr> {
+    trans_field(bcx, base, |_, _| idx)
 }
 
 fn trans_index<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
@@ -1238,6 +1238,10 @@ pub fn with_field_tys<R>(tcx: &ty::ctxt,
             op(0, struct_fields(tcx, did, substs).as_slice())
         }
 
+        ty::ty_tup(ref v) => {
+            op(0, tup_fields(v.as_slice()).as_slice())
+        }
+
         ty::ty_enum(_, ref substs) => {
             // We want the *variant* ID here, not the enum ID.
             match node_id_opt {
index 00b9977c7523ce46a47c750bfd5234a4bf47e4c6..c0d19b31cb8ede9d3d1d428f0bfbf04caeef34b2 100644 (file)
@@ -72,14 +72,19 @@ pub fn make_drop_glue_unboxed<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
         };
 
         if should_deallocate {
-            let not_null = IsNotNull(bcx, dataptr);
-            with_cond(bcx, not_null, |bcx| {
-                let llty = type_of::type_of(ccx, unit_ty);
-                let llsize = machine::llsize_of(ccx, llty);
-                let llalign = C_uint(ccx, machine::llalign_of_min(ccx, llty) as uint);
-                let size = Mul(bcx, llsize, get_len(bcx, vptr));
-                glue::trans_exchange_free_dyn(bcx, dataptr, size, llalign)
-            })
+            let llty = type_of::type_of(ccx, unit_ty);
+            let unit_size = llsize_of_alloc(ccx, llty);
+            if unit_size != 0 {
+                let len = get_len(bcx, vptr);
+                let not_empty = ICmp(bcx, llvm::IntNE, len, C_uint(ccx, 0));
+                with_cond(bcx, not_empty, |bcx| {
+                    let llalign = C_uint(ccx, machine::llalign_of_min(ccx, llty) as uint);
+                    let size = Mul(bcx, C_uint(ccx, unit_size as uint), len);
+                    glue::trans_exchange_free_dyn(bcx, dataptr, size, llalign)
+                })
+            } else {
+                bcx
+            }
         } else {
             bcx
         }
index 69b73436477c1ac6b5ee0c980398a33f070feb20..e196304b82ac39a6b65ae086bbef84e8b480884e 100644 (file)
@@ -3600,6 +3600,7 @@ pub fn expr_kind(tcx: &ctxt, expr: &ast::Expr) -> ExprKind {
 
         ast::ExprUnary(ast::UnDeref, _) |
         ast::ExprField(..) |
+        ast::ExprTupField(..) |
         ast::ExprIndex(..) => {
             LvalueExpr
         }
@@ -4529,6 +4530,11 @@ pub fn lookup_struct_fields(cx: &ctxt, did: ast::DefId) -> Vec<field_ty> {
     }
 }
 
+pub fn is_tuple_struct(cx: &ctxt, did: ast::DefId) -> bool {
+    let fields = lookup_struct_fields(cx, did);
+    !fields.is_empty() && fields.iter().all(|f| f.name == token::special_names::unnamed_field)
+}
+
 pub fn lookup_struct_field(cx: &ctxt,
                            parent: ast::DefId,
                            field_id: ast::DefId)
@@ -4556,6 +4562,21 @@ pub fn struct_fields(cx: &ctxt, did: ast::DefId, substs: &Substs)
     }).collect()
 }
 
+// Returns a list of fields corresponding to the tuple's items. trans uses
+// this.
+pub fn tup_fields(v: &[t]) -> Vec<field> {
+    v.iter().enumerate().map(|(i, &f)| {
+       field {
+            // FIXME #6993: change type of field to Name and get rid of new()
+            ident: ast::Ident::new(token::intern(i.to_string().as_slice())),
+            mt: mt {
+                ty: f,
+                mutbl: MutImmutable
+            }
+        }
+    }).collect()
+}
+
 pub struct UnboxedClosureUpvar {
     pub def: def::Def,
     pub span: Span,
index 01b5fd6e429eeaec1e675f1c7b5f3774b70c06d2..4f0f6121904a128e5d4011bbfc2f8fc655bb3247 100644 (file)
@@ -2603,6 +2603,16 @@ pub fn lookup_field_ty(tcx: &ty::ctxt,
     o_field.map(|f| ty::lookup_field_type(tcx, class_id, f.id, substs))
 }
 
+pub fn lookup_tup_field_ty(tcx: &ty::ctxt,
+                           class_id: ast::DefId,
+                           items: &[ty::field_ty],
+                           idx: uint,
+                           substs: &subst::Substs) -> Option<ty::t> {
+
+    let o_field = if idx < items.len() { Some(&items[idx]) } else { None };
+    o_field.map(|f| ty::lookup_field_type(tcx, class_id, f.id, substs))
+}
+
 // Controls whether the arguments are automatically referenced. This is useful
 // for overloaded binary and unary operators.
 pub enum DerefArgs {
@@ -3286,6 +3296,68 @@ fn check_field(fcx: &FnCtxt,
         fcx.write_error(expr.id);
     }
 
+    // Check tuple index expressions
+    fn check_tup_field(fcx: &FnCtxt,
+                       expr: &ast::Expr,
+                       lvalue_pref: LvaluePreference,
+                       base: &ast::Expr,
+                       idx: codemap::Spanned<uint>,
+                       _tys: &[ast::P<ast::Ty>]) {
+        let tcx = fcx.ccx.tcx;
+        check_expr_with_lvalue_pref(fcx, base, lvalue_pref);
+        let expr_t = structurally_resolved_type(fcx, expr.span,
+                                                fcx.expr_ty(base));
+        let mut tuple_like = false;
+        // FIXME(eddyb) #12808 Integrate privacy into this auto-deref loop.
+        let (_, autoderefs, field_ty) =
+            autoderef(fcx, expr.span, expr_t, Some(base.id), lvalue_pref, |base_t, _| {
+                match ty::get(base_t).sty {
+                    ty::ty_struct(base_id, ref substs) => {
+                        tuple_like = ty::is_tuple_struct(tcx, base_id);
+                        if tuple_like {
+                            debug!("tuple struct named {}", ppaux::ty_to_string(tcx, base_t));
+                            let fields = ty::lookup_struct_fields(tcx, base_id);
+                            lookup_tup_field_ty(tcx, base_id, fields.as_slice(),
+                                                idx.node, &(*substs))
+                        } else {
+                            None
+                        }
+                    }
+                    ty::ty_tup(ref v) => {
+                        tuple_like = true;
+                        if idx.node < v.len() { Some(v[idx.node]) } else { None }
+                    }
+                    _ => None
+                }
+            });
+        match field_ty {
+            Some(field_ty) => {
+                fcx.write_ty(expr.id, field_ty);
+                fcx.write_autoderef_adjustment(base.id, autoderefs);
+                return;
+            }
+            None => {}
+        }
+        fcx.type_error_message(
+            expr.span,
+            |actual| {
+                if tuple_like {
+                    format!("attempted out-of-bounds tuple index `{}` on \
+                                    type `{}`",
+                                   idx.node,
+                                   actual)
+                } else {
+                    format!("attempted tuple index `{}` on type `{}`, but the \
+                                     type was not a tuple or tuple struct",
+                                    idx.node,
+                                    actual)
+                }
+            },
+            expr_t, None);
+
+        fcx.write_error(expr.id);
+    }
+
     fn check_struct_or_variant_fields(fcx: &FnCtxt,
                                       struct_ty: ty::t,
                                       span: Span,
@@ -4065,6 +4137,9 @@ fn check_struct_fields_on_error(fcx: &FnCtxt,
       ast::ExprField(ref base, ref field, ref tys) => {
         check_field(fcx, expr, lvalue_pref, &**base, field, tys.as_slice());
       }
+      ast::ExprTupField(ref base, idx, ref tys) => {
+        check_tup_field(fcx, expr, lvalue_pref, &**base, idx, tys.as_slice());
+      }
       ast::ExprIndex(ref base, ref idx) => {
           check_expr_with_lvalue_pref(fcx, &**base, lvalue_pref);
           check_expr(fcx, &**idx);
index eb630d0fc7bbe083ba7e88e393f1e6395a4f28b1..c08401375ca7dc441f9b0c579c990eebd1275b3a 100644 (file)
@@ -769,6 +769,10 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
             }
 
             rcx.visit_expr(&**head, ());
+            type_of_node_must_outlive(rcx,
+                                      infer::AddrOf(expr.span),
+                                      head.id,
+                                      ty::ReScope(expr.id));
 
             let repeating_scope = rcx.set_repeating_scope(body.id);
             rcx.visit_block(&**body, ());
index 742d22cc3793ff396dfdde686f2e67f1f69db63e..d1d76734941e8b68cac3fde546cd8f00bd02a144 100644 (file)
@@ -488,7 +488,9 @@ pub fn ensure_no_ty_param_bounds(ccx: &CrateCtxt,
                                  generics: &ast::Generics,
                                  thing: &'static str) {
     for ty_param in generics.ty_params.iter() {
-        for bound in ty_param.bounds.iter() {
+        let bounds = ty_param.bounds.iter();
+        let mut bounds = bounds.chain(ty_param.unbound.iter());
+        for bound in bounds {
             match *bound {
                 ast::TraitTyParamBound(..) | ast::UnboxedFnTyParamBound(..) => {
                     // According to accepted RFC #XXX, we should
@@ -1076,9 +1078,10 @@ fn add_unsized_bound(ccx: &CrateCtxt,
                      desc: &str,
                      span: Span) {
     let kind_id = ccx.tcx.lang_items.require(SizedTraitLangItem);
+
     match unbound {
         &Some(ast::TraitTyParamBound(ref tpb)) => {
-            // #FIXME(8559) currently requires the unbound to be built-in.
+            // FIXME(#8559) currently requires the unbound to be built-in.
             let trait_def_id = ty::trait_ref_to_def_id(ccx.tcx, tpb);
             match kind_id {
                 Ok(kind_id) if trait_def_id != kind_id => {
index 6af19d948e0e8b467c153ae03fb825d3394ae441..8e24fc1ad5bff80de9df5e5a5443f0ddd24bf2b4 100644 (file)
@@ -222,6 +222,7 @@ pub enum SawExprComponent<'a> {
 
         SawExprLoop(Option<token::InternedString>),
         SawExprField(token::InternedString),
+        SawExprTupField(uint),
         SawExprBreak(Option<token::InternedString>),
         SawExprAgain(Option<token::InternedString>),
 
@@ -276,6 +277,7 @@ fn saw_expr<'a>(node: &'a Expr_) -> SawExprComponent<'a> {
             ExprAssign(..)           => SawExprAssign,
             ExprAssignOp(op, _, _)   => SawExprAssignOp(op),
             ExprField(_, id, _)      => SawExprField(content(id.node)),
+            ExprTupField(_, id, _)   => SawExprTupField(id.node),
             ExprIndex(..)            => SawExprIndex,
             ExprPath(..)             => SawExprPath,
             ExprAddrOf(m, _)         => SawExprAddrOf(m),
index 305c18480f6690911110129febeb7134b644b2cf..86f56660d3a64ed3bbaa6e59b972959ce031f395 100644 (file)
@@ -153,27 +153,17 @@ fn stripped_filtered_line<'a>(s: &'a str) -> Option<&'a str> {
 local_data_key!(pub playground_krate: Option<String>)
 
 pub fn render(w: &mut fmt::Formatter, s: &str, print_toc: bool) -> fmt::Result {
-    extern fn block(ob: *mut hoedown_buffer, text: *const hoedown_buffer,
+    extern fn block(ob: *mut hoedown_buffer, orig_text: *const hoedown_buffer,
                     lang: *const hoedown_buffer, opaque: *mut libc::c_void) {
         unsafe {
-            if text.is_null() { return }
+            if orig_text.is_null() { return }
 
             let opaque = opaque as *mut hoedown_html_renderer_state;
             let my_opaque: &MyOpaque = &*((*opaque).opaque as *const MyOpaque);
-            slice::raw::buf_as_slice((*text).data, (*text).size as uint, |text| {
+            slice::raw::buf_as_slice((*orig_text).data, (*orig_text).size as uint,
+                                     |text| {
                 let origtext = str::from_utf8(text).unwrap();
                 debug!("docblock: ==============\n{}\n=======", text);
-                let mut lines = origtext.lines().filter(|l| {
-                    stripped_filtered_line(*l).is_none()
-                });
-                let text = lines.collect::<Vec<&str>>().connect("\n");
-
-                let buf = hoedown_buffer {
-                    data: text.as_bytes().as_ptr(),
-                    size: text.len() as libc::size_t,
-                    asize: text.len() as libc::size_t,
-                    unit: 0,
-                };
                 let rendered = if lang.is_null() {
                     false
                 } else {
@@ -181,7 +171,7 @@ pub fn render(w: &mut fmt::Formatter, s: &str, print_toc: bool) -> fmt::Result {
                                            (*lang).size as uint, |rlang| {
                         let rlang = str::from_utf8(rlang).unwrap();
                         if LangString::parse(rlang).notrust {
-                            (my_opaque.dfltblk)(ob, &buf, lang,
+                            (my_opaque.dfltblk)(ob, orig_text, lang,
                                                 opaque as *mut libc::c_void);
                             true
                         } else {
@@ -190,6 +180,10 @@ pub fn render(w: &mut fmt::Formatter, s: &str, print_toc: bool) -> fmt::Result {
                     })
                 };
 
+                let mut lines = origtext.lines().filter(|l| {
+                    stripped_filtered_line(*l).is_none()
+                });
+                let text = lines.collect::<Vec<&str>>().connect("\n");
                 if !rendered {
                     let mut s = String::new();
                     let id = playground_krate.get().map(|krate| {
index 000def0cc3b626d3b3a838b3a781e2f16baaba57..5e0004f2a2a3e04861cf4d1f8d6b5c1bff09bb03 100644 (file)
@@ -671,7 +671,7 @@ fn test_as_str() {
     #[test]
     #[should_fail]
     fn test_new_fail() {
-        let c_str = unsafe { CString::new(ptr::null(), false) };
+        let _c_str = unsafe { CString::new(ptr::null(), false) };
     }
 
     #[test]
index 9d921943313d8e206d125474e97b1afd9263f69a..3d42b91fef17eb817a56cee8073ef8e8b9b3e7de 100644 (file)
@@ -662,7 +662,7 @@ fn drop_new_task_ok() {
     #[test]
     fn block_and_wake() {
         let task = box Task::new();
-        let mut task = BlockedTask::block(task).wake().unwrap();
+        let task = BlockedTask::block(task).wake().unwrap();
         task.drop();
     }
 }
index b29200597aa1c03984e8ede35d9ea207eca32e79..733bc593922dedf32f399b21240bfee1843823d8 100644 (file)
@@ -2128,7 +2128,15 @@ fn read_struct_field<T>(&mut self,
         let mut obj = try!(expect!(self.pop(), Object));
 
         let value = match obj.pop(&name.to_string()) {
-            None => return Err(MissingFieldError(name.to_string())),
+            None => {
+                // Add a Null and try to parse it as an Option<_>
+                // to get None as a default value.
+                self.stack.push(Null);
+                match f(self) {
+                    Ok(x) => x,
+                    Err(_) => return Err(MissingFieldError(name.to_string())),
+                }
+            },
             Some(json) => {
                 self.stack.push(json);
                 try!(f(self))
@@ -2167,6 +2175,7 @@ fn read_tuple_struct_arg<T>(&mut self,
     }
 
     fn read_option<T>(&mut self, f: |&mut Decoder, bool| -> DecodeResult<T>) -> DecodeResult<T> {
+        debug!("read_option()");
         match self.pop() {
             Null => f(self, false),
             value => { self.stack.push(value); f(self, true) }
@@ -2372,6 +2381,33 @@ mod tests {
     use std::{i64, u64, f32, f64, io};
     use std::collections::TreeMap;
 
+    #[deriving(Decodable, Eq, PartialEq, Show)]
+    struct OptionData {
+        opt: Option<uint>,
+    }
+
+    #[test]
+    fn test_decode_option_none() {
+        let s ="{}";
+        let obj: OptionData = super::decode(s).unwrap();
+        assert_eq!(obj, OptionData { opt: None });
+    }
+
+    #[test]
+    fn test_decode_option_some() {
+        let s = "{ \"opt\": 10 }";
+        let obj: OptionData = super::decode(s).unwrap();
+        assert_eq!(obj, OptionData { opt: Some(10u) });
+    }
+
+    #[test]
+    fn test_decode_option_malformed() {
+        check_err::<OptionData>("{ \"opt\": [] }",
+                                ExpectedError("Number".to_string(), "[]".to_string()));
+        check_err::<OptionData>("{ \"opt\": false }",
+                                ExpectedError("Number".to_string(), "false".to_string()));
+    }
+
     #[deriving(PartialEq, Encodable, Decodable, Show)]
     enum Animal {
         Dog,
index 32b77be78a43806487c8d777556aec1de5525b45..cb4d33049d84fcb5e191ca45f3a6c7af3cc5c180 100644 (file)
@@ -298,7 +298,7 @@ mod test {
 
     use native;
 
-    use super::{queue, Queue};
+    use super::{queue};
 
     #[test]
     fn smoke() {
index 68a1c521f1942e3be312a816969d38811a35c75b..4e65082fe3ad23f83b61f47206c71867aff1392a 100644 (file)
@@ -540,6 +540,7 @@ pub enum Expr_ {
     ExprAssign(Gc<Expr>, Gc<Expr>),
     ExprAssignOp(BinOp, Gc<Expr>, Gc<Expr>),
     ExprField(Gc<Expr>, SpannedIdent, Vec<P<Ty>>),
+    ExprTupField(Gc<Expr>, Spanned<uint>, Vec<P<Ty>>),
     ExprIndex(Gc<Expr>, Gc<Expr>),
 
     /// Variable reference, possibly containing `::` and/or
index 64ab0e5cb191f442b448cabd015443baacff3fb6..6bd1fba4b58a390997ce0a08b5ea9cd67bdbc6fe 100644 (file)
@@ -120,6 +120,8 @@ fn expr_binary(&self, sp: Span, op: ast::BinOp,
     fn expr_mut_addr_of(&self, sp: Span, e: Gc<ast::Expr>) -> Gc<ast::Expr>;
     fn expr_field_access(&self, span: Span, expr: Gc<ast::Expr>,
                          ident: ast::Ident) -> Gc<ast::Expr>;
+    fn expr_tup_field_access(&self, sp: Span, expr: Gc<ast::Expr>,
+                             idx: uint) -> Gc<ast::Expr>;
     fn expr_call(&self, span: Span, expr: Gc<ast::Expr>,
                  args: Vec<Gc<ast::Expr>>) -> Gc<ast::Expr>;
     fn expr_call_ident(&self, span: Span, id: ast::Ident,
@@ -605,6 +607,16 @@ fn expr_field_access(&self, sp: Span, expr: Gc<ast::Expr>, ident: ast::Ident) ->
         let id = Spanned { node: ident, span: field_span };
         self.expr(sp, ast::ExprField(expr, id, Vec::new()))
     }
+    fn expr_tup_field_access(&self, sp: Span, expr: Gc<ast::Expr>, idx: uint) -> Gc<ast::Expr> {
+        let field_span = Span {
+            lo: sp.lo - Pos::from_uint(idx.to_string().len()),
+            hi: sp.hi,
+            expn_info: sp.expn_info,
+        };
+
+        let id = Spanned { node: idx, span: field_span };
+        self.expr(sp, ast::ExprTupField(expr, id, Vec::new()))
+    }
     fn expr_addr_of(&self, sp: Span, e: Gc<ast::Expr>) -> Gc<ast::Expr> {
         self.expr(sp, ast::ExprAddrOf(ast::MutImmutable, e))
     }
index b3bb01e1d0409881735cc831a04f895e74edbdfe..0bb32c73ca264ce666fb956819cb376515be6efa 100644 (file)
@@ -49,11 +49,16 @@ struct Context<'a, 'b:'a> {
     name_types: HashMap<String, ArgumentType>,
     name_ordering: Vec<String>,
 
-    /// The latest consecutive literal strings
-    literal: Option<String>,
+    /// The latest consecutive literal strings, or empty if there weren't any.
+    literal: String,
 
-    /// Collection of the compiled `rt::Piece` structures
+    /// Collection of the compiled `rt::Argument` structures
     pieces: Vec<Gc<ast::Expr>>,
+    /// Collection of string literals
+    str_pieces: Vec<Gc<ast::Expr>>,
+    /// Stays `true` if all formatting parameters are default (as in "{}{}").
+    all_pieces_simple: bool,
+
     name_positions: HashMap<String, uint>,
     method_statics: Vec<Gc<ast::Item>>,
 
@@ -370,28 +375,21 @@ fn trans_count(&self, c: parse::Count) -> Gc<ast::Expr> {
         }
     }
 
-    /// Translate the accumulated string literals to a static `rt::Piece`
-    fn trans_literal_string(&mut self) -> Option<Gc<ast::Expr>> {
+    /// Translate the accumulated string literals to a literal expression
+    fn trans_literal_string(&mut self) -> Gc<ast::Expr> {
         let sp = self.fmtsp;
-        self.literal.take().map(|s| {
-            let s = token::intern_and_get_ident(s.as_slice());
-            self.ecx.expr_call_global(sp,
-                                      self.rtpath("String"),
-                                      vec!(
-                self.ecx.expr_str(sp, s)
-            ))
-        })
+        let s = token::intern_and_get_ident(self.literal.as_slice());
+        self.literal.clear();
+        self.ecx.expr_str(sp, s)
     }
 
-    /// Translate a `parse::Piece` to a static `rt::Piece`
+    /// Translate a `parse::Piece` to a static `rt::Argument` or append
+    /// to the `literal` string.
     fn trans_piece(&mut self, piece: &parse::Piece) -> Option<Gc<ast::Expr>> {
         let sp = self.fmtsp;
         match *piece {
             parse::String(s) => {
-                match self.literal {
-                    Some(ref mut sb) => sb.push_str(s),
-                    ref mut empty => *empty = Some(String::from_str(s)),
-                }
+                self.literal.push_str(s);
                 None
             }
             parse::Argument(ref arg) => {
@@ -420,8 +418,25 @@ fn trans_piece(&mut self, piece: &parse::Piece) -> Option<Gc<ast::Expr>> {
                     }
                 };
 
-                // Translate the format
+                let simple_arg = parse::Argument {
+                    position: parse::ArgumentNext,
+                    format: parse::FormatSpec {
+                        fill: arg.format.fill,
+                        align: parse::AlignUnknown,
+                        flags: 0,
+                        precision: parse::CountImplied,
+                        width: parse::CountImplied,
+                        ty: arg.format.ty
+                    }
+                };
+
                 let fill = match arg.format.fill { Some(c) => c, None => ' ' };
+
+                if *arg != simple_arg || fill != ' ' {
+                    self.all_pieces_simple = false;
+                }
+
+                // Translate the format
                 let fill = self.ecx.expr_lit(sp, ast::LitChar(fill));
                 let align = match arg.format.align {
                     parse::AlignLeft => {
@@ -450,14 +465,33 @@ fn trans_piece(&mut self, piece: &parse::Piece) -> Option<Gc<ast::Expr>> {
                     self.ecx.field_imm(sp, self.ecx.ident_of("width"), width)));
 
                 let path = self.ecx.path_global(sp, self.rtpath("Argument"));
-                let s = self.ecx.expr_struct(sp, path, vec!(
+                Some(self.ecx.expr_struct(sp, path, vec!(
                     self.ecx.field_imm(sp, self.ecx.ident_of("position"), pos),
-                    self.ecx.field_imm(sp, self.ecx.ident_of("format"), fmt)));
-                Some(self.ecx.expr_call_global(sp, self.rtpath("Argument"), vec!(s)))
+                    self.ecx.field_imm(sp, self.ecx.ident_of("format"), fmt))))
             }
         }
     }
 
+    fn item_static_array(&self,
+                         name: ast::Ident,
+                         piece_ty: Gc<ast::Ty>,
+                         pieces: Vec<Gc<ast::Expr>>)
+        -> ast::Stmt
+    {
+        let pieces_len = self.ecx.expr_uint(self.fmtsp, pieces.len());
+        let fmt = self.ecx.expr_vec(self.fmtsp, pieces);
+        let ty = ast::TyFixedLengthVec(
+            piece_ty,
+            pieces_len
+        );
+        let ty = self.ecx.ty(self.fmtsp, ty);
+        let st = ast::ItemStatic(ty, ast::MutImmutable, fmt);
+        let item = self.ecx.item(self.fmtsp, name,
+                                 self.static_attrs(), st);
+        let decl = respan(self.fmtsp, ast::DeclItem(item));
+        respan(self.fmtsp, ast::StmtDecl(box(GC) decl, ast::DUMMY_NODE_ID))
+    }
+
     /// Actually builds the expression which the iformat! block will be expanded
     /// to
     fn to_expr(&self, invocation: Invocation) -> Gc<ast::Expr> {
@@ -476,30 +510,31 @@ fn to_expr(&self, invocation: Invocation) -> Gc<ast::Expr> {
 
         // Next, build up the static array which will become our precompiled
         // format "string"
-        let fmt = self.ecx.expr_vec(self.fmtsp, self.pieces.clone());
-        let piece_ty = self.ecx.ty_path(self.ecx.path_all(
+        let static_str_name = self.ecx.ident_of("__STATIC_FMTSTR");
+        let static_lifetime = self.ecx.lifetime(self.fmtsp, self.ecx.ident_of("'static").name);
+        let piece_ty = self.ecx.ty_rptr(
                 self.fmtsp,
-                true, vec!(
-                    self.ecx.ident_of("std"),
-                    self.ecx.ident_of("fmt"),
-                    self.ecx.ident_of("rt"),
-                    self.ecx.ident_of("Piece")),
-                vec!(self.ecx.lifetime(self.fmtsp,
-                                       self.ecx.ident_of("'static").name)),
-                Vec::new()
-            ), None);
-        let ty = ast::TyFixedLengthVec(
-            piece_ty,
-            self.ecx.expr_uint(self.fmtsp, self.pieces.len())
-        );
-        let ty = self.ecx.ty(self.fmtsp, ty);
-        let st = ast::ItemStatic(ty, ast::MutImmutable, fmt);
-        let static_name = self.ecx.ident_of("__STATIC_FMTSTR");
-        let item = self.ecx.item(self.fmtsp, static_name,
-                                 self.static_attrs(), st);
-        let decl = respan(self.fmtsp, ast::DeclItem(item));
-        lets.push(box(GC) respan(self.fmtsp,
-                                 ast::StmtDecl(box(GC) decl, ast::DUMMY_NODE_ID)));
+                self.ecx.ty_ident(self.fmtsp, self.ecx.ident_of("str")),
+                Some(static_lifetime),
+                ast::MutImmutable);
+        lets.push(box(GC) self.item_static_array(static_str_name,
+                                                 piece_ty,
+                                                 self.str_pieces.clone()));
+
+        // Then, build up the static array which will store our precompiled
+        // nonstandard placeholders, if there are any.
+        let static_args_name = self.ecx.ident_of("__STATIC_FMTARGS");
+        if !self.all_pieces_simple {
+            let piece_ty = self.ecx.ty_path(self.ecx.path_all(
+                    self.fmtsp,
+                    true, self.rtpath("Argument"),
+                    vec![static_lifetime],
+                    vec![]
+                ), None);
+            lets.push(box(GC) self.item_static_array(static_args_name,
+                                                     piece_ty,
+                                                     self.pieces.clone()));
+        }
 
         // Right now there is a bug such that for the expression:
         //      foo(bar(&1))
@@ -545,13 +580,21 @@ fn to_expr(&self, invocation: Invocation) -> Gc<ast::Expr> {
         }
 
         // Now create the fmt::Arguments struct with all our locals we created.
-        let fmt = self.ecx.expr_ident(self.fmtsp, static_name);
+        let pieces = self.ecx.expr_ident(self.fmtsp, static_str_name);
         let args_slice = self.ecx.expr_ident(self.fmtsp, slicename);
+
+        let (fn_name, fn_args) = if self.all_pieces_simple {
+            ("new", vec![pieces, args_slice])
+        } else {
+            let fmt = self.ecx.expr_ident(self.fmtsp, static_args_name);
+            ("with_placeholders", vec![pieces, fmt, args_slice])
+        };
+
         let result = self.ecx.expr_call_global(self.fmtsp, vec!(
                 self.ecx.ident_of("std"),
                 self.ecx.ident_of("fmt"),
                 self.ecx.ident_of("Arguments"),
-                self.ecx.ident_of("new")), vec!(fmt, args_slice));
+                self.ecx.ident_of(fn_name)), fn_args);
 
         // We did all the work of making sure that the arguments
         // structure is safe, so we can safely have an unsafe block.
@@ -718,8 +761,10 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, sp: Span,
         name_ordering: name_ordering,
         nest_level: 0,
         next_arg: 0,
-        literal: None,
+        literal: String::new(),
         pieces: Vec::new(),
+        str_pieces: Vec::new(),
+        all_pieces_simple: true,
         method_statics: Vec::new(),
         fmtsp: sp,
     };
@@ -739,8 +784,8 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, sp: Span,
                 cx.verify_piece(&piece);
                 match cx.trans_piece(&piece) {
                     Some(piece) => {
-                        cx.trans_literal_string().map(|piece|
-                                                      cx.pieces.push(piece));
+                        let s = cx.trans_literal_string();
+                        cx.str_pieces.push(s);
                         cx.pieces.push(piece);
                     }
                     None => {}
@@ -758,7 +803,10 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, sp: Span,
         }
         None => {}
     }
-    cx.trans_literal_string().map(|piece| cx.pieces.push(piece));
+    if !cx.literal.is_empty() {
+        let s = cx.trans_literal_string();
+        cx.str_pieces.push(s);
+    }
 
     // Make sure that all arguments were used and all arguments have types.
     for (i, ty) in cx.arg_types.iter().enumerate() {
index 0c41db7ecd685180b9d58b31b471906b74ca19c3..808e671f868d3a7d573a9fe8adf2fcc4d8c6ad4f 100644 (file)
@@ -766,7 +766,9 @@ fn expand_wrapper(cx: &ExtCtxt,
         cx.view_use_glob(sp, ast::Inherited, ids_ext(path))
     }).collect();
 
-    let stmt_let_ext_cx = cx.stmt_let(sp, false, id_ext("ext_cx"), cx_expr);
+    // Explicitly borrow to avoid moving from the invoker (#16992)
+    let cx_expr_borrow = cx.expr_addr_of(sp, cx.expr_deref(sp, cx_expr));
+    let stmt_let_ext_cx = cx.stmt_let(sp, false, id_ext("ext_cx"), cx_expr_borrow);
 
     cx.expr_block(cx.block_all(sp, uses, vec!(stmt_let_ext_cx), Some(expr)))
 }
index 7deabed04b824505eb4c754f9ce60f35f2bffa5b..30b7317fa56f181df008ded97ff8f3e4540deeab 100644 (file)
@@ -134,6 +134,10 @@ fn fold_ident(&mut self, i: Ident) -> Ident {
         noop_fold_ident(i, self)
     }
 
+    fn fold_uint(&mut self, i: uint) -> uint {
+        noop_fold_uint(i, self)
+    }
+
     fn fold_path(&mut self, p: &Path) -> Path {
         noop_fold_path(p, self)
     }
@@ -466,6 +470,10 @@ pub fn noop_fold_ident<T: Folder>(i: Ident, _: &mut T) -> Ident {
     i
 }
 
+pub fn noop_fold_uint<T: Folder>(i: uint, _: &mut T) -> uint {
+    i
+}
+
 pub fn noop_fold_path<T: Folder>(p: &Path, fld: &mut T) -> Path {
     ast::Path {
         span: fld.new_span(p.span),
@@ -1180,6 +1188,11 @@ pub fn noop_fold_expr<T: Folder>(e: Gc<Expr>, folder: &mut T) -> Gc<Expr> {
                       respan(id.span, folder.fold_ident(id.node)),
                       tys.iter().map(|&x| folder.fold_ty(x)).collect())
         }
+        ExprTupField(el, id, ref tys) => {
+            ExprTupField(folder.fold_expr(el),
+                      respan(id.span, folder.fold_uint(id.node)),
+                      tys.iter().map(|&x| folder.fold_ty(x)).collect())
+        }
         ExprIndex(el, er) => {
             ExprIndex(folder.fold_expr(el), folder.fold_expr(er))
         }
index 5273addf4f57d73d7253540e5c34545d294591c5..9ed9e626c3d32f40150363d6e56b806d146084c2 100644 (file)
@@ -35,6 +35,8 @@ pub enum ObsoleteSyntax {
     ObsoleteManagedType,
     ObsoleteManagedExpr,
     ObsoleteImportRenaming,
+    ObsoleteSubsliceMatch,
+    ObsoleteExternCrateRenaming,
 }
 
 pub trait ParserObsoleteMethods {
@@ -87,6 +89,14 @@ fn obsolete(&mut self, sp: Span, kind: ObsoleteSyntax) {
             ObsoleteImportRenaming => (
                 "`use foo = bar` syntax",
                 "write `use bar as foo` instead"
+            ),
+            ObsoleteSubsliceMatch => (
+                "subslice match syntax",
+                "instead of `..xs`, write `xs..` in a pattern"
+            ),
+            ObsoleteExternCrateRenaming => (
+                "`extern crate foo = bar` syntax",
+                "write `extern crate bar as foo` instead"
             )
         };
 
index 936cabc54d1788717cc46700396ebce4c80e3771..328bdf883356c9234c28d98f52e3791d7786be0b 100644 (file)
@@ -23,7 +23,7 @@
 use ast::{Expr, Expr_, ExprAddrOf, ExprMatch, ExprAgain};
 use ast::{ExprAssign, ExprAssignOp, ExprBinary, ExprBlock, ExprBox};
 use ast::{ExprBreak, ExprCall, ExprCast};
-use ast::{ExprField, ExprFnBlock, ExprIf, ExprIndex};
+use ast::{ExprField, ExprTupField, ExprFnBlock, ExprIf, ExprIndex};
 use ast::{ExprLit, ExprLoop, ExprMac};
 use ast::{ExprMethodCall, ExprParen, ExprPath, ExprProc};
 use ast::{ExprRepeat, ExprRet, ExprStruct, ExprTup, ExprUnary, ExprUnboxedFn};
@@ -1937,6 +1937,11 @@ pub fn mk_field(&mut self, expr: Gc<Expr>, ident: ast::SpannedIdent,
         ExprField(expr, ident, tys)
     }
 
+    pub fn mk_tup_field(&mut self, expr: Gc<Expr>, idx: codemap::Spanned<uint>,
+                    tys: Vec<P<Ty>>) -> ast::Expr_ {
+        ExprTupField(expr, idx, tys)
+    }
+
     pub fn mk_assign_op(&mut self, binop: ast::BinOp,
                         lhs: Gc<Expr>, rhs: Gc<Expr>) -> ast::Expr_ {
         ExprAssignOp(binop, lhs, rhs)
@@ -2286,6 +2291,41 @@ pub fn parse_dot_or_call_expr_with(&mut self, e0: Gc<Expr>) -> Gc<Expr> {
                         }
                     }
                   }
+                  token::LIT_INTEGER(n) => {
+                    let index = n.as_str();
+                    let dot = self.last_span.hi;
+                    hi = self.span.hi;
+                    self.bump();
+                    let (_, tys) = if self.eat(&token::MOD_SEP) {
+                        self.expect_lt();
+                        self.parse_generic_values_after_lt()
+                    } else {
+                        (Vec::new(), Vec::new())
+                    };
+
+                    let num = from_str::<uint>(index);
+                    match num {
+                        Some(n) => {
+                            let id = spanned(dot, hi, n);
+                            let field = self.mk_tup_field(e, id, tys);
+                            e = self.mk_expr(lo, hi, field);
+                        }
+                        None => {
+                            let last_span = self.last_span;
+                            self.span_err(last_span, "invalid tuple or tuple struct index");
+                        }
+                    }
+                  }
+                  token::LIT_FLOAT(n) => {
+                    self.bump();
+                    let last_span = self.last_span;
+                    self.span_err(last_span,
+                                  format!("unexpected token: `{}`", n.as_str()).as_slice());
+                    self.span_note(last_span,
+                                   "try parenthesizing the first index; e.g., `(foo.0).1`");
+                    self.abort_if_errors();
+
+                  }
                   _ => self.unexpected()
                 }
                 continue;
@@ -2858,43 +2898,42 @@ fn parse_pat_vec_elements(
         let mut before_slice = true;
 
         while self.token != token::RBRACKET {
-            if first { first = false; }
-            else { self.expect(&token::COMMA); }
+            if first {
+                first = false;
+            } else {
+                self.expect(&token::COMMA);
+            }
 
-            let mut is_slice = false;
             if before_slice {
                 if self.token == token::DOTDOT {
                     self.bump();
-                    is_slice = true;
-                    before_slice = false;
-                }
-            }
 
-            if is_slice {
-                if self.token == token::COMMA || self.token == token::RBRACKET {
-                    slice = Some(box(GC) ast::Pat {
-                        id: ast::DUMMY_NODE_ID,
-                        node: PatWild(PatWildMulti),
-                        span: self.span,
-                    })
-                } else {
-                    let subpat = self.parse_pat();
-                    match *subpat {
-                        ast::Pat { node: PatIdent(_, _, _), .. } => {
-                            slice = Some(subpat);
-                        }
-                        ast::Pat { span, .. } => self.span_fatal(
-                            span, "expected an identifier or nothing"
-                        )
+                    if self.token == token::COMMA ||
+                            self.token == token::RBRACKET {
+                        slice = Some(box(GC) ast::Pat {
+                            id: ast::DUMMY_NODE_ID,
+                            node: PatWild(PatWildMulti),
+                            span: self.span,
+                        });
+                        before_slice = false;
+                    } else {
+                        let _ = self.parse_pat();
+                        let span = self.span;
+                        self.obsolete(span, ObsoleteSubsliceMatch);
                     }
+                    continue
                 }
+            }
+
+            let subpat = self.parse_pat();
+            if before_slice && self.token == token::DOTDOT {
+                self.bump();
+                slice = Some(subpat);
+                before_slice = false;
+            } else if before_slice {
+                before.push(subpat);
             } else {
-                let subpat = self.parse_pat();
-                if before_slice {
-                    before.push(subpat);
-                } else {
-                    after.push(subpat);
-                }
+                after.push(subpat);
             }
         }
 
@@ -3065,7 +3104,11 @@ pub fn parse_pat(&mut self) -> Gc<Pat> {
             // These expressions are limited to literals (possibly
             // preceded by unary-minus) or identifiers.
             let val = self.parse_literal_maybe_minus();
-            if self.eat(&token::DOTDOT) {
+            if self.token == token::DOTDOT &&
+                    self.look_ahead(1, |t| {
+                        *t != token::COMMA && *t != token::RBRACKET
+                    }) {
+                self.bump();
                 let end = if is_ident_or_path(&self.token) {
                     let path = self.parse_path(LifetimeAndTypesWithColons)
                                    .path;
@@ -3106,7 +3149,10 @@ pub fn parse_pat(&mut self) -> Gc<Pat> {
                 }
             });
 
-            if self.look_ahead(1, |t| *t == token::DOTDOT) {
+            if self.look_ahead(1, |t| *t == token::DOTDOT) &&
+                    self.look_ahead(2, |t| {
+                        *t != token::COMMA && *t != token::RBRACKET
+                    }) {
                 let start = self.parse_expr_res(RESTRICT_NO_BAR_OP);
                 self.eat(&token::DOTDOT);
                 let end = self.parse_expr_res(RESTRICT_NO_BAR_OP);
@@ -4777,11 +4823,7 @@ fn parse_item_extern_crate(&mut self,
                     self.bump();
                     let path = self.parse_str();
                     let span = self.span;
-                    self.span_warn(span,
-                            format!("this extern crate syntax is deprecated. \
-                            Use: extern crate \"{}\" as {};",
-                            path.ref0().get(), the_ident.as_str() ).as_slice()
-                    );
+                    self.obsolete(span, ObsoleteExternCrateRenaming);
                     Some(path)
                 } else {None};
 
index d5bc1bfe956fbd14f99fdd6c0aca02f400b2884e..a4dff45ad359f96f31bf40b58c049e1f9e4e422d 100644 (file)
@@ -1607,6 +1607,18 @@ pub fn print_expr(&mut self, expr: &ast::Expr) -> IoResult<()> {
                     try!(word(&mut self.s, ">"));
                 }
             }
+            ast::ExprTupField(ref expr, id, ref tys) => {
+                try!(self.print_expr(&**expr));
+                try!(word(&mut self.s, "."));
+                try!(self.print_uint(id.node));
+                if tys.len() > 0u {
+                    try!(word(&mut self.s, "::<"));
+                    try!(self.commasep(
+                        Inconsistent, tys.as_slice(),
+                        |s, ty| s.print_type_ref(ty)));
+                    try!(word(&mut self.s, ">"));
+                }
+            }
             ast::ExprIndex(ref expr, ref index) => {
                 try!(self.print_expr(&**expr));
                 try!(word(&mut self.s, "["));
@@ -1738,6 +1750,10 @@ pub fn print_ident(&mut self, ident: ast::Ident) -> IoResult<()> {
         self.ann.post(self, NodeIdent(&ident))
     }
 
+    pub fn print_uint(&mut self, i: uint) -> IoResult<()> {
+        word(&mut self.s, i.to_string().as_slice())
+    }
+
     pub fn print_name(&mut self, name: ast::Name) -> IoResult<()> {
         try!(word(&mut self.s, token::get_name(name).get()));
         self.ann.post(self, NodeName(&name))
@@ -1912,13 +1928,13 @@ pub fn print_pat(&mut self, pat: &ast::Pat) -> IoResult<()> {
                                    |s, p| s.print_pat(&**p)));
                 for p in slice.iter() {
                     if !before.is_empty() { try!(self.word_space(",")); }
+                    try!(self.print_pat(&**p));
                     match **p {
                         ast::Pat { node: ast::PatWild(ast::PatWildMulti), .. } => {
                             // this case is handled by print_pat
                         }
                         _ => try!(word(&mut self.s, "..")),
                     }
-                    try!(self.print_pat(&**p));
                     if !after.is_empty() { try!(self.word_space(",")); }
                 }
                 try!(self.commasep(Inconsistent,
index 65e192e8437f3a6e9490b73d7f5401ea698097c3..50b42ea2c0fd90fcd8df36e514ca24318f8b96fe 100644 (file)
@@ -830,6 +830,12 @@ pub fn walk_expr<E: Clone, V: Visitor<E>>(visitor: &mut V, expression: &Expr, en
                 visitor.visit_ty(&**typ, env.clone())
             }
         }
+        ExprTupField(ref subexpression, _, ref types) => {
+            visitor.visit_expr(&**subexpression, env.clone());
+            for typ in types.iter() {
+                visitor.visit_ty(&**typ, env.clone())
+            }
+        }
         ExprIndex(ref main_expression, ref index_expression) => {
             visitor.visit_expr(&**main_expression, env.clone());
             visitor.visit_expr(&**index_expression, env.clone())
index 98dd129f3d2518e092d4f562a4afed25251c4ef6..09dc8166908d92061944c4783888630f777fe38b 100644 (file)
@@ -527,7 +527,6 @@ mod uuidtest {
     use super::{Uuid, VariantMicrosoft, VariantNCS, VariantRFC4122,
                 Version1Mac, Version2Dce, Version3Md5, Version4Random,
                 Version5Sha1};
-    use std::io::MemWriter;
     use std::rand;
 
     #[test]
@@ -798,7 +797,6 @@ fn test_rand_rand() {
     #[test]
     fn test_serialize_round_trip() {
         use serialize::json;
-        use serialize::{Encodable, Decodable};
 
         let u = Uuid::new_v4();
         let s = json::encode(&u);
@@ -809,7 +807,7 @@ fn test_serialize_round_trip() {
     #[test]
     fn test_bad_decode() {
         use serialize::json;
-        use serialize::{Encodable, Decodable};
+        use serialize::{Decodable};
 
         let js_good = json::String("a1a2a3a4a5a6a7a8a1a2a3a4a5a6a7a8".to_string());
         let js_bad1 = json::String("a1a2a3a4a5a6a7a8a1a2a3a4a5a6a7ah".to_string());
index 0c76d14852e08695cf9ebc83272b1c2979741080..05ecb9def9b5c10e4dcbfde22012cbb20787cd95 100644 (file)
@@ -1,12 +1,42 @@
-// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
+// The Computer Language Benchmarks Game
+// http://benchmarksgame.alioth.debian.org/
 //
-// 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.
+// contributed by the Rust Project Developers
+
+// Copyright (c) 2012-2014 The Rust Project Developers
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// - Redistributions of source code must retain the above copyright
+//   notice, this list of conditions and the following disclaimer.
+//
+// - Redistributions in binary form must reproduce the above copyright
+//   notice, this list of conditions and the following disclaimer in
+//   the documentation and/or other materials provided with the
+//   distribution.
+//
+// - Neither the name of "The Computer Language Benchmarks Game" nor
+//   the name of "The Computer Language Shootout Benchmarks" nor the
+//   names of its contributors may be used to endorse or promote
+//   products derived from this software without specific prior
+//   written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+// OF THE POSSIBILITY OF SUCH DAMAGE.
 
 // no-pretty-expanded
 
index 5a077b377475c3aee20a8466764aabc59c9c2aa1..9e30a5124771929c3610057ee0f5136746b85d6b 100644 (file)
@@ -1,12 +1,42 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
+// The Computer Language Benchmarks Game
+// http://benchmarksgame.alioth.debian.org/
 //
-// 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.
+// contributed by the Rust Project Developers
+
+// Copyright (c) 2011-2014 The Rust Project Developers
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// - Redistributions of source code must retain the above copyright
+//   notice, this list of conditions and the following disclaimer.
+//
+// - Redistributions in binary form must reproduce the above copyright
+//   notice, this list of conditions and the following disclaimer in
+//   the documentation and/or other materials provided with the
+//   distribution.
+//
+// - Neither the name of "The Computer Language Benchmarks Game" nor
+//   the name of "The Computer Language Shootout Benchmarks" nor the
+//   names of its contributors may be used to endorse or promote
+//   products derived from this software without specific prior
+//   written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+// OF THE POSSIBILITY OF SUCH DAMAGE.
 
 static PI: f64 = 3.141592653589793;
 static SOLAR_MASS: f64 = 4.0 * PI * PI;
index fdd711d22c760f93e9eb79f1ffb679f0746f0fba..52defe6a2767d5d2bee768e4061a4b5fcda16697 100644 (file)
@@ -1,12 +1,42 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
+// The Computer Language Benchmarks Game
+// http://benchmarksgame.alioth.debian.org/
 //
-// 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.
+// contributed by the Rust Project Developers
+
+// Copyright (c) 2013-2014 The Rust Project Developers
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// - Redistributions of source code must retain the above copyright
+//   notice, this list of conditions and the following disclaimer.
+//
+// - Redistributions in binary form must reproduce the above copyright
+//   notice, this list of conditions and the following disclaimer in
+//   the documentation and/or other materials provided with the
+//   distribution.
+//
+// - Neither the name of "The Computer Language Benchmarks Game" nor
+//   the name of "The Computer Language Shootout Benchmarks" nor the
+//   names of its contributors may be used to endorse or promote
+//   products derived from this software without specific prior
+//   written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+// OF THE POSSIBILITY OF SUCH DAMAGE.
 
 // ignore-pretty very bad with line comments
 // ignore-android doesn't terminate?
diff --git a/src/test/compile-fail/borrow-tuple-fields.rs b/src/test/compile-fail/borrow-tuple-fields.rs
new file mode 100644 (file)
index 0000000..519bad4
--- /dev/null
@@ -0,0 +1,42 @@
+// Copyright 2014 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(tuple_indexing)]
+
+struct Foo(Box<int>, int);
+
+struct Bar(int, int);
+
+fn main() {
+    let x = (box 1i, 2i);
+    let r = &x.0;
+    let y = x; //~ ERROR cannot move out of `x` because it is borrowed
+
+    let mut x = (1i, 2i);
+    let a = &x.0;
+    let b = &mut x.0; //~ ERROR cannot borrow `x.0` as mutable because it is also borrowed as
+
+    let mut x = (1i, 2i);
+    let a = &mut x.0;
+    let b = &mut x.0; //~ ERROR cannot borrow `x.0` as mutable more than once at a time
+
+
+    let x = Foo(box 1i, 2i);
+    let r = &x.0;
+    let y = x; //~ ERROR cannot move out of `x` because it is borrowed
+
+    let mut x = Bar(1i, 2i);
+    let a = &x.0;
+    let b = &mut x.0; //~ ERROR cannot borrow `x.0` as mutable because it is also borrowed as
+
+    let mut x = Bar(1i, 2i);
+    let a = &mut x.0;
+    let b = &mut x.0; //~ ERROR cannot borrow `x.0` as mutable more than once at a time
+}
diff --git a/src/test/compile-fail/borrowck-for-loop-head-linkage.rs b/src/test/compile-fail/borrowck-for-loop-head-linkage.rs
new file mode 100644 (file)
index 0000000..600c0ac
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+    let mut vector = vec![1u, 2];
+    for &x in vector.iter() {
+        let cap = vector.capacity();
+        vector.grow(cap, &0u);      //~ ERROR cannot borrow
+        *vector.get_mut(1u) = 5u;   //~ ERROR cannot borrow
+    }
+}
+
index d87557a46f753d2aa5231836a9fd53a982512bb4..d3c6a280e8c2a2dcabd6c582f56b758f47599250 100644 (file)
@@ -25,7 +25,7 @@ pub fn main() {
     );
     let x: &[Foo] = x.as_slice();
     match x {
-        [_, ..tail] => {
+        [_, tail..] => {
             match tail {
                 [Foo { string: a }, //~ ERROR cannot move out of dereference of `&`-pointer
                  Foo { string: b }] => {
index 53ebaa38fddba7f4ddf796758ef814980ff7c8b7..d256b033298ed988d7d6b292eaaed6b426b2cfdf 100644 (file)
@@ -8,11 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(advanced_slice_patterns)]
+
 fn a<'a>() -> &'a [int] {
     let vec = vec!(1, 2, 3, 4);
     let vec: &[int] = vec.as_slice(); //~ ERROR does not live long enough
     let tail = match vec {
-        [_, ..tail] => tail,
+        [_, tail..] => tail,
         _ => fail!("a")
     };
     tail
@@ -22,7 +24,7 @@ fn b<'a>() -> &'a [int] {
     let vec = vec!(1, 2, 3, 4);
     let vec: &[int] = vec.as_slice(); //~ ERROR does not live long enough
     let init = match vec {
-        [..init, _] => init,
+        [init.., _] => init,
         _ => fail!("b")
     };
     init
@@ -32,7 +34,7 @@ fn c<'a>() -> &'a [int] {
     let vec = vec!(1, 2, 3, 4);
     let vec: &[int] = vec.as_slice(); //~ ERROR does not live long enough
     let slice = match vec {
-        [_, ..slice, _] => slice,
+        [_, slice.., _] => slice,
         _ => fail!("c")
     };
     slice
index 393ec8b0b1b3ba9d80e8a7a44e6a2e03dbbf9a60..cc1dbc81955435b7aab2029a2b0c3ff4d54c7660 100644 (file)
@@ -12,7 +12,7 @@ fn a() {
     let mut v = vec!(1, 2, 3);
     let vb: &mut [int] = v.as_mut_slice();
     match vb {
-        [_a, ..tail] => {
+        [_a, tail..] => {
             v.push(tail[0] + tail[1]); //~ ERROR cannot borrow
         }
         _ => {}
index 7b092d16eec69d9d9d0e298339265a74f757802d..cb8762f44fb7932ceef6283b1648635788e741cf 100644 (file)
@@ -11,7 +11,7 @@
 fn main() {
     let mut a = [1i, 2, 3, 4];
     let t = match a {
-        [1, 2, ..tail] => tail,
+        [1, 2, tail..] => tail,
         _ => unreachable!()
     };
     a[0] = 0; //~ ERROR cannot assign to `a[..]` because it is borrowed
index 4a56f9821065bfd51163d0d39d9eba6fa5392bd8..2eec788785605183711b9cbaa8802d2e7e41f058 100644 (file)
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(advanced_slice_patterns)]
 
 fn a() {
     let mut vec = [box 1i, box 2, box 3];
@@ -22,7 +23,7 @@ fn b() {
     let mut vec = vec!(box 1i, box 2, box 3);
     let vec: &mut [Box<int>] = vec.as_mut_slice();
     match vec {
-        [.._b] => {
+        [_b..] => {
             vec[0] = box 4; //~ ERROR cannot assign
         }
     }
@@ -33,7 +34,7 @@ fn c() {
     let vec: &mut [Box<int>] = vec.as_mut_slice();
     match vec {
         [_a,         //~ ERROR cannot move out
-         .._b] => {  //~^ NOTE attempting to move value to here
+         _b..] => {  //~^ NOTE attempting to move value to here
 
             // Note: `_a` is *moved* here, but `b` is borrowing,
             // hence illegal.
@@ -50,7 +51,7 @@ fn d() {
     let mut vec = vec!(box 1i, box 2, box 3);
     let vec: &mut [Box<int>] = vec.as_mut_slice();
     match vec {
-        [.._a,     //~ ERROR cannot move out
+        [_a..,     //~ ERROR cannot move out
          _b] => {} //~ NOTE attempting to move value to here
         _ => {}
     }
index 57a276bec81bc4f8a78f908e269de05bf0ae7416..2c9cf7d1b65be0abf147be7a86b1e360afb9a0f9 100644 (file)
@@ -12,7 +12,7 @@ fn a<'a>() -> &'a int {
     let vec = vec!(1, 2, 3, 4);
     let vec: &[int] = vec.as_slice(); //~ ERROR `vec` does not live long enough
     let tail = match vec {
-        [_a, ..tail] => &tail[0],
+        [_a, tail..] => &tail[0],
         _ => fail!("foo")
     };
     tail
diff --git a/src/test/compile-fail/feature-gate-advanced-slice-features.rs b/src/test/compile-fail/feature-gate-advanced-slice-features.rs
new file mode 100644 (file)
index 0000000..97d593d
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+    let x = [ 1i, 2, 3, 4, 5 ];
+    match x {
+        [ xs.., 4, 5 ] => {}    //~ ERROR multiple-element slice matches
+        [ 1, xs.., 5 ] => {}    //~ ERROR multiple-element slice matches
+        [ 1, 2, xs.. ] => {}    // OK without feature gate
+    }
+}
+
diff --git a/src/test/compile-fail/generic-lifetime-trait-impl.rs b/src/test/compile-fail/generic-lifetime-trait-impl.rs
new file mode 100644 (file)
index 0000000..8b52324
--- /dev/null
@@ -0,0 +1,30 @@
+// Copyright 2012 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.
+
+// This code used to produce an ICE on the definition of trait Bar
+// with the following message:
+//
+// Type parameter out of range when substituting in region 'a (root
+// type=fn(Self) -> 'astr) (space=FnSpace, index=0)
+//
+// Regression test for issue #16218.
+
+trait Bar<'a> {}
+
+trait Foo<'a> {
+    fn bar<'a, T: Bar<'a>>(self) -> &'a str;
+}
+
+impl<'a> Foo<'a> for &'a str {
+    fn bar<T: Bar<'a>>(self) -> &'a str { fail!() } //~ ERROR lifetime
+}
+
+fn main() {
+}
index 7d800899e520945c66f50c077b59043e5fbcbb1c..4522b536ffd347eea776c924d58506608f00b6f4 100644 (file)
@@ -13,7 +13,7 @@ fn main() {
     let v: int = match sl.as_slice() {
         [] => 0,
         [a,b,c] => 3,
-        [a, ..rest] => a,
-        [10,a, ..rest] => 10 //~ ERROR: unreachable pattern
+        [a, rest..] => a,
+        [10,a, rest..] => 10 //~ ERROR: unreachable pattern
     };
 }
index d5a8339ba19380765269652bf91d18a7ceb76f24..26866cbbc6033c85e5de3a9536caf879226b0491 100644 (file)
 fn match_vecs<'a, T>(l1: &'a [T], l2: &'a [T]) {
     match (l1, l2) {
         ([], []) => println!("both empty"),
-        ([], [hd, ..tl]) | ([hd, ..tl], []) => println!("one empty"),
+        ([], [hd, tl..]) | ([hd, tl..], []) => println!("one empty"),
         //~^ ERROR: cannot move out of dereference
         //~^^ ERROR: cannot move out of dereference
-        ([hd1, ..tl1], [hd2, ..tl2]) => println!("both nonempty"),
+        ([hd1, tl1..], [hd2, tl2..]) => println!("both nonempty"),
         //~^ ERROR: cannot move out of dereference
         //~^^ ERROR: cannot move out of dereference
     }
index c8179c3adb039c122bc8b3d6eae53e71f518f39e..81b186a2998a83c00be2bdcf17af837ee44c074e 100644 (file)
@@ -49,6 +49,7 @@ fn main() {
     let x = -2147483649_i32; //~ error: literal out of range for its type
 
     let x = 9223372036854775808_i64; //~ error: literal out of range for its type
+    let x = -9223372036854775808_i64; // should be OK
     let x = 18446744073709551615_i64; //~ error: literal out of range for its type
 
     let x = -3.40282348e+38_f32; //~ error: literal out of range for its type
index 389e26aa400dcad4d0b19e50fe30cbfff3837e51..51e83c14aa0082686c1fd2c56969aeb67d381d86 100644 (file)
@@ -11,7 +11,7 @@
 fn main() {
     let a = Vec::new();
     match a {
-        [1, ..tail, ..tail] => {}, //~ ERROR: unexpected token: `..`
+        [1, tail.., tail..] => {}, //~ ERROR: expected `,`, found `..`
         _ => ()
     }
 }
index a94b0709646383a2136db8701b0cf242ed1d28a5..a85ce660e8b1ffc08302b5a7bb2f2b06edf47075 100644 (file)
@@ -31,7 +31,7 @@ fn main() {
     let x: Vec<char> = vec!('a', 'b', 'c');
     let x: &[char] = x.as_slice();
     match x {
-        ['a', 'b', 'c', .._tail] => {}
+        ['a', 'b', 'c', _tail..] => {}
         ['a', 'b', 'c'] => {} //~ ERROR unreachable pattern
         _ => {}
     }
diff --git a/src/test/compile-fail/move-out-of-tuple-field.rs b/src/test/compile-fail/move-out-of-tuple-field.rs
new file mode 100644 (file)
index 0000000..7f55a78
--- /dev/null
@@ -0,0 +1,23 @@
+// Copyright 2014 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(tuple_indexing)]
+
+struct Foo(Box<int>);
+
+fn main() {
+    let x = (box 1i,);
+    let y = x.0;
+    let z = x.0; //~ ERROR use of moved value: `x.0`
+
+    let x = Foo(box 1i);
+    let y = x.0;
+    let z = x.0; //~ ERROR use of moved value: `x.0`
+}
index 4de4af877127d1db27ef418e48ade49822a41321..ae5f40d4874c991def4b70f6cf134d4b8925afe9 100644 (file)
@@ -38,14 +38,14 @@ fn main() {
     let vec = vec!(Some(42i), None, Some(21i));
     let vec: &[Option<int>] = vec.as_slice();
     match vec { //~ ERROR non-exhaustive patterns: `[]` not covered
-        [Some(..), None, ..tail] => {}
-        [Some(..), Some(..), ..tail] => {}
+        [Some(..), None, tail..] => {}
+        [Some(..), Some(..), tail..] => {}
         [None] => {}
     }
     let vec = vec!(1i);
     let vec: &[int] = vec.as_slice();
     match vec {
-        [_, ..tail] => (),
+        [_, tail..] => (),
         [] => ()
     }
     let vec = vec!(0.5f32);
@@ -59,10 +59,10 @@ fn main() {
     let vec = vec!(Some(42i), None, Some(21i));
     let vec: &[Option<int>] = vec.as_slice();
     match vec {
-        [Some(..), None, ..tail] => {}
-        [Some(..), Some(..), ..tail] => {}
-        [None, None, ..tail] => {}
-        [None, Some(..), ..tail] => {}
+        [Some(..), None, tail..] => {}
+        [Some(..), Some(..), tail..] => {}
+        [None, None, tail..] => {}
+        [None, Some(..), tail..] => {}
         [Some(_)] => {}
         [None] => {}
         [] => {}
index 6dc5ad8b606c37e7055f17596f5db1b43def01f0..b7ff3a18fcf7a3a19cf30b01a0328c9fc1655cc7 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(struct_variant)]
+#![feature(advanced_slice_patterns, struct_variant)]
 
 struct Foo {
     first: bool,
@@ -63,7 +63,7 @@ fn vectors_with_nested_enums() {
         [Second(true), First] => (),
         [Second(true), Second(true)] => (),
         [Second(false), _] => (),
-        [_, _, ..tail, _] => ()
+        [_, _, tail.., _] => ()
     }
 }
 
diff --git a/src/test/compile-fail/tuple-index-not-tuple.rs b/src/test/compile-fail/tuple-index-not-tuple.rs
new file mode 100644 (file)
index 0000000..d4ef0e2
--- /dev/null
@@ -0,0 +1,22 @@
+// Copyright 2014 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(tuple_indexing)]
+
+struct Point { x: int, y: int }
+struct Empty;
+
+fn main() {
+    let origin = Point { x: 0, y: 0 };
+    origin.0;
+    //~^ ERROR attempted tuple index `0` on type `Point`, but the type was not
+    Empty.0;
+    //~^ ERROR attempted tuple index `0` on type `Empty`, but the type was not
+}
diff --git a/src/test/compile-fail/tuple-index-out-of-bounds.rs b/src/test/compile-fail/tuple-index-out-of-bounds.rs
new file mode 100644 (file)
index 0000000..d16f950
--- /dev/null
@@ -0,0 +1,26 @@
+// Copyright 2014 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(tuple_indexing)]
+
+struct Point(int, int);
+
+fn main() {
+    let origin = Point(0, 0);
+    origin.0;
+    origin.1;
+    origin.2;
+    //~^ ERROR attempted out-of-bounds tuple index `2` on type `Point`
+    let tuple = (0i, 0i);
+    tuple.0;
+    tuple.1;
+    tuple.2;
+    //~^ ERROR attempted out-of-bounds tuple index `2` on type `(int,int)`
+}
index cf42e79b3941e23bd0c614854d3fb7d55b8c00ae..f71afeb1b308f5f15080de2913b6f2570e11e63c 100644 (file)
@@ -57,20 +57,18 @@ fn f9<Sized? X>(x1: Box<S<X>>, x2: Box<E<X>>) {
     //~^ ERROR instantiating a type parameter with an incompatible type
 }
 
-// I would like these to fail eventually.
-/*
 // impl - bounded
 trait T1<Z: T> {
 }
 struct S3<Sized? Y>;
-impl<Sized? X: T> T1<X> for S3<X> { //ERROR instantiating a type parameter with an incompatible type
+impl<Sized? X: T> T1<X> for S3<X> { //~ ERROR instantiating a type parameter with an incompatible
 }
 
 // impl - unbounded
 trait T2<Z> {
 }
-impl<Sized? X> T2<X> for S3<X> { //ERROR instantiating a type parameter with an incompatible type `X
-*/
+impl<Sized? X> T2<X> for S3<X> { //~ ERROR instantiating a type parameter with an incompatible type
+}
 
 // impl - struct
 trait T3<Sized? Z> {
diff --git a/src/test/compile-fail/vec-matching-obsolete-syntax.rs b/src/test/compile-fail/vec-matching-obsolete-syntax.rs
new file mode 100644 (file)
index 0000000..6330aac
--- /dev/null
@@ -0,0 +1,22 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+    let x = [1i, 2, 3];
+    match x {
+        [a, b, ..c] => {    //~ ERROR obsolete syntax
+            assert_eq!(a, 1);
+            assert_eq!(b, 2);
+            let expected: &[_] = &[3];
+            assert_eq!(c, expected);
+        }
+    }
+}
+
index 86e394e5408781e0120a3bbb32378fa46840157d..376a3a38fda1ed3d566a8dc2550ff1b6008f37e5 100644 (file)
@@ -39,26 +39,20 @@ pub fn bar() {
          () => {
              #[inline]
              #[allow(dead_code)]
-             static __STATIC_FMTSTR:
-                    [::std::fmt::rt::Piece<'static>, ..(1u as uint)] =
-                 ([((::std::fmt::rt::String as
-                        fn(&'static str) -> core::fmt::rt::Piece<'static>)(("test"
-                                                                               as
-                                                                               &'static str))
-                       as core::fmt::rt::Piece<'static>)] as
-                     [core::fmt::rt::Piece<'static>, .. 1]);
+             static __STATIC_FMTSTR: [&'static str, ..(1u as uint)] =
+                 ([("test" as &'static str)] as [&'static str, .. 1]);
              let __args_vec =
                  (&([] as [core::fmt::Argument<'_>, .. 0]) as
                      &[core::fmt::Argument<'_>, .. 0]);
              let __args =
                  (unsafe {
                       ((::std::fmt::Arguments::new as
-                           unsafe fn(&'static [core::fmt::rt::Piece<'static>], &'a [core::fmt::Argument<'a>]) -> core::fmt::Arguments<'a>)((__STATIC_FMTSTR
-                                                                                                                                               as
-                                                                                                                                               [core::fmt::rt::Piece<'static>, .. 1]),
-                                                                                                                                           (__args_vec
-                                                                                                                                               as
-                                                                                                                                               &[core::fmt::Argument<'_>, .. 0]))
+                           unsafe fn(&'static [&'static str], &'a [core::fmt::Argument<'a>]) -> core::fmt::Arguments<'a>)((__STATIC_FMTSTR
+                                                                                                                              as
+                                                                                                                              [&'static str, .. 1]),
+                                                                                                                          (__args_vec
+                                                                                                                              as
+                                                                                                                              &[core::fmt::Argument<'_>, .. 0]))
                           as core::fmt::Arguments<'_>)
                   } as core::fmt::Arguments<'_>);
 
diff --git a/src/test/run-pass-fulldeps/issue-16992.rs b/src/test/run-pass-fulldeps/issue-16992.rs
new file mode 100644 (file)
index 0000000..563b839
--- /dev/null
@@ -0,0 +1,26 @@
+// Copyright 2014 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.
+
+// ignore-pretty
+// ignore-android
+
+#![feature(quote)]
+
+extern crate syntax;
+
+use syntax::ext::base::ExtCtxt;
+
+#[allow(dead_code)]
+fn foobar(cx: &mut ExtCtxt) {
+    quote_expr!(cx, 1i);
+    quote_expr!(cx, 2i);
+}
+
+fn main() { }
diff --git a/src/test/run-pass/borrow-tuple-fields.rs b/src/test/run-pass/borrow-tuple-fields.rs
new file mode 100644 (file)
index 0000000..046d76c
--- /dev/null
@@ -0,0 +1,48 @@
+// Copyright 2014 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(tuple_indexing)]
+
+struct Foo(int, int);
+
+fn main() {
+    let x = (1i, 2i);
+    let a = &x.0;
+    let b = &x.0;
+    assert_eq!(*a, 1);
+    assert_eq!(*b, 1);
+
+    let mut x = (1i, 2i);
+    {
+        let a = &x.0;
+        let b = &mut x.1;
+        *b = 5;
+        assert_eq!(*a, 1);
+    }
+    assert_eq!(x.0, 1);
+    assert_eq!(x.1, 5);
+
+
+    let x = Foo(1i, 2i);
+    let a = &x.0;
+    let b = &x.0;
+    assert_eq!(*a, 1);
+    assert_eq!(*b, 1);
+
+    let mut x = Foo(1i, 2i);
+    {
+        let a = &x.0;
+        let b = &mut x.1;
+        *b = 5;
+        assert_eq!(*a, 1);
+    }
+    assert_eq!(x.0, 1);
+    assert_eq!(x.1, 5);
+}
diff --git a/src/test/run-pass/borrowck-trait-lifetime.rs b/src/test/run-pass/borrowck-trait-lifetime.rs
new file mode 100644 (file)
index 0000000..b39f03a
--- /dev/null
@@ -0,0 +1,21 @@
+// Copyright 2014 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.
+
+// This test verifies that casting from the same lifetime on a value
+// to the same lifetime on a trait succeeds. See issue #10766.
+
+#![allow(dead_code)]
+fn main() {
+    trait T {}
+
+    fn f<'a, V: T>(v: &'a V) -> &'a T {
+        v as &'a T
+    }
+}
index 15544468ae992a7ecdc4cbbce137c92ee54bbfbc..56eb340ef59acc922235790df8b2dc2b5ea882bd 100644 (file)
 pub fn main() {
     assert!(Some(box() ()).is_some());
 
+    let xs: Box<[()]> = box [];
+    assert!(Some(xs).is_some());
+
     struct Foo;
     assert!(Some(box Foo).is_some());
+
+    let ys: Box<[Foo]> = box [];
+    assert!(Some(ys).is_some());
 }
diff --git a/src/test/run-pass/for-loop-does-not-borrow-iterators.rs b/src/test/run-pass/for-loop-does-not-borrow-iterators.rs
deleted file mode 100644 (file)
index 206ab0d..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2014 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 `for` loop use to keep a mutable borrow when executing its body,
-// making it impossible to re-use the iterator as follows.
-// https://github.com/rust-lang/rust/issues/8372
-//
-// This was fixed in https://github.com/rust-lang/rust/pull/15809
-
-pub fn main() {
-    let mut for_loop_values = Vec::new();
-    let mut explicit_next_call_values = Vec::new();
-
-    let mut iter = range(1i, 10);
-    for i in iter {
-        for_loop_values.push(i);
-        explicit_next_call_values.push(iter.next());
-    }
-
-    assert_eq!(for_loop_values, vec![1, 3, 5, 7, 9]);
-    assert_eq!(explicit_next_call_values, vec![Some(2), Some(4), Some(6), Some(8), None]);
-}
index 27c63d425bf387a872ef925608d06217d360f7fb..1c87b6dad8970abffcbdd4f03cbd4b9df2bdb98a 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(advanced_slice_patterns)]
+
 struct Foo(int, int, int, int);
 struct Bar{a: int, b: int, c: int, d: int}
 
index 444e8bd37707e7273ed3f8221f75f723d2b41e3b..1709321a71cfdaa76f64f93a90abfad8012c2a8c 100644 (file)
@@ -14,11 +14,11 @@ fn main() {
     let mut result = vec!();
     loop {
         x = match x {
-            [1, n, 3, ..rest] => {
+            [1, n, 3, rest..] => {
                 result.push(n);
                 rest
             }
-            [n, ..rest] => {
+            [n, rest..] => {
                 result.push(n);
                 rest
             }
index d2711339ccbd41d10677c9e9b479d6fb074870d4..c6c9e8004558cce19afae47a568bd14ef69e7e5f 100644 (file)
@@ -16,6 +16,6 @@ fn count_members(v: &[uint]) -> uint {
     match v {
         []         => 0,
         [_]        => 1,
-        [_x, ..xs] => 1 + count_members(xs)
+        [_x, xs..] => 1 + count_members(xs)
     }
 }
diff --git a/src/test/run-pass/issue-17074.rs b/src/test/run-pass/issue-17074.rs
new file mode 100644 (file)
index 0000000..e346148
--- /dev/null
@@ -0,0 +1,20 @@
+// Copyright 2014 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.
+
+static X: u64 = -1 as u16 as u64;
+static Y: u64 = -1 as u32 as u64;
+
+fn main() {
+    assert_eq!(match 1 {
+        X => unreachable!(),
+        Y => unreachable!(),
+        _ => 1i
+    }, 1);
+}
index d307a057038438ca5315856cb28d2e2bde5b668c..666847517efdeda568d337a45d628f586e46fb20 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(advanced_slice_patterns)]
+
 fn foo<T: Add<T, T> + Clone>([x, y, z]: [T, ..3]) -> (T, T, T) {
     (x.clone(), x.clone() + y.clone(), x + y + z)
 }
@@ -29,7 +31,7 @@ fn main() {
     assert_eq!(d, "baz");
 
     let out = bar("baz", "foo");
-    let [a, ..xs, d] = out;
+    let [a, xs.., d] = out;
     assert_eq!(a, "baz");
     assert!(xs == ["foo", "foo"]);
     assert_eq!(d, "baz");
index de1bb02bfefc675964c5a482975ddcc741538572..ae4fd1f1993b7227ebcded4fa9c28e999972dacb 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(advanced_slice_patterns)]
+
 fn match_vecs<'a, T>(l1: &'a [T], l2: &'a [T]) -> &'static str {
     match (l1, l2) {
         ([], []) => "both empty",
diff --git a/src/test/run-pass/tuple-index-fat-types.rs b/src/test/run-pass/tuple-index-fat-types.rs
new file mode 100644 (file)
index 0000000..fdee1d9
--- /dev/null
@@ -0,0 +1,23 @@
+// Copyright 2014 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(tuple_indexing)]
+
+struct Foo<'a>(&'a [int]);
+
+fn main() {
+    let x: &[int] = &[1i, 2, 3];
+    let y = (x,);
+    assert_eq!(y.0, x);
+
+    let x: &[int] = &[1i, 2, 3];
+    let y = Foo(x);
+    assert_eq!(y.0, x);
+}
diff --git a/src/test/run-pass/tuple-index.rs b/src/test/run-pass/tuple-index.rs
new file mode 100644 (file)
index 0000000..107dc40
--- /dev/null
@@ -0,0 +1,42 @@
+// Copyright 2014 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(tuple_indexing)]
+
+struct Point(int, int);
+
+fn main() {
+    let mut x = Point(3, 2);
+    assert_eq!(x.0, 3);
+    assert_eq!(x.1, 2);
+    x.0 += 5;
+    assert_eq!(x.0, 8);
+    {
+        let ry = &mut x.1;
+        *ry -= 2;
+        x.0 += 3;
+        assert_eq!(x.0, 11);
+    }
+    assert_eq!(x.1, 0);
+
+    let mut x = (3i, 2i);
+    assert_eq!(x.0, 3);
+    assert_eq!(x.1, 2);
+    x.0 += 5;
+    assert_eq!(x.0, 8);
+    {
+        let ry = &mut x.1;
+        *ry -= 2;
+        x.0 += 3;
+        assert_eq!(x.0, 11);
+    }
+    assert_eq!(x.1, 0);
+
+}
diff --git a/src/test/run-pass/unboxed-closures-unique-type-id.rs b/src/test/run-pass/unboxed-closures-unique-type-id.rs
new file mode 100644 (file)
index 0000000..55d89d4
--- /dev/null
@@ -0,0 +1,34 @@
+// Copyright 2012 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.
+//
+// This code used to produce the following ICE:
+//
+//    error: internal compiler error: get_unique_type_id_of_type() -
+//    unexpected type: closure,
+//    ty_unboxed_closure(syntax::ast::DefId{krate: 0u32, node: 66u32},
+//    ReScope(63u32))
+//
+// This is a regression test for issue #17021.
+
+#![feature(unboxed_closures, overloaded_calls)]
+
+use std::ptr;
+
+pub fn replace_map<'a, T, F>(src: &mut T, prod: F)
+where F: |: T| -> T {
+    unsafe { *src = prod(ptr::read(src as *mut T as *const T)); }
+}
+
+pub fn main() {
+    let mut a = 7u;
+    let b = &mut a;
+    replace_map(b, |: x: uint| x * 2);
+    assert_eq!(*b, 14u);
+}
index 0530c8a6ab3dd48fd0b816357631e7604f07c6ec..141d6c88dd96108607083019bdceb5d4cf6928b7 100644 (file)
@@ -24,6 +24,7 @@ trait T8<Sized? X: T2> {}
 enum E<Sized? X> {}
 impl <Sized? X> T1 for S1<X> {}
 fn f<Sized? X>() {}
+type TT<Sized? T> = T;
 
 pub fn main() {
 }
index 3e9d4b9fc3a24ef98a3093b3fd16b0604f6b24bc..a1a14823ff5955b5923d6d6021bd4c7d903c3959 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(advanced_slice_patterns)]
+
 fn a() {
     let x = [1i, 2, 3];
     match x {
index 07ee5f535e9baa170e75e3da86e69e248c6fbdd3..63914a8df31cdc52e7474c5ce18646d45dd45d9f 100644 (file)
@@ -8,12 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(advanced_slice_patterns)]
+
 fn foldl<T,U:Clone>(values: &[T],
                     initial: U,
                     function: |partial: U, element: &T| -> U)
                     -> U {
     match values {
-        [ref head, ..tail] =>
+        [ref head, tail..] =>
             foldl(tail, function(initial, head), function),
         [] => initial.clone()
     }
@@ -24,7 +26,7 @@ fn foldr<T,U:Clone>(values: &[T],
                     function: |element: &T, partial: U| -> U)
                     -> U {
     match values {
-        [..head, ref tail] =>
+        [head.., ref tail] =>
             foldr(head, function(tail, initial), function),
         [] => initial.clone()
     }
index 2fd8a4ab256fd8fb1dee7ed20966c5fc2b280b4f..a140399447b3bcbb99837f04b8f433a9eed021da 100644 (file)
@@ -13,7 +13,7 @@ pub fn main() {
     let x: &[int] = &[1, 2, 3, 4, 5];
     if !x.is_empty() {
         let el = match x {
-            [1, ..ref tail] => &tail[0],
+            [1, ref tail..] => &tail[0],
             _ => unreachable!()
         };
         println!("{}", *el);
index e95495a42d2823bac8292c3e521469c61ee52abb..187d97f483ddaa6ff787ac23cff471f0b4089018 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(advanced_slice_patterns)]
+
 fn a() {
     let x = [1i];
     match x {
@@ -20,7 +22,7 @@ fn a() {
 fn b() {
     let x = [1i, 2, 3];
     match x {
-        [a, b, ..c] => {
+        [a, b, c..] => {
             assert_eq!(a, 1);
             assert_eq!(b, 2);
             let expected: &[_] = &[3];
@@ -28,7 +30,7 @@ fn b() {
         }
     }
     match x {
-        [..a, b, c] => {
+        [a.., b, c] => {
             let expected: &[_] = &[1];
             assert_eq!(a, expected);
             assert_eq!(b, 2);
@@ -36,7 +38,7 @@ fn b() {
         }
     }
     match x {
-        [a, ..b, c] => {
+        [a, b.., c] => {
             assert_eq!(a, 1);
             let expected: &[_] = &[2];
             assert_eq!(b, expected);
index e58aebcddfe0e94bfb3b0d92e494e408b25d6607..a1a222549a086a10913365612ec7d78a17bffabf 100644 (file)
@@ -20,14 +20,14 @@ pub fn main() {
         Foo { string: "baz".to_string() }
     ];
     match x {
-        [ref first, ..tail] => {
+        [ref first, tail..] => {
             assert!(first.string == "foo".to_string());
             assert_eq!(tail.len(), 2);
             assert!(tail[0].string == "bar".to_string());
             assert!(tail[1].string == "baz".to_string());
 
             match tail {
-                [Foo { .. }, _, Foo { .. }, .. _tail] => {
+                [Foo { .. }, _, Foo { .. }, _tail..] => {
                     unreachable!();
                 }
                 [Foo { string: ref a }, Foo { string: ref b }] => {