]> git.lizzy.rs Git - rust.git/commitdiff
auto merge of #16493 : kballard/rust/fix_drop_field_order, r=pnkfelix
authorbors <bors@rust-lang.org>
Fri, 15 Aug 2014 22:36:15 +0000 (22:36 +0000)
committerbors <bors@rust-lang.org>
Fri, 15 Aug 2014 22:36:15 +0000 (22:36 +0000)
When a struct implements Drop, its fields should still drop in
declaration order (just as they do when the struct does not implement
Drop).

Fixes #16492.

274 files changed:
src/compiletest/header.rs
src/compiletest/runtest.rs
src/compiletest/util.rs
src/doc/guide-ffi.md
src/doc/guide-runtime.md
src/doc/guide-testing.md
src/doc/guide-unsafe.md
src/doc/guide.md
src/doc/rust.md
src/etc/mklldeps.py
src/etc/unicode.py
src/etc/vim/after/syntax/rust.vim
src/etc/vim/ftplugin/rust.vim
src/libcollections/hash/mod.rs
src/libcollections/hash/sip.rs
src/libcollections/ringbuf.rs
src/libcollections/slice.rs
src/libcollections/str.rs
src/libcollections/string.rs
src/libcollections/trie.rs
src/libcollections/vec.rs
src/libcore/cmp.rs
src/libcore/fmt/float.rs
src/libcore/fmt/mod.rs
src/libcore/fmt/num.rs
src/libcore/option.rs
src/libcore/prelude.rs
src/libcore/slice.rs
src/libcore/str.rs
src/libcoretest/lib.rs
src/libcoretest/slice.rs [new file with mode: 0644]
src/libgraphviz/maybe_owned_vec.rs
src/libgreen/sched.rs
src/liblibc/lib.rs
src/libnative/io/mod.rs
src/libnative/io/process.rs
src/libnum/rational.rs
src/librand/isaac.rs
src/libregex/parse.rs
src/libregex/vm.rs
src/librlibc/lib.rs
src/librustc/back/link.rs
src/librustc/driver/config.rs
src/librustc/driver/driver.rs
src/librustc/driver/mod.rs
src/librustc/front/config.rs
src/librustc/front/feature_gate.rs
src/librustc/front/test.rs
src/librustc/lint/builtin.rs
src/librustc/lint/context.rs
src/librustc/lint/mod.rs
src/librustc/metadata/common.rs
src/librustc/metadata/csearch.rs
src/librustc/metadata/decoder.rs
src/librustc/metadata/encoder.rs
src/librustc/metadata/loader.rs
src/librustc/metadata/tydecode.rs
src/librustc/metadata/tyencode.rs
src/librustc/middle/astencode.rs
src/librustc/middle/borrowck/gather_loans/mod.rs
src/librustc/middle/borrowck/gather_loans/restrictions.rs
src/librustc/middle/borrowck/mod.rs
src/librustc/middle/check_loop.rs
src/librustc/middle/dead.rs
src/librustc/middle/expr_use_visitor.rs
src/librustc/middle/freevars.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/reachable.rs
src/librustc/middle/resolve.rs
src/librustc/middle/save/mod.rs
src/librustc/middle/stability.rs
src/librustc/middle/trans/adt.rs
src/librustc/middle/trans/base.rs
src/librustc/middle/trans/cabi.rs
src/librustc/middle/trans/cabi_x86.rs
src/librustc/middle/trans/callee.rs
src/librustc/middle/trans/closure.rs
src/librustc/middle/trans/common.rs
src/librustc/middle/trans/controlflow.rs
src/librustc/middle/trans/debuginfo.rs
src/librustc/middle/trans/expr.rs
src/librustc/middle/trans/foreign.rs
src/librustc/middle/trans/glue.rs
src/librustc/middle/trans/inline.rs
src/librustc/middle/trans/meth.rs
src/librustc/middle/trans/monomorphize.rs
src/librustc/middle/trans/reflect.rs
src/librustc/middle/trans/type_of.rs
src/librustc/middle/ty.rs
src/librustc/middle/ty_fold.rs
src/librustc/middle/typeck/astconv.rs
src/librustc/middle/typeck/check/method.rs
src/librustc/middle/typeck/check/mod.rs
src/librustc/middle/typeck/check/regionck.rs
src/librustc/middle/typeck/check/vtable.rs
src/librustc/middle/typeck/check/writeback.rs
src/librustc/middle/typeck/coherence.rs
src/librustc/middle/typeck/collect.rs
src/librustc/middle/typeck/infer/combine.rs
src/librustc/middle/typeck/infer/error_reporting.rs
src/librustc/middle/typeck/infer/test.rs
src/librustc/middle/typeck/variance.rs
src/librustc/util/ppaux.rs
src/librustc_back/archive.rs
src/librustc_back/arm.rs
src/librustc_back/mips.rs
src/librustc_back/mipsel.rs
src/librustc_back/rpath.rs
src/librustc_back/svh.rs
src/librustc_back/x86.rs
src/librustc_back/x86_64.rs
src/librustdoc/clean/inline.rs
src/librustdoc/clean/mod.rs
src/librustdoc/doctree.rs
src/librustdoc/fold.rs
src/librustdoc/html/render.rs
src/librustdoc/lib.rs
src/librustdoc/passes.rs
src/librustdoc/plugins.rs
src/librustdoc/stability_summary.rs
src/librustdoc/visit_ast.rs
src/librustrt/args.rs
src/librustrt/libunwind.rs
src/librustrt/stack.rs
src/librustuv/uvll.rs
src/libstd/ascii.rs
src/libstd/c_vec.rs
src/libstd/collections/hashmap.rs
src/libstd/dynamic_lib.rs
src/libstd/io/buffered.rs
src/libstd/io/comm_adapters.rs
src/libstd/io/extensions.rs
src/libstd/io/fs.rs
src/libstd/io/mem.rs
src/libstd/io/mod.rs
src/libstd/io/net/ip.rs
src/libstd/io/net/tcp.rs
src/libstd/io/net/unix.rs
src/libstd/io/process.rs
src/libstd/io/signal.rs
src/libstd/io/stdio.rs
src/libstd/io/test.rs
src/libstd/io/timer.rs
src/libstd/lib.rs
src/libstd/num/i16.rs
src/libstd/num/i32.rs
src/libstd/num/i64.rs
src/libstd/num/i8.rs
src/libstd/num/int.rs
src/libstd/num/strconv.rs
src/libstd/num/u16.rs
src/libstd/num/u32.rs
src/libstd/num/u64.rs
src/libstd/num/u8.rs
src/libstd/num/uint.rs
src/libstd/os.rs
src/libstd/path/mod.rs
src/libstd/path/posix.rs
src/libstd/path/windows.rs
src/libstd/prelude.rs
src/libstd/rand/os.rs
src/libstd/rt/backtrace.rs
src/libstd/task.rs
src/libstd/time/duration.rs [new file with mode: 0644]
src/libstd/time/mod.rs [new file with mode: 0644]
src/libsync/comm/mod.rs
src/libsyntax/abi.rs
src/libsyntax/ast.rs
src/libsyntax/ast_map/blocks.rs
src/libsyntax/ast_map/mod.rs
src/libsyntax/ast_util.rs
src/libsyntax/crateid.rs
src/libsyntax/ext/build.rs
src/libsyntax/ext/deriving/generic/mod.rs
src/libsyntax/ext/deriving/generic/ty.rs
src/libsyntax/ext/expand.rs
src/libsyntax/ext/quote.rs
src/libsyntax/fold.rs
src/libsyntax/parse/lexer/mod.rs
src/libsyntax/parse/mod.rs
src/libsyntax/parse/parser.rs
src/libsyntax/parse/token.rs
src/libsyntax/print/pprust.rs
src/libsyntax/visit.rs
src/libunicode/normalize.rs
src/libunicode/tables.rs
src/liburl/lib.rs
src/test/auxiliary/macro_crate_test.rs
src/test/auxiliary/privacy_reexport.rs
src/test/auxiliary/reexported_static_methods.rs
src/test/auxiliary/static_priv_by_default.rs
src/test/auxiliary/where_clauses_xc.rs [new file with mode: 0644]
src/test/bench/shootout-regex-dna.rs
src/test/compile-fail-fulldeps/macro-crate-cannot-read-embedded-ident.rs [new file with mode: 0644]
src/test/compile-fail-fulldeps/syntax-extension-regex-invalid.rs
src/test/compile-fail-fulldeps/syntax-extension-regex-unused-static.rs
src/test/compile-fail-fulldeps/syntax-extension-regex-unused.rs
src/test/compile-fail/borrowck-closures-unique-imm.rs [new file with mode: 0644]
src/test/compile-fail/borrowck-for-loop-correct-cmt-for-pattern.rs [new file with mode: 0644]
src/test/compile-fail/borrowck-struct-update-with-dtor.rs
src/test/compile-fail/borrowck-unboxed-closures.rs [new file with mode: 0644]
src/test/compile-fail/glob-resolve1.rs
src/test/compile-fail/import-from-rename.rs
src/test/compile-fail/import-glob-rename.rs
src/test/compile-fail/inaccessible-test-modules.rs
src/test/compile-fail/issue-2937.rs
src/test/compile-fail/lint-dead-code-3.rs
src/test/compile-fail/lint-missing-doc.rs
src/test/compile-fail/lint-unused-imports.rs
src/test/compile-fail/match-static-const-lc.rs
src/test/compile-fail/privacy1.rs
src/test/compile-fail/regionck-unboxed-closure-lifetimes.rs [new file with mode: 0644]
src/test/compile-fail/unboxed-closures-wrong-trait.rs [new file with mode: 0644]
src/test/compile-fail/unresolved-import.rs
src/test/compile-fail/where-clauses-no-bounds-or-predicates.rs [new file with mode: 0644]
src/test/compile-fail/where-clauses-not-parameter.rs [new file with mode: 0644]
src/test/compile-fail/where-clauses-unsatisfied.rs [new file with mode: 0644]
src/test/debuginfo/basic-types-globals-metadata.rs
src/test/debuginfo/basic-types-globals.rs
src/test/debuginfo/basic-types-mut-globals.rs
src/test/debuginfo/c-style-enum.rs
src/test/debuginfo/lexical-scopes-in-block-expression.rs
src/test/debuginfo/no-debug-attribute.rs [new file with mode: 0644]
src/test/debuginfo/simple-struct.rs
src/test/debuginfo/simple-tuple.rs
src/test/debuginfo/vec-slices.rs
src/test/debuginfo/vec.rs
src/test/run-make/cannot-read-embedded-idents/Makefile [new file with mode: 0644]
src/test/run-make/cannot-read-embedded-idents/create_and_compile.rs [new file with mode: 0644]
src/test/run-pass-fulldeps/macro-crate-does-hygiene-work.rs [new file with mode: 0644]
src/test/run-pass/auto-encode.rs
src/test/run-pass/backtrace.rs
src/test/run-pass/capture-clauses-boxed-closures.rs [new file with mode: 0644]
src/test/run-pass/capture-clauses-unboxed-closures.rs [new file with mode: 0644]
src/test/run-pass/core-run-destroy.rs
src/test/run-pass/dupe-first-attr.rc
src/test/run-pass/exponential-notation.rs
src/test/run-pass/filter-block-view-items.rs
src/test/run-pass/fsu-moves-and-copies.rs
src/test/run-pass/glob-std.rs
src/test/run-pass/import.rs
src/test/run-pass/import8.rs
src/test/run-pass/intrinsic-alignment.rs
src/test/run-pass/issue-12684.rs
src/test/run-pass/issue-12699.rs
src/test/run-pass/issue-14393.rs
src/test/run-pass/issue-15487.rs
src/test/run-pass/issue-16441.rs [new file with mode: 0644]
src/test/run-pass/issue-5950.rs
src/test/run-pass/issue-9396.rs
src/test/run-pass/lang-item-public.rs
src/test/run-pass/linkage-visibility.rs
src/test/run-pass/linkage1.rs
src/test/run-pass/logging-only-prints-once.rs
src/test/run-pass/logging-separate-lines.rs
src/test/run-pass/match-static-const-rename.rs
src/test/run-pass/process-detach.rs
src/test/run-pass/rec-align-u64.rs
src/test/run-pass/signal-exit-status.rs
src/test/run-pass/spawning-with-debug.rs
src/test/run-pass/tcp-connect-timeouts.rs
src/test/run-pass/tcp-stress.rs
src/test/run-pass/tempfile.rs
src/test/run-pass/test-runner-hides-main.rs
src/test/run-pass/unboxed-closures-all-traits.rs [new file with mode: 0644]
src/test/run-pass/unboxed-closures-drop.rs [new file with mode: 0644]
src/test/run-pass/unboxed-closures-single-word-env.rs [new file with mode: 0644]
src/test/run-pass/use.rs
src/test/run-pass/where-clauses-cross-crate.rs [new file with mode: 0644]
src/test/run-pass/where-clauses.rs [new file with mode: 0644]
src/test/run-pass/xcrate-static-addresses.rs

index aa96f3e272712e87165309ab37f122e01f122dbf..f6cd217b580cd24be78747dc23cca861906771ef 100644 (file)
@@ -233,7 +233,7 @@ fn parse_exec_env(line: &str) -> Option<(String, String)> {
     parse_name_value_directive(line, "exec-env").map(|nv| {
         // nv is either FOO or FOO=BAR
         let mut strs: Vec<String> = nv.as_slice()
-                                      .splitn('=', 1)
+                                      .splitn(1, '=')
                                       .map(|s| s.to_string())
                                       .collect();
 
index a9c7673d4ddfbff90feca391b653d4f339954792..94b6ea0d7b44981d9524cdde38d4a7dba980b45f 100644 (file)
@@ -16,7 +16,8 @@
 use header;
 use procsrv;
 use util::logv;
-#[cfg(target_os = "win32")]
+#[cfg(target_os = "windows")]
+#[cfg(stage0, target_os = "win32")] // NOTE: Remove after snapshot
 use util;
 
 use std::io::File;
@@ -30,6 +31,7 @@
 use std::str;
 use std::string::String;
 use std::task;
+use std::time::Duration;
 use test::MetricMap;
 
 pub fn run(config: Config, testfile: String) {
@@ -400,7 +402,7 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) {
                 .expect(format!("failed to exec `{}`", config.adb_path).as_slice());
             loop {
                 //waiting 1 second for gdbserver start
-                timer::sleep(1000);
+                timer::sleep(Duration::milliseconds(1000));
                 let result = task::try(proc() {
                     tcp::TcpStream::connect("127.0.0.1", 5039).unwrap();
                 });
@@ -816,7 +818,8 @@ fn check_expected_errors(expected_errors: Vec<errors::ExpectedError> ,
         format!("{}:{}:", testfile.display(), ee.line)
     }).collect::<Vec<String> >();
 
-    #[cfg(target_os = "win32")]
+    #[cfg(target_os = "windows")]
+    #[cfg(stage0, target_os = "win32")] // NOTE: Remove after snapshot
     fn to_lower( s : &str ) -> String {
         let i = s.chars();
         let c : Vec<char> = i.map( |c| {
@@ -829,7 +832,8 @@ fn to_lower( s : &str ) -> String {
         String::from_chars(c.as_slice())
     }
 
-    #[cfg(target_os = "win32")]
+    #[cfg(target_os = "windows")]
+    #[cfg(stage0, target_os = "win32")] // NOTE: Remove after snapshot
     fn prefix_matches( line : &str, prefix : &str ) -> bool {
         to_lower(line).as_slice().starts_with(to_lower(prefix).as_slice())
     }
@@ -1246,14 +1250,16 @@ fn make_cmdline(_libpath: &str, prog: &str, args: &[String]) -> String {
     format!("{} {}", prog, args.connect(" "))
 }
 
-#[cfg(target_os = "win32")]
+#[cfg(target_os = "windows")]
+#[cfg(stage0, target_os = "win32")] // NOTE: Remove after snapshot
 fn make_cmdline(libpath: &str, prog: &str, args: &[String]) -> String {
     format!("{} {} {}", lib_path_cmd_prefix(libpath), prog, args.connect(" "))
 }
 
 // Build the LD_LIBRARY_PATH variable as it would be seen on the command line
 // for diagnostic purposes
-#[cfg(target_os = "win32")]
+#[cfg(target_os = "windows")]
+#[cfg(stage0, target_os = "win32")] // NOTE: Remove after snapshot
 fn lib_path_cmd_prefix(path: &str) -> String {
     format!("{}=\"{}\"", util::lib_path_env_var(), util::make_new_path(path))
 }
index 445e814a1eb04fddb83b39e1bb54c3ef80a8eea7..8947856e332a7c748a0bf8ae35a44ac242516f14 100644 (file)
 
 use common::Config;
 
-#[cfg(target_os = "win32")]
+#[cfg(target_os = "windows")]
+#[cfg(stage0, target_os = "win32")] // NOTE: Remove after snapshot
 use std::os::getenv;
 
 /// Conversion table from triple OS name to Rust SYSNAME
 static OS_TABLE: &'static [(&'static str, &'static str)] = &[
-    ("mingw32", "win32"),
-    ("win32", "win32"),
+    ("mingw32", "windows"),
+    ("win32", "windows"),
+    ("windows", "windows"),
     ("darwin", "macos"),
     ("android", "android"),
     ("linux", "linux"),
@@ -33,7 +35,8 @@ pub fn get_os(triple: &str) -> &'static str {
     fail!("Cannot determine OS from triple");
 }
 
-#[cfg(target_os = "win32")]
+#[cfg(target_os = "windows")]
+#[cfg(stage0, target_os = "win32")] // NOTE: Remove after snapshot
 pub fn make_new_path(path: &str) -> String {
 
     // Windows just uses PATH as the library search path, so we have to
@@ -46,10 +49,12 @@ pub fn make_new_path(path: &str) -> String {
     }
 }
 
-#[cfg(target_os = "win32")]
+#[cfg(target_os = "windows")]
+#[cfg(stage0, target_os = "win32")] // NOTE: Remove after snapshot
 pub fn lib_path_env_var() -> &'static str { "PATH" }
 
-#[cfg(target_os = "win32")]
+#[cfg(target_os = "windows")]
+#[cfg(stage0, target_os = "win32")] // NOTE: Remove after snapshot
 pub fn path_div() -> &'static str { ";" }
 
 pub fn logv(config: &Config, s: String) {
index fb03d7bc11f5ea9e9b14c8b4f5f3c4f34cc6c6ed..600a9019e6b944478780f0c632e1a3e74297ab69 100644 (file)
@@ -350,9 +350,9 @@ linking to, and in the second case `bar` is the type of native library that the
 compiler is linking to. There are currently three known types of native
 libraries:
 
-* Dynamic - `#[link(name = "readline")]
-* Static - `#[link(name = "my_build_dependency", kind = "static")]
-* Frameworks - `#[link(name = "CoreFoundation", kind = "framework")]
+* Dynamic - `#[link(name = "readline")]`
+* Static - `#[link(name = "my_build_dependency", kind = "static")]`
+* Frameworks - `#[link(name = "CoreFoundation", kind = "framework")]`
 
 Note that frameworks are only available on OSX targets.
 
index 1367bdc07555fb1ee3650e1db560a8d24040861b..24b5834ef7c085fc6ffdf8f667b799063e783a2c 100644 (file)
@@ -128,7 +128,7 @@ itself, yet again implying that they are not defined in the standard library.
 The full complement of runtime features is defined by the [`Runtime`
 trait](std/rt/trait.Runtime.html) and the [`Task`
 struct](std/rt/task/struct.Task.html). A `Task` is constant among all runtime
-implementations, but each runtime implements has its own implementation of the
+implementations, but each runtime has its own implementation of the
 `Runtime` trait.
 
 The local `Task` stores the runtime value inside of itself, and then ownership
index 1d6513972a6d26f59e2776a8ae1401fc472e283e..6fb198fbd2ba4053aa3a809cfe1f6cca975732bc 100644 (file)
@@ -198,7 +198,7 @@ per-iteration speed of.
 
 For benchmarks relating to processing/generating data, one can set the
 `bytes` field to the number of bytes consumed/produced in each
-iteration; this will used to show the throughput of the benchmark.
+iteration; this will be used to show the throughput of the benchmark.
 This must be the amount used in each iteration, *not* the total
 amount.
 
index 8349c8ebcb6489e72d288c967186b6e9a1722cf8..2ff63055480834843fa3444796c9431585c5a6ed 100644 (file)
@@ -137,7 +137,7 @@ explicitly with, respectively, `value as *const T` and `value as *mut T`).
 
 Going the opposite direction, from `*const` to a reference `&`, is not
 safe. A `&T` is always valid, and so, at a minimum, the raw pointer
-`*const T` has to be a valid to a valid instance of type `T`. Furthermore,
+`*const T` has to point to a valid instance of type `T`. Furthermore,
 the resulting pointer must satisfy the aliasing and mutability laws of
 references. The compiler assumes these properties are true for any
 references, no matter how they are created, and so any conversion from
index ecde51538e2c798cb51e7d14c26ae9b108c5f224..2593ddc556b433c01845c8a068390d3e84e91ac7 100644 (file)
@@ -666,7 +666,7 @@ This is not the same as this, which won't compile:
 ```{ignore}
 let x = 5i;
 
-let y: int = if x == 5 { 10i; } else { 15i; };
+let y: int = if x == 5i { 10i; } else { 15i; };
 ```
 
 Note the semicolons after the 10 and 15. Rust will give us the following error:
@@ -1360,7 +1360,7 @@ while !done {
 ```
 
 `while` loops are the correct choice when you're not sure how many times
-you need to loop. 
+you need to loop.
 
 If you need an infinite loop, you may be tempted to write this:
 
@@ -1650,7 +1650,7 @@ a full line of input. Nice and easy.
 .ok().expect("Failed to read line");
 ```
 
-Do you remember this code? 
+Do you remember this code?
 
 ```
 enum OptionalInt {
@@ -1796,6 +1796,21 @@ Excellent! Open up your `src/main.rs` again. We'll be writing all of
 our code in this file. We'll talk about multiple-file projects later on in the
 guide.
 
+Before we move on, let me show you one more Cargo command: `run`. `cargo run`
+is kind of like `cargo build`, but it also then runs the produced exectuable.
+Try it out:
+
+```{notrust,ignore}
+$ cargo run
+   Compiling guessing_game v0.1.0 (file:/home/you/projects/guessing_game)
+     Running `target/guessing_game`
+Hello, world!
+$
+```
+
+Great! The `run` command comes in handy when you need to rapidly iterate on a project.
+Our game is just such a project, we need to quickly test each iteration before moving on to the next one.
+
 ## Processing a Guess
 
 Let's get to it! The first thing we need to do for our guessing game is
 Excellent! Try running our new program a few times:
 
 ```{notrust,ignore}
-$ ./target/guessing_game 
+$ ./target/guessing_game
 Guess the number!
 The secret number is: 7
 Please input your guess.
 4
 You guessed: 4
-$ ./target/guessing_game 
+$ ./target/guessing_game
 Guess the number!
 The secret number is: 83
 Please input your guess.
 5
 You guessed: 5
-$ ./target/guessing_game 
+$ ./target/guessing_game
 Guess the number!
 The secret number is: -29
 Please input your guess.
@@ -1986,7 +2001,7 @@ And trying it out:
 ```{notrust,ignore}
 $ cargo build
    Compiling guessing_game v0.1.0 (file:/home/you/projects/guessing_game)
-$ ./target/guessing_game 
+$ ./target/guessing_game
 Guess the number!
 The secret number is: 57
 Please input your guess.
@@ -2022,7 +2037,7 @@ fn main() {
 
     println!("You guessed: {}", input);
 
-    match cmp(input, secret_number) { 
+    match cmp(input, secret_number) {
         Less    => println!("Too small!"),
         Greater => println!("Too big!"),
         Equal   => { println!("You win!"); },
@@ -2106,7 +2121,7 @@ a `String` instead! That's because our `input` variable is coming from the
 standard input, and you can guess anything. Try it:
 
 ```{notrust,ignore}
-$ ./target/guessing_game 
+$ ./target/guessing_game
 Guess the number!
 The secret number is: 73
 Please input your guess.
@@ -2257,7 +2272,7 @@ print an error message and return. Let's give this a shot:
 ```{notrust,ignore}
 $ cargo build
    Compiling guessing_game v0.1.0 (file:/home/you/projects/guessing_game)
-$ ./target/guessing_game 
+$ ./target/guessing_game
 Guess the number!
 The secret number is: 17
 Please input your guess.
@@ -2323,7 +2338,7 @@ Let's try it!
 ```{notrust,ignore}
 $ cargo build
    Compiling guessing_game v0.1.0 (file:/home/you/projects/guessing_game)
-$ ./target/guessing_game 
+$ ./target/guessing_game
 Guess the number!
 The secret number is: 58
 Please input your guess.
@@ -2401,7 +2416,7 @@ that `return`? If we give a non-number answer, we'll `return` and quit. Observe:
 ```{notrust,ignore}
 $ cargo build
    Compiling guessing_game v0.1.0 (file:/home/you/projects/guessing_game)
-$ ./target/guessing_game 
+$ ./target/guessing_game
 Guess the number!
 The secret number is: 59
 Please input your guess.
@@ -2534,7 +2549,7 @@ Now we should be good! Let's try:
 ```{rust,ignore}
 $ cargo build
    Compiling guessing_game v0.1.0 (file:/home/you/projects/guessing_game)
-$ ./target/guessing_game 
+$ ./target/guessing_game
 Guess the number!
 The secret number is: 61
 Please input your guess.
@@ -2731,16 +2746,6 @@ mod hello {
 
 This will work:
 
-```{notrust,ignore}
-$ cargo build
-   Compiling modules v0.1.0 (file:/home/you/projects/modules)
-$
-```
-
-Before we move on, let me show you one more Cargo command: `run`. `cargo run`
-is kind of like `cargo build`, but it also then runs the produced exectuable.
-Try it out:
-
 ```{notrust,ignore}
 $ cargo run
    Compiling modules v0.1.0 (file:/home/steve/tmp/modules)
@@ -3647,14 +3652,14 @@ In order to truly understand this error, we have to learn a few new concepts:
 All of our references so far have been to variables we've created on the stack.
 In Rust, the simplest way to allocate heap variables is using a *box*.  To
 create a box, use the `box` keyword:
+
 ```{rust}
 let x = box 5i;
 ```
 
 This allocates an integer `5` on the heap, and creates a binding `x` that
 refers to it.. The great thing about boxed pointers is that we don't have to
-manually free this allocation! If we write 
+manually free this allocation! If we write
 
 ```{rust}
 {
@@ -4189,7 +4194,7 @@ the match:
 
 ```{rust,ignore}
 let x = inverse(25.0f64);
-println!("{}", x + 2.0f64); // error: binary operation `+` cannot be applied 
+println!("{}", x + 2.0f64); // error: binary operation `+` cannot be applied
            // to type `core::result::Result<f64,collections::string::String>`
 ```
 
@@ -4700,4 +4705,3 @@ fail.
 # Macros
 
 # Unsafe
-
index 9061a623c03f024256c5af2a8fae9cf67f5b0efe..564e61b9912fd2f333d04a2ccb8165da7110913a 100644 (file)
@@ -135,9 +135,9 @@ The `ident` production is any nonempty Unicode string of the following form:
 
 that does _not_ occur in the set of [keywords](#keywords).
 
-Note: `XID_start` and `XID_continue` as character properties cover the
-character ranges used to form the more familiar C and Java language-family
-identifiers.
+> **Note**: `XID_start` and `XID_continue` as character properties cover the
+character ranges used to form the more familiar C and Java language-family
+identifiers.
 
 ### Delimiter-restricted productions
 
@@ -919,7 +919,7 @@ extern crate foo = "some/where/rust-foo#foo:1.0"; // a full crate ID for externa
 ##### Use declarations
 
 ~~~~ {.ebnf .gram}
-use_decl : "pub" ? "use" [ ident '=' path
+use_decl : "pub" ? "use" [ path "as" ident
                           | path_glob ] ;
 
 path_glob : ident [ "::" [ path_glob
@@ -933,13 +933,13 @@ Usually a `use` declaration is used to shorten the path required to refer to a
 module item. These declarations may appear at the top of [modules](#modules) and
 [blocks](#blocks).
 
-*Note*: Unlike in many languages,
-`use` declarations in Rust do *not* declare linkage dependency with external crates.
-Rather, [`extern crate` declarations](#extern-crate-declarations) declare linkage dependencies.
+> **Note**: Unlike in many languages,
+`use` declarations in Rust do *not* declare linkage dependency with external crates.
+Rather, [`extern crate` declarations](#extern-crate-declarations) declare linkage dependencies.
 
 Use declarations support a number of convenient shortcuts:
 
-  * Rebinding the target name as a new local name, using the syntax `use x = p::q::r;`.
+  * Rebinding the target name as a new local name, using the syntax `use p::q::r as x;`.
   * Simultaneously binding a list of paths differing only in their final element,
     using the glob-like brace syntax `use a::b::{c,d,e,f};`
   * Binding all paths matching a given prefix, using the asterisk wildcard syntax `use a::b::*;`
@@ -1356,6 +1356,9 @@ A *static item* is a named _constant value_ stored in the global data section of
 Immutable static items are stored in the read-only data section.
 The constant value bound to a static item is, like all constant values, evaluated at compile time.
 Static items have the `static` lifetime, which outlives all other lifetimes in a Rust program.
+Only values stored in the global data section (such as string constants
+and static items) can have the `static` lifetime;
+dynamically constructed values cannot safely be assigned the `static` lifetime.
 Static items are declared with the `static` keyword.
 A static item must have a _constant expression_ giving its definition.
 
@@ -1535,7 +1538,7 @@ Likewise, supertrait methods may also be called on trait objects.
 # impl Shape for int { fn area(&self) -> f64 { 0.0 } }
 # impl Circle for int { fn radius(&self) -> f64 { 0.0 } }
 # let mycircle = 0;
-let mycircle: Circle = ~mycircle as ~Circle;
+let mycircle = box mycircle as Box<Circle>;
 let nonsense = mycircle.radius() * mycircle.area();
 ~~~~
 
@@ -1870,13 +1873,13 @@ type int8_t = i8;
 - `crate_id` - specify the this crate's crate ID.
 - `crate_type` - see [linkage](#linkage).
 - `feature` - see [compiler features](#compiler-features).
+- `no_builtins` - disable optimizing certain code patterns to invocations of
+                  library functions that are assumed to exist
 - `no_main` - disable emitting the `main` symbol. Useful when some other
   object being linked to defines `main`.
 - `no_start` - disable linking to the `native` crate, which specifies the
   "start" language item.
 - `no_std` - disable linking to the `std` crate.
-- `no_builtins` - disable optimizing certain code patterns to invocations of
-                  library functions that are assumed to exist
 
 ### Module-only attributes
 
@@ -1890,10 +1893,10 @@ type int8_t = i8;
 
 ### Function-only attributes
 
-- `plugin_registrar` - mark this function as the registration point for
-  compiler plugins, such as loadable syntax extensions.
 - `main` - indicates that this function should be passed to the entry point,
   rather than the function in the crate root named `main`.
+- `plugin_registrar` - mark this function as the registration point for
+  compiler plugins, such as loadable syntax extensions.
 - `start` - indicates that this function should be used as the entry point,
   overriding the "start" language item.  See the "start" [language
   item](#language-items) for more details.
@@ -1925,6 +1928,8 @@ interpreted:
 
 ### Miscellaneous attributes
 
+- `export_name` - on statics and functions, this determines the name of the
+  exported symbol.
 - `link_section` - on statics and functions, this specifies the section of the
   object file that this item's contents will be placed into.
 - `macro_export` - export a macro for cross-crate usage.
@@ -1932,6 +1937,12 @@ interpreted:
   symbol for this item to its identifier.
 - `packed` - on structs or enums, eliminate any padding that would be used to
   align fields.
+- `phase` - on `extern crate` statements, allows specifying which "phase" of
+  compilation the crate should be loaded for. Currently, there are two
+  choices: `link` and `plugin`. `link` is the default. `plugin` will load the
+  crate at compile-time and use any syntax extensions or lints that the crate
+  defines. They can both be specified, `#[phase(link, plugin)]` to use a crate
+  both at runtime and compiletime.
 - `repr` - on C-like enums, this sets the underlying type used for
   representation. Useful for FFI. Takes one argument, which is the primitive
   type this enum should be represented for, or `C`, which specifies that it
@@ -1949,12 +1960,6 @@ interpreted:
 - `unsafe_no_drop_flag` - on structs, remove the flag that prevents
   destructors from being run twice. Destructors might be run multiple times on
   the same object with this attribute.
-- `phase` - on `extern crate` statements, allows specifying which "phase" of
-  compilation the crate should be loaded for. Currently, there are two
-  choices: `link` and `plugin`. `link` is the default. `plugin` will load the
-  crate at compile-time and use any syntax extensions or lints that the crate
-  defines. They can both be specified, `#[phase(link, plugin)]` to use a crate
-  both at runtime and compiletime.
 
 ### Conditional compilation
 
@@ -2021,12 +2026,12 @@ which the attribute applies.
 
 For any lint check `C`:
 
- * `warn(C)` warns about violations of `C` but continues compilation,
- * `deny(C)` signals an error after encountering a violation of `C`,
  * `allow(C)` overrides the check for `C` so that violations will go
     unreported,
+ * `deny(C)` signals an error after encountering a violation of `C`,
  * `forbid(C)` is the same as `deny(C)`, but also forbids changing the lint
-    level afterwards.
+    level afterwards,
+ * `warn(C)` warns about violations of `C` but continues compilation.
 
 The lint checks supported by the compiler can be found via `rustc -W help`,
 along with their default settings.
@@ -2105,16 +2110,16 @@ A complete list of the built-in language items follows:
 
 #### Built-in Traits
 
+* `copy`
+  : Types that do not move ownership when used by-value.
+* `drop`
+  : Have destructors.
 * `send`
   : Able to be sent across task boundaries.
 * `sized`
   : Has a size known at compile time.
-* `copy`
-  : Types that do not move ownership when used by-value.
 * `sync`
   : Able to be safely shared between tasks when aliased.
-* `drop`
-  : Have destructors.
 
 #### Operators
 
@@ -2146,6 +2151,8 @@ These language items are traits:
   : Elements have a right shift operation.
 * `index`
   : Elements can be indexed.
+* `index_mut`
+  : ___Needs filling in___
 * `eq`
   : Elements can be compared for equality.
 * `ord`
@@ -2155,9 +2162,14 @@ These language items are traits:
 * `deref_mut`
   : `*` can be applied, yielding a mutable reference to another type
 
-
 These are functions:
 
+* `fn`
+  : ___Needs filling in___
+* `fn_mut`
+  : ___Needs filling in___
+* `fn_once`
+  : ___Needs filling in___
 * `str_eq`
   : Compare two strings (`&str`) for equality.
 * `strdup_uniq`
@@ -2166,48 +2178,73 @@ These are functions:
 
 #### Types
 
-* `unsafe`
-  : A type whose contents can be mutated through an immutable reference
 * `type_id`
   : The type returned by the `type_id` intrinsic.
+* `unsafe`
+  : A type whose contents can be mutated through an immutable reference
 
 #### Marker types
 
 These types help drive the compiler's analysis
 
-* `covariant_type`
-  : The type parameter should be considered covariant
-* `contravariant_type`
-  : The type parameter should be considered contravariant
-* `invariant_type`
-  : The type parameter should be considered invariant
-* `covariant_lifetime`
-  : The lifetime parameter should be considered covariant
-* `contravariant_lifetime`
-  : The lifetime parameter should be considered contravariant
-* `invariant_lifetime`
-  : The lifetime parameter should be considered invariant
-* `no_send_bound`
-  : This type does not implement "send", even if eligible
+* `begin_unwind`
+  : ___Needs filling in___
 * `no_copy_bound`
   : This type does not implement "copy", even if eligible
+* `no_send_bound`
+  : This type does not implement "send", even if eligible
 * `no_sync_bound`
   : This type does not implement "sync", even if eligible
 * `managed_bound`
   : This type implements "managed"
-
+* `eh_personality`
+  : ___Needs filling in___
+* `exchange_free`
+  : Free memory that was allocated on the exchange heap.
+* `exchange_malloc`
+  : Allocate memory on the exchange heap.
+* `closure_exchange_malloc`
+  : ___Needs filling in___
 * `fail_`
   : Abort the program with an error.
 * `fail_bounds_check`
   : Abort the program with a bounds check error.
-* `exchange_malloc`
-  : Allocate memory on the exchange heap.
-* `exchange_free`
-  : Free memory that was allocated on the exchange heap.
-* `malloc`
-  : Allocate memory on the managed heap.
 * `free`
   : Free memory that was allocated on the managed heap.
+* `gc`
+  : ___Needs filling in___
+* `exchange_heap`
+  : ___Needs filling in___
+* `managed_heap`
+  : ___Needs filling in___
+* `iterator`
+  : ___Needs filling in___
+* `contravariant_lifetime`
+  : The lifetime parameter should be considered contravariant
+* `covariant_lifetime`
+  : The lifetime parameter should be considered covariant
+* `invariant_lifetime`
+  : The lifetime parameter should be considered invariant
+* `malloc`
+  : Allocate memory on the managed heap.
+* `opaque`
+  : ___Needs filling in___
+* `owned_box`
+  : ___Needs filling in___
+* `stack_exhausted`
+  : ___Needs filling in___
+* `start`
+  : ___Needs filling in___
+* `contravariant_type`
+  : The type parameter should be considered contravariant
+* `covariant_type`
+  : The type parameter should be considered covariant
+* `invariant_type`
+  : The type parameter should be considered invariant
+* `ty_desc`
+  : ___Needs filling in___
+* `ty_visitor`
+  : ___Needs filling in___
 
 > **Note:** This list is likely to become out of date. We should auto-generate it
 > from `librustc/middle/lang_items.rs`.
@@ -2276,12 +2313,12 @@ Supported traits for `deriving` are:
 * Comparison traits: `PartialEq`, `Eq`, `PartialOrd`, `Ord`.
 * Serialization: `Encodable`, `Decodable`. These require `serialize`.
 * `Clone`, to create `T` from `&T` via a copy.
-* `Hash`, to iterate over the bytes in a data type.
-* `Rand`, to create a random instance of a data type.
 * `Default`, to create an empty instance of a data type.
-* `Zero`, to create a zero instance of a numeric data type.
 * `FromPrimitive`, to create an instance from a numeric primitive.
+* `Hash`, to iterate over the bytes in a data type.
+* `Rand`, to create a random instance of a data type.
 * `Show`, to format a value using the `{}` formatter.
+* `Zero`, to create a zero instance of a numeric data type.
 
 ### Stability
 
@@ -2375,34 +2412,48 @@ considered off, and using the features will result in a compiler error.
 
 The currently implemented features of the reference compiler are:
 
-* `macro_rules` - The definition of new macros. This does not encompass
-                  macro-invocation, that is always enabled by default, this only
-                  covers the definition of new macros. There are currently
-                  various problems with invoking macros, how they interact with
-                  their environment, and possibly how they are used outside of
-                  location in which they are defined. Macro definitions are
-                  likely to change slightly in the future, so they are currently
-                  hidden behind this feature.
+* `asm` - The `asm!` macro provides a means for inline assembly. This is often
+          useful, but the exact syntax for this feature along with its semantics
+          are likely to change, so this macro usage must be opted into.
+
+* `concat_idents` - Allows use of the `concat_idents` macro, which is in many
+                    ways insufficient for concatenating identifiers, and may
+                    be removed entirely for something more wholsome.
+
+* `default_type_params` - Allows use of default type parameters. The future of
+                          this feature is uncertain.
 
 * `globs` - Importing everything in a module through `*`. This is currently a
             large source of bugs in name resolution for Rust, and it's not clear
             whether this will continue as a feature or not. For these reasons,
             the glob import statement has been hidden behind this feature flag.
 
-* `struct_variant` - Structural enum variants (those with named fields). It is
-                     currently unknown whether this style of enum variant is as
-                     fully supported as the tuple-forms, and it's not certain
-                     that this style of variant should remain in the language.
-                     For now this style of variant is hidden behind a feature
-                     flag.
+* `intrinsics` - Allows use of the "rust-intrinsics" ABI. Compiler intrinsics
+                 are inherently unstable and no promise about them is made.
 
-* `once_fns` - Onceness guarantees a closure is only executed once. Defining a
-               closure as `once` is unlikely to be supported going forward. So
-               they are hidden behind this feature until they are to be removed.
+* `lang_items` - Allows use of the `#[lang]` attribute. Like `intrinsics`,
+                 lang items are inherently unstable and no promise about
+                 them is made.
 
-* `asm` - The `asm!` macro provides a means for inline assembly. This is often
-          useful, but the exact syntax for this feature along with its semantics
-          are likely to change, so this macro usage must be opted into.
+* `link_args` - This attribute is used to specify custom flags to the linker,
+                but usage is strongly discouraged. The compiler's usage of the
+                system linker is not guaranteed to continue in the future, and
+                if the system linker is not used then specifying custom flags
+                doesn't have much meaning.
+
+* `linkage` - Allows use of the `linkage` attribute, which is not portable.
+
+* `log_syntax` - Allows use of the `log_syntax` macro attribute, which is a
+                 nasty hack that will certainly be removed.
+
+* `macro_rules` - The definition of new macros. This does not encompass
+                  macro-invocation, that is always enabled by default, this only
+                  covers the definition of new macros. There are currently
+                  various problems with invoking macros, how they interact with
+                  their environment, and possibly how they are used outside of
+                  location in which they are defined. Macro definitions are
+                  likely to change slightly in the future, so they are currently
+                  hidden behind this feature.
 
 * `managed_boxes` - Usage of `@` is gated due to many
                     planned changes to this feature. In the past, this has meant
@@ -2417,20 +2468,14 @@ The currently implemented features of the reference compiler are:
                        now until the specification of identifiers is fully
                        fleshed out.
 
-* `thread_local` - The usage of the `#[thread_local]` attribute is experimental
-                   and should be seen as unstable. This attribute is used to
-                   declare a `static` as being unique per-thread leveraging
-                   LLVM's implementation which works in concert with the kernel
-                   loader and dynamic linker. This is not necessarily available
-                   on all platforms, and usage of it is discouraged (rust
-                   focuses more on task-local data instead of thread-local
-                   data).
+* `once_fns` - Onceness guarantees a closure is only executed once. Defining a
+               closure as `once` is unlikely to be supported going forward. So
+               they are hidden behind this feature until they are to be removed.
 
-* `link_args` - This attribute is used to specify custom flags to the linker,
-                but usage is strongly discouraged. The compiler's usage of the
-                system linker is not guaranteed to continue in the future, and
-                if the system linker is not used then specifying custom flags
-                doesn't have much meaning.
+* `overloaded_calls` - Allow implementing the `Fn*` family of traits on user
+                       types, allowing overloading the call operator (`()`).
+                       This feature may still undergo changes before being
+                       stabilized.
 
 * `phase` - Usage of the `#[phase]` attribute allows loading compiler plugins
             for custom lints or syntax extensions. The implementation is considered
@@ -2442,56 +2487,48 @@ The currently implemented features of the reference compiler are:
                        in need of a overhaul, and it is not clear that plugins
                        defined using this will continue to work.
 
-* `log_syntax` - Allows use of the `log_syntax` macro attribute, which is a
-                 nasty hack that will certainly be removed.
-
-* `trace_macros` - Allows use of the `trace_macros` macro, which is a nasty
-                   hack that will certainly be removed.
-
-* `concat_idents` - Allows use of the `concat_idents` macro, which is in many
-                    ways insufficient for concatenating identifiers, and may
-                    be removed entirely for something more wholsome.
-
-* `unsafe_destructor` - Allows use of the `#[unsafe_destructor]` attribute,
-                        which is considered wildly unsafe and will be
-                        obsoleted by language improvements.
-
-* `intrinsics` - Allows use of the "rust-intrinsics" ABI. Compiler intrinsics
-                 are inherently unstable and no promise about them is made.
-
-* `lang_items` - Allows use of the `#[lang]` attribute. Like `intrinsics`,
-                 lang items are inherently unstable and no promise about
-                 them is made.
-
-* `simd` - Allows use of the `#[simd]` attribute, which is overly simple and
-           not the SIMD interface we want to expose in the long term.
-
-* `default_type_params` - Allows use of default type parameters. The future of
-                          this feature is uncertain.
-
 * `quote` - Allows use of the `quote_*!` family of macros, which are
             implemented very poorly and will likely change significantly
             with a proper implementation.
 
-* `linkage` - Allows use of the `linkage` attribute, which is not portable.
+* `rustc_diagnostic_macros`- A mysterious feature, used in the implementation
+                             of rustc, not meant for mortals.
+
+* `simd` - Allows use of the `#[simd]` attribute, which is overly simple and
+           not the SIMD interface we want to expose in the long term.
 
 * `struct_inherit` - Allows using struct inheritance, which is barely
                      implemented and will probably be removed. Don't use this.
 
-* `overloaded_calls` - Allow implementing the `Fn*` family of traits on user
-                       types, allowing overloading the call operator (`()`).
-                       This feature may still undergo changes before being
-                       stabilized.
+* `struct_variant` - Structural enum variants (those with named fields). It is
+                     currently unknown whether this style of enum variant is as
+                     fully supported as the tuple-forms, and it's not certain
+                     that this style of variant should remain in the language.
+                     For now this style of variant is hidden behind a feature
+                     flag.
+
+* `thread_local` - The usage of the `#[thread_local]` attribute is experimental
+                   and should be seen as unstable. This attribute is used to
+                   declare a `static` as being unique per-thread leveraging
+                   LLVM's implementation which works in concert with the kernel
+                   loader and dynamic linker. This is not necessarily available
+                   on all platforms, and usage of it is discouraged (rust
+                   focuses more on task-local data instead of thread-local
+                   data).
+
+* `trace_macros` - Allows use of the `trace_macros` macro, which is a nasty
+                   hack that will certainly be removed.
 
 * `unboxed_closure_sugar` - Allows using `|Foo| -> Bar` as a trait bound
                             meaning one of the `Fn` traits.  Still
                             experimental.
 
-* `rustc_diagnostic_macros`- A mysterious feature, used in the implementation
-                             of rustc, not meant for mortals.
-
 * `unboxed_closures` - A work in progress feature with many known bugs.
 
+* `unsafe_destructor` - Allows use of the `#[unsafe_destructor]` attribute,
+                        which is considered wildly unsafe and will be
+                        obsoleted by language improvements.
+
 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
@@ -2538,8 +2575,8 @@ within a statement block is simply a way of restricting its scope to a narrow
 region containing all of its uses; it is otherwise identical in meaning to
 declaring the item outside the statement block.
 
-Note: there is no implicit capture of the function's dynamic environment when
-declaring a function-local item.
+> **Note**: there is no implicit capture of the function's dynamic environment when
+declaring a function-local item.
 
 #### Slot declarations
 
@@ -3621,7 +3658,10 @@ There are four varieties of pointer in Rust:
     References arise by (automatic) conversion from owning pointers, managed pointers,
     or by applying the borrowing operator `&` to some other value,
     including [lvalues, rvalues or temporaries](#lvalues,-rvalues-and-temporaries).
-    References are written `&content`, or in some cases `&'f content` for some lifetime-variable `f`,
+    A borrow expression is written `&content`.
+
+    A reference type is written `&'f type` for some lifetime-variable `f`,
+    or just `&type` when the lifetime can be elided;
     for example `&int` means a reference to an integer.
     Copying a reference is a "shallow" operation:
     it involves only copying the pointer itself.
index 113c192ec07bf46b0a5c77e24965a5900b1eda88..5d0f35fbd6064811f28e6e1459f3b629b86c8978 100644 (file)
@@ -61,13 +61,15 @@ for llconfig in sys.argv[4:]:
     elif 'android' in os:
         os = 'android'
     elif 'win' in os or 'mingw' in os:
-        os = 'win32'
+        os = 'windows'
     cfg = [
         "target_arch = \"" + arch + "\"",
         "target_os = \"" + os + "\"",
     ]
 
     f.write("#[cfg(" + ', '.join(cfg) + ")]\n")
+    if os == "windows": # NOTE: Remove after snapshot
+        f.write("#[cfg(stage0, target_arch = \"%s\", target_os = \"win32\")]\n" % (arch,))
 
     version = run([llconfig, '--version']).strip()
 
index 5424cd3b3ab98e1c0e203927d81a184d57068d9e..7663cd1e3466abb3d0bfb1ff5d67d455e8aa86f7 100755 (executable)
@@ -293,13 +293,12 @@ def emit_bsearch_range_table(f):
     f.write("""
 fn bsearch_range_table(c: char, r: &'static [(char,char)]) -> bool {
     use core::cmp::{Equal, Less, Greater};
-    use core::slice::ImmutableVector;
-    use core::option::None;
-    r.bsearch(|&(lo,hi)| {
+    use core::slice::ImmutableSlice;
+    r.binary_search(|&(lo,hi)| {
         if lo <= c && c <= hi { Equal }
         else if hi < c { Less }
         else { Greater }
-    }) != None
+    }).found().is_some()
 }\n
 """)
 
@@ -352,9 +351,10 @@ def emit_conversions_module(f, lowerupper, upperlower):
     f.write("pub mod conversions {")
     f.write("""
     use core::cmp::{Equal, Less, Greater};
-    use core::slice::ImmutableVector;
+    use core::slice::ImmutableSlice;
     use core::tuple::Tuple2;
     use core::option::{Option, Some, None};
+    use core::slice;
 
     pub fn to_lower(c: char) -> char {
         match bsearch_case_table(c, LuLl_table) {
@@ -371,11 +371,14 @@ def emit_conversions_module(f, lowerupper, upperlower):
     }
 
     fn bsearch_case_table(c: char, table: &'static [(char, char)]) -> Option<uint> {
-        table.bsearch(|&(key, _)| {
+        match table.binary_search(|&(key, _)| {
             if c == key { Equal }
             else if key < c { Less }
             else { Greater }
-        })
+        }) {
+            slice::Found(i) => Some(i),
+            slice::NotFound(_) => None,
+        }
     }
 
 """)
@@ -387,8 +390,8 @@ def emit_conversions_module(f, lowerupper, upperlower):
 
 def emit_grapheme_module(f, grapheme_table, grapheme_cats):
     f.write("""pub mod grapheme {
-    use core::option::{Some, None};
-    use core::slice::ImmutableVector;
+    use core::slice::ImmutableSlice;
+    use core::slice;
 
     #[allow(non_camel_case_types)]
     #[deriving(Clone)]
@@ -400,16 +403,16 @@ def emit_grapheme_module(f, grapheme_table, grapheme_cats):
 
     fn bsearch_range_value_table(c: char, r: &'static [(char, char, GraphemeCat)]) -> GraphemeCat {
         use core::cmp::{Equal, Less, Greater};
-        match r.bsearch(|&(lo, hi, _)| {
+        match r.binary_search(|&(lo, hi, _)| {
             if lo <= c && c <= hi { Equal }
             else if hi < c { Less }
             else { Greater }
         }) {
-            Some(idx) => {
+            slice::Found(idx) => {
                 let (_, _, cat) = r[idx];
                 cat
             }
-            None => GC_Any
+            slice::NotFound(_) => GC_Any
         }
     }
 
@@ -427,20 +430,21 @@ def emit_grapheme_module(f, grapheme_table, grapheme_cats):
 def emit_charwidth_module(f, width_table):
     f.write("pub mod charwidth {\n")
     f.write("    use core::option::{Option, Some, None};\n")
-    f.write("    use core::slice::ImmutableVector;\n")
+    f.write("    use core::slice::ImmutableSlice;\n")
+    f.write("    use core::slice;\n")
     f.write("""
     fn bsearch_range_value_table(c: char, is_cjk: bool, r: &'static [(char, char, u8, u8)]) -> u8 {
         use core::cmp::{Equal, Less, Greater};
-        match r.bsearch(|&(lo, hi, _, _)| {
+        match r.binary_search(|&(lo, hi, _, _)| {
             if lo <= c && c <= hi { Equal }
             else if hi < c { Less }
             else { Greater }
         }) {
-            Some(idx) => {
+            slice::Found(idx) => {
                 let (_, _, r_ncjk, r_cjk) = r[idx];
                 if is_cjk { r_cjk } else { r_ncjk }
             }
-            None => 1
+            slice::NotFound(_) => 1
         }
     }
 """)
@@ -525,19 +529,19 @@ def emit_norm_module(f, canon, compat, combine, norm_props):
 
     f.write("""
     fn bsearch_range_value_table(c: char, r: &'static [(char, char, u8)]) -> u8 {
-        use core::option::{Some, None};
         use core::cmp::{Equal, Less, Greater};
-        use core::slice::ImmutableVector;
-        match r.bsearch(|&(lo, hi, _)| {
+        use core::slice::ImmutableSlice;
+        use core::slice;
+        match r.binary_search(|&(lo, hi, _)| {
             if lo <= c && c <= hi { Equal }
             else if hi < c { Less }
             else { Greater }
         }) {
-            Some(idx) => {
+            slice::Found(idx) => {
                 let (_, _, result) = r[idx];
                 result
             }
-            None => 0
+            slice::NotFound(_) => 0
         }
     }\n
 """)
index 1ab8394e565a07e975180bfc73ca0fdb77f59a33..735c1e153a60dc070662d424cfcf1eef2714f6d4 100644 (file)
@@ -29,5 +29,3 @@ hi link rustNiceOperator Operator
 if !exists('g:rust_conceal_mod_path')
     hi! link Conceal Operator
 endif
-
-setlocal conceallevel=2
index 39edc1f9a20d754f880999235f63f1d1c35d1a92..8a538177403d35ff58b7ddc823e3c713d361d163 100644 (file)
@@ -56,6 +56,11 @@ if exists("g:loaded_delimitMate")
        let b:delimitMate_excluded_regions = delimitMate#Get("excluded_regions") . ',rustLifetimeCandidate,rustGenericLifetimeCandidate'
 endif
 
+if has('conceal') && exists('g:rust_conceal')
+       let b:rust_set_conceallevel=1
+       setlocal conceallevel=2
+endif
+
 " Motion Commands {{{1
 
 " Bind motion commands to support hanging indents
@@ -103,6 +108,10 @@ let b:undo_ftplugin = "
                \|else
                  \|unlet! b:delimitMate_excluded_regions
                \|endif
+               \|if exists('b:rust_set_conceallevel')
+                 \|setlocal conceallevel<
+                 \|unlet b:rust_set_conceallevel
+               \|endif
                \|unlet! b:rust_last_rustc_args b:rust_last_args
                \|delcommand RustRun
                \|delcommand RustExpand
index 6f8b63953e2b495d4f8a60ca6bbd95f05cc96448..dd07e718af418f05f55da322eb84d2635d8c1473 100644 (file)
@@ -296,7 +296,7 @@ mod tests {
     use std::prelude::*;
     use std::mem;
 
-    use slice::ImmutableVector;
+    use slice::ImmutableSlice;
     use super::{Hash, Hasher, Writer};
 
     struct MyWriterHasher;
index 485dc8c5959b74f3d5dae4650bd8451e8398fbcb..b31d811c2c966596aac6c572cc44f458836602c0 100644 (file)
@@ -275,7 +275,7 @@ mod tests {
 
     use str::Str;
     use string::String;
-    use slice::{Vector, ImmutableVector};
+    use slice::{Slice, ImmutableSlice};
     use vec::Vec;
 
     use super::super::{Hash, Writer};
index ce08f169366dad8fb0937ad13ae460a12210cf3e..354beb56d2dc3cbcf8386a2bdaf8d258e92f9418 100644 (file)
@@ -362,6 +362,7 @@ pub struct MutItems<'a, T> {
 
 impl<'a, T> Iterator<&'a mut T> for MutItems<'a, T> {
     #[inline]
+    #[allow(deprecated)] // mut_shift_ref
     fn next(&mut self) -> Option<&'a mut T> {
         if self.nelts == 0 {
             return None;
@@ -384,6 +385,7 @@ fn size_hint(&self) -> (uint, Option<uint>) {
 
 impl<'a, T> DoubleEndedIterator<&'a mut T> for MutItems<'a, T> {
     #[inline]
+    #[allow(deprecated)] // mut_shift_ref
     fn next_back(&mut self) -> Option<&'a mut T> {
         if self.nelts == 0 {
             return None;
index 4c7c7e3ea74bb1fa8bbd7171ac840798b1f6c1e5..aac5b24fa6f02e4bbba57ac5f3ab60af2ad65a1d 100644 (file)
@@ -45,8 +45,8 @@
 ## Traits
 
 A number of traits add methods that allow you to accomplish tasks with slices.
-These traits include `ImmutableVector`, which is defined for `&[T]` types,
-and `MutableVector`, defined for `&mut [T]` types.
+These traits include `ImmutableSlice`, which is defined for `&[T]` types,
+and `MutableSlice`, defined for `&mut [T]` types.
 
 An example is the method `.slice(a, b)` that returns an immutable "view" into
 a `Vec` or another slice from the index interval `[a, b)`:
 use vec::Vec;
 
 pub use core::slice::{ref_slice, mut_ref_slice, Splits, Windows};
-pub use core::slice::{Chunks, Vector, ImmutableVector, ImmutableEqVector};
-pub use core::slice::{ImmutableOrdVector, MutableVector, Items, MutItems};
+pub use core::slice::{Chunks, Slice, ImmutableSlice, ImmutablePartialEqSlice};
+pub use core::slice::{ImmutableOrdSlice, MutableSlice, Items, MutItems};
 pub use core::slice::{MutSplits, MutChunks};
-pub use core::slice::{bytes, MutableCloneableVector};
+pub use core::slice::{bytes, MutableCloneableSlice};
+pub use core::slice::{BinarySearchResult, Found, NotFound};
 
 // Functional utilities
 
@@ -116,7 +117,7 @@ pub trait VectorVector<T> {
     fn connect_vec(&self, sep: &T) -> Vec<T>;
 }
 
-impl<'a, T: Clone, V: Vector<T>> VectorVector<T> for &'a [V] {
+impl<'a, T: Clone, V: Slice<T>> VectorVector<T> for &'a [V] {
     fn concat_vec(&self) -> Vec<T> {
         let size = self.iter().fold(0u, |acc, v| acc + v.as_slice().len());
         let mut result = Vec::with_capacity(size);
@@ -558,7 +559,7 @@ unsafe fn step<T>(ptr: &mut *mut T) -> *mut T {
 
 /// Extension methods for vectors such that their elements are
 /// mutable.
-pub trait MutableVectorAllocating<'a, T> {
+pub trait MutableSliceAllocating<'a, T> {
     /// Sort the vector, in place, using `compare` to compare
     /// elements.
     ///
@@ -604,7 +605,7 @@ pub trait MutableVectorAllocating<'a, T> {
     fn move_from(self, src: Vec<T>, start: uint, end: uint) -> uint;
 }
 
-impl<'a,T> MutableVectorAllocating<'a, T> for &'a mut [T] {
+impl<'a,T> MutableSliceAllocating<'a, T> for &'a mut [T] {
     #[inline]
     fn sort_by(self, compare: |&T, &T| -> Ordering) {
         merge_sort(self, compare)
@@ -621,7 +622,7 @@ fn move_from(self, mut src: Vec<T>, start: uint, end: uint) -> uint {
 
 /// Methods for mutable vectors with orderable elements, such as
 /// in-place sorting.
-pub trait MutableOrdVector<T> {
+pub trait MutableOrdSlice<T> {
     /// Sort the vector, in place.
     ///
     /// This is equivalent to `self.sort_by(|a, b| a.cmp(b))`.
@@ -667,7 +668,7 @@ pub trait MutableOrdVector<T> {
     fn prev_permutation(self) -> bool;
 }
 
-impl<'a, T: Ord> MutableOrdVector<T> for &'a mut [T] {
+impl<'a, T: Ord> MutableOrdSlice<T> for &'a mut [T] {
     #[inline]
     fn sort(self) {
         self.sort_by(|a,b| a.cmp(b))
index d911ca6bb14f9824d080449f2729131e6053e8eb..60ee8cc04f74c667e4f05a9479f91915f581930b 100644 (file)
@@ -894,7 +894,7 @@ mod tests {
     use {Collection, MutableSeq};
 
     use super::*;
-    use std::slice::{Vector, ImmutableVector};
+    use std::slice::{Slice, ImmutableSlice};
     use string::String;
     use vec::Vec;
 
@@ -1812,17 +1812,17 @@ fn test_split_char_iterator() {
     fn test_splitn_char_iterator() {
         let data = "\nMäry häd Ã¤ little lämb\nLittle lämb\n";
 
-        let split: Vec<&str> = data.splitn(' ', 3).collect();
+        let split: Vec<&str> = data.splitn(3, ' ').collect();
         assert_eq!(split, vec!["\nMäry", "häd", "ä", "little lämb\nLittle lämb\n"]);
 
-        let split: Vec<&str> = data.splitn(|c: char| c == ' ', 3).collect();
+        let split: Vec<&str> = data.splitn(3, |c: char| c == ' ').collect();
         assert_eq!(split, vec!["\nMäry", "häd", "ä", "little lämb\nLittle lämb\n"]);
 
         // Unicode
-        let split: Vec<&str> = data.splitn('ä', 3).collect();
+        let split: Vec<&str> = data.splitn(3, 'ä').collect();
         assert_eq!(split, vec!["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]);
 
-        let split: Vec<&str> = data.splitn(|c: char| c == 'ä', 3).collect();
+        let split: Vec<&str> = data.splitn(3, |c: char| c == 'ä').collect();
         assert_eq!(split, vec!["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]);
     }
 
@@ -1830,20 +1830,20 @@ fn test_splitn_char_iterator() {
     fn test_rsplitn_char_iterator() {
         let data = "\nMäry häd Ã¤ little lämb\nLittle lämb\n";
 
-        let mut split: Vec<&str> = data.rsplitn(' ', 3).collect();
+        let mut split: Vec<&str> = data.rsplitn(3, ' ').collect();
         split.reverse();
         assert_eq!(split, vec!["\nMäry häd Ã¤", "little", "lämb\nLittle", "lämb\n"]);
 
-        let mut split: Vec<&str> = data.rsplitn(|c: char| c == ' ', 3).collect();
+        let mut split: Vec<&str> = data.rsplitn(3, |c: char| c == ' ').collect();
         split.reverse();
         assert_eq!(split, vec!["\nMäry häd Ã¤", "little", "lämb\nLittle", "lämb\n"]);
 
         // Unicode
-        let mut split: Vec<&str> = data.rsplitn('ä', 3).collect();
+        let mut split: Vec<&str> = data.rsplitn(3, 'ä').collect();
         split.reverse();
         assert_eq!(split, vec!["\nMäry häd ", " little l", "mb\nLittle l", "mb\n"]);
 
-        let mut split: Vec<&str> = data.rsplitn(|c: char| c == 'ä', 3).collect();
+        let mut split: Vec<&str> = data.rsplitn(3, |c: char| c == 'ä').collect();
         split.reverse();
         assert_eq!(split, vec!["\nMäry häd ", " little l", "mb\nLittle l", "mb\n"]);
     }
index 952f28da2af891980a6bafc96d723979fdb39b1f..3b9e2ac72dc4b02952976d03a9bf8ab850ba0c41 100644 (file)
 use core::fmt;
 use core::mem;
 use core::ptr;
-use core::raw::Slice;
+// FIXME: ICE's abound if you import the `Slice` type while importing `Slice` trait
+use RawSlice = core::raw::Slice;
+use core::slice::Slice;
 
 use {Collection, Mutable, MutableSeq};
 use hash;
 use str;
-use str::{CharRange, StrAllocating, MaybeOwned, Owned, Slice};
+use str::{CharRange, StrAllocating, MaybeOwned, Owned};
+use MaybeOwnedSlice = str::Slice; // So many `Slice`s...
 use vec::Vec;
 
 /// A growable string stored as a UTF-8 encoded buffer.
@@ -130,7 +133,7 @@ pub fn from_utf8(vec: Vec<u8>) -> Result<String, Vec<u8>> {
     /// ```
     pub fn from_utf8_lossy<'a>(v: &'a [u8]) -> MaybeOwned<'a> {
         if str::is_utf8(v) {
-            return Slice(unsafe { mem::transmute(v) })
+            return MaybeOwnedSlice(unsafe { mem::transmute(v) })
         }
 
         static TAG_CONT_U8: u8 = 128u8;
@@ -138,7 +141,7 @@ pub fn from_utf8_lossy<'a>(v: &'a [u8]) -> MaybeOwned<'a> {
         let mut i = 0;
         let total = v.len();
         fn unsafe_get(xs: &[u8], i: uint) -> u8 {
-            unsafe { *xs.unsafe_ref(i) }
+            unsafe { *xs.unsafe_get(i) }
         }
         fn safe_get(xs: &[u8], i: uint, total: uint) -> u8 {
             if i >= total {
@@ -496,7 +499,7 @@ pub fn push_char(&mut self, ch: char) {
         unsafe {
             // Attempt to not use an intermediate buffer by just pushing bytes
             // directly onto this string.
-            let slice = Slice {
+            let slice = RawSlice {
                 data: self.vec.as_ptr().offset(cur_len as int),
                 len: 4,
             };
index c3dcebfc815b1fd4cddbe1715e4d733a30ff7139..dcfe256807467fdeaa9f3f59867153d3e1aa68c9 100644 (file)
@@ -926,7 +926,7 @@ unsafe fn new() -> $name<'a, T> {
                 // such thing as invalid pointers and memory unsafety. The
                 // reason is performance, without doing this we can get the
                 // bench_iter_large microbenchmark down to about 30000 ns/iter
-                // (using .unsafe_ref to index self.stack directly, 38000
+                // (using .unsafe_get to index self.stack directly, 38000
                 // ns/iter with [] checked indexing), but this smashes that down
                 // to 13500 ns/iter.
                 //
index 6bda0eed66dd937c66e3b3ff2d221eed6b2d804f..b49e8aa01bb4101044108818880a2052256e5a8c 100644 (file)
@@ -13,7 +13,8 @@
 use core::prelude::*;
 
 use alloc::heap::{allocate, reallocate, deallocate};
-use core::raw::Slice;
+use RawSlice = core::raw::Slice;
+use core::slice::Slice;
 use core::cmp::max;
 use core::default::Default;
 use core::fmt;
@@ -24,7 +25,7 @@
 use core::uint;
 
 use {Collection, Mutable, MutableSeq};
-use slice::{MutableOrdVector, MutableVectorAllocating, CloneableVector};
+use slice::{MutableOrdSlice, MutableSliceAllocating, CloneableVector};
 use slice::{Items, MutItems};
 
 
@@ -347,7 +348,7 @@ pub fn push_all(&mut self, other: &[T]) {
             unsafe {
                 ptr::write(
                     self.as_mut_slice().unsafe_mut_ref(len),
-                    other.unsafe_ref(i).clone());
+                    other.unsafe_get(i).clone());
                 self.set_len(len + 1);
             }
         }
@@ -506,7 +507,7 @@ fn partial_cmp(&self, other: &Vec<T>) -> Option<Ordering> {
 
 impl<T: Eq> Eq for Vec<T> {}
 
-impl<T: PartialEq, V: Vector<T>> Equiv<V> for Vec<T> {
+impl<T: PartialEq, V: Slice<T>> Equiv<V> for Vec<T> {
     #[inline]
     fn equiv(&self, other: &V) -> bool { self.as_slice() == other.as_slice() }
 }
@@ -702,7 +703,7 @@ pub fn truncate(&mut self, len: uint) {
                 // decrement len before the read(), so a failure on Drop doesn't
                 // re-drop the just-failed value.
                 self.len -= 1;
-                ptr::read(self.as_slice().unsafe_ref(self.len));
+                ptr::read(self.as_slice().unsafe_get(self.len));
             }
         }
     }
@@ -720,7 +721,7 @@ pub fn truncate(&mut self, len: uint) {
     #[inline]
     pub fn as_mut_slice<'a>(&'a mut self) -> &'a mut [T] {
         unsafe {
-            mem::transmute(Slice {
+            mem::transmute(RawSlice {
                 data: self.as_mut_ptr() as *const T,
                 len: self.len,
             })
@@ -911,8 +912,9 @@ pub fn tail<'a>(&'a self) -> &'a [T] {
     /// assert!(vec.tailn(2) == [3, 4]);
     /// ```
     #[inline]
+    #[deprecated = "use slice_from"]
     pub fn tailn<'a>(&'a self, n: uint) -> &'a [T] {
-        self.as_slice().tailn(n)
+        self.as_slice().slice_from(n)
     }
 
     /// Returns a reference to the last element of a vector, or `None` if it is
@@ -1502,7 +1504,7 @@ pub fn dedup(&mut self) {
     }
 }
 
-impl<T> Vector<T> for Vec<T> {
+impl<T> Slice<T> for Vec<T> {
     /// Work with `self` as a slice.
     ///
     /// # Example
@@ -1515,11 +1517,11 @@ impl<T> Vector<T> for Vec<T> {
     /// ```
     #[inline]
     fn as_slice<'a>(&'a self) -> &'a [T] {
-        unsafe { mem::transmute(Slice { data: self.as_ptr(), len: self.len }) }
+        unsafe { mem::transmute(RawSlice { data: self.as_ptr(), len: self.len }) }
     }
 }
 
-impl<T: Clone, V: Vector<T>> Add<V, Vec<T>> for Vec<T> {
+impl<T: Clone, V: Slice<T>> Add<V, Vec<T>> for Vec<T> {
     #[inline]
     fn add(&self, rhs: &V) -> Vec<T> {
         let mut res = Vec::with_capacity(self.len() + rhs.as_slice().len());
@@ -1604,7 +1606,7 @@ fn pop(&mut self) -> Option<T> {
         } else {
             unsafe {
                 self.len -= 1;
-                Some(ptr::read(self.as_slice().unsafe_ref(self.len())))
+                Some(ptr::read(self.as_slice().unsafe_get(self.len())))
             }
         }
     }
index a2537a1281e918480763f5db85ac022391819eb3..bfd10c835e2061a64b71e5d3bfa13f8172bd894a 100644 (file)
@@ -273,7 +273,7 @@ mod impls {
               Less, Greater, Equal};
     use option::{Option, Some, None};
 
-    macro_rules! eq_impl(
+    macro_rules! partial_eq_impl(
         ($($t:ty)*) => ($(
             #[unstable = "Trait is unstable."]
             impl PartialEq for $t {
@@ -293,18 +293,18 @@ fn eq(&self, _other: &()) -> bool { true }
         fn ne(&self, _other: &()) -> bool { false }
     }
 
-    eq_impl!(bool char uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64)
+    partial_eq_impl!(bool char uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64)
 
-    macro_rules! totaleq_impl(
+    macro_rules! eq_impl(
         ($($t:ty)*) => ($(
             #[unstable = "Trait is unstable."]
             impl Eq for $t {}
         )*)
     )
 
-    totaleq_impl!(() bool char uint u8 u16 u32 u64 int i8 i16 i32 i64)
+    eq_impl!(() bool char uint u8 u16 u32 u64 int i8 i16 i32 i64)
 
-    macro_rules! ord_impl(
+    macro_rules! partial_ord_impl(
         ($($t:ty)*) => ($(
             #[unstable = "Trait is unstable."]
             impl PartialOrd for $t {
@@ -345,9 +345,9 @@ fn partial_cmp(&self, other: &bool) -> Option<Ordering> {
         }
     }
 
-    ord_impl!(char uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64)
+    partial_ord_impl!(char uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64)
 
-    macro_rules! totalord_impl(
+    macro_rules! ord_impl(
         ($($t:ty)*) => ($(
             #[unstable = "Trait is unstable."]
             impl Ord for $t {
@@ -375,7 +375,7 @@ fn cmp(&self, other: &bool) -> Ordering {
         }
     }
 
-    totalord_impl!(char uint u8 u16 u32 u64 int i8 i16 i32 i64)
+    ord_impl!(char uint u8 u16 u32 u64 int i8 i16 i32 i64)
 
     // & pointers
     #[unstable = "Trait is unstable."]
index 1bfa5168cf7960adf8d63eb15cc975509129ec1c..3a07e43e50993d3dbf3b18c63aac7d533b2f6044 100644 (file)
@@ -17,7 +17,7 @@
 use num::{Float, FPNaN, FPInfinite, ToPrimitive, Primitive};
 use num::{Zero, One, cast};
 use result::Ok;
-use slice::{ImmutableVector, MutableVector};
+use slice::{ImmutableSlice, MutableSlice};
 use slice;
 use str::StrSlice;
 
index 9cb64747c91b42ca2e73b144e57b8a80b10f0257..942f7f8b71019f2db0ecdf495b620f86a92caf9b 100644 (file)
@@ -24,7 +24,7 @@
 use ops::Deref;
 use result::{Ok, Err};
 use result;
-use slice::{Vector, ImmutableVector};
+use slice::{Slice, ImmutableSlice};
 use slice;
 use str::StrSlice;
 use str;
index bba3e4cb9afccdef116e3419940e091cea6d4c34..21cbafdc60538b1052058bca2a832038c2dfacb6 100644 (file)
@@ -18,7 +18,7 @@
 use fmt;
 use iter::DoubleEndedIterator;
 use num::{Int, cast, zero};
-use slice::{ImmutableVector, MutableVector};
+use slice::{ImmutableSlice, MutableSlice};
 
 /// A type that represents a specific radix
 #[doc(hidden)]
index f8293aeb03d1910651677ceb44175a797730e9ab..74d87712a02ef96cc6d36a44a0f6f3558077fa87 100644 (file)
 
 use cmp::{PartialEq, Eq, Ord};
 use default::Default;
-use slice::Vector;
+use slice::Slice;
 use iter::{Iterator, DoubleEndedIterator, FromIterator, ExactSize};
 use mem;
 use slice;
@@ -518,7 +518,7 @@ pub fn unwrap_or_default(self) -> T {
 // Trait implementations
 /////////////////////////////////////////////////////////////////////////////
 
-impl<T> Vector<T> for Option<T> {
+impl<T> Slice<T> for Option<T> {
     /// Convert from `Option<T>` to `&[T]` (without copying)
     #[inline]
     fn as_slice<'a>(&'a self) -> &'a [T] {
index 5b7c7c8f31a6f2a80a4615801c93f20ac658bdf5..ead48092c4dcf46163cdc8e784b8ab2f00da1428 100644 (file)
@@ -61,6 +61,6 @@
 pub use tuple::{Tuple1, Tuple2, Tuple3, Tuple4};
 pub use tuple::{Tuple5, Tuple6, Tuple7, Tuple8};
 pub use tuple::{Tuple9, Tuple10, Tuple11, Tuple12};
-pub use slice::{ImmutableEqVector, ImmutableOrdVector};
-pub use slice::{MutableVector};
-pub use slice::{Vector, ImmutableVector};
+pub use slice::{ImmutablePartialEqSlice, ImmutableOrdSlice};
+pub use slice::{MutableSlice};
+pub use slice::{Slice, ImmutableSlice};
index d3b761f9665d425f78efd8f101d8f69a02f7434c..93dafc153b6b206878f5547f072e4c6718f1ae4a 100644 (file)
@@ -12,6 +12,7 @@
 //!
 //! For more details `std::slice`.
 
+#![stable]
 #![doc(primitive = "slice")]
 
 // How this module is organized.
 use mem;
 use mem::size_of;
 use kinds::marker;
-use raw::{Repr, Slice};
+use raw::Repr;
+// Avoid conflicts with *both* the Slice trait (buggy) and the `slice::raw` module.
+use RawSlice = raw::Slice;
+
 
 //
 // Extension traits
 //
 
 /// Extension methods for vectors
-pub trait ImmutableVector<'a, T> {
+#[unstable = "may merge with other traits; region parameter may disappear"]
+pub trait ImmutableSlice<'a, T> {
     /**
      * Returns a slice of self spanning the interval [`start`, `end`).
      *
      * Fails when the slice (or part of it) is outside the bounds of self,
      * or when `start` > `end`.
      */
+    #[unstable]
     fn slice(&self, start: uint, end: uint) -> &'a [T];
 
     /**
@@ -68,6 +74,7 @@ pub trait ImmutableVector<'a, T> {
      *
      * Fails when `start` points outside the bounds of self.
      */
+    #[unstable]
     fn slice_from(&self, start: uint) -> &'a [T];
 
     /**
@@ -75,6 +82,7 @@ pub trait ImmutableVector<'a, T> {
      *
      * Fails when `end` points outside the bounds of self.
      */
+    #[unstable]
     fn slice_to(&self, end: uint) -> &'a [T];
 
     /// Divides one slice into two at an index.
@@ -84,24 +92,29 @@ pub trait ImmutableVector<'a, T> {
     /// indices from `[mid, len)` (excluding the index `len` itself).
     ///
     /// Fails if `mid > len`.
+    #[unstable]
     fn split_at(&self, mid: uint) -> (&'a [T], &'a [T]);
 
     /// Returns an iterator over the vector
+    #[unstable = "iterator type may change"]
     fn iter(self) -> Items<'a, T>;
     /// Returns an iterator over the subslices of the vector which are
     /// separated by elements that match `pred`.  The matched element
     /// is not contained in the subslices.
+    #[unstable = "iterator type may change"]
     fn split(self, pred: |&T|: 'a -> bool) -> Splits<'a, T>;
     /// Returns an iterator over the subslices of the vector which are
     /// separated by elements that match `pred`, limited to splitting
     /// at most `n` times.  The matched element is not contained in
     /// the subslices.
+    #[unstable = "iterator type may change"]
     fn splitn(self, n: uint, pred: |&T|: 'a -> bool) -> SplitsN<'a, T>;
     /// Returns an iterator over the subslices of the vector which are
     /// separated by elements that match `pred` limited to splitting
     /// at most `n` times. This starts at the end of the vector and
     /// works backwards.  The matched element is not contained in the
     /// subslices.
+    #[unstable = "iterator type may change"]
     fn rsplitn(self,  n: uint, pred: |&T|: 'a -> bool) -> SplitsN<'a, T>;
 
     /**
@@ -126,6 +139,7 @@ pub trait ImmutableVector<'a, T> {
      * ```
      *
      */
+    #[unstable = "iterator type may change"]
     fn windows(self, size: uint) -> Windows<'a, T>;
     /**
      *
@@ -151,28 +165,42 @@ pub trait ImmutableVector<'a, T> {
      * ```
      *
      */
+    #[unstable = "iterator type may change"]
     fn chunks(self, size: uint) -> Chunks<'a, T>;
 
     /// Returns the element of a vector at the given index, or `None` if the
     /// index is out of bounds
+    #[unstable]
     fn get(&self, index: uint) -> Option<&'a T>;
     /// Returns the first element of a vector, or `None` if it is empty
+    #[unstable = "name may change"]
     fn head(&self) -> Option<&'a T>;
     /// Returns all but the first element of a vector
+    #[unstable = "name may change"]
     fn tail(&self) -> &'a [T];
     /// Returns all but the first `n' elements of a vector
+    #[deprecated = "use slice_from"]
     fn tailn(&self, n: uint) -> &'a [T];
     /// Returns all but the last element of a vector
+    #[unstable = "name may change"]
     fn init(&self) -> &'a [T];
     /// Returns all but the last `n' elements of a vector
+    #[deprecated = "use slice_to but note the arguments are different"]
     fn initn(&self, n: uint) -> &'a [T];
     /// Returns the last element of a vector, or `None` if it is empty.
+    #[unstable = "name may change"]
     fn last(&self) -> Option<&'a T>;
 
     /// Returns a pointer to the element at the given index, without doing
     /// bounds checking.
+    #[deprecated = "renamed to `unsafe_get`"]
     unsafe fn unsafe_ref(self, index: uint) -> &'a T;
 
+    /// Returns a pointer to the element at the given index, without doing
+    /// bounds checking.
+    #[unstable]
+    unsafe fn unsafe_get(self, index: uint) -> &'a T;
+
     /**
      * Returns an unsafe pointer to the vector's buffer
      *
@@ -182,6 +210,7 @@ pub trait ImmutableVector<'a, T> {
      * Modifying the vector may cause its buffer to be reallocated, which
      * would also make any pointers to it invalid.
      */
+    #[unstable]
     fn as_ptr(&self) -> *const T;
 
     /**
@@ -195,8 +224,23 @@ pub trait ImmutableVector<'a, T> {
      * Returns the index where the comparator returned `Equal`, or `None` if
      * not found.
      */
+    #[deprecated = "use binary_search"]
     fn bsearch(&self, f: |&T| -> Ordering) -> Option<uint>;
 
+    /// Binary search a sorted vector with a comparator function.
+    ///
+    /// The comparator function should implement an order consistent
+    /// with the sort order of the underlying vector, returning an
+    /// order code that indicates whether its argument is `Less`,
+    /// `Equal` or `Greater` the desired target.
+    ///
+    /// If the value is found then `Found` is returned, containing the
+    /// index of the matching element; if the value is not found then
+    /// `NotFound` is returned, containing the index where a matching
+    /// element could be inserted while maintaining sorted order.
+    #[unstable]
+    fn binary_search(&self, f: |&T| -> Ordering) -> BinarySearchResult;
+
     /**
      * Returns an immutable reference to the first element in this slice
      * and adjusts the slice in place so that it no longer contains
@@ -213,6 +257,7 @@ pub trait ImmutableVector<'a, T> {
      *
      * Returns `None` if vector is empty
      */
+    #[deprecated = "find some other way. sorry"]
     fn shift_ref(&mut self) -> Option<&'a T>;
 
     /**
@@ -231,16 +276,18 @@ pub trait ImmutableVector<'a, T> {
      *
      * Returns `None` if slice is empty.
      */
+    #[deprecated = "find some other way. sorry"]
     fn pop_ref(&mut self) -> Option<&'a T>;
 }
 
-impl<'a,T> ImmutableVector<'a, T> for &'a [T] {
+#[unstable]
+impl<'a,T> ImmutableSlice<'a, T> for &'a [T] {
     #[inline]
     fn slice(&self, start: uint, end: uint) -> &'a [T] {
         assert!(start <= end);
         assert!(end <= self.len());
         unsafe {
-            transmute(Slice {
+            transmute(RawSlice {
                     data: self.as_ptr().offset(start as int),
                     len: (end - start)
                 })
@@ -331,6 +378,7 @@ fn head(&self) -> Option<&'a T> {
     fn tail(&self) -> &'a [T] { self.slice(1, self.len()) }
 
     #[inline]
+    #[deprecated = "use slice_from"]
     fn tailn(&self, n: uint) -> &'a [T] { self.slice(n, self.len()) }
 
     #[inline]
@@ -339,6 +387,7 @@ fn init(&self) -> &'a [T] {
     }
 
     #[inline]
+    #[deprecated = "use slice_to but note the arguments are different"]
     fn initn(&self, n: uint) -> &'a [T] {
         self.slice(0, self.len() - n)
     }
@@ -349,16 +398,23 @@ fn last(&self) -> Option<&'a T> {
     }
 
     #[inline]
+    #[deprecated = "renamed to `unsafe_get`"]
     unsafe fn unsafe_ref(self, index: uint) -> &'a T {
         transmute(self.repr().data.offset(index as int))
     }
 
+    #[inline]
+    unsafe fn unsafe_get(self, index: uint) -> &'a T {
+        transmute(self.repr().data.offset(index as int))
+    }
+
     #[inline]
     fn as_ptr(&self) -> *const T {
         self.repr().data
     }
 
 
+    #[deprecated = "use binary_search"]
     fn bsearch(&self, f: |&T| -> Ordering) -> Option<uint> {
         let mut base : uint = 0;
         let mut lim : uint = self.len();
@@ -378,9 +434,29 @@ fn bsearch(&self, f: |&T| -> Ordering) -> Option<uint> {
         return None;
     }
 
+    #[unstable]
+    fn binary_search(&self, f: |&T| -> Ordering) -> BinarySearchResult {
+        let mut base : uint = 0;
+        let mut lim : uint = self.len();
+
+        while lim != 0 {
+            let ix = base + (lim >> 1);
+            match f(&self[ix]) {
+                Equal => return Found(ix),
+                Less => {
+                    base = ix + 1;
+                    lim -= 1;
+                }
+                Greater => ()
+            }
+            lim >>= 1;
+        }
+        return NotFound(base);
+    }
+
     fn shift_ref(&mut self) -> Option<&'a T> {
         unsafe {
-            let s: &mut Slice<T> = transmute(self);
+            let s: &mut RawSlice<T> = transmute(self);
             match raw::shift_ptr(s) {
                 Some(p) => Some(&*p),
                 None => None
@@ -390,7 +466,7 @@ fn shift_ref(&mut self) -> Option<&'a T> {
 
     fn pop_ref(&mut self) -> Option<&'a T> {
         unsafe {
-            let s: &mut Slice<T> = transmute(self);
+            let s: &mut RawSlice<T> = transmute(self);
             match raw::pop_ptr(s) {
                 Some(p) => Some(&*p),
                 None => None
@@ -401,7 +477,8 @@ fn pop_ref(&mut self) -> Option<&'a T> {
 
 /// Extension methods for vectors such that their elements are
 /// mutable.
-pub trait MutableVector<'a, T> {
+#[experimental = "may merge with other traits; may lose region param; needs review"]
+pub trait MutableSlice<'a, T> {
     /// Returns a mutable reference to the element at the given index,
     /// or `None` if the index is out of bounds
     fn get_mut(self, index: uint) -> Option<&'a mut T>;
@@ -465,6 +542,7 @@ pub trait MutableVector<'a, T> {
      *
      * Returns `None` if slice is empty
      */
+    #[deprecated = "find some other way. sorry"]
     fn mut_shift_ref(&mut self) -> Option<&'a mut T>;
 
     /**
@@ -483,6 +561,7 @@ pub trait MutableVector<'a, T> {
      *
      * Returns `None` if slice is empty.
      */
+    #[deprecated = "find some other way. sorry"]
     fn mut_pop_ref(&mut self) -> Option<&'a mut T>;
 
     /// Swaps two elements in a vector.
@@ -607,7 +686,8 @@ pub trait MutableVector<'a, T> {
     unsafe fn copy_memory(self, src: &[T]);
 }
 
-impl<'a,T> MutableVector<'a, T> for &'a mut [T] {
+#[experimental = "trait is experimental"]
+impl<'a,T> MutableSlice<'a, T> for &'a mut [T] {
     #[inline]
     fn get_mut(self, index: uint) -> Option<&'a mut T> {
         if index < self.len() { Some(&mut self[index]) } else { None }
@@ -620,7 +700,7 @@ fn mut_slice(self, start: uint, end: uint) -> &'a mut [T] {
         assert!(start <= end);
         assert!(end <= self.len());
         unsafe {
-            transmute(Slice {
+            transmute(RawSlice {
                     data: self.as_mut_ptr().offset(start as int) as *const T,
                     len: (end - start)
                 })
@@ -685,7 +765,7 @@ fn mut_chunks(self, chunk_size: uint) -> MutChunks<'a, T> {
 
     fn mut_shift_ref(&mut self) -> Option<&'a mut T> {
         unsafe {
-            let s: &mut Slice<T> = transmute(self);
+            let s: &mut RawSlice<T> = transmute(self);
             match raw::shift_ptr(s) {
                 // FIXME #13933: this `&` -> `&mut` cast is a little
                 // dubious
@@ -697,7 +777,7 @@ fn mut_shift_ref(&mut self) -> Option<&'a mut T> {
 
     fn mut_pop_ref(&mut self) -> Option<&'a mut T> {
         unsafe {
-            let s: &mut Slice<T> = transmute(self);
+            let s: &mut RawSlice<T> = transmute(self);
             match raw::pop_ptr(s) {
                 // FIXME #13933: this `&` -> `&mut` cast is a little
                 // dubious
@@ -755,7 +835,8 @@ unsafe fn copy_memory(self, src: &[T]) {
 }
 
 /// Extension methods for vectors contain `PartialEq` elements.
-pub trait ImmutableEqVector<T:PartialEq> {
+#[unstable = "may merge with other traits"]
+pub trait ImmutablePartialEqSlice<T:PartialEq> {
     /// Find the first index containing a matching value
     fn position_elem(&self, t: &T) -> Option<uint>;
 
@@ -772,7 +853,8 @@ pub trait ImmutableEqVector<T:PartialEq> {
     fn ends_with(&self, needle: &[T]) -> bool;
 }
 
-impl<'a,T:PartialEq> ImmutableEqVector<T> for &'a [T] {
+#[unstable = "trait is unstable"]
+impl<'a,T:PartialEq> ImmutablePartialEqSlice<T> for &'a [T] {
     #[inline]
     fn position_elem(&self, x: &T) -> Option<uint> {
         self.iter().position(|y| *x == *y)
@@ -802,23 +884,51 @@ fn ends_with(&self, needle: &[T]) -> bool {
 }
 
 /// Extension methods for vectors containing `Ord` elements.
-pub trait ImmutableOrdVector<T: Ord> {
+#[unstable = "may merge with other traits"]
+pub trait ImmutableOrdSlice<T: Ord> {
     /**
      * Binary search a sorted vector for a given element.
      *
      * Returns the index of the element or None if not found.
      */
+    #[deprecated = "use binary_search_elem"]
     fn bsearch_elem(&self, x: &T) -> Option<uint>;
+
+    /**
+     * Binary search a sorted vector for a given element.
+     *
+     * If the value is found then `Found` is returned, containing the
+     * index of the matching element; if the value is not found then
+     * `NotFound` is returned, containing the index where a matching
+     * element could be inserted while maintaining sorted order.
+     */
+    #[unstable]
+    fn binary_search_elem(&self, x: &T) -> BinarySearchResult;
 }
 
-impl<'a, T: Ord> ImmutableOrdVector<T> for &'a [T] {
+#[unstable = "trait is unstable"]
+impl<'a, T: Ord> ImmutableOrdSlice<T> for &'a [T] {
+    #[deprecated = "use binary_search_elem"]
+    #[allow(deprecated)]
     fn bsearch_elem(&self, x: &T) -> Option<uint> {
         self.bsearch(|p| p.cmp(x))
     }
+
+    #[unstable]
+    fn binary_search_elem(&self, x: &T) -> BinarySearchResult {
+        self.binary_search(|p| p.cmp(x))
+    }
 }
 
 /// Trait for &[T] where T is Cloneable
-pub trait MutableCloneableVector<T> {
+#[unstable = "may merge with other traits"]
+pub trait MutableCloneableSlice<T> {
+    /// Copies as many elements from `src` as it can into `self` (the
+    /// shorter of `self.len()` and `src.len()`). Returns the number
+    /// of elements copied.
+    #[deprecated = "renamed to clone_from_slice"]
+    fn copy_from(self, s: &[T]) -> uint { self.clone_from_slice(s) }
+
     /// Copies as many elements from `src` as it can into `self` (the
     /// shorter of `self.len()` and `src.len()`). Returns the number
     /// of elements copied.
@@ -826,7 +936,7 @@ pub trait MutableCloneableVector<T> {
     /// # Example
     ///
     /// ```rust
-    /// use std::slice::MutableCloneableVector;
+    /// use std::slice::MutableCloneableSlice;
     ///
     /// let mut dst = [0i, 0, 0];
     /// let src = [1i, 2];
@@ -838,12 +948,13 @@ pub trait MutableCloneableVector<T> {
     /// assert!(dst.copy_from(src2) == 3);
     /// assert!(dst == [3i, 4, 5]);
     /// ```
-    fn copy_from(self, &[T]) -> uint;
+    fn clone_from_slice(self, &[T]) -> uint;
 }
 
-impl<'a, T:Clone> MutableCloneableVector<T> for &'a mut [T] {
+#[unstable = "trait is unstable"]
+impl<'a, T:Clone> MutableCloneableSlice<T> for &'a mut [T] {
     #[inline]
-    fn copy_from(self, src: &[T]) -> uint {
+    fn clone_from_slice(self, src: &[T]) -> uint {
         for (a, b) in self.mut_iter().zip(src.iter()) {
             a.clone_from(b);
         }
@@ -859,16 +970,19 @@ fn copy_from(self, src: &[T]) -> uint {
 //
 
 /// Any vector that can be represented as a slice.
-pub trait Vector<T> {
+#[unstable = "may merge with other traits"]
+pub trait Slice<T> {
     /// Work with `self` as a slice.
     fn as_slice<'a>(&'a self) -> &'a [T];
 }
 
-impl<'a,T> Vector<T> for &'a [T] {
+#[unstable = "trait is unstable"]
+impl<'a,T> Slice<T> for &'a [T] {
     #[inline(always)]
     fn as_slice<'a>(&'a self) -> &'a [T] { *self }
 }
 
+#[experimental = "trait is experimental"]
 impl<'a, T> Collection for &'a [T] {
     /// Returns the length of a vector
     #[inline]
@@ -877,6 +991,7 @@ fn len(&self) -> uint {
     }
 }
 
+#[unstable = "waiting for DST"]
 impl<'a, T> Default for &'a [T] {
     fn default() -> &'a [T] { &[] }
 }
@@ -891,6 +1006,7 @@ fn default() -> &'a [T] { &[] }
 // The shared definition of the `Item` and `MutItems` iterators
 macro_rules! iterator {
     (struct $name:ident -> $ptr:ty, $elem:ty) => {
+        #[experimental = "needs review"]
         impl<'a, T> Iterator<$elem> for $name<'a, T> {
             #[inline]
             fn next(&mut self) -> Option<$elem> {
@@ -926,6 +1042,7 @@ fn size_hint(&self) -> (uint, Option<uint>) {
             }
         }
 
+        #[experimental = "needs review"]
         impl<'a, T> DoubleEndedIterator<$elem> for $name<'a, T> {
             #[inline]
             fn next_back(&mut self) -> Option<$elem> {
@@ -953,6 +1070,7 @@ fn next_back(&mut self) -> Option<$elem> {
 }
 
 /// Immutable slice iterator
+#[experimental = "needs review"]
 pub struct Items<'a, T> {
     ptr: *const T,
     end: *const T,
@@ -961,12 +1079,15 @@ pub struct Items<'a, T> {
 
 iterator!{struct Items -> *const T, &'a T}
 
+#[experimental = "needs review"]
 impl<'a, T> ExactSize<&'a T> for Items<'a, T> {}
 
+#[experimental = "needs review"]
 impl<'a, T> Clone for Items<'a, T> {
     fn clone(&self) -> Items<'a, T> { *self }
 }
 
+#[experimental = "needs review"]
 impl<'a, T> RandomAccessIterator<&'a T> for Items<'a, T> {
     #[inline]
     fn indexable(&self) -> uint {
@@ -992,6 +1113,7 @@ fn idx(&mut self, index: uint) -> Option<&'a T> {
 }
 
 /// Mutable slice iterator
+#[experimental = "needs review"]
 pub struct MutItems<'a, T> {
     ptr: *mut T,
     end: *mut T,
@@ -1001,16 +1123,19 @@ pub struct MutItems<'a, T> {
 
 iterator!{struct MutItems -> *mut T, &'a mut T}
 
+#[experimental = "needs review"]
 impl<'a, T> ExactSize<&'a mut T> for MutItems<'a, T> {}
 
 /// An iterator over the slices of a vector separated by elements that
 /// match a predicate function.
+#[experimental = "needs review"]
 pub struct Splits<'a, T> {
     v: &'a [T],
     pred: |t: &T|: 'a -> bool,
     finished: bool
 }
 
+#[experimental = "needs review"]
 impl<'a, T> Iterator<&'a [T]> for Splits<'a, T> {
     #[inline]
     fn next(&mut self) -> Option<&'a [T]> {
@@ -1039,6 +1164,7 @@ fn size_hint(&self) -> (uint, Option<uint>) {
     }
 }
 
+#[experimental = "needs review"]
 impl<'a, T> DoubleEndedIterator<&'a [T]> for Splits<'a, T> {
     #[inline]
     fn next_back(&mut self) -> Option<&'a [T]> {
@@ -1060,12 +1186,14 @@ fn next_back(&mut self) -> Option<&'a [T]> {
 
 /// An iterator over the subslices of the vector which are separated
 /// by elements that match `pred`.
+#[experimental = "needs review"]
 pub struct MutSplits<'a, T> {
     v: &'a mut [T],
     pred: |t: &T|: 'a -> bool,
     finished: bool
 }
 
+#[experimental = "needs review"]
 impl<'a, T> Iterator<&'a mut [T]> for MutSplits<'a, T> {
     #[inline]
     fn next(&mut self) -> Option<&'a mut [T]> {
@@ -1102,6 +1230,7 @@ fn size_hint(&self) -> (uint, Option<uint>) {
     }
 }
 
+#[experimental = "needs review"]
 impl<'a, T> DoubleEndedIterator<&'a mut [T]> for MutSplits<'a, T> {
     #[inline]
     fn next_back(&mut self) -> Option<&'a mut [T]> {
@@ -1126,12 +1255,14 @@ fn next_back(&mut self) -> Option<&'a mut [T]> {
 
 /// An iterator over the slices of a vector separated by elements that
 /// match a predicate function, splitting at most a fixed number of times.
+#[experimental = "needs review"]
 pub struct SplitsN<'a, T> {
     iter: Splits<'a, T>,
     count: uint,
     invert: bool
 }
 
+#[experimental = "needs review"]
 impl<'a, T> Iterator<&'a [T]> for SplitsN<'a, T> {
     #[inline]
     fn next(&mut self) -> Option<&'a [T]> {
@@ -1161,11 +1292,13 @@ fn size_hint(&self) -> (uint, Option<uint>) {
 /// An iterator over the (overlapping) slices of length `size` within
 /// a vector.
 #[deriving(Clone)]
+#[experimental = "needs review"]
 pub struct Windows<'a, T> {
     v: &'a [T],
     size: uint
 }
 
+#[experimental = "needs review"]
 impl<'a, T> Iterator<&'a [T]> for Windows<'a, T> {
     #[inline]
     fn next(&mut self) -> Option<&'a [T]> {
@@ -1195,11 +1328,13 @@ fn size_hint(&self) -> (uint, Option<uint>) {
 /// When the vector len is not evenly divided by the chunk size,
 /// the last slice of the iteration will be the remainder.
 #[deriving(Clone)]
+#[experimental = "needs review"]
 pub struct Chunks<'a, T> {
     v: &'a [T],
     size: uint
 }
 
+#[experimental = "needs review"]
 impl<'a, T> Iterator<&'a [T]> for Chunks<'a, T> {
     #[inline]
     fn next(&mut self) -> Option<&'a [T]> {
@@ -1225,6 +1360,7 @@ fn size_hint(&self) -> (uint, Option<uint>) {
     }
 }
 
+#[experimental = "needs review"]
 impl<'a, T> DoubleEndedIterator<&'a [T]> for Chunks<'a, T> {
     #[inline]
     fn next_back(&mut self) -> Option<&'a [T]> {
@@ -1240,6 +1376,7 @@ fn next_back(&mut self) -> Option<&'a [T]> {
     }
 }
 
+#[experimental = "needs review"]
 impl<'a, T> RandomAccessIterator<&'a [T]> for Chunks<'a, T> {
     #[inline]
     fn indexable(&self) -> uint {
@@ -1263,11 +1400,13 @@ fn idx(&mut self, index: uint) -> Option<&'a [T]> {
 /// An iterator over a vector in (non-overlapping) mutable chunks (`size`  elements at a time). When
 /// the vector len is not evenly divided by the chunk size, the last slice of the iteration will be
 /// the remainder.
+#[experimental = "needs review"]
 pub struct MutChunks<'a, T> {
     v: &'a mut [T],
     chunk_size: uint
 }
 
+#[experimental = "needs review"]
 impl<'a, T> Iterator<&'a mut [T]> for MutChunks<'a, T> {
     #[inline]
     fn next(&mut self) -> Option<&'a mut [T]> {
@@ -1294,6 +1433,7 @@ fn size_hint(&self) -> (uint, Option<uint>) {
     }
 }
 
+#[experimental = "needs review"]
 impl<'a, T> DoubleEndedIterator<&'a mut [T]> for MutChunks<'a, T> {
     #[inline]
     fn next_back(&mut self) -> Option<&'a mut [T]> {
@@ -1313,6 +1453,43 @@ fn next_back(&mut self) -> Option<&'a mut [T]> {
 
 
 
+/// The result of calling `binary_search`.
+///
+/// `Found` means the search succeeded, and the contained value is the
+/// index of the matching element. `NotFound` means the search
+/// succeeded, and the contained value is an index where a matching
+/// value could be inserted while maintaining sort order.
+#[deriving(PartialEq, Show)]
+#[experimental = "needs review"]
+pub enum BinarySearchResult {
+    /// The index of the found value.
+    Found(uint),
+    /// The index where the value should have been found.
+    NotFound(uint)
+}
+
+#[experimental = "needs review"]
+impl BinarySearchResult {
+    /// Converts a `Found` to `Some`, `NotFound` to `None`.
+    /// Similar to `Result::ok`.
+    pub fn found(&self) -> Option<uint> {
+        match *self {
+            Found(i) => Some(i),
+            NotFound(_) => None
+        }
+    }
+
+    /// Convert a `Found` to `None`, `NotFound` to `Some`.
+    /// Similar to `Result::err`.
+    pub fn not_found(&self) -> Option<uint> {
+        match *self {
+            Found(_) => None,
+            NotFound(i) => Some(i)
+        }
+    }
+}
+
+
 
 //
 // Free functions
@@ -1321,19 +1498,21 @@ fn next_back(&mut self) -> Option<&'a mut [T]> {
 /**
  * Converts a pointer to A into a slice of length 1 (without copying).
  */
+#[unstable = "waiting for DST"]
 pub fn ref_slice<'a, A>(s: &'a A) -> &'a [A] {
     unsafe {
-        transmute(Slice { data: s, len: 1 })
+        transmute(RawSlice { data: s, len: 1 })
     }
 }
 
 /**
  * Converts a pointer to A into a slice of length 1 (without copying).
  */
+#[unstable = "waiting for DST"]
 pub fn mut_ref_slice<'a, A>(s: &'a mut A) -> &'a mut [A] {
     unsafe {
         let ptr: *const A = transmute(s);
-        transmute(Slice { data: ptr, len: 1 })
+        transmute(RawSlice { data: ptr, len: 1 })
     }
 }
 
@@ -1345,6 +1524,7 @@ pub fn mut_ref_slice<'a, A>(s: &'a mut A) -> &'a mut [A] {
 //
 
 /// Unsafe operations
+#[experimental = "needs review"]
 pub mod raw {
     use mem::transmute;
     use ptr::RawPtr;
@@ -1410,10 +1590,11 @@ pub unsafe fn pop_ptr<T>(slice: &mut Slice<T>) -> Option<*const T> {
 }
 
 /// Operations on `[u8]`.
+#[experimental = "needs review"]
 pub mod bytes {
     use collections::Collection;
     use ptr;
-    use slice::MutableVector;
+    use slice::MutableSlice;
 
     /// A trait for operations on mutable `[u8]`s.
     pub trait MutableByteVector {
@@ -1447,6 +1628,7 @@ pub fn copy_memory(dst: &mut [u8], src: &[u8]) {
 // Boilerplate traits
 //
 
+#[unstable = "waiting for DST"]
 impl<'a,T:PartialEq> PartialEq for &'a [T] {
     fn eq(&self, other: & &'a [T]) -> bool {
         self.len() == other.len() &&
@@ -1458,19 +1640,23 @@ fn ne(&self, other: & &'a [T]) -> bool {
     }
 }
 
+#[unstable = "waiting for DST"]
 impl<'a,T:Eq> Eq for &'a [T] {}
 
-impl<'a,T:PartialEq, V: Vector<T>> Equiv<V> for &'a [T] {
+#[unstable = "waiting for DST"]
+impl<'a,T:PartialEq, V: Slice<T>> Equiv<V> for &'a [T] {
     #[inline]
     fn equiv(&self, other: &V) -> bool { self.as_slice() == other.as_slice() }
 }
 
+#[unstable = "waiting for DST"]
 impl<'a,T:Ord> Ord for &'a [T] {
     fn cmp(&self, other: & &'a [T]) -> Ordering {
         order::cmp(self.iter(), other.iter())
     }
 }
 
+#[unstable = "waiting for DST"]
 impl<'a, T: PartialOrd> PartialOrd for &'a [T] {
     #[inline]
     fn partial_cmp(&self, other: &&'a [T]) -> Option<Ordering> {
index c1166a7621e193e6515c1745248d0f67c5125737..4f7db7b41f38b7403ef1a496250790a34b400d26 100644 (file)
@@ -30,7 +30,7 @@
 use num::{CheckedMul, Saturating};
 use option::{Option, None, Some};
 use raw::Repr;
-use slice::ImmutableVector;
+use slice::ImmutableSlice;
 use slice;
 use uint;
 
@@ -964,7 +964,7 @@ pub mod raw {
     use collections::Collection;
     use ptr::RawPtr;
     use raw::Slice;
-    use slice::{ImmutableVector};
+    use slice::{ImmutableSlice};
     use str::{is_utf8, StrSlice};
 
     /// Converts a slice of bytes to a string slice without checking
@@ -1147,22 +1147,22 @@ pub trait StrSlice<'a> {
     /// # Example
     ///
     /// ```rust
-    /// let v: Vec<&str> = "Mary had a little lambda".splitn(' ', 2).collect();
+    /// let v: Vec<&str> = "Mary had a little lambda".splitn(2, ' ').collect();
     /// assert_eq!(v, vec!["Mary", "had", "a little lambda"]);
     ///
-    /// let v: Vec<&str> = "abc1def2ghi".splitn(|c: char| c.is_digit(), 1).collect();
+    /// let v: Vec<&str> = "abc1def2ghi".splitn(1, |c: char| c.is_digit()).collect();
     /// assert_eq!(v, vec!["abc", "def2ghi"]);
     ///
-    /// let v: Vec<&str> = "lionXXtigerXleopard".splitn('X', 2).collect();
+    /// let v: Vec<&str> = "lionXXtigerXleopard".splitn(2, 'X').collect();
     /// assert_eq!(v, vec!["lion", "", "tigerXleopard"]);
     ///
-    /// let v: Vec<&str> = "abcXdef".splitn('X', 0).collect();
+    /// let v: Vec<&str> = "abcXdef".splitn(0, 'X').collect();
     /// assert_eq!(v, vec!["abcXdef"]);
     ///
-    /// let v: Vec<&str> = "".splitn('X', 1).collect();
+    /// let v: Vec<&str> = "".splitn(1, 'X').collect();
     /// assert_eq!(v, vec![""]);
     /// ```
-    fn splitn<Sep: CharEq>(&self, sep: Sep, count: uint) -> CharSplitsN<'a, Sep>;
+    fn splitn<Sep: CharEq>(&self, count: uint, sep: Sep) -> CharSplitsN<'a, Sep>;
 
     /// An iterator over substrings of `self`, separated by characters
     /// matched by `sep`.
@@ -1197,16 +1197,16 @@ pub trait StrSlice<'a> {
     /// # Example
     ///
     /// ```rust
-    /// let v: Vec<&str> = "Mary had a little lamb".rsplitn(' ', 2).collect();
+    /// let v: Vec<&str> = "Mary had a little lamb".rsplitn(2, ' ').collect();
     /// assert_eq!(v, vec!["lamb", "little", "Mary had a"]);
     ///
-    /// let v: Vec<&str> = "abc1def2ghi".rsplitn(|c: char| c.is_digit(), 1).collect();
+    /// let v: Vec<&str> = "abc1def2ghi".rsplitn(1, |c: char| c.is_digit()).collect();
     /// assert_eq!(v, vec!["ghi", "abc1def"]);
     ///
-    /// let v: Vec<&str> = "lionXXtigerXleopard".rsplitn('X', 2).collect();
+    /// let v: Vec<&str> = "lionXXtigerXleopard".rsplitn(2, 'X').collect();
     /// assert_eq!(v, vec!["leopard", "tiger", "lionX"]);
     /// ```
-    fn rsplitn<Sep: CharEq>(&self, sep: Sep, count: uint) -> CharSplitsN<'a, Sep>;
+    fn rsplitn<Sep: CharEq>(&self, count: uint, sep: Sep) -> CharSplitsN<'a, Sep>;
 
     /// An iterator over the start and end indices of the disjoint
     /// matches of `sep` within `self`.
@@ -1697,7 +1697,7 @@ fn split<Sep: CharEq>(&self, sep: Sep) -> CharSplits<'a, Sep> {
     }
 
     #[inline]
-    fn splitn<Sep: CharEq>(&self, sep: Sep, count: uint)
+    fn splitn<Sep: CharEq>(&self, count: uint, sep: Sep)
         -> CharSplitsN<'a, Sep> {
         CharSplitsN {
             iter: self.split(sep),
@@ -1716,7 +1716,7 @@ fn split_terminator<Sep: CharEq>(&self, sep: Sep)
     }
 
     #[inline]
-    fn rsplitn<Sep: CharEq>(&self, sep: Sep, count: uint)
+    fn rsplitn<Sep: CharEq>(&self, count: uint, sep: Sep)
         -> CharSplitsN<'a, Sep> {
         CharSplitsN {
             iter: self.split(sep),
index 0b8ae09c9a3461ad10bb5393b5d1c28d8d180d6b..3864321586ca67f643efbe9190c3c8dd8e6958ac 100644 (file)
@@ -28,4 +28,5 @@
 mod ptr;
 mod raw;
 mod result;
+mod slice;
 mod tuple;
diff --git a/src/libcoretest/slice.rs b/src/libcoretest/slice.rs
new file mode 100644 (file)
index 0000000..1288756
--- /dev/null
@@ -0,0 +1,35 @@
+// 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.
+
+use std::slice::{Found, NotFound};
+
+#[test]
+fn binary_search_not_found() {
+    let b = [1i, 2, 4, 6, 8, 9];
+    assert!(b.binary_search(|v| v.cmp(&6)) == Found(3));
+    let b = [1i, 2, 4, 6, 8, 9];
+    assert!(b.binary_search(|v| v.cmp(&5)) == NotFound(3));
+    let b = [1i, 2, 4, 6, 7, 8, 9];
+    assert!(b.binary_search(|v| v.cmp(&6)) == Found(3));
+    let b = [1i, 2, 4, 6, 7, 8, 9];
+    assert!(b.binary_search(|v| v.cmp(&5)) == NotFound(3));
+    let b = [1i, 2, 4, 6, 8, 9];
+    assert!(b.binary_search(|v| v.cmp(&8)) == Found(4));
+    let b = [1i, 2, 4, 6, 8, 9];
+    assert!(b.binary_search(|v| v.cmp(&7)) == NotFound(4));
+    let b = [1i, 2, 4, 6, 7, 8, 9];
+    assert!(b.binary_search(|v| v.cmp(&8)) == Found(5));
+    let b = [1i, 2, 4, 5, 6, 8, 9];
+    assert!(b.binary_search(|v| v.cmp(&7)) == NotFound(5));
+    let b = [1i, 2, 4, 5, 6, 8, 9];
+    assert!(b.binary_search(|v| v.cmp(&0)) == NotFound(0));
+    let b = [1i, 2, 4, 5, 6, 8];
+    assert!(b.binary_search(|v| v.cmp(&9)) == NotFound(6));
+}
index 9e52af72138bba2fb839a25a8554b733956677d6..987f214b153e07d3ba107024563594cf6b27ee2c 100644 (file)
@@ -84,7 +84,7 @@ fn cmp(&self, other: &MaybeOwnedVector<T>) -> Ordering {
     }
 }
 
-impl<'a, T: PartialEq, V: Vector<T>> Equiv<V> for MaybeOwnedVector<'a, T> {
+impl<'a, T: PartialEq, V: Slice<T>> Equiv<V> for MaybeOwnedVector<'a, T> {
     fn equiv(&self, other: &V) -> bool {
         self.as_slice() == other.as_slice()
     }
@@ -99,7 +99,7 @@ fn equiv(&self, other: &V) -> bool {
 // In any case, with `Vector` in place, the client can just use
 // `as_slice` if they prefer that over `match`.
 
-impl<'b,T> slice::Vector<T> for MaybeOwnedVector<'b,T> {
+impl<'b,T> Slice<T> for MaybeOwnedVector<'b,T> {
     fn as_slice<'a>(&'a self) -> &'a [T] {
         match self {
             &Growable(ref v) => v.as_slice(),
index b9144047df5c0b7e3017f3fdeb27bedd594a82d4..e041547082885dbfdccdcb2e27868d42571d16db 100644 (file)
@@ -1029,6 +1029,7 @@ mod test {
     use std::rt::task::TaskOpts;
     use std::rt::task::Task;
     use std::rt::local::Local;
+    use std::time::Duration;
 
     use {TaskState, PoolConfig, SchedPool};
     use basic;
@@ -1291,7 +1292,7 @@ fn test_io_callback() {
         // doesn't exit before emptying the work queue
         pool.spawn(TaskOpts::new(), proc() {
             spawn(proc() {
-                timer::sleep(10);
+                timer::sleep(Duration::milliseconds(10));
             });
         });
 
index e368a5644159c7126b27386e07385a75c4ae28c0..c005ae71480517c94b75eedc21169a4b142b1f7a 100644 (file)
@@ -1138,7 +1138,8 @@ pub mod extra {
         }
     }
 
-    #[cfg(target_os = "win32")]
+    #[cfg(target_os = "windows")]
+    #[cfg(stage0, target_os = "win32")] // NOTE: Remove after snapshot
     pub mod os {
         pub mod common {
             pub mod posix01 {
@@ -1803,7 +1804,8 @@ pub mod consts {
     // Consts tend to vary per OS so we pull their definitions out
     // into this module.
 
-    #[cfg(target_os = "win32")]
+    #[cfg(target_os = "windows")]
+    #[cfg(stage0, target_os = "win32")] // NOTE: Remove after snapshot
     pub mod os {
         pub mod c95 {
             use types::os::arch::c95::{c_int, c_uint};
@@ -3887,7 +3889,8 @@ pub fn memchr(cx: *const c_void, c: c_int,
     // so be careful when trying to write portable code; it won't always work
     // with the same POSIX functions and types as other platforms.
 
-    #[cfg(target_os = "win32")]
+    #[cfg(target_os = "windows")]
+    #[cfg(stage0, target_os = "win32")] // NOTE: Remove after snapshot
     pub mod posix88 {
         pub mod stat_ {
             use types::os::common::posix01::{stat, utimbuf};
@@ -4316,7 +4319,8 @@ pub fn posix_madvise(addr: *mut c_void,
         }
     }
 
-    #[cfg(target_os = "win32")]
+    #[cfg(target_os = "windows")]
+    #[cfg(stage0, target_os = "win32")] // NOTE: Remove after snapshot
     pub mod posix01 {
         pub mod stat_ {
         }
@@ -4332,7 +4336,8 @@ pub mod mman {
     }
 
 
-    #[cfg(target_os = "win32")]
+    #[cfg(target_os = "windows")]
+    #[cfg(stage0, target_os = "win32")] // NOTE: Remove after snapshot
     #[cfg(target_os = "linux")]
     #[cfg(target_os = "android")]
     #[cfg(target_os = "macos")]
@@ -4470,7 +4475,8 @@ pub fn mincore(addr: *mut c_void, len: size_t, vec: *mut c_uchar)
     }
 
 
-    #[cfg(target_os = "win32")]
+    #[cfg(target_os = "windows")]
+    #[cfg(stage0, target_os = "win32")] // NOTE: Remove after snapshot
     pub mod bsd44 {
     }
 
@@ -4496,7 +4502,8 @@ pub mod extra {
     }
 
 
-    #[cfg(target_os = "win32")]
+    #[cfg(target_os = "windows")]
+    #[cfg(stage0, target_os = "win32")] // NOTE: Remove after snapshot
     pub mod extra {
 
         pub mod kernel32 {
index db5421481ee42eca7fbb8520a988ce87d4e6f347..afd818bd7d7e7d23a8e82ed8623c1771ef33d20c 100644 (file)
@@ -58,7 +58,8 @@
 #[path = "timer_unix.rs"]
 pub mod timer;
 
-#[cfg(target_os = "win32")]
+#[cfg(target_os = "windows")]
+#[cfg(stage0, target_os = "win32")] // NOTE: Remove after snapshot
 #[path = "timer_win32.rs"]
 pub mod timer;
 
index 77822bbbc20ff8376cb2f192db5297b27f8cd3bb..4b832a4a97efa00946188d1a64a640df39c6bab6 100644 (file)
@@ -80,7 +80,7 @@ fn get_io(io: rtio::StdioContainer,
                 rtio::Ignored => { ret.push(None); Ok(None) }
                 rtio::InheritFd(fd) => {
                     ret.push(None);
-                    Ok(Some(file::FileDesc::new(fd, true)))
+                    Ok(Some(file::FileDesc::new(fd, false)))
                 }
                 rtio::CreatePipe(readable, _writable) => {
                     let (reader, writer) = try!(pipe());
index e0f6b4fb9af66a12ccb06e6f4282d12f6ed65890..f3e4b0b21adf85ba94b9f918bd48fdacd5d3406c 100644 (file)
@@ -341,7 +341,7 @@ impl<T: FromStr + Clone + Integer + PartialOrd>
     FromStr for Ratio<T> {
     /// Parses `numer/denom` or just `numer`.
     fn from_str(s: &str) -> Option<Ratio<T>> {
-        let mut split = s.splitn('/', 1);
+        let mut split = s.splitn(1, '/');
 
         let num = split.next().and_then(|n| FromStr::from_str(n));
         let den = split.next().or(Some("1")).and_then(|d| FromStr::from_str(d));
@@ -357,7 +357,7 @@ impl<T: FromStrRadix + Clone + Integer + PartialOrd>
     FromStrRadix for Ratio<T> {
     /// Parses `numer/denom` where the numbers are in base `radix`.
     fn from_str_radix(s: &str, radix: uint) -> Option<Ratio<T>> {
-        let split: Vec<&str> = s.splitn('/', 1).collect();
+        let split: Vec<&str> = s.splitn(1, '/').collect();
         if split.len() < 2 {
             None
         } else {
index 134e7af507010db11a2f0980e1951c8b73dd2ab3..2fbfa6d6e85a0da393ae2050cb9d7ff963e4ab3f 100644 (file)
@@ -348,7 +348,7 @@ fn isaac64(&mut self) {
         static MP_VEC: [(uint, uint), .. 2] = [(0,MIDPOINT), (MIDPOINT, 0)];
         macro_rules! ind (
             ($x:expr) => {
-                *self.mem.unsafe_ref(($x as uint >> 3) & (RAND_SIZE_64 - 1))
+                *self.mem.unsafe_get(($x as uint >> 3) & (RAND_SIZE_64 - 1))
             }
         );
 
@@ -362,8 +362,8 @@ macro_rules! rngstepp(
                             let mix = if $j == 0 {!mix} else {mix};
 
                             unsafe {
-                                let x = *self.mem.unsafe_ref(base + mr_offset);
-                                a = mix + *self.mem.unsafe_ref(base + m2_offset);
+                                let x = *self.mem.unsafe_get(base + mr_offset);
+                                a = mix + *self.mem.unsafe_get(base + m2_offset);
                                 let y = ind!(x) + a + b;
                                 self.mem.unsafe_set(base + mr_offset, y);
 
@@ -379,8 +379,8 @@ macro_rules! rngstepn(
                             let mix = if $j == 0 {!mix} else {mix};
 
                             unsafe {
-                                let x = *self.mem.unsafe_ref(base + mr_offset);
-                                a = mix + *self.mem.unsafe_ref(base + m2_offset);
+                                let x = *self.mem.unsafe_get(base + mr_offset);
+                                a = mix + *self.mem.unsafe_get(base + m2_offset);
                                 let y = ind!(x) + a + b;
                                 self.mem.unsafe_set(base + mr_offset, y);
 
@@ -416,7 +416,7 @@ fn next_u64(&mut self) -> u64 {
             self.isaac64();
         }
         self.cnt -= 1;
-        unsafe { *self.rsl.unsafe_ref(self.cnt) }
+        unsafe { *self.rsl.unsafe_get(self.cnt) }
     }
 }
 
index a1fd62cecbed973514e937e57b57c5e863d8ef26..13b094a2cf2e6475bfacc54c19ed7a979a1e86d4 100644 (file)
@@ -13,6 +13,7 @@
 use std::fmt;
 use std::iter;
 use std::num;
+use std::slice;
 
 /// Static data containing Unicode ranges for general categories and scripts.
 use unicode::regex::{UNICODE_CLASSES, PERLD, PERLS, PERLW};
@@ -518,7 +519,7 @@ fn parse_counted(&mut self) -> Result<(), Error> {
             min = try!(self.parse_uint(inner.as_slice()));
             max = Some(min);
         } else {
-            let pieces: Vec<&str> = inner.as_slice().splitn(',', 1).collect();
+            let pieces: Vec<&str> = inner.as_slice().splitn(1, ',').collect();
             let (smin, smax) = (pieces[0], pieces[1]);
             if smin.len() == 0 {
                 return self.err("Max repetitions cannot be specified \
@@ -1017,9 +1018,9 @@ fn is_valid_cap(c: char) -> bool {
 }
 
 fn find_class(classes: NamedClasses, name: &str) -> Option<Vec<(char, char)>> {
-    match classes.bsearch(|&(s, _)| s.cmp(&name)) {
-        Some(i) => Some(Vec::from_slice(classes[i].val1())),
-        None => None,
+    match classes.binary_search(|&(s, _)| s.cmp(&name)) {
+        slice::Found(i) => Some(Vec::from_slice(classes[i].val1())),
+        slice::NotFound(_) => None,
     }
 }
 
index b37000df02dbec436e2c862fbb26c711efbbca28..507a7641f2201bf100982cf9cb3b8e2e63527679 100644 (file)
@@ -35,7 +35,7 @@
 
 use std::cmp;
 use std::mem;
-use std::slice::MutableVector;
+use std::slice::MutableSlice;
 use compile::{
     Program,
     Match, OneChar, CharClass, Any, EmptyBegin, EmptyEnd, EmptyWordBoundary,
@@ -222,8 +222,8 @@ fn step(&self, groups: &mut [Option<uint>], nlist: &mut Threads,
                     let negate = flags & FLAG_NEGATED > 0;
                     let casei = flags & FLAG_NOCASE > 0;
                     let found = ranges.as_slice();
-                    let found = found.bsearch(|&rc| class_cmp(casei, c, rc));
-                    let found = found.is_some();
+                    let found = found.binary_search(|&rc| class_cmp(casei, c, rc))
+                        .found().is_some();
                     if found ^ negate {
                         self.add(nlist, pc+1, caps);
                     }
@@ -513,7 +513,7 @@ pub fn is_word(c: Option<char>) -> bool {
     // Try the common ASCII case before invoking binary search.
     match c {
         '_' | '0' .. '9' | 'a' .. 'z' | 'A' .. 'Z' => true,
-        _ => PERLW.bsearch(|&(start, end)| {
+        _ => PERLW.binary_search(|&(start, end)| {
             if c >= start && c <= end {
                 Equal
             } else if start > c {
@@ -521,7 +521,7 @@ pub fn is_word(c: Option<char>) -> bool {
             } else {
                 Less
             }
-        }).is_some()
+        }).found().is_some()
     }
 }
 
index c7295125f42f7504de4c1c22546b748058b9f197..706b5c3325576c212dc72be9055ec4b9a035166c 100644 (file)
@@ -112,7 +112,7 @@ mod test {
     use core::iter::Iterator;
     use core::collections::Collection;
     use core::str::StrSlice;
-    use core::slice::{MutableVector, ImmutableVector};
+    use core::slice::{MutableSlice, ImmutableSlice};
 
     use super::{memcmp, memset, memcpy, memmove};
 
index 7c9844dbe33fb4693616efda8aaa6400786f96a6..f3e130cf768604773e621744d0806c08218e77af 100644 (file)
@@ -200,7 +200,7 @@ pub fn run_passes(sess: &Session,
             // OSX has -dead_strip, which doesn't rely on ffunction_sections
             // FIXME(#13846) this should be enabled for windows
             let ffunction_sections = sess.targ_cfg.os != abi::OsMacos &&
-                                     sess.targ_cfg.os != abi::OsWin32;
+                                     sess.targ_cfg.os != abi::OsWindows;
             let fdata_sections = ffunction_sections;
 
             let reloc_model = match sess.opts.cg.relocation_model.as_slice() {
@@ -858,7 +858,7 @@ pub fn get_cc_prog(sess: &Session) -> String {
     // instead of hard-coded gcc.
     // For win32, there is no cc command, so we add a condition to make it use gcc.
     match sess.targ_cfg.os {
-        abi::OsWin32 => "gcc",
+        abi::OsWindows => "gcc",
         _ => "cc",
     }.to_string()
 }
@@ -954,7 +954,7 @@ pub fn filename_for_input(sess: &Session,
         }
         config::CrateTypeDylib => {
             let (prefix, suffix) = match sess.targ_cfg.os {
-                abi::OsWin32 => (loader::WIN32_DLL_PREFIX, loader::WIN32_DLL_SUFFIX),
+                abi::OsWindows => (loader::WIN32_DLL_PREFIX, loader::WIN32_DLL_SUFFIX),
                 abi::OsMacos => (loader::MACOS_DLL_PREFIX, loader::MACOS_DLL_SUFFIX),
                 abi::OsLinux => (loader::LINUX_DLL_PREFIX, loader::LINUX_DLL_SUFFIX),
                 abi::OsAndroid => (loader::ANDROID_DLL_PREFIX, loader::ANDROID_DLL_SUFFIX),
@@ -972,7 +972,7 @@ pub fn filename_for_input(sess: &Session,
         }
         config::CrateTypeExecutable => {
             match sess.targ_cfg.os {
-                abi::OsWin32 => out_filename.with_extension("exe"),
+                abi::OsWindows => out_filename.with_extension("exe"),
                 abi::OsMacos |
                 abi::OsLinux |
                 abi::OsAndroid |
@@ -1388,7 +1388,7 @@ fn link_args(cmd: &mut Command,
     // subset we wanted.
     //
     // FIXME(#11937) we should invoke the system linker directly
-    if sess.targ_cfg.os != abi::OsWin32 {
+    if sess.targ_cfg.os != abi::OsWindows {
         cmd.arg("-nodefaultlibs");
     }
 
@@ -1440,7 +1440,7 @@ fn link_args(cmd: &mut Command,
         cmd.arg("-Wl,-dead_strip");
     }
 
-    if sess.targ_cfg.os == abi::OsWin32 {
+    if sess.targ_cfg.os == abi::OsWindows {
         // Make sure that we link to the dynamic libgcc, otherwise cross-module
         // DWARF stack unwinding will not work.
         // This behavior may be overridden by --link-args "-static-libgcc"
@@ -1715,7 +1715,7 @@ fn add_upstream_rust_crates(cmd: &mut Command, sess: &Session,
 
     // Converts a library file-stem into a cc -l argument
     fn unlib<'a>(config: &config::Config, stem: &'a [u8]) -> &'a [u8] {
-        if stem.starts_with("lib".as_bytes()) && config.os != abi::OsWin32 {
+        if stem.starts_with("lib".as_bytes()) && config.os != abi::OsWindows {
             stem.tailn(3)
         } else {
             stem
index f4309d9e51b56f7ae14c84349c09fb896aa0fd94..c402c256a37196b692f2a45b9805fb6c1a0997e3 100644 (file)
@@ -353,7 +353,7 @@ pub fn build_codegen_options(matches: &getopts::Matches) -> CodegenOptions
 {
     let mut cg = basic_codegen_options();
     for option in matches.opt_strs("C").move_iter() {
-        let mut iter = option.as_slice().splitn('=', 1);
+        let mut iter = option.as_slice().splitn(1, '=');
         let key = iter.next().unwrap();
         let value = iter.next();
         let option_to_lookup = key.replace("-", "_");
@@ -390,7 +390,7 @@ pub fn default_lib_output() -> CrateType {
 
 pub fn default_configuration(sess: &Session) -> ast::CrateConfig {
     let tos = match sess.targ_cfg.os {
-        abi::OsWin32 =>     InternedString::new("win32"),
+        abi::OsWindows =>   InternedString::new("windows"),
         abi::OsMacos =>     InternedString::new("macos"),
         abi::OsLinux =>     InternedString::new("linux"),
         abi::OsAndroid =>   InternedString::new("android"),
@@ -410,7 +410,7 @@ pub fn default_configuration(sess: &Session) -> ast::CrateConfig {
     };
 
     let fam = match sess.targ_cfg.os {
-        abi::OsWin32 => InternedString::new("windows"),
+        abi::OsWindows => InternedString::new("windows"),
         _ => InternedString::new("unix")
     };
 
@@ -452,8 +452,9 @@ pub fn get_os(triple: &str) -> Option<abi::Os> {
     None
 }
 static os_names : &'static [(&'static str, abi::Os)] = &[
-    ("mingw32",   abi::OsWin32),
-    ("win32",     abi::OsWin32),
+    ("mingw32",   abi::OsWindows),
+    ("win32",     abi::OsWindows),
+    ("windows",   abi::OsWindows),
     ("darwin",    abi::OsMacos),
     ("android",   abi::OsAndroid),
     ("linux",     abi::OsLinux),
@@ -750,7 +751,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
 
     let mut externs = HashMap::new();
     for arg in matches.opt_strs("extern").iter() {
-        let mut parts = arg.as_slice().splitn('=', 1);
+        let mut parts = arg.as_slice().splitn(1, '=');
         let name = match parts.next() {
             Some(s) => s,
             None => early_error("--extern value must not be empty"),
index 477fc5e1c0f30374080c2e2d3564e31d8c17ff98..5f86745f3f2210cb37dfbed38d8e16fe49dda674 100644 (file)
@@ -360,8 +360,9 @@ pub fn phase_3_run_analysis_passes(sess: Session,
             plugin::build::find_plugin_registrar(
                 sess.diagnostic(), krate)));
 
-    let freevars = time(time_passes, "freevar finding", (), |_|
-                        freevars::annotate_freevars(&def_map, krate));
+    let (freevars, capture_modes) =
+        time(time_passes, "freevar finding", (), |_|
+             freevars::annotate_freevars(&def_map, krate));
 
     let region_map = time(time_passes, "region resolution", (), |_|
                           middle::region::resolve_crate(&sess, krate));
@@ -372,8 +373,15 @@ pub fn phase_3_run_analysis_passes(sess: Session,
     let stability_index = time(time_passes, "stability index", (), |_|
                                stability::Index::build(krate));
 
-    let ty_cx = ty::mk_ctxt(sess, def_map, named_region_map, ast_map,
-                            freevars, region_map, lang_items, stability_index);
+    let ty_cx = ty::mk_ctxt(sess,
+                            def_map,
+                            named_region_map,
+                            ast_map,
+                            freevars,
+                            capture_modes,
+                            region_map,
+                            lang_items,
+                            stability_index);
 
     // passes are timed inside typeck
     typeck::check_crate(&ty_cx, trait_map, krate);
index 05762aa3db2762c709cc8570e48342374ec36218..dc600e0da3ec06ae26253c8ada1eee7ff7f2b918 100644 (file)
@@ -356,7 +356,7 @@ pub enum PpMode {
 }
 
 fn parse_pretty(sess: &Session, name: &str) -> (PpMode, Option<driver::UserIdentifiedItem>) {
-    let mut split = name.splitn('=', 1);
+    let mut split = name.splitn(1, '=');
     let first = split.next().unwrap();
     let opt_second = split.next();
     let first = match first {
index ab363a88db2d9dfb1cd76d7deb5b2065136e2b97..93320caf5f2819c8f4c115942cb9dc3f899be10d 100644 (file)
@@ -109,10 +109,14 @@ fn fold_foreign_mod(cx: &mut Context, nm: &ast::ForeignMod) -> ast::ForeignMod {
 
 fn fold_item_underscore(cx: &mut Context, item: &ast::Item_) -> ast::Item_ {
     let item = match *item {
-        ast::ItemImpl(ref a, ref b, c, ref methods) => {
-            let methods = methods.iter().filter(|m| method_in_cfg(cx, &***m))
-                .map(|x| *x).collect();
-            ast::ItemImpl((*a).clone(), (*b).clone(), c, methods)
+        ast::ItemImpl(ref a, ref b, c, ref impl_items) => {
+            let impl_items = impl_items.iter()
+                                       .filter(|ii| {
+                                           impl_item_in_cfg(cx, &**ii)
+                                       })
+                                       .map(|x| *x)
+                                       .collect();
+            ast::ItemImpl((*a).clone(), (*b).clone(), c, impl_items)
         }
         ast::ItemTrait(ref a, ref b, ref c, ref methods) => {
             let methods = methods.iter()
@@ -230,14 +234,16 @@ fn view_item_in_cfg(cx: &mut Context, item: &ast::ViewItem) -> bool {
     return (cx.in_cfg)(item.attrs.as_slice());
 }
 
-fn method_in_cfg(cx: &mut Context, meth: &ast::Method) -> bool {
-    return (cx.in_cfg)(meth.attrs.as_slice());
+fn trait_method_in_cfg(cx: &mut Context, meth: &ast::TraitItem) -> bool {
+    match *meth {
+        ast::RequiredMethod(ref meth) => (cx.in_cfg)(meth.attrs.as_slice()),
+        ast::ProvidedMethod(meth) => (cx.in_cfg)(meth.attrs.as_slice())
+    }
 }
 
-fn trait_method_in_cfg(cx: &mut Context, meth: &ast::TraitMethod) -> bool {
-    match *meth {
-        ast::Required(ref meth) => (cx.in_cfg)(meth.attrs.as_slice()),
-        ast::Provided(meth) => (cx.in_cfg)(meth.attrs.as_slice())
+fn impl_item_in_cfg(cx: &mut Context, impl_item: &ast::ImplItem) -> bool {
+    match *impl_item {
+        ast::MethodImplItem(meth) => (cx.in_cfg)(meth.attrs.as_slice()),
     }
 }
 
index 99855c7345cb4e5269a35959944a4edc71e66389..fdfbdea245bb20226ec11b5a8b511e9da02590e1 100644 (file)
@@ -314,7 +314,7 @@ fn visit_ty(&mut self, t: &ast::Ty, _: ()) {
 
             },
             ast::TyBox(_) => { self.gate_box(t.span); }
-            ast::TyUnboxedFn(_) => {
+            ast::TyUnboxedFn(..) => {
                 self.gate_feature("unboxed_closure_sugar",
                                   t.span,
                                   "unboxed closure trait sugar is experimental");
index 14cda7d62c35def4dc62053e12af7a95184c1f61..ceb7dcc54560c04931744bf91f3dbaeecdcd0d1d 100644 (file)
@@ -379,7 +379,7 @@ fn mk_test_module(cx: &TestCtxt, reexport_test_harness_main: &Option<InternedStr
     let mainfn = (quote_item!(&cx.ext_cx,
         pub fn main() {
             #![main]
-            use std::slice::Vector;
+            use std::slice::Slice;
             test::test_main_static(::std::os::args().as_slice(), TESTS);
         }
     )).unwrap();
index f929860c6864bedd969ec832027a7eba64dca114..738c5d9be79076bc76f88f854e86c326e0e0b05a 100644 (file)
@@ -568,6 +568,7 @@ fn check_attribute(&mut self, cx: &Context, attr: &ast::Attribute) {
             // FIXME: #14406 these are processed in trans, which happens after the
             // lint pass
             "cold",
+            "export_name",
             "inline",
             "link",
             "link_name",
@@ -578,6 +579,7 @@ fn check_attribute(&mut self, cx: &Context, attr: &ast::Attribute) {
             "packed",
             "static_assert",
             "thread_local",
+            "no_debug",
 
             // not used anywhere (!?) but apparently we want to keep them around
             "comment",
@@ -801,15 +803,19 @@ fn method_context(cx: &Context, m: &ast::Method) -> MethodContext {
         node: m.id
     };
 
-    match cx.tcx.methods.borrow().find_copy(&did) {
+    match cx.tcx.impl_or_trait_items.borrow().find_copy(&did) {
         None => cx.sess().span_bug(m.span, "missing method descriptor?!"),
         Some(md) => {
-            match md.container {
-                ty::TraitContainer(..) => TraitDefaultImpl,
-                ty::ImplContainer(cid) => {
-                    match ty::impl_trait_ref(cx.tcx, cid) {
-                        Some(..) => TraitImpl,
-                        None => PlainImpl
+            match md {
+                ty::MethodTraitItem(md) => {
+                    match md.container {
+                        ty::TraitContainer(..) => TraitDefaultImpl,
+                        ty::ImplContainer(cid) => {
+                            match ty::impl_trait_ref(cx.tcx, cid) {
+                                Some(..) => TraitImpl,
+                                None => PlainImpl
+                            }
+                        }
                     }
                 }
             }
@@ -1470,7 +1476,15 @@ fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
                                 trait_id: trait_id,
                                 method_num: index,
                                 ..
-                            }) => ty::trait_method(cx.tcx, trait_id, index).def_id
+                            }) => {
+                                match ty::trait_item(cx.tcx,
+                                                     trait_id,
+                                                     index) {
+                                    ty::MethodTraitItem(method) => {
+                                        method.def_id
+                                    }
+                                }
+                            }
                         }
                     }
                     None => return
index 59a6b08638e9170191134f9e469e4ac2aa377500..cf018927f70b460aae25795e75bf91e22387d1a9 100644 (file)
@@ -563,9 +563,9 @@ fn visit_generics(&mut self, g: &ast::Generics, _: ()) {
         visit::walk_generics(self, g, ());
     }
 
-    fn visit_trait_method(&mut self, m: &ast::TraitMethod, _: ()) {
+    fn visit_trait_item(&mut self, m: &ast::TraitItem, _: ()) {
         run_lints!(self, check_trait_method, m);
-        visit::walk_trait_method(self, m, ());
+        visit::walk_trait_item(self, m, ());
     }
 
     fn visit_opt_lifetime_ref(&mut self, sp: Span, lt: &Option<ast::Lifetime>, _: ()) {
index 1bf77b42bec049d0d7259f385036ecd45089f649..dbdda96dcb84fb7f9e1c785309d8f96a01363f35 100644 (file)
@@ -141,7 +141,7 @@ fn check_generics(&mut self, _: &Context, _: &ast::Generics) { }
     fn check_fn(&mut self, _: &Context,
         _: &FnKind, _: &ast::FnDecl, _: &ast::Block, _: Span, _: ast::NodeId) { }
     fn check_ty_method(&mut self, _: &Context, _: &ast::TypeMethod) { }
-    fn check_trait_method(&mut self, _: &Context, _: &ast::TraitMethod) { }
+    fn check_trait_method(&mut self, _: &Context, _: &ast::TraitItem) { }
     fn check_struct_def(&mut self, _: &Context,
         _: &ast::StructDef, _: ast::Ident, _: &ast::Generics, _: ast::NodeId) { }
     fn check_struct_def_post(&mut self, _: &Context,
index 8ed471ec58a5e7da3a805bb7968d690245d0dc4b..6a1c7c6c951c99a507194bbeac344014f98f0815 100644 (file)
@@ -77,7 +77,7 @@
 
 pub static tag_mod_impl: uint = 0x1f;
 
-pub static tag_item_trait_method: uint = 0x20;
+pub static tag_item_trait_item: uint = 0x20;
 
 pub static tag_item_trait_ref: uint = 0x21;
 pub static tag_item_super_trait_ref: uint = 0x22;
 
 pub static tag_item_variances: uint = 0x2a;
 /*
-  trait items contain tag_item_trait_method elements,
-  impl items contain tag_item_impl_method elements, and classes
+  trait items contain tag_item_trait_item elements,
+  impl items contain tag_item_impl_item elements, and classes
   have both. That's because some code treats classes like traits,
   and other code treats them like impls. Because classes can contain
-  both, tag_item_trait_method and tag_item_impl_method have to be two
+  both, tag_item_trait_item and tag_item_impl_item have to be two
   different tags.
  */
-pub static tag_item_impl_method: uint = 0x30;
+pub static tag_item_impl_item: uint = 0x30;
 pub static tag_item_trait_method_explicit_self: uint = 0x31;
 
 
@@ -139,11 +139,12 @@ pub enum astencode_tag { // Reserves 0x40 -- 0x5f
     tag_table_adjustments = 0x51,
     tag_table_moves_map = 0x52,
     tag_table_capture_map = 0x53,
-    tag_table_unboxed_closure_type = 0x54,
+    tag_table_unboxed_closures = 0x54,
     tag_table_upvar_borrow_map = 0x55,
+    tag_table_capture_modes = 0x56,
 }
 static first_astencode_tag: uint = tag_ast as uint;
-static last_astencode_tag: uint = tag_table_upvar_borrow_map as uint;
+static last_astencode_tag: uint = tag_table_capture_modes as uint;
 impl astencode_tag {
     pub fn from_uint(value : uint) -> Option<astencode_tag> {
         let is_a_tag = first_astencode_tag <= value && value <= last_astencode_tag;
@@ -153,9 +154,11 @@ pub fn from_uint(value : uint) -> Option<astencode_tag> {
     }
 }
 
-pub static tag_item_trait_method_sort: uint = 0x60;
+pub static tag_item_trait_item_sort: uint = 0x60;
 
-pub static tag_item_impl_type_basename: uint = 0x61;
+pub static tag_item_trait_parent_sort: uint = 0x61;
+
+pub static tag_item_impl_type_basename: uint = 0x62;
 
 pub static tag_crate_triple: uint = 0x66;
 
@@ -228,9 +231,11 @@ pub struct LinkMeta {
 pub static tag_unboxed_closures: uint = 0x95;
 pub static tag_unboxed_closure: uint = 0x96;
 pub static tag_unboxed_closure_type: uint = 0x97;
+pub static tag_unboxed_closure_kind: uint = 0x98;
+
+pub static tag_struct_fields: uint = 0x99;
+pub static tag_struct_field: uint = 0x9a;
+pub static tag_struct_field_id: uint = 0x9b;
 
-pub static tag_struct_fields: uint = 0x98;
-pub static tag_struct_field: uint = 0x99;
-pub static tag_struct_field_id: uint = 0x9a;
+pub static tag_attribute_is_sugared_doc: uint = 0x9c;
 
-pub static tag_attribute_is_sugared_doc: uint = 0x9b;
index 252d19bbb237b838cab6db360de0bcc8b1e3c018..ac161ef8bdefefde46dd9cf72e41ad12d7582459 100644 (file)
@@ -16,6 +16,7 @@
 use metadata::cstore;
 use metadata::decoder;
 use middle::lang_items;
+use middle::resolve;
 use middle::ty;
 use middle::typeck;
 use middle::subst::VecPerParamSpace;
@@ -121,30 +122,33 @@ pub fn get_enum_variants(tcx: &ty::ctxt, def: ast::DefId)
 }
 
 /// Returns information about the given implementation.
-pub fn get_impl_methods(cstore: &cstore::CStore, impl_def_id: ast::DefId)
-                        -> Vec<ast::DefId> {
+pub fn get_impl_items(cstore: &cstore::CStore, impl_def_id: ast::DefId)
+                      -> Vec<ty::ImplOrTraitItemId> {
     let cdata = cstore.get_crate_data(impl_def_id.krate);
-    decoder::get_impl_methods(&*cdata, impl_def_id.node)
+    decoder::get_impl_items(&*cdata, impl_def_id.node)
 }
 
-pub fn get_method(tcx: &ty::ctxt, def: ast::DefId) -> ty::Method {
+pub fn get_impl_or_trait_item(tcx: &ty::ctxt, def: ast::DefId)
+                              -> ty::ImplOrTraitItem {
     let cdata = tcx.sess.cstore.get_crate_data(def.krate);
-    decoder::get_method(tcx.sess.cstore.intr.clone(), &*cdata, def.node, tcx)
+    decoder::get_impl_or_trait_item(tcx.sess.cstore.intr.clone(),
+                                    &*cdata,
+                                    def.node,
+                                    tcx)
 }
 
-pub fn get_method_name_and_explicit_self(cstore: &cstore::CStore,
-                                         def: ast::DefId)
-                                         -> (ast::Ident,
-                                             ty::ExplicitSelfCategory)
-{
+pub fn get_trait_item_name_and_kind(cstore: &cstore::CStore, def: ast::DefId)
+                                    -> (ast::Ident, resolve::TraitItemKind) {
     let cdata = cstore.get_crate_data(def.krate);
-    decoder::get_method_name_and_explicit_self(cstore.intr.clone(), &*cdata, def.node)
+    decoder::get_trait_item_name_and_kind(cstore.intr.clone(),
+                                          &*cdata,
+                                          def.node)
 }
 
-pub fn get_trait_method_def_ids(cstore: &cstore::CStore,
-                                def: ast::DefId) -> Vec<ast::DefId> {
+pub fn get_trait_item_def_ids(cstore: &cstore::CStore, def: ast::DefId)
+                              -> Vec<ty::ImplOrTraitItemId> {
     let cdata = cstore.get_crate_data(def.krate);
-    decoder::get_trait_method_def_ids(&*cdata, def.node)
+    decoder::get_trait_item_def_ids(&*cdata, def.node)
 }
 
 pub fn get_item_variances(cstore: &cstore::CStore,
@@ -286,15 +290,15 @@ pub fn each_implementation_for_trait(cstore: &cstore::CStore,
     decoder::each_implementation_for_trait(&*cdata, def_id.node, callback)
 }
 
-/// If the given def ID describes a method belonging to a trait (either a
+/// If the given def ID describes an item belonging to a trait (either a
 /// default method or an implementation of a trait method), returns the ID of
 /// the trait that the method belongs to. Otherwise, returns `None`.
-pub fn get_trait_of_method(cstore: &cstore::CStore,
-                           def_id: ast::DefId,
-                           tcx: &ty::ctxt)
-                           -> Option<ast::DefId> {
+pub fn get_trait_of_item(cstore: &cstore::CStore,
+                         def_id: ast::DefId,
+                         tcx: &ty::ctxt)
+                         -> Option<ast::DefId> {
     let cdata = cstore.get_crate_data(def_id.krate);
-    decoder::get_trait_of_method(&*cdata, def_id.node, tcx)
+    decoder::get_trait_of_item(&*cdata, def_id.node, tcx)
 }
 
 pub fn get_tuple_struct_definition_if_ctor(cstore: &cstore::CStore,
index c9807a18383e8ef5bc932222cfb55f306e44b121..74810261d4a750de1bada065dba5e80ec2404376 100644 (file)
 use metadata::csearch::StaticMethodInfo;
 use metadata::csearch;
 use metadata::cstore;
-use metadata::tydecode::{parse_ty_data, parse_def_id,
-                         parse_type_param_def_data,
-                         parse_bare_fn_ty_data, parse_trait_ref_data};
-use middle::lang_items;
+use metadata::tydecode::{parse_ty_data, parse_def_id};
+use metadata::tydecode::{parse_type_param_def_data, parse_bare_fn_ty_data};
+use metadata::tydecode::{parse_trait_ref_data};
 use middle::def;
+use middle::lang_items;
+use middle::resolve::TraitItemKind;
 use middle::subst;
 use middle::ty::{ImplContainer, TraitContainer};
 use middle::ty;
@@ -165,9 +166,9 @@ fn item_visibility(item: rbml::Doc) -> ast::Visibility {
     }
 }
 
-fn item_method_sort(item: rbml::Doc) -> char {
+fn item_sort(item: rbml::Doc) -> char {
     let mut ret = 'r';
-    reader::tagged_docs(item, tag_item_trait_method_sort, |doc| {
+    reader::tagged_docs(item, tag_item_trait_item_sort, |doc| {
         ret = doc.as_str_slice().as_bytes()[0] as char;
         false
     });
@@ -338,15 +339,18 @@ fn item_to_def_like(item: rbml::Doc, did: ast::DefId, cnum: ast::CrateNum)
         UnsafeFn  => DlDef(def::DefFn(did, ast::UnsafeFn)),
         Fn        => DlDef(def::DefFn(did, ast::NormalFn)),
         StaticMethod | UnsafeStaticMethod => {
-            let fn_style = if fam == UnsafeStaticMethod { ast::UnsafeFn } else
-                { ast::NormalFn };
+            let fn_style = if fam == UnsafeStaticMethod {
+                ast::UnsafeFn
+            } else {
+                ast::NormalFn
+            };
             // def_static_method carries an optional field of its enclosing
             // trait or enclosing impl (if this is an inherent static method).
             // So we need to detect whether this is in a trait or not, which
             // we do through the mildly hacky way of checking whether there is
-            // a trait_method_sort.
+            // a trait_parent_sort.
             let provenance = if reader::maybe_get_doc(
-                  item, tag_item_trait_method_sort).is_some() {
+                  item, tag_item_trait_parent_sort).is_some() {
                 def::FromTrait(item_reqd_and_translated_parent_item(cnum,
                                                                     item))
             } else {
@@ -536,14 +540,11 @@ fn each_child_of_item_or_crate(intr: Rc<IdentInterner>,
             None => {}
             Some(inherent_impl_doc) => {
                 let _ = reader::tagged_docs(inherent_impl_doc,
-                                            tag_item_impl_method,
-                                            |impl_method_def_id_doc| {
-                    let impl_method_def_id =
-                        reader::with_doc_data(impl_method_def_id_doc,
-                                              parse_def_id);
-                    let impl_method_def_id =
-                        translate_def_id(cdata, impl_method_def_id);
-                    match maybe_find_item(impl_method_def_id.node, items) {
+                                            tag_item_impl_item,
+                                            |impl_item_def_id_doc| {
+                    let impl_item_def_id = item_def_id(impl_item_def_id_doc,
+                                                       cdata);
+                    match maybe_find_item(impl_item_def_id.node, items) {
                         None => {}
                         Some(impl_method_doc) => {
                             match item_family(impl_method_doc) {
@@ -554,7 +555,7 @@ fn each_child_of_item_or_crate(intr: Rc<IdentInterner>,
                                         item_name(&*intr, impl_method_doc);
                                     let static_method_def_like =
                                         item_to_def_like(impl_method_doc,
-                                                         impl_method_def_id,
+                                                         impl_item_def_id,
                                                          cdata.cnum);
                                     callback(static_method_def_like,
                                              static_method_name,
@@ -752,33 +753,46 @@ fn get_mutability(ch: u8) -> ast::Mutability {
     }
 }
 
-/// Returns information about the given implementation.
-pub fn get_impl_methods(cdata: Cmd, impl_id: ast::NodeId) -> Vec<ast::DefId> {
-    let mut methods = Vec::new();
+/// Returns the def IDs of all the items in the given implementation.
+pub fn get_impl_items(cdata: Cmd, impl_id: ast::NodeId)
+                      -> Vec<ty::ImplOrTraitItemId> {
+    let mut impl_items = Vec::new();
     reader::tagged_docs(lookup_item(impl_id, cdata.data()),
-                        tag_item_impl_method, |doc| {
-        let m_did = reader::with_doc_data(doc, parse_def_id);
-        methods.push(translate_def_id(cdata, m_did));
+                        tag_item_impl_item, |doc| {
+        let def_id = item_def_id(doc, cdata);
+        match item_sort(doc) {
+            'r' | 'p' => impl_items.push(ty::MethodTraitItemId(def_id)),
+            _ => fail!("unknown impl item sort"),
+        }
         true
     });
 
-    methods
+    impl_items
 }
 
-pub fn get_method_name_and_explicit_self(intr: Rc<IdentInterner>,
-                                         cdata: Cmd,
-                                         id: ast::NodeId)
-                                         -> (ast::Ident,
-                                             ty::ExplicitSelfCategory) {
-    let method_doc = lookup_item(id, cdata.data());
-    let name = item_name(&*intr, method_doc);
-    let explicit_self = get_explicit_self(method_doc);
-    (name, explicit_self)
+pub fn get_trait_item_name_and_kind(intr: Rc<IdentInterner>,
+                                    cdata: Cmd,
+                                    id: ast::NodeId)
+                                    -> (ast::Ident, TraitItemKind) {
+    let doc = lookup_item(id, cdata.data());
+    let name = item_name(&*intr, doc);
+    match item_sort(doc) {
+        'r' | 'p' => {
+            let explicit_self = get_explicit_self(doc);
+            (name, TraitItemKind::from_explicit_self_category(explicit_self))
+        }
+        c => {
+            fail!("get_trait_item_name_and_kind(): unknown trait item kind \
+                   in metadata: `{}`", c)
+        }
+    }
 }
 
-pub fn get_method(intr: Rc<IdentInterner>, cdata: Cmd, id: ast::NodeId,
-                  tcx: &ty::ctxt) -> ty::Method
-{
+pub fn get_impl_or_trait_item(intr: Rc<IdentInterner>,
+                              cdata: Cmd,
+                              id: ast::NodeId,
+                              tcx: &ty::ctxt)
+                              -> ty::ImplOrTraitItem {
     let method_doc = lookup_item(id, cdata.data());
     let def_id = item_def_id(method_doc, cdata);
 
@@ -791,36 +805,45 @@ pub fn get_method(intr: Rc<IdentInterner>, cdata: Cmd, id: ast::NodeId,
     };
 
     let name = item_name(&*intr, method_doc);
-    let type_param_defs = item_ty_param_defs(method_doc, tcx, cdata,
-                                             tag_item_method_tps);
-    let rp_defs = item_region_param_defs(method_doc, cdata);
-    let fty = doc_method_fty(method_doc, tcx, cdata);
-    let vis = item_visibility(method_doc);
-    let explicit_self = get_explicit_self(method_doc);
-    let provided_source = get_provided_source(method_doc, cdata);
-
-    ty::Method::new(
-        name,
-        ty::Generics {
-            types: type_param_defs,
-            regions: rp_defs,
-        },
-        fty,
-        explicit_self,
-        vis,
-        def_id,
-        container,
-        provided_source
-    )
-}
-
-pub fn get_trait_method_def_ids(cdata: Cmd,
-                                id: ast::NodeId) -> Vec<ast::DefId> {
+
+    match item_sort(method_doc) {
+        'r' | 'p' => {
+            let type_param_defs = item_ty_param_defs(method_doc, tcx, cdata,
+                                                     tag_item_method_tps);
+            let rp_defs = item_region_param_defs(method_doc, cdata);
+            let fty = doc_method_fty(method_doc, tcx, cdata);
+            let vis = item_visibility(method_doc);
+            let explicit_self = get_explicit_self(method_doc);
+            let provided_source = get_provided_source(method_doc, cdata);
+
+            let generics = ty::Generics {
+                types: type_param_defs,
+                regions: rp_defs,
+            };
+            ty::MethodTraitItem(Rc::new(ty::Method::new(name,
+                                                        generics,
+                                                        fty,
+                                                        explicit_self,
+                                                        vis,
+                                                        def_id,
+                                                        container,
+                                                        provided_source)))
+        }
+        _ => fail!("unknown impl/trait item sort"),
+    }
+}
+
+pub fn get_trait_item_def_ids(cdata: Cmd, id: ast::NodeId)
+                              -> Vec<ty::ImplOrTraitItemId> {
     let data = cdata.data();
     let item = lookup_item(id, data);
     let mut result = Vec::new();
-    reader::tagged_docs(item, tag_item_trait_method, |mth| {
-        result.push(item_def_id(mth, cdata));
+    reader::tagged_docs(item, tag_item_trait_item, |mth| {
+        let def_id = item_def_id(mth, cdata);
+        match item_sort(mth) {
+            'r' | 'p' => result.push(ty::MethodTraitItemId(def_id)),
+            _ => fail!("unknown trait item sort"),
+        }
         true
     });
     result
@@ -834,19 +857,29 @@ pub fn get_item_variances(cdata: Cmd, id: ast::NodeId) -> ty::ItemVariances {
     Decodable::decode(&mut decoder).unwrap()
 }
 
-pub fn get_provided_trait_methods(intr: Rc<IdentInterner>, cdata: Cmd,
-                                  id: ast::NodeId, tcx: &ty::ctxt)
+pub fn get_provided_trait_methods(intr: Rc<IdentInterner>,
+                                  cdata: Cmd,
+                                  id: ast::NodeId,
+                                  tcx: &ty::ctxt)
                                   -> Vec<Rc<ty::Method>> {
     let data = cdata.data();
     let item = lookup_item(id, data);
     let mut result = Vec::new();
 
-    reader::tagged_docs(item, tag_item_trait_method, |mth_id| {
+    reader::tagged_docs(item, tag_item_trait_item, |mth_id| {
         let did = item_def_id(mth_id, cdata);
         let mth = lookup_item(did.node, data);
 
-        if item_method_sort(mth) == 'p' {
-            result.push(Rc::new(get_method(intr.clone(), cdata, did.node, tcx)));
+        if item_sort(mth) == 'p' {
+            let trait_item = get_impl_or_trait_item(intr.clone(),
+                                                    cdata,
+                                                    did.node,
+                                                    tcx);
+            match trait_item {
+                ty::MethodTraitItem(ref method) => {
+                    result.push((*method).clone())
+                }
+            }
         }
         true
     });
@@ -905,8 +938,8 @@ pub fn get_static_methods_if_impl(intr: Rc<IdentInterner>,
     if !ret { return None }
 
     let mut impl_method_ids = Vec::new();
-    reader::tagged_docs(item, tag_item_impl_method, |impl_method_doc| {
-        impl_method_ids.push(reader::with_doc_data(impl_method_doc, parse_def_id));
+    reader::tagged_docs(item, tag_item_impl_item, |impl_method_doc| {
+        impl_method_ids.push(item_def_id(impl_method_doc, cdata));
         true
     });
 
@@ -1230,8 +1263,8 @@ pub fn each_implementation_for_trait(cdata: Cmd,
     });
 }
 
-pub fn get_trait_of_method(cdata: Cmd, id: ast::NodeId, tcx: &ty::ctxt)
-                           -> Option<ast::DefId> {
+pub fn get_trait_of_item(cdata: Cmd, id: ast::NodeId, tcx: &ty::ctxt)
+                         -> Option<ast::DefId> {
     let item_doc = lookup_item(id, cdata.data());
     let parent_item_id = match item_parent_item(item_doc) {
         None => return None,
index 9b31d3a1b6460f7fe55a7266268568f0479dfee2..1d426aaaf5c91fdb7c57d2659248c11b3ac2721d 100644 (file)
 use rbml::writer;
 use rbml::io::SeekableMemWriter;
 
-/// A borrowed version of ast::InlinedItem.
+/// A borrowed version of `ast::InlinedItem`.
 pub enum InlinedItemRef<'a> {
     IIItemRef(&'a ast::Item),
-    IIMethodRef(ast::DefId, bool, &'a ast::Method),
+    IITraitItemRef(ast::DefId, InlinedTraitItemRef<'a>),
     IIForeignRef(&'a ast::ForeignItem)
 }
 
+/// A borrowed version of `ast::InlinedTraitItem`.
+pub enum InlinedTraitItemRef<'a> {
+    ProvidedInlinedTraitItemRef(&'a Method),
+    RequiredInlinedTraitItemRef(&'a Method),
+}
+
 pub type Encoder<'a> = writer::Encoder<'a, SeekableMemWriter>;
 
 pub type EncodeInlinedItem<'a> = |ecx: &EncodeContext,
@@ -403,14 +409,24 @@ fn encode_reexported_static_base_methods(ecx: &EncodeContext,
                                          rbml_w: &mut Encoder,
                                          exp: &middle::resolve::Export2)
                                          -> bool {
-    let impl_methods = ecx.tcx.impl_methods.borrow();
+    let impl_items = ecx.tcx.impl_items.borrow();
     match ecx.tcx.inherent_impls.borrow().find(&exp.def_id) {
         Some(implementations) => {
             for base_impl_did in implementations.borrow().iter() {
-                for &method_did in impl_methods.get(base_impl_did).iter() {
-                    let m = ty::method(ecx.tcx, method_did);
-                    if m.explicit_self == ty::StaticExplicitSelfCategory {
-                        encode_reexported_static_method(rbml_w, exp, m.def_id, m.ident);
+                for &method_did in impl_items.get(base_impl_did).iter() {
+                    let impl_item = ty::impl_or_trait_item(
+                        ecx.tcx,
+                        method_did.def_id());
+                    match impl_item {
+                        ty::MethodTraitItem(ref m) => {
+                            if m.explicit_self ==
+                                    ty::StaticExplicitSelfCategory {
+                                encode_reexported_static_method(rbml_w,
+                                                                exp,
+                                                                m.def_id,
+                                                                m.ident);
+                            }
+                        }
                     }
                 }
             }
@@ -425,11 +441,18 @@ fn encode_reexported_static_trait_methods(ecx: &EncodeContext,
                                           rbml_w: &mut Encoder,
                                           exp: &middle::resolve::Export2)
                                           -> bool {
-    match ecx.tcx.trait_methods_cache.borrow().find(&exp.def_id) {
-        Some(methods) => {
-            for m in methods.iter() {
-                if m.explicit_self == ty::StaticExplicitSelfCategory {
-                    encode_reexported_static_method(rbml_w, exp, m.def_id, m.ident);
+    match ecx.tcx.trait_items_cache.borrow().find(&exp.def_id) {
+        Some(trait_items) => {
+            for trait_item in trait_items.iter() {
+                match *trait_item {
+                    ty::MethodTraitItem(ref m) if m.explicit_self ==
+                            ty::StaticExplicitSelfCategory => {
+                        encode_reexported_static_method(rbml_w,
+                                                        exp,
+                                                        m.def_id,
+                                                        m.ident);
+                    }
+                    _ => {}
                 }
             }
 
@@ -630,6 +653,18 @@ fn encode_visibility(rbml_w: &mut Encoder, visibility: Visibility) {
     rbml_w.end_tag();
 }
 
+fn encode_unboxed_closure_kind(rbml_w: &mut Encoder,
+                               kind: ty::UnboxedClosureKind) {
+    rbml_w.start_tag(tag_unboxed_closure_kind);
+    let ch = match kind {
+        ty::FnUnboxedClosureKind => 'f',
+        ty::FnMutUnboxedClosureKind => 'm',
+        ty::FnOnceUnboxedClosureKind => 'o',
+    };
+    rbml_w.wr_str(ch.to_string().as_slice());
+    rbml_w.end_tag();
+}
+
 fn encode_explicit_self(rbml_w: &mut Encoder,
                         explicit_self: &ty::ExplicitSelfCategory) {
     rbml_w.start_tag(tag_item_trait_method_explicit_self);
@@ -663,8 +698,14 @@ fn encode_mutability(rbml_w: &mut Encoder,
     }
 }
 
-fn encode_method_sort(rbml_w: &mut Encoder, sort: char) {
-    rbml_w.start_tag(tag_item_trait_method_sort);
+fn encode_item_sort(rbml_w: &mut Encoder, sort: char) {
+    rbml_w.start_tag(tag_item_trait_item_sort);
+    rbml_w.writer.write(&[ sort as u8 ]);
+    rbml_w.end_tag();
+}
+
+fn encode_parent_sort(rbml_w: &mut Encoder, sort: char) {
+    rbml_w.start_tag(tag_item_trait_parent_sort);
     rbml_w.writer.write(&[ sort as u8 ]);
     rbml_w.end_tag();
 }
@@ -787,6 +828,7 @@ fn encode_info_for_method(ecx: &EncodeContext,
 
     encode_method_ty_fields(ecx, rbml_w, m);
     encode_parent_item(rbml_w, local_def(parent_id));
+    encode_item_sort(rbml_w, 'r');
 
     let stab = stability::lookup(ecx.tcx, m.def_id);
     encode_stability(rbml_w, stab);
@@ -807,9 +849,11 @@ fn encode_info_for_method(ecx: &EncodeContext,
     for &ast_method in ast_method_opt.iter() {
         let any_types = !pty.generics.types.is_empty();
         if any_types || is_default_impl || should_inline(ast_method.attrs.as_slice()) {
-            encode_inlined_item(ecx, rbml_w,
-                                IIMethodRef(local_def(parent_id), false,
-                                            &*ast_method));
+            encode_inlined_item(ecx,
+                                rbml_w,
+                                IITraitItemRef(local_def(parent_id),
+                                               RequiredInlinedTraitItemRef(
+                                                   &*ast_method)));
         } else {
             encode_symbol(ecx, rbml_w, m.def_id.node);
         }
@@ -1094,11 +1138,11 @@ fn add_to_index(item: &Item, rbml_w: &Encoder,
             None => {}
         }
       }
-      ItemImpl(_, ref opt_trait, ty, ref ast_methods) => {
+      ItemImpl(_, ref opt_trait, ty, ref ast_items) => {
         // We need to encode information about the default methods we
         // have inherited, so we drive this based on the impl structure.
-        let impl_methods = tcx.impl_methods.borrow();
-        let methods = impl_methods.get(&def_id);
+        let impl_items = tcx.impl_items.borrow();
+        let items = impl_items.get(&def_id);
 
         add_to_index(item, rbml_w, index);
         rbml_w.start_tag(tag_items_data_item);
@@ -1116,10 +1160,14 @@ fn add_to_index(item: &Item, rbml_w: &Encoder,
             }
             _ => {}
         }
-        for &method_def_id in methods.iter() {
-            rbml_w.start_tag(tag_item_impl_method);
-            let s = def_to_string(method_def_id);
-            rbml_w.writer.write(s.as_bytes());
+        for &item_def_id in items.iter() {
+            rbml_w.start_tag(tag_item_impl_item);
+            match item_def_id {
+                ty::MethodTraitItemId(item_def_id) => {
+                    encode_def_id(rbml_w, item_def_id);
+                    encode_item_sort(rbml_w, 'r');
+                }
+            }
             rbml_w.end_tag();
         }
         for ast_trait_ref in opt_trait.iter() {
@@ -1133,27 +1181,46 @@ fn add_to_index(item: &Item, rbml_w: &Encoder,
         encode_stability(rbml_w, stab);
         rbml_w.end_tag();
 
-        // Iterate down the methods, emitting them. We rely on the
-        // assumption that all of the actually implemented methods
+        // Iterate down the trait items, emitting them. We rely on the
+        // assumption that all of the actually implemented trait items
         // appear first in the impl structure, in the same order they do
         // in the ast. This is a little sketchy.
-        let num_implemented_methods = ast_methods.len();
-        for (i, &method_def_id) in methods.iter().enumerate() {
-            let ast_method = if i < num_implemented_methods {
-                Some(*ast_methods.get(i))
-            } else { None };
+        let num_implemented_methods = ast_items.len();
+        for (i, &trait_item_def_id) in items.iter().enumerate() {
+            let ast_item = if i < num_implemented_methods {
+                Some(*ast_items.get(i))
+            } else {
+                None
+            };
 
             index.push(entry {
-                val: method_def_id.node as i64,
+                val: trait_item_def_id.def_id().node as i64,
                 pos: rbml_w.writer.tell().unwrap(),
             });
-            encode_info_for_method(ecx,
-                                   rbml_w,
-                                   &*ty::method(tcx, method_def_id),
-                                   path.clone(),
-                                   false,
-                                   item.id,
-                                   ast_method)
+
+            let trait_item_type =
+                ty::impl_or_trait_item(tcx, trait_item_def_id.def_id());
+            match (trait_item_type, ast_item) {
+                (ty::MethodTraitItem(method_type),
+                 Some(ast::MethodImplItem(ast_method))) => {
+                    encode_info_for_method(ecx,
+                                           rbml_w,
+                                           &*method_type,
+                                           path.clone(),
+                                           false,
+                                           item.id,
+                                           Some(ast_method))
+                }
+                (ty::MethodTraitItem(method_type), None) => {
+                    encode_info_for_method(ecx,
+                                           rbml_w,
+                                           &*method_type,
+                                           path.clone(),
+                                           false,
+                                           item.id,
+                                           None)
+                }
+            }
         }
       }
       ItemTrait(_, _, ref super_traits, ref ms) => {
@@ -1172,13 +1239,18 @@ fn add_to_index(item: &Item, rbml_w: &Encoder,
         encode_attributes(rbml_w, item.attrs.as_slice());
         encode_visibility(rbml_w, vis);
         encode_stability(rbml_w, stab);
-        for &method_def_id in ty::trait_method_def_ids(tcx, def_id).iter() {
-            rbml_w.start_tag(tag_item_trait_method);
-            encode_def_id(rbml_w, method_def_id);
+        for &method_def_id in ty::trait_item_def_ids(tcx, def_id).iter() {
+            rbml_w.start_tag(tag_item_trait_item);
+            match method_def_id {
+                ty::MethodTraitItemId(method_def_id) => {
+                    encode_def_id(rbml_w, method_def_id);
+                    encode_item_sort(rbml_w, 'r');
+                }
+            }
             rbml_w.end_tag();
 
             rbml_w.start_tag(tag_mod_child);
-            rbml_w.wr_str(def_to_string(method_def_id).as_slice());
+            rbml_w.wr_str(def_to_string(method_def_id.def_id()).as_slice());
             rbml_w.end_tag();
         }
         encode_path(rbml_w, path.clone());
@@ -1195,66 +1267,83 @@ fn add_to_index(item: &Item, rbml_w: &Encoder,
 
         rbml_w.end_tag();
 
-        // Now output the method info for each method.
-        let r = ty::trait_method_def_ids(tcx, def_id);
-        for (i, &method_def_id) in r.iter().enumerate() {
-            assert_eq!(method_def_id.krate, ast::LOCAL_CRATE);
-
-            let method_ty = ty::method(tcx, method_def_id);
+        // Now output the trait item info for each trait item.
+        let r = ty::trait_item_def_ids(tcx, def_id);
+        for (i, &item_def_id) in r.iter().enumerate() {
+            assert_eq!(item_def_id.def_id().krate, ast::LOCAL_CRATE);
 
             index.push(entry {
-                val: method_def_id.node as i64,
+                val: item_def_id.def_id().node as i64,
                 pos: rbml_w.writer.tell().unwrap(),
             });
 
             rbml_w.start_tag(tag_items_data_item);
 
-            encode_method_ty_fields(ecx, rbml_w, &*method_ty);
-            encode_parent_item(rbml_w, def_id);
-
-            let stab = stability::lookup(tcx, method_def_id);
-            encode_stability(rbml_w, stab);
-
-            let elem = ast_map::PathName(method_ty.ident.name);
-            encode_path(rbml_w, path.clone().chain(Some(elem).move_iter()));
-
-            match method_ty.explicit_self {
-                ty::StaticExplicitSelfCategory => {
-                    encode_family(rbml_w,
-                                  fn_style_static_method_family(
-                                      method_ty.fty.fn_style));
-
-                    let pty = ty::lookup_item_type(tcx, method_def_id);
-                    encode_bounds_and_type(rbml_w, ecx, &pty);
-                }
-
-                _ => {
-                    encode_family(rbml_w,
-                                  style_fn_family(
-                                      method_ty.fty.fn_style));
-                }
-            }
-
-            match ms.get(i) {
-                &Required(ref tm) => {
-                    encode_attributes(rbml_w, tm.attrs.as_slice());
-                    encode_method_sort(rbml_w, 'r');
-                    encode_method_argument_names(rbml_w, &*tm.decl);
-                }
+            let trait_item_type =
+                ty::impl_or_trait_item(tcx, item_def_id.def_id());
+            match trait_item_type {
+                 ty::MethodTraitItem(method_ty) => {
+                    let method_def_id = item_def_id.def_id();
+
+                    encode_method_ty_fields(ecx, rbml_w, &*method_ty);
+                    encode_parent_item(rbml_w, def_id);
+
+                    let stab = stability::lookup(tcx, method_def_id);
+                    encode_stability(rbml_w, stab);
+
+                    let elem = ast_map::PathName(method_ty.ident.name);
+                    encode_path(rbml_w,
+                                path.clone().chain(Some(elem).move_iter()));
+
+                    match method_ty.explicit_self {
+                        ty::StaticExplicitSelfCategory => {
+                            encode_family(rbml_w,
+                                          fn_style_static_method_family(
+                                              method_ty.fty.fn_style));
+
+                            let pty = ty::lookup_item_type(tcx,
+                                                           method_def_id);
+                            encode_bounds_and_type(rbml_w, ecx, &pty);
+                        }
+
+                        _ => {
+                            encode_family(rbml_w,
+                                          style_fn_family(
+                                              method_ty.fty.fn_style));
+                        }
+                    }
 
-                &Provided(m) => {
-                    encode_attributes(rbml_w, m.attrs.as_slice());
-                    // If this is a static method, we've already encoded
-                    // this.
-                    if method_ty.explicit_self != ty::StaticExplicitSelfCategory {
-                        // FIXME: I feel like there is something funny going on.
-                        let pty = ty::lookup_item_type(tcx, method_def_id);
-                        encode_bounds_and_type(rbml_w, ecx, &pty);
+                    match ms.get(i) {
+                        &RequiredMethod(ref tm) => {
+                            encode_attributes(rbml_w, tm.attrs.as_slice());
+                            encode_item_sort(rbml_w, 'r');
+                            encode_parent_sort(rbml_w, 't');
+                            encode_method_argument_names(rbml_w, &*tm.decl);
+                        }
+
+                        &ProvidedMethod(m) => {
+                            encode_attributes(rbml_w, m.attrs.as_slice());
+                            // If this is a static method, we've already
+                            // encoded this.
+                            if method_ty.explicit_self !=
+                                    ty::StaticExplicitSelfCategory {
+                                // FIXME: I feel like there is something funny
+                                // going on.
+                                let pty = ty::lookup_item_type(tcx, method_def_id);
+                                encode_bounds_and_type(rbml_w, ecx, &pty);
+                            }
+                            encode_item_sort(rbml_w, 'p');
+                            encode_parent_sort(rbml_w, 't');
+                            encode_inlined_item(
+                                ecx,
+                                rbml_w,
+                                IITraitItemRef(
+                                    def_id,
+                                    ProvidedInlinedTraitItemRef(&*m)));
+                            encode_method_argument_names(rbml_w,
+                                                         &*m.pe_fn_decl());
+                        }
                     }
-                    encode_method_sort(rbml_w, 'p');
-                    encode_inlined_item(ecx, rbml_w,
-                                        IIMethodRef(def_id, true, &*m));
-                    encode_method_argument_names(rbml_w, &*m.pe_fn_decl());
                 }
             }
 
@@ -1629,8 +1718,10 @@ fn encode_unboxed_closures<'a>(
                            ecx: &'a EncodeContext,
                            rbml_w: &'a mut Encoder) {
     rbml_w.start_tag(tag_unboxed_closures);
-    for (unboxed_closure_id, unboxed_closure_type) in
-            ecx.tcx.unboxed_closure_types.borrow().iter() {
+    for (unboxed_closure_id, unboxed_closure) in ecx.tcx
+                                                    .unboxed_closures
+                                                    .borrow()
+                                                    .iter() {
         if unboxed_closure_id.krate != LOCAL_CRATE {
             continue
         }
@@ -1638,8 +1729,9 @@ fn encode_unboxed_closures<'a>(
         rbml_w.start_tag(tag_unboxed_closure);
         encode_def_id(rbml_w, *unboxed_closure_id);
         rbml_w.start_tag(tag_unboxed_closure_type);
-        write_closure_type(ecx, rbml_w, unboxed_closure_type);
+        write_closure_type(ecx, rbml_w, &unboxed_closure.closure_type);
         rbml_w.end_tag();
+        encode_unboxed_closure_kind(rbml_w, unboxed_closure.kind);
         rbml_w.end_tag();
     }
     rbml_w.end_tag();
index d2e1fca0da75d3cc7c4bec3fc28d05ea21789ab7..cd8ebf5081ba72533dcf6aca8308063ec93f2750 100644 (file)
@@ -615,7 +615,7 @@ fn crate_matches(&mut self, crate_data: &[u8], libpath: &Path) -> bool {
     // dynamic libraries
     fn dylibname(&self) -> Option<(&'static str, &'static str)> {
         match self.os {
-            abi::OsWin32 => Some((WIN32_DLL_PREFIX, WIN32_DLL_SUFFIX)),
+            abi::OsWindows => Some((WIN32_DLL_PREFIX, WIN32_DLL_SUFFIX)),
             abi::OsMacos => Some((MACOS_DLL_PREFIX, MACOS_DLL_SUFFIX)),
             abi::OsLinux => Some((LINUX_DLL_PREFIX, LINUX_DLL_SUFFIX)),
             abi::OsAndroid => Some((ANDROID_DLL_PREFIX, ANDROID_DLL_SUFFIX)),
@@ -824,7 +824,7 @@ pub fn meta_section_name(os: abi::Os) -> Option<&'static str> {
     match os {
         abi::OsMacos => Some("__DATA,__note.rustc"),
         abi::OsiOS => Some("__DATA,__note.rustc"),
-        abi::OsWin32 => Some(".note.rustc"),
+        abi::OsWindows => Some(".note.rustc"),
         abi::OsLinux => Some(".note.rustc"),
         abi::OsAndroid => Some(".note.rustc"),
         abi::OsFreebsd => Some(".note.rustc"),
@@ -836,7 +836,7 @@ pub fn read_meta_section_name(os: abi::Os) -> &'static str {
     match os {
         abi::OsMacos => "__note.rustc",
         abi::OsiOS => unreachable!(),
-        abi::OsWin32 => ".note.rustc",
+        abi::OsWindows => ".note.rustc",
         abi::OsLinux => ".note.rustc",
         abi::OsAndroid => ".note.rustc",
         abi::OsFreebsd => ".note.rustc",
index fed23185c5d27388fcd58f7723c85f6d60086655..e6e7d8bf8d1a63de55d13de394233fef1cea65fc 100644 (file)
@@ -432,7 +432,8 @@ fn parse_ty(st: &mut PState, conv: conv_did) -> ty::t {
       }
       'k' => {
           let did = parse_def(st, NominalType, |x,y| conv(x,y));
-          return ty::mk_unboxed_closure(st.tcx, did);
+          let region = parse_region(st, conv);
+          return ty::mk_unboxed_closure(st.tcx, did, region);
       }
       'e' => {
           return ty::mk_err();
index ba865c7ab04d01e5e9a019f250c1f568e2eba2e2..fc5e267aa90500fdf16700f92e8642c73464622a 100644 (file)
@@ -285,8 +285,9 @@ fn enc_sty(w: &mut SeekableMemWriter, cx: &ctxt, st: &ty::sty) {
             enc_substs(w, cx, substs);
             mywrite!(w, "]");
         }
-        ty::ty_unboxed_closure(def) => {
+        ty::ty_unboxed_closure(def, region) => {
             mywrite!(w, "k{}", (cx.ds)(def));
+            enc_region(w, cx, region);
         }
         ty::ty_err => {
             mywrite!(w, "e");
index 33b663dea1557b5ea208b4d24b196eb5280de252..26cb2f25129aa61ef02964eedda615a95fa412de 100644 (file)
@@ -18,8 +18,8 @@
 use metadata::decoder;
 use middle::def;
 use e = metadata::encoder;
+use middle::freevars::{CaptureMode, freevar_entry};
 use middle::freevars;
-use middle::freevars::freevar_entry;
 use middle::region;
 use metadata::tydecode;
 use metadata::tydecode::{DefIdSource, NominalType, TypeWithId, TypeParameter,
@@ -84,7 +84,8 @@ pub fn encode_inlined_item(ecx: &e::EncodeContext,
     let id = match ii {
         e::IIItemRef(i) => i.id,
         e::IIForeignRef(i) => i.id,
-        e::IIMethodRef(_, _, m) => m.id,
+        e::IITraitItemRef(_, e::ProvidedInlinedTraitItemRef(m)) => m.id,
+        e::IITraitItemRef(_, e::RequiredInlinedTraitItemRef(m)) => m.id,
     };
     debug!("> Encoding inlined item: {} ({})",
            ecx.tcx.map.path_to_string(id),
@@ -137,7 +138,12 @@ pub fn decode_inlined_item(cdata: &cstore::crate_metadata,
         let ident = match ii {
             ast::IIItem(i) => i.ident,
             ast::IIForeign(i) => i.ident,
-            ast::IIMethod(_, _, m) => m.pe_ident(),
+            ast::IITraitItem(_, iti) => {
+                match iti {
+                    ast::ProvidedInlinedTraitItem(m) => m.pe_ident(),
+                    ast::RequiredInlinedTraitItem(m) => m.pe_ident(),
+                }
+            }
         };
         debug!("Fn named: {}", token::get_ident(ident));
         debug!("< Decoded inlined fn: {}::{}",
@@ -344,12 +350,29 @@ fn simplify_ast(ii: e::InlinedItemRef) -> ast::InlinedItem {
 
     match ii {
         // HACK we're not dropping items.
-        e::IIItemRef(i) => ast::IIItem(fold::noop_fold_item(i, &mut fld)
-                                       .expect_one("expected one item")),
-        e::IIMethodRef(d, p, m) => ast::IIMethod(d, p, fold::noop_fold_method(m, &mut fld)
-                                                 .expect_one(
-                "noop_fold_method must produce exactly one method")),
-        e::IIForeignRef(i) => ast::IIForeign(fold::noop_fold_foreign_item(i, &mut fld))
+        e::IIItemRef(i) => {
+            ast::IIItem(fold::noop_fold_item(i, &mut fld)
+                            .expect_one("expected one item"))
+        }
+        e::IITraitItemRef(d, iti) => {
+            ast::IITraitItem(d, match iti {
+                e::ProvidedInlinedTraitItemRef(m) => {
+                    ast::ProvidedInlinedTraitItem(
+                        fold::noop_fold_method(m, &mut fld)
+                            .expect_one("noop_fold_method must produce \
+                                         exactly one method"))
+                }
+                e::RequiredInlinedTraitItemRef(m) => {
+                    ast::RequiredInlinedTraitItem(
+                        fold::noop_fold_method(m, &mut fld)
+                            .expect_one("noop_fold_method must produce \
+                                         exactly one method"))
+                }
+            })
+        }
+        e::IIForeignRef(i) => {
+            ast::IIForeign(fold::noop_fold_foreign_item(i, &mut fld))
+        }
     }
 }
 
@@ -389,9 +412,23 @@ fn renumber_and_map_ast(xcx: &ExtendedDecodeContext,
             ast::IIItem(i) => {
                 ast::IIItem(fld.fold_item(i).expect_one("expected one item"))
             }
-            ast::IIMethod(d, is_provided, m) => {
-                ast::IIMethod(xcx.tr_def_id(d), is_provided, fld.fold_method(m)
-                              .expect_one("expected one method"))
+            ast::IITraitItem(d, iti) => {
+                match iti {
+                    ast::ProvidedInlinedTraitItem(m) => {
+                        ast::IITraitItem(
+                            xcx.tr_def_id(d),
+                            ast::ProvidedInlinedTraitItem(
+                                fld.fold_method(m)
+                                   .expect_one("expected one method")))
+                    }
+                    ast::RequiredInlinedTraitItem(m) => {
+                        ast::IITraitItem(
+                            xcx.tr_def_id(d),
+                            ast::RequiredInlinedTraitItem(
+                                fld.fold_method(m)
+                                   .expect_one("expected one method")))
+                    }
+                }
             }
             ast::IIForeign(i) => ast::IIForeign(fld.fold_foreign_item(i))
         }
@@ -530,9 +567,14 @@ fn encode_freevar_entry(rbml_w: &mut Encoder, fv: &freevar_entry) {
     (*fv).encode(rbml_w).unwrap();
 }
 
+fn encode_capture_mode(rbml_w: &mut Encoder, cm: CaptureMode) {
+    cm.encode(rbml_w).unwrap();
+}
+
 trait rbml_decoder_helper {
     fn read_freevar_entry(&mut self, xcx: &ExtendedDecodeContext)
                           -> freevar_entry;
+    fn read_capture_mode(&mut self) -> CaptureMode;
 }
 
 impl<'a> rbml_decoder_helper for reader::Decoder<'a> {
@@ -541,6 +583,11 @@ fn read_freevar_entry(&mut self, xcx: &ExtendedDecodeContext)
         let fv: freevar_entry = Decodable::decode(self).unwrap();
         fv.tr(xcx)
     }
+
+    fn read_capture_mode(&mut self) -> CaptureMode {
+        let cm: CaptureMode = Decodable::decode(self).unwrap();
+        cm
+    }
 }
 
 impl tr for freevar_entry {
@@ -679,10 +726,35 @@ pub fn encode_vtable_param_res(ecx: &e::EncodeContext,
     }).unwrap()
 }
 
+pub fn encode_unboxed_closure_kind(ebml_w: &mut Encoder,
+                                   kind: ty::UnboxedClosureKind) {
+    ebml_w.emit_enum("UnboxedClosureKind", |ebml_w| {
+        match kind {
+            ty::FnUnboxedClosureKind => {
+                ebml_w.emit_enum_variant("FnUnboxedClosureKind", 0, 3, |_| {
+                    Ok(())
+                })
+            }
+            ty::FnMutUnboxedClosureKind => {
+                ebml_w.emit_enum_variant("FnMutUnboxedClosureKind", 1, 3, |_| {
+                    Ok(())
+                })
+            }
+            ty::FnOnceUnboxedClosureKind => {
+                ebml_w.emit_enum_variant("FnOnceUnboxedClosureKind",
+                                         2,
+                                         3,
+                                         |_| {
+                    Ok(())
+                })
+            }
+        }
+    }).unwrap()
+}
 
 pub fn encode_vtable_origin(ecx: &e::EncodeContext,
-                        rbml_w: &mut Encoder,
-                        vtable_origin: &typeck::vtable_origin) {
+                            rbml_w: &mut Encoder,
+                            vtable_origin: &typeck::vtable_origin) {
     rbml_w.emit_enum("vtable_origin", |rbml_w| {
         match *vtable_origin {
           typeck::vtable_static(def_id, ref substs, ref vtable_res) => {
@@ -1096,6 +1168,15 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
         }
     }
 
+    for &cm in tcx.capture_modes.borrow().find(&id).iter() {
+        rbml_w.tag(c::tag_table_capture_modes, |rbml_w| {
+            rbml_w.id(id);
+            rbml_w.tag(c::tag_table_val, |rbml_w| {
+                encode_capture_mode(rbml_w, *cm);
+            })
+        })
+    }
+
     let lid = ast::DefId { krate: ast::LOCAL_CRATE, node: id };
     for &pty in tcx.tcache.borrow().find(&lid).iter() {
         rbml_w.tag(c::tag_table_tcache, |rbml_w| {
@@ -1191,14 +1272,15 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
         })
     }
 
-    for unboxed_closure_type in tcx.unboxed_closure_types
-                                   .borrow()
-                                   .find(&ast_util::local_def(id))
-                                   .iter() {
-        rbml_w.tag(c::tag_table_unboxed_closure_type, |rbml_w| {
+    for unboxed_closure in tcx.unboxed_closures
+                              .borrow()
+                              .find(&ast_util::local_def(id))
+                              .iter() {
+        rbml_w.tag(c::tag_table_unboxed_closures, |rbml_w| {
             rbml_w.id(id);
             rbml_w.tag(c::tag_table_val, |rbml_w| {
-                rbml_w.emit_closure_type(ecx, *unboxed_closure_type)
+                rbml_w.emit_closure_type(ecx, &unboxed_closure.closure_type);
+                encode_unboxed_closure_kind(rbml_w, unboxed_closure.kind)
             })
         })
     }
@@ -1225,8 +1307,8 @@ fn read_polytype(&mut self, xcx: &ExtendedDecodeContext)
                      -> ty::Polytype;
     fn read_substs(&mut self, xcx: &ExtendedDecodeContext) -> subst::Substs;
     fn read_auto_adjustment(&mut self, xcx: &ExtendedDecodeContext) -> ty::AutoAdjustment;
-    fn read_unboxed_closure_type(&mut self, xcx: &ExtendedDecodeContext)
-                                 -> ty::ClosureTy;
+    fn read_unboxed_closure(&mut self, xcx: &ExtendedDecodeContext)
+                            -> ty::UnboxedClosure;
     fn convert_def_id(&mut self,
                       xcx: &ExtendedDecodeContext,
                       source: DefIdSource,
@@ -1399,16 +1481,33 @@ fn read_auto_adjustment(&mut self, xcx: &ExtendedDecodeContext) -> ty::AutoAdjus
         }).unwrap()
     }
 
-    fn read_unboxed_closure_type(&mut self, xcx: &ExtendedDecodeContext)
-                                 -> ty::ClosureTy {
-        self.read_opaque(|this, doc| {
+    fn read_unboxed_closure(&mut self, xcx: &ExtendedDecodeContext)
+                            -> ty::UnboxedClosure {
+        let closure_type = self.read_opaque(|this, doc| {
             Ok(tydecode::parse_ty_closure_data(
                 doc.data,
                 xcx.dcx.cdata.cnum,
                 doc.start,
                 xcx.dcx.tcx,
                 |s, a| this.convert_def_id(xcx, s, a)))
-        }).unwrap()
+        }).unwrap();
+        let variants = [
+            "FnUnboxedClosureKind",
+            "FnMutUnboxedClosureKind",
+            "FnOnceUnboxedClosureKind"
+        ];
+        let kind = self.read_enum_variant(variants, |_, i| {
+            Ok(match i {
+                0 => ty::FnUnboxedClosureKind,
+                1 => ty::FnMutUnboxedClosureKind,
+                2 => ty::FnOnceUnboxedClosureKind,
+                _ => fail!("bad enum variant for ty::UnboxedClosureKind"),
+            })
+        }).unwrap();
+        ty::UnboxedClosure {
+            closure_type: closure_type,
+            kind: kind,
+        }
     }
 
     fn convert_def_id(&mut self,
@@ -1509,6 +1608,13 @@ fn decode_side_tables(xcx: &ExtendedDecodeContext,
                         let ub: ty::UpvarBorrow = Decodable::decode(val_dsr).unwrap();
                         dcx.tcx.upvar_borrow_map.borrow_mut().insert(upvar_id, ub.tr(xcx));
                     }
+                    c::tag_table_capture_modes => {
+                        let capture_mode = val_dsr.read_capture_mode();
+                        dcx.tcx
+                           .capture_modes
+                           .borrow_mut()
+                           .insert(id, capture_mode);
+                    }
                     c::tag_table_tcache => {
                         let pty = val_dsr.read_polytype(xcx);
                         let lid = ast::DefId { krate: ast::LOCAL_CRATE, node: id };
@@ -1540,14 +1646,14 @@ fn decode_side_tables(xcx: &ExtendedDecodeContext,
                         let adj: ty::AutoAdjustment = val_dsr.read_auto_adjustment(xcx);
                         dcx.tcx.adjustments.borrow_mut().insert(id, adj);
                     }
-                    c::tag_table_unboxed_closure_type => {
-                        let unboxed_closure_type =
-                            val_dsr.read_unboxed_closure_type(xcx);
+                    c::tag_table_unboxed_closures => {
+                        let unboxed_closure =
+                            val_dsr.read_unboxed_closure(xcx);
                         dcx.tcx
-                           .unboxed_closure_types
+                           .unboxed_closures
                            .borrow_mut()
                            .insert(ast_util::local_def(id),
-                                   unboxed_closure_type);
+                                   unboxed_closure);
                     }
                     _ => {
                         xcx.dcx.tcx.sess.bug(
index 454c3dcd5d3cadd211f996dda5243469ac9a46e6..18323c26dd985629a65765c8d78ecde88716dafa 100644 (file)
@@ -261,6 +261,8 @@ fn guarantee_valid(&mut self,
             self.bccx, borrow_span, cause,
             cmt.clone(), loan_region);
 
+        debug!("guarantee_valid(): restrictions={:?}", restr);
+
         // Create the loan record (if needed).
         let loan = match restr {
             restrictions::Safe => {
index da739faabad93b5ed93b074226dcd62c6d28f547..7d50d07a11e3215a1e69c18ccdf7be89facbc6a6 100644 (file)
@@ -122,9 +122,7 @@ fn restrict(&self,
             }
 
             mc::cat_deref(cmt_base, _, mc::BorrowedPtr(ty::ImmBorrow, lt)) |
-            mc::cat_deref(cmt_base, _, mc::BorrowedPtr(ty::UniqueImmBorrow, lt)) |
-            mc::cat_deref(cmt_base, _, mc::Implicit(ty::ImmBorrow, lt)) |
-            mc::cat_deref(cmt_base, _, mc::Implicit(ty::UniqueImmBorrow, lt)) => {
+            mc::cat_deref(cmt_base, _, mc::Implicit(ty::ImmBorrow, lt)) => {
                 // R-Deref-Imm-Borrowed
                 if !self.bccx.is_subregion_of(self.loan_region, lt) {
                     self.bccx.report(
@@ -142,7 +140,9 @@ fn restrict(&self,
             mc::cat_deref(cmt_base, _, pk) => {
                 match pk {
                     mc::BorrowedPtr(ty::MutBorrow, lt) |
-                    mc::Implicit(ty::MutBorrow, lt) => {
+                    mc::BorrowedPtr(ty::UniqueImmBorrow, lt) |
+                    mc::Implicit(ty::MutBorrow, lt) |
+                    mc::Implicit(ty::UniqueImmBorrow, lt) => {
                         // R-Deref-Mut-Borrowed
                         if !self.bccx.is_subregion_of(self.loan_region, lt) {
                             self.bccx.report(
index 6c5352ed796d689c2e3c76159f22c5ec2d34a8b4..77dd7ed1c4204f1d8d25398a85d84c092d44d630 100644 (file)
@@ -290,8 +290,9 @@ pub fn closure_to_block(closure_id: ast::NodeId,
                     tcx: &ty::ctxt) -> ast::NodeId {
     match tcx.map.get(closure_id) {
         ast_map::NodeExpr(expr) => match expr.node {
-            ast::ExprProc(_decl, block) |
-            ast::ExprFnBlock(_decl, block) => { block.id }
+            ast::ExprProc(_, block) |
+            ast::ExprFnBlock(_, _, block) |
+            ast::ExprUnboxedFn(_, _, _, block) => { block.id }
             _ => fail!("encountered non-closure id: {}", closure_id)
         },
         _ => fail!("encountered non-expr id: {}", closure_id)
index 61a2e8407303b730c6ae88ac076e5e293720b666..12841fb20d26fdcf4161644f6bb63a538e6a68bf 100644 (file)
@@ -46,9 +46,9 @@ fn visit_expr(&mut self, e: &ast::Expr, cx:Context) {
                 self.visit_expr(&**e, cx);
                 self.visit_block(&**b, Loop);
             }
-            ast::ExprFnBlock(_, ref b) |
+            ast::ExprFnBlock(_, _, ref b) |
             ast::ExprProc(_, ref b) |
-            ast::ExprUnboxedFn(_, ref b) => {
+            ast::ExprUnboxedFn(_, _, _, ref b) => {
                 self.visit_block(&**b, Closure);
             }
             ast::ExprBreak(_) => self.require_loop("break", cx, e.span),
index 86fe6dc0ddc6c921bd17bd8320b7a3df2c3837d9..9a7bfb0e6dca257cedfca8138e4f6599c1f05d66 100644 (file)
@@ -40,9 +40,9 @@ fn should_explore(tcx: &ty::ctxt, def_id: ast::DefId) -> bool {
 
     match tcx.map.find(def_id.node) {
         Some(ast_map::NodeItem(..))
-        | Some(ast_map::NodeMethod(..))
+        | Some(ast_map::NodeImplItem(..))
         | Some(ast_map::NodeForeignItem(..))
-        | Some(ast_map::NodeTraitMethod(..)) => true,
+        | Some(ast_map::NodeTraitItem(..)) => true,
         _ => false
     }
 }
@@ -114,9 +114,14 @@ fn lookup_and_handle_method(&mut self, id: ast::NodeId,
                         method_num: index,
                         ..
                     }) => {
-                        let def_id = ty::trait_method(self.tcx,
-                                                      trait_id, index).def_id;
-                        self.check_def_id(def_id);
+                        let trait_item = ty::trait_item(self.tcx,
+                                                        trait_id,
+                                                        index);
+                        match trait_item {
+                            ty::MethodTraitItem(method) => {
+                                self.check_def_id(method.def_id);
+                            }
+                        }
                     }
                 }
             }
@@ -208,11 +213,15 @@ fn visit_node(&mut self, node: &ast_map::Node) {
                     _ => ()
                 }
             }
-            ast_map::NodeTraitMethod(trait_method) => {
-                visit::walk_trait_method(self, &*trait_method, ctxt);
+            ast_map::NodeTraitItem(trait_method) => {
+                visit::walk_trait_item(self, &*trait_method, ctxt);
             }
-            ast_map::NodeMethod(method) => {
-                visit::walk_block(self, &*method.pe_body(), ctxt);
+            ast_map::NodeImplItem(impl_item) => {
+                match *impl_item {
+                    ast::MethodImplItem(method) => {
+                        visit::walk_block(self, &*method.pe_body(), ctxt);
+                    }
+                }
             }
             ast_map::NodeForeignItem(foreign_item) => {
                 visit::walk_foreign_item(self, &*foreign_item, ctxt);
@@ -316,9 +325,13 @@ fn visit_item(&mut self, item: &ast::Item, _: ()) {
             self.worklist.push(item.id);
         }
         match item.node {
-            ast::ItemImpl(_, Some(ref _trait_ref), _, ref methods) => {
-                for method in methods.iter() {
-                    self.worklist.push(method.id);
+            ast::ItemImpl(_, Some(ref _trait_ref), _, ref impl_items) => {
+                for impl_item in impl_items.iter() {
+                    match *impl_item {
+                        ast::MethodImplItem(method) => {
+                            self.worklist.push(method.id);
+                        }
+                    }
                 }
             }
             _ => ()
@@ -443,13 +456,14 @@ fn symbol_is_live(&mut self, id: ast::NodeId,
         // This is done to handle the case where, for example, the static
         // method of a private type is used, but the type itself is never
         // called directly.
-        let impl_methods = self.tcx.impl_methods.borrow();
+        let impl_items = self.tcx.impl_items.borrow();
         match self.tcx.inherent_impls.borrow().find(&local_def(id)) {
             None => (),
             Some(impl_list) => {
                 for impl_did in impl_list.borrow().iter() {
-                    for method_did in impl_methods.get(impl_did).iter() {
-                        if self.live_symbols.contains(&method_did.node) {
+                    for item_did in impl_items.get(impl_did).iter() {
+                        if self.live_symbols.contains(&item_did.def_id()
+                                                               .node) {
                             return true;
                         }
                     }
@@ -516,12 +530,12 @@ fn visit_struct_field(&mut self, field: &ast::StructField, _: ()) {
     }
 
     // Overwrite so that we don't warn the trait method itself.
-    fn visit_trait_method(&mut self, trait_method: &ast::TraitMethod, _: ()) {
+    fn visit_trait_item(&mut self, trait_method: &ast::TraitItem, _: ()) {
         match *trait_method {
-            ast::Provided(ref method) => {
+            ast::ProvidedMethod(ref method) => {
                 visit::walk_block(self, &*method.pe_body(), ())
             }
-            ast::Required(_) => ()
+            ast::RequiredMethod(_) => ()
         }
     }
 }
index 605811555a16819b70d69d99a42b614b4c6a0560..b76b85e024c447309844607cd789cf384b07c469 100644 (file)
@@ -131,12 +131,14 @@ fn from_trait_id(tcx: &ty::ctxt, trait_id: ast::DefId)
     fn from_method_id(tcx: &ty::ctxt, method_id: ast::DefId)
                       -> OverloadedCallType {
         let method_descriptor =
-            match tcx.methods.borrow_mut().find(&method_id) {
+            match tcx.impl_or_trait_items.borrow_mut().find(&method_id) {
+                Some(&ty::MethodTraitItem(ref method_descriptor)) => {
+                    (*method_descriptor).clone()
+                }
                 None => {
                     tcx.sess.bug("overloaded call method wasn't in method \
                                   map")
                 }
-                Some(ref method_descriptor) => (*method_descriptor).clone(),
             };
         let impl_id = match method_descriptor.container {
             ty::TraitContainer(_) => {
@@ -399,10 +401,16 @@ pub fn walk_expr(&mut self, expr: &ast::Expr) {
             ast::ExprForLoop(ref pat, ref head, ref blk, _) => {
                 // The pattern lives as long as the block.
                 debug!("walk_expr for loop case: blk id={}", blk.id);
-                self.walk_expr(&**head);
+                self.consume_expr(&**head);
 
-                let head_cmt = return_if_err!(self.mc.cat_expr(&**head));
-                self.walk_pat(head_cmt, pat.clone());
+                // Fetch the type of the value that the iteration yields to
+                // produce the pattern's categorized mutable type.
+                let pattern_type = ty::node_id_to_type(self.tcx(), pat.id);
+                let pat_cmt = self.mc.cat_rvalue(pat.id,
+                                                 pat.span,
+                                                 ty::ReScope(blk.id),
+                                                 pattern_type);
+                self.walk_pat(pat_cmt, pat.clone());
 
                 self.walk_block(&**blk);
             }
@@ -835,6 +843,7 @@ fn walk_pat(&mut self, cmt_discr: mc::cmt, pat: Gc<ast::Pat>) {
                     }
                     ast::PatIdent(ast::BindByValue(_), _, _) => {
                         let mode = copy_or_move(typer.tcx(), cmt_pat.ty, PatBindingMove);
+                        debug!("walk_pat binding consuming pat");
                         delegate.consume_pat(pat, cmt_pat, mode);
                     }
                     _ => {
index eda567f7d187c1a33745f52b154601c20eac2c57..1a2d21baa210a20e20a0f103f8dbb597177252a5 100644 (file)
 use middle::mem_categorization::Typer;
 use middle::resolve;
 use middle::ty;
-use util::nodemap::{DefIdSet, NodeMap, NodeSet};
+use util::nodemap::{NodeMap, NodeSet};
 
+use syntax::ast;
 use syntax::codemap::Span;
-use syntax::{ast};
-use syntax::visit;
 use syntax::visit::Visitor;
+use syntax::visit;
 
-#[deriving(Show)]
+#[deriving(Clone, Decodable, Encodable, Show)]
 pub enum CaptureMode {
     /// Copy/move the value from this llvm ValueRef into the environment.
     CaptureByValue,
@@ -43,12 +43,13 @@ pub struct freevar_entry {
 
 pub type freevar_map = NodeMap<Vec<freevar_entry>>;
 
-pub type UnboxedClosureList = DefIdSet;
+pub type CaptureModeMap = NodeMap<CaptureMode>;
 
 struct CollectFreevarsVisitor<'a> {
     seen: NodeSet,
     refs: Vec<freevar_entry>,
     def_map: &'a resolve::DefMap,
+    capture_mode_map: &'a mut CaptureModeMap,
 }
 
 impl<'a> Visitor<int> for CollectFreevarsVisitor<'a> {
@@ -58,8 +59,27 @@ fn visit_item(&mut self, _: &ast::Item, _: int) {
 
     fn visit_expr(&mut self, expr: &ast::Expr, depth: int) {
         match expr.node {
-            ast::ExprFnBlock(..) | ast::ExprProc(..) |
-            ast::ExprUnboxedFn(..) => {
+            ast::ExprProc(..) => {
+                self.capture_mode_map.insert(expr.id, CaptureByValue);
+                visit::walk_expr(self, expr, depth + 1)
+            }
+            ast::ExprFnBlock(_, _, _) => {
+                // NOTE(stage0): After snapshot, change to:
+                //
+                //let capture_mode = match capture_clause {
+                //    ast::CaptureByValue => CaptureByValue,
+                //    ast::CaptureByRef => CaptureByRef,
+                //};
+                let capture_mode = CaptureByRef;
+                self.capture_mode_map.insert(expr.id, capture_mode);
+                visit::walk_expr(self, expr, depth + 1)
+            }
+            ast::ExprUnboxedFn(capture_clause, _, _, _) => {
+                let capture_mode = match capture_clause {
+                    ast::CaptureByValue => CaptureByValue,
+                    ast::CaptureByRef => CaptureByRef,
+                };
+                self.capture_mode_map.insert(expr.id, capture_mode);
                 visit::walk_expr(self, expr, depth + 1)
             }
             ast::ExprPath(..) => {
@@ -91,8 +111,6 @@ fn visit_expr(&mut self, expr: &ast::Expr, depth: int) {
             _ => visit::walk_expr(self, expr, depth)
         }
     }
-
-
 }
 
 // Searches through part of the AST for all references to locals or
@@ -100,26 +118,34 @@ fn visit_expr(&mut self, expr: &ast::Expr, depth: int) {
 // Since we want to be able to collect upvars in some arbitrary piece
 // of the AST, we take a walker function that we invoke with a visitor
 // in order to start the search.
-fn collect_freevars(def_map: &resolve::DefMap, blk: &ast::Block) -> Vec<freevar_entry> {
+fn collect_freevars(def_map: &resolve::DefMap,
+                    blk: &ast::Block,
+                    capture_mode_map: &mut CaptureModeMap)
+                    -> Vec<freevar_entry> {
     let mut v = CollectFreevarsVisitor {
         seen: NodeSet::new(),
         refs: Vec::new(),
         def_map: def_map,
+        capture_mode_map: &mut *capture_mode_map,
     };
 
     v.visit_block(blk, 1);
+
     v.refs
 }
 
 struct AnnotateFreevarsVisitor<'a> {
     def_map: &'a resolve::DefMap,
     freevars: freevar_map,
+    capture_mode_map: CaptureModeMap,
 }
 
 impl<'a> Visitor<()> for AnnotateFreevarsVisitor<'a> {
     fn visit_fn(&mut self, fk: &visit::FnKind, fd: &ast::FnDecl,
                 blk: &ast::Block, s: Span, nid: ast::NodeId, _: ()) {
-        let vars = collect_freevars(self.def_map, blk);
+        let vars = collect_freevars(self.def_map,
+                                    blk,
+                                    &mut self.capture_mode_map);
         self.freevars.insert(nid, vars);
         visit::walk_fn(self, fk, fd, blk, s, ());
     }
@@ -131,14 +157,20 @@ fn visit_fn(&mut self, fk: &visit::FnKind, fd: &ast::FnDecl,
 // node of interest rather than building up the free variables in
 // one pass. This could be improved upon if it turns out to matter.
 pub fn annotate_freevars(def_map: &resolve::DefMap, krate: &ast::Crate)
-                         -> freevar_map {
+                         -> (freevar_map, CaptureModeMap) {
     let mut visitor = AnnotateFreevarsVisitor {
         def_map: def_map,
         freevars: NodeMap::new(),
+        capture_mode_map: NodeMap::new(),
     };
     visit::walk_crate(&mut visitor, krate, ());
 
-    visitor.freevars
+    let AnnotateFreevarsVisitor {
+        freevars,
+        capture_mode_map,
+        ..
+    } = visitor;
+    (freevars, capture_mode_map)
 }
 
 pub fn with_freevars<T>(tcx: &ty::ctxt, fid: ast::NodeId, f: |&[freevar_entry]| -> T) -> T {
@@ -148,10 +180,7 @@ pub fn with_freevars<T>(tcx: &ty::ctxt, fid: ast::NodeId, f: |&[freevar_entry]|
     }
 }
 
-pub fn get_capture_mode<T: Typer>(tcx: &T, closure_expr_id: ast::NodeId) -> CaptureMode {
-    let fn_ty = tcx.node_ty(closure_expr_id).ok().expect("couldn't find closure ty?");
-    match ty::ty_closure_store(fn_ty) {
-        ty::RegionTraitStore(..) => CaptureByRef,
-        ty::UniqTraitStore => CaptureByValue
-    }
+pub fn get_capture_mode<T:Typer>(tcx: &T, closure_expr_id: ast::NodeId)
+                        -> CaptureMode {
+    tcx.capture_mode(closure_expr_id)
 }
index 83f4fbaed67928f21f01ae701bbf27471f4bdbb9..17b2c69f4531629bf9ca6e0260cd6a21585208e6 100644 (file)
@@ -225,7 +225,7 @@ fn check_for_bare(cx: &Context, fv: &freevar_entry) {
             b(check_for_bare)
         }
 
-        ty::ty_unboxed_closure(_) => {}
+        ty::ty_unboxed_closure(..) => {}
 
         ref s => {
             cx.tcx.sess.bug(format!("expect fn type in kind checker, not \
index 1c31b671a947bafe1118999bdafb28b32e937686..baac68904d553308cc69f260806d4b1232018f8a 100644 (file)
@@ -965,9 +965,9 @@ fn propagate_through_expr(&mut self, expr: &Expr, succ: LiveNode)
               self.propagate_through_expr(&**e, succ)
           }
 
-          ExprFnBlock(_, ref blk) |
+          ExprFnBlock(_, _, ref blk) |
           ExprProc(_, ref blk) |
-          ExprUnboxedFn(_, ref blk) => {
+          ExprUnboxedFn(_, _, _, ref blk) => {
               debug!("{} is an ExprFnBlock, ExprProc, or ExprUnboxedFn",
                      expr_to_string(expr));
 
index 39a7b4aa3d68ec7a512df051f7ada80aa5071032..ef1e0515156c038811fc4d6346b486bb049ccb41 100644 (file)
 #![allow(non_camel_case_types)]
 
 use middle::def;
+use middle::freevars;
 use middle::ty;
 use middle::typeck;
-use util::nodemap::NodeMap;
+use util::nodemap::{DefIdMap, NodeMap};
 use util::ppaux::{ty_to_string, Repr};
 
 use syntax::ast::{MutImmutable, MutMutable};
@@ -270,6 +271,10 @@ pub trait Typer {
     fn is_method_call(&self, id: ast::NodeId) -> bool;
     fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option<ast::NodeId>;
     fn upvar_borrow(&self, upvar_id: ty::UpvarId) -> ty::UpvarBorrow;
+    fn capture_mode(&self, closure_expr_id: ast::NodeId)
+                    -> freevars::CaptureMode;
+    fn unboxed_closures<'a>(&'a self)
+                        -> &'a RefCell<DefIdMap<ty::UnboxedClosure>>;
 }
 
 impl MutabilityCategory {
@@ -595,13 +600,22 @@ pub fn cat_def(&self,
                           }))
                       }
                   }
-                  ty::ty_unboxed_closure(_) => {
+                  ty::ty_unboxed_closure(closure_id, _) => {
+                      let unboxed_closures = self.typer
+                                                 .unboxed_closures()
+                                                 .borrow();
+                      let kind = unboxed_closures.get(&closure_id).kind;
+                      let onceness = match kind {
+                          ty::FnUnboxedClosureKind |
+                          ty::FnMutUnboxedClosureKind => ast::Many,
+                          ty::FnOnceUnboxedClosureKind => ast::Once,
+                      };
                       Ok(Rc::new(cmt_ {
                           id: id,
                           span: span,
                           cat: cat_copied_upvar(CopiedUpvar {
                               upvar_id: var_id,
-                              onceness: ast::Many,
+                              onceness: onceness,
                               capturing_proc: fn_node_id,
                           }),
                           mutbl: MutabilityCategory::from_def(&def),
index 62b5299f8fbc8619cb0d02319c41f878d8eecc21..61e6debb0864714cbd8d8a41255300e59488eac7 100644 (file)
@@ -83,8 +83,8 @@ fn visit_item(&mut self, item: &ast::Item, _: ()) {
             ast::ItemTrait(_, _, _, ref methods) if item.vis != ast::Public => {
                 for m in methods.iter() {
                     match *m {
-                        ast::Provided(ref m) => self.parents.insert(m.id, item.id),
-                        ast::Required(ref m) => self.parents.insert(m.id, item.id),
+                        ast::ProvidedMethod(ref m) => self.parents.insert(m.id, item.id),
+                        ast::RequiredMethod(ref m) => self.parents.insert(m.id, item.id),
                     };
                 }
             }
@@ -240,7 +240,7 @@ fn visit_item(&mut self, item: &ast::Item, _: ()) {
             //   undefined symbols at linkage time if this case is not handled.
             //
             // * Private trait impls for private types can be completely ignored
-            ast::ItemImpl(_, _, ref ty, ref methods) => {
+            ast::ItemImpl(_, _, ref ty, ref impl_items) => {
                 let public_ty = match ty.node {
                     ast::TyPath(_, _, id) => {
                         match self.tcx.def_map.borrow().get_copy(&id) {
@@ -261,13 +261,18 @@ fn visit_item(&mut self, item: &ast::Item, _: ()) {
                 });
 
                 if public_ty || public_trait {
-                    for method in methods.iter() {
-                        let meth_public = match method.pe_explicit_self().node {
-                            ast::SelfStatic => public_ty,
-                            _ => true,
-                        } && method.pe_vis() == ast::Public;
-                        if meth_public || tr.is_some() {
-                            self.exported_items.insert(method.id);
+                    for impl_item in impl_items.iter() {
+                        match *impl_item {
+                            ast::MethodImplItem(method) => {
+                                let meth_public =
+                                    match method.pe_explicit_self().node {
+                                        ast::SelfStatic => public_ty,
+                                        _ => true,
+                                    } && method.pe_vis() == ast::Public;
+                                if meth_public || tr.is_some() {
+                                    self.exported_items.insert(method.id);
+                                }
+                            }
                         }
                     }
                 }
@@ -278,11 +283,11 @@ fn visit_item(&mut self, item: &ast::Item, _: ()) {
             ast::ItemTrait(_, _, _, ref methods) if public_first => {
                 for method in methods.iter() {
                     match *method {
-                        ast::Provided(ref m) => {
+                        ast::ProvidedMethod(ref m) => {
                             debug!("provided {}", m.id);
                             self.exported_items.insert(m.id);
                         }
-                        ast::Required(ref m) => {
+                        ast::RequiredMethod(ref m) => {
                             debug!("required {}", m.id);
                             self.exported_items.insert(m.id);
                         }
@@ -387,9 +392,10 @@ fn def_privacy(&self, did: ast::DefId) -> PrivacyResult {
             }
             debug!("privacy - is {:?} a public method", did);
 
-            return match self.tcx.methods.borrow().find(&did) {
-                Some(meth) => {
-                    debug!("privacy - well at least it's a method: {:?}", meth);
+            return match self.tcx.impl_or_trait_items.borrow().find(&did) {
+                Some(&ty::MethodTraitItem(ref meth)) => {
+                    debug!("privacy - well at least it's a method: {:?}",
+                           *meth);
                     match meth.container {
                         ty::TraitContainer(id) => {
                             debug!("privacy - recursing on trait {:?}", id);
@@ -451,15 +457,23 @@ fn def_privacy(&self, did: ast::DefId) -> PrivacyResult {
                 // invocation.
                 // FIXME(#10573) is this the right behavior? Why not consider
                 //               where the method was defined?
-                Some(ast_map::NodeMethod(ref m)) => {
-                    let imp = self.tcx.map.get_parent_did(closest_private_id);
-                    match ty::impl_trait_ref(self.tcx, imp) {
-                        Some(..) => return Allowable,
-                        _ if m.pe_vis() == ast::Public => return Allowable,
-                        _ => m.pe_vis()
+                Some(ast_map::NodeImplItem(ref ii)) => {
+                    match **ii {
+                        ast::MethodImplItem(m) => {
+                            let imp = self.tcx
+                                          .map
+                                          .get_parent_did(closest_private_id);
+                            match ty::impl_trait_ref(self.tcx, imp) {
+                                Some(..) => return Allowable,
+                                _ if m.pe_vis() == ast::Public => {
+                                    return Allowable
+                                }
+                                _ => m.pe_vis()
+                            }
+                        }
                     }
                 }
-                Some(ast_map::NodeTraitMethod(_)) => {
+                Some(ast_map::NodeTraitItem(_)) => {
                     return Allowable;
                 }
 
@@ -648,12 +662,17 @@ fn check_field(&mut self,
     }
 
     // Given the ID of a method, checks to ensure it's in scope.
-    fn check_static_method(&mut self, span: Span, method_id: ast::DefId,
+    fn check_static_method(&mut self,
+                           span: Span,
+                           method_id: ast::DefId,
                            name: ast::Ident) {
         // If the method is a default method, we need to use the def_id of
         // the default implementation.
-        let method_id = ty::method(self.tcx, method_id).provided_source
-                                                       .unwrap_or(method_id);
+        let method_id = match ty::impl_or_trait_item(self.tcx, method_id) {
+            ty::MethodTraitItem(method_type) => {
+                method_type.provided_source.unwrap_or(method_id)
+            }
+        };
 
         let string = token::get_ident(name);
         self.report_error(self.ensure_public(span,
@@ -1075,12 +1094,16 @@ fn check_sane_privacy(&self, item: &ast::Item) {
         match item.node {
             // implementations of traits don't need visibility qualifiers because
             // that's controlled by having the trait in scope.
-            ast::ItemImpl(_, Some(..), _, ref methods) => {
+            ast::ItemImpl(_, Some(..), _, ref impl_items) => {
                 check_inherited(item.span, item.vis,
                                 "visibility qualifiers have no effect on trait \
                                  impls");
-                for m in methods.iter() {
-                    check_inherited(m.span, m.pe_vis(), "");
+                for impl_item in impl_items.iter() {
+                    match *impl_item {
+                        ast::MethodImplItem(m) => {
+                            check_inherited(m.span, m.pe_vis(), "");
+                        }
+                    }
                 }
             }
 
@@ -1111,11 +1134,11 @@ fn check_sane_privacy(&self, item: &ast::Item) {
             ast::ItemTrait(_, _, _, ref methods) => {
                 for m in methods.iter() {
                     match *m {
-                        ast::Provided(ref m) => {
+                        ast::ProvidedMethod(ref m) => {
                             check_inherited(m.span, m.pe_vis(),
                                             "unnecessary visibility");
                         }
-                        ast::Required(ref m) => {
+                        ast::RequiredMethod(ref m) => {
                             check_inherited(m.span, m.vis,
                                             "unnecessary visibility");
                         }
@@ -1148,9 +1171,13 @@ fn check_inherited(tcx: &ty::ctxt, sp: Span, vis: ast::Visibility) {
         };
         check_inherited(tcx, item.span, item.vis);
         match item.node {
-            ast::ItemImpl(_, _, _, ref methods) => {
-                for m in methods.iter() {
-                    check_inherited(tcx, m.span, m.pe_vis());
+            ast::ItemImpl(_, _, _, ref impl_items) => {
+                for impl_item in impl_items.iter() {
+                    match *impl_item {
+                        ast::MethodImplItem(m) => {
+                            check_inherited(tcx, m.span, m.pe_vis());
+                        }
+                    }
                 }
             }
             ast::ItemForeignMod(ref fm) => {
@@ -1174,8 +1201,8 @@ fn check_inherited(tcx: &ty::ctxt, sp: Span, vis: ast::Visibility) {
             ast::ItemTrait(_, _, _, ref methods) => {
                 for m in methods.iter() {
                     match *m {
-                        ast::Required(..) => {}
-                        ast::Provided(ref m) => check_inherited(tcx, m.span,
+                        ast::RequiredMethod(..) => {}
+                        ast::ProvidedMethod(ref m) => check_inherited(tcx, m.span,
                                                                 m.pe_vis()),
                     }
                 }
@@ -1270,7 +1297,7 @@ fn visit_item(&mut self, item: &ast::Item, _: ()) {
             // (i.e. we could just return here to not check them at
             // all, or some worse estimation of whether an impl is
             // publicly visible.
-            ast::ItemImpl(ref g, ref trait_ref, self_, ref methods) => {
+            ast::ItemImpl(ref g, ref trait_ref, self_, ref impl_items) => {
                 // `impl [... for] Private` is never visible.
                 let self_contains_private;
                 // impl [... for] Public<...>, but not `impl [... for]
@@ -1311,7 +1338,14 @@ fn visit_item(&mut self, item: &ast::Item, _: ()) {
                 // are private (because `T` won't be visible externally).
                 let trait_or_some_public_method =
                     trait_ref.is_some() ||
-                    methods.iter().any(|m| self.exported_items.contains(&m.id));
+                    impl_items.iter()
+                              .any(|impl_item| {
+                                  match *impl_item {
+                                      ast::MethodImplItem(m) => {
+                                          self.exported_items.contains(&m.id)
+                                      }
+                                  }
+                              });
 
                 if !self_contains_private &&
                         not_private_trait &&
@@ -1321,8 +1355,14 @@ fn visit_item(&mut self, item: &ast::Item, _: ()) {
 
                     match *trait_ref {
                         None => {
-                            for method in methods.iter() {
-                                visit::walk_method_helper(self, &**method, ())
+                            for impl_item in impl_items.iter() {
+                                match *impl_item {
+                                    ast::MethodImplItem(method) => {
+                                        visit::walk_method_helper(self,
+                                                                  &*method,
+                                                                  ())
+                                    }
+                                }
                             }
                         }
                         Some(ref tr) => {
@@ -1345,11 +1385,19 @@ fn visit_item(&mut self, item: &ast::Item, _: ()) {
                     // impl Public<Private> { ... }. Any public static
                     // methods will be visible as `Public::foo`.
                     let mut found_pub_static = false;
-                    for method in methods.iter() {
-                        if method.pe_explicit_self().node == ast::SelfStatic &&
-                            self.exported_items.contains(&method.id) {
-                            found_pub_static = true;
-                            visit::walk_method_helper(self, &**method, ());
+                    for impl_item in impl_items.iter() {
+                        match *impl_item {
+                            ast::MethodImplItem(method) => {
+                                if method.pe_explicit_self().node ==
+                                        ast::SelfStatic &&
+                                        self.exported_items
+                                            .contains(&method.id) {
+                                    found_pub_static = true;
+                                    visit::walk_method_helper(self,
+                                                              &*method,
+                                                              ());
+                                }
+                            }
                         }
                     }
                     if found_pub_static {
index 7ed1209bdf75097485a6f2043565948230e65479..5dfc43daa646f763dcb0c9c835d3d007641a991c 100644 (file)
@@ -193,26 +193,37 @@ fn def_id_represents_local_inlined_item(&self, def_id: ast::DefId) -> bool {
                     _ => false,
                 }
             }
-            Some(ast_map::NodeTraitMethod(trait_method)) => {
+            Some(ast_map::NodeTraitItem(trait_method)) => {
                 match *trait_method {
-                    ast::Required(_) => false,
-                    ast::Provided(_) => true,
+                    ast::RequiredMethod(_) => false,
+                    ast::ProvidedMethod(_) => true,
                 }
             }
-            Some(ast_map::NodeMethod(method)) => {
-                if generics_require_inlining(method.pe_generics()) ||
-                        attributes_specify_inlining(method.attrs.as_slice()) {
-                    true
-                } else {
-                    let impl_did = self.tcx.map.get_parent_did(node_id);
-                    // Check the impl. If the generics on the self type of the
-                    // impl require inlining, this method does too.
-                    assert!(impl_did.krate == ast::LOCAL_CRATE);
-                    match self.tcx.map.expect_item(impl_did.node).node {
-                        ast::ItemImpl(ref generics, _, _, _) => {
-                            generics_require_inlining(generics)
+            Some(ast_map::NodeImplItem(impl_item)) => {
+                match *impl_item {
+                    ast::MethodImplItem(method) => {
+                        if generics_require_inlining(method.pe_generics()) ||
+                                attributes_specify_inlining(
+                                    method.attrs.as_slice()) {
+                            true
+                        } else {
+                            let impl_did = self.tcx
+                                               .map
+                                               .get_parent_did(node_id);
+                            // Check the impl. If the generics on the self
+                            // type of the impl require inlining, this method
+                            // does too.
+                            assert!(impl_did.krate == ast::LOCAL_CRATE);
+                            match self.tcx
+                                      .map
+                                      .expect_item(impl_did.node)
+                                      .node {
+                                ast::ItemImpl(ref generics, _, _, _) => {
+                                    generics_require_inlining(generics)
+                                }
+                                _ => false
+                            }
                         }
-                        _ => false
                     }
                 }
             }
@@ -310,20 +321,24 @@ fn propagate_node(&mut self, node: &ast_map::Node,
                     }
                 }
             }
-            ast_map::NodeTraitMethod(trait_method) => {
+            ast_map::NodeTraitItem(trait_method) => {
                 match *trait_method {
-                    ast::Required(..) => {
+                    ast::RequiredMethod(..) => {
                         // Keep going, nothing to get exported
                     }
-                    ast::Provided(ref method) => {
+                    ast::ProvidedMethod(ref method) => {
                         visit::walk_block(self, &*method.pe_body(), ())
                     }
                 }
             }
-            ast_map::NodeMethod(method) => {
-                let did = self.tcx.map.get_parent_did(search_item);
-                if method_might_be_inlined(self.tcx, &*method, did) {
-                    visit::walk_block(self, &*method.pe_body(), ())
+            ast_map::NodeImplItem(impl_item) => {
+                match *impl_item {
+                    ast::MethodImplItem(method) => {
+                        let did = self.tcx.map.get_parent_did(search_item);
+                        if method_might_be_inlined(self.tcx, &*method, did) {
+                            visit::walk_block(self, &*method.pe_body(), ())
+                        }
+                    }
                 }
             }
             // Nothing to recurse on for these
index 95c04ad6607d66ead0852153c3689e4b233ee014..3ce6f72610095d2f9af5975528d9f92f2dfa06a0 100644 (file)
@@ -24,7 +24,7 @@
 use syntax::ast::*;
 use syntax::ast;
 use syntax::ast_util::{local_def, PostExpansionMethod};
-use syntax::ast_util::{walk_pat, trait_method_to_ty_method};
+use syntax::ast_util::{walk_pat, trait_item_to_ty_method};
 use syntax::ext::mtwt;
 use syntax::parse::token::special_names;
 use syntax::parse::token::special_idents;
@@ -36,7 +36,7 @@
 
 use std::collections::{HashMap, HashSet};
 use std::cell::{Cell, RefCell};
-use std::gc::{Gc, GC};
+use std::gc::GC;
 use std::mem::replace;
 use std::rc::{Rc, Weak};
 use std::uint;
@@ -225,7 +225,7 @@ enum FallbackSuggestion {
     NoSuggestion,
     Field,
     Method,
-    TraitMethod,
+    TraitItem,
     StaticMethod(String),
     StaticTraitMethod(String),
 }
@@ -272,10 +272,10 @@ enum RibKind {
     ConstantItemRibKind
 }
 
-// Methods can be required or provided. Required methods only occur in traits.
+// Methods can be required or provided. RequiredMethod methods only occur in traits.
 enum MethodSort {
-    Required,
-    Provided(NodeId)
+    RequiredMethod,
+    ProvidedMethod(NodeId)
 }
 
 enum UseLexicalScopeFlag {
@@ -289,19 +289,19 @@ enum ModulePrefixResult {
 }
 
 #[deriving(Clone, Eq, PartialEq)]
-enum MethodIsStaticFlag {
-    MethodIsNotStatic,
-    MethodIsStatic,
+pub enum TraitItemKind {
+    NonstaticMethodTraitItemKind,
+    StaticMethodTraitItemKind,
 }
 
-impl MethodIsStaticFlag {
-    fn from_explicit_self_category(explicit_self_category:
-                                   ExplicitSelfCategory)
-                                   -> MethodIsStaticFlag {
+impl TraitItemKind {
+    pub fn from_explicit_self_category(explicit_self_category:
+                                       ExplicitSelfCategory)
+                                       -> TraitItemKind {
         if explicit_self_category == StaticExplicitSelfCategory {
-            MethodIsStatic
+            StaticMethodTraitItemKind
         } else {
-            MethodIsNotStatic
+            NonstaticMethodTraitItemKind
         }
     }
 }
@@ -824,7 +824,7 @@ struct Resolver<'a> {
 
     graph_root: NameBindings,
 
-    method_map: RefCell<FnvHashMap<(Name, DefId), MethodIsStaticFlag>>,
+    trait_item_map: RefCell<FnvHashMap<(Name, DefId), TraitItemKind>>,
 
     structs: FnvHashMap<DefId, Vec<Name>>,
 
@@ -934,7 +934,7 @@ fn new(session: &'a Session, crate_span: Span) -> Resolver<'a> {
 
             graph_root: graph_root,
 
-            method_map: RefCell::new(FnvHashMap::new()),
+            trait_item_map: RefCell::new(FnvHashMap::new()),
             structs: FnvHashMap::new(),
 
             unresolved_imports: 0,
@@ -1263,7 +1263,7 @@ fn build_reduced_graph_for_item(&mut self,
                 parent
             }
 
-            ItemImpl(_, None, ty, ref methods) => {
+            ItemImpl(_, None, ty, ref impl_items) => {
                 // If this implements an anonymous trait, then add all the
                 // methods within to a new module, if the type was defined
                 // within this module.
@@ -1315,35 +1315,43 @@ fn build_reduced_graph_for_item(&mut self,
                             }
                         };
 
-                        // For each method...
-                        for method in methods.iter() {
-                            // Add the method to the module.
-                            let ident = method.pe_ident();
-                            let method_name_bindings =
-                                self.add_child(ident,
-                                               new_parent.clone(),
-                                               ForbidDuplicateValues,
-                                               method.span);
-                            let def = match method.pe_explicit_self().node {
-                                SelfStatic => {
-                                    // Static methods become
-                                    // `def_static_method`s.
-                                    DefStaticMethod(local_def(method.id),
-                                                      FromImpl(local_def(
-                                                        item.id)),
-                                                      method.pe_fn_style())
-                                }
-                                _ => {
-                                    // Non-static methods become
-                                    // `def_method`s.
-                                    DefMethod(local_def(method.id), None)
-                                }
-                            };
+                        // For each implementation item...
+                        for impl_item in impl_items.iter() {
+                            match *impl_item {
+                                MethodImplItem(method) => {
+                                    // Add the method to the module.
+                                    let ident = method.pe_ident();
+                                    let method_name_bindings =
+                                        self.add_child(ident,
+                                                       new_parent.clone(),
+                                                       ForbidDuplicateValues,
+                                                       method.span);
+                                    let def = match method.pe_explicit_self()
+                                                          .node {
+                                        SelfStatic => {
+                                            // Static methods become
+                                            // `def_static_method`s.
+                                            DefStaticMethod(
+                                                local_def(method.id),
+                                                FromImpl(local_def(item.id)),
+                                                         method.pe_fn_style())
+                                        }
+                                        _ => {
+                                            // Non-static methods become
+                                            // `def_method`s.
+                                            DefMethod(local_def(method.id),
+                                                      None)
+                                        }
+                                    };
 
-                            let is_public = method.pe_vis() == ast::Public;
-                            method_name_bindings.define_value(def,
-                                                              method.span,
-                                                              is_public);
+                                    let is_public =
+                                        method.pe_vis() == ast::Public;
+                                    method_name_bindings.define_value(
+                                        def,
+                                        method.span,
+                                        is_public);
+                                }
+                            }
                         }
                     }
                     _ => {}
@@ -1376,7 +1384,7 @@ fn build_reduced_graph_for_item(&mut self,
 
                 // Add the names of all the methods to the trait info.
                 for method in methods.iter() {
-                    let ty_m = trait_method_to_ty_method(method);
+                    let ty_m = trait_item_to_ty_method(method);
 
                     let ident = ty_m.ident;
 
@@ -1387,13 +1395,13 @@ fn build_reduced_graph_for_item(&mut self,
                             (DefStaticMethod(local_def(ty_m.id),
                                               FromTrait(local_def(item.id)),
                                               ty_m.fn_style),
-                             MethodIsStatic)
+                             StaticMethodTraitItemKind)
                         }
                         _ => {
                             // Non-static methods become `def_method`s.
                             (DefMethod(local_def(ty_m.id),
                                        Some(local_def(item.id))),
-                             MethodIsNotStatic)
+                             NonstaticMethodTraitItemKind)
                         }
                     };
 
@@ -1404,7 +1412,7 @@ fn build_reduced_graph_for_item(&mut self,
                                        ty_m.span);
                     method_name_bindings.define_value(def, ty_m.span, true);
 
-                    self.method_map
+                    self.trait_item_map
                         .borrow_mut()
                         .insert((ident.name, def_id), static_flag);
                 }
@@ -1714,29 +1722,29 @@ fn handle_external_def(&mut self,
               debug!("(building reduced graph for external \
                       crate) building type {}", final_ident);
 
-              // If this is a trait, add all the method names
-              // to the trait info.
+              // If this is a trait, add all the trait item names to the trait
+              // info.
 
-              let method_def_ids =
-                csearch::get_trait_method_def_ids(&self.session.cstore, def_id);
-              for &method_def_id in method_def_ids.iter() {
-                  let (method_name, explicit_self) =
-                      csearch::get_method_name_and_explicit_self(&self.session.cstore,
-                                                                 method_def_id);
+              let trait_item_def_ids =
+                csearch::get_trait_item_def_ids(&self.session.cstore, def_id);
+              for trait_item_def_id in trait_item_def_ids.iter() {
+                  let (trait_item_name, trait_item_kind) =
+                      csearch::get_trait_item_name_and_kind(
+                          &self.session.cstore,
+                          trait_item_def_id.def_id());
 
-                  debug!("(building reduced graph for \
-                          external crate) ... adding \
-                          trait method '{}'",
-                         token::get_ident(method_name));
+                  debug!("(building reduced graph for external crate) ... \
+                          adding trait item '{}'",
+                         token::get_ident(trait_item_name));
 
-                  self.method_map
+                  self.trait_item_map
                       .borrow_mut()
-                      .insert((method_name.name, def_id),
-                              MethodIsStaticFlag::from_explicit_self_category(
-                                  explicit_self));
+                      .insert((trait_item_name.name, def_id),
+                              trait_item_kind);
 
                   if is_exported {
-                      self.external_exports.insert(method_def_id);
+                      self.external_exports
+                          .insert(trait_item_def_id.def_id());
                   }
               }
 
@@ -3663,6 +3671,7 @@ fn resolve_item(&mut self, item: &Item) {
                                                                ItemRibKind),
                                              |this| {
                     this.resolve_type_parameters(&generics.ty_params);
+                    this.resolve_where_clause(&generics.where_clause);
                     visit::walk_item(this, item, ());
                 });
             }
@@ -3680,12 +3689,12 @@ fn resolve_item(&mut self, item: &Item) {
             ItemImpl(ref generics,
                      ref implemented_traits,
                      ref self_type,
-                     ref methods) => {
+                     ref impl_items) => {
                 self.resolve_implementation(item.id,
                                             generics,
                                             implemented_traits,
                                             &**self_type,
-                                            methods.as_slice());
+                                            impl_items.as_slice());
             }
 
             ItemTrait(ref generics, ref unbound, ref traits, ref methods) => {
@@ -3705,6 +3714,7 @@ fn resolve_item(&mut self, item: &Item) {
                                                                NormalRibKind),
                                              |this| {
                     this.resolve_type_parameters(&generics.ty_params);
+                    this.resolve_where_clause(&generics.where_clause);
 
                     // Resolve derived traits.
                     for trt in traits.iter() {
@@ -3724,18 +3734,20 @@ fn resolve_item(&mut self, item: &Item) {
                         // FIXME #4951: Do we need a node ID here?
 
                         match *method {
-                          ast::Required(ref ty_m) => {
+                          ast::RequiredMethod(ref ty_m) => {
                             this.with_type_parameter_rib
                                 (HasTypeParameters(&ty_m.generics,
                                                    FnSpace,
                                                    item.id,
-                                        MethodRibKind(item.id, Required)),
+                                        MethodRibKind(item.id, RequiredMethod)),
                                  |this| {
 
                                 // Resolve the method-specific type
                                 // parameters.
                                 this.resolve_type_parameters(
                                     &ty_m.generics.ty_params);
+                                this.resolve_where_clause(&ty_m.generics
+                                                               .where_clause);
 
                                 for argument in ty_m.decl.inputs.iter() {
                                     this.resolve_type(&*argument.ty);
@@ -3751,9 +3763,9 @@ fn resolve_item(&mut self, item: &Item) {
                                 this.resolve_type(&*ty_m.decl.output);
                             });
                           }
-                          ast::Provided(ref m) => {
+                          ast::ProvidedMethod(ref m) => {
                               this.resolve_method(MethodRibKind(item.id,
-                                                                Provided(m.id)),
+                                                                ProvidedMethod(m.id)),
                                                   &**m)
                           }
                         }
@@ -3899,6 +3911,7 @@ fn resolve_function(&mut self,
                 }
                 HasTypeParameters(ref generics, _, _, _) => {
                     this.resolve_type_parameters(&generics.ty_params);
+                    this.resolve_where_clause(&generics.where_clause);
                 }
             }
 
@@ -4014,6 +4027,30 @@ fn resolve_trait_reference(&mut self,
         }
     }
 
+    fn resolve_where_clause(&mut self, where_clause: &ast::WhereClause) {
+        for predicate in where_clause.predicates.iter() {
+            match self.resolve_identifier(predicate.ident,
+                                          TypeNS,
+                                          true,
+                                          predicate.span) {
+                Some((def @ DefTyParam(_, _, _), last_private)) => {
+                    self.record_def(predicate.id, (def, last_private));
+                }
+                _ => {
+                    self.resolve_error(
+                        predicate.span,
+                        format!("undeclared type parameter `{}`",
+                                token::get_ident(
+                                    predicate.ident)).as_slice());
+                }
+            }
+
+            for bound in predicate.bounds.iter() {
+                self.resolve_type_parameter_bound(predicate.id, bound);
+            }
+        }
+    }
+
     fn resolve_struct(&mut self,
                       id: NodeId,
                       generics: &Generics,
@@ -4027,6 +4064,7 @@ fn resolve_struct(&mut self,
                                      |this| {
             // Resolve the type parameters.
             this.resolve_type_parameters(&generics.ty_params);
+            this.resolve_where_clause(&generics.where_clause);
 
             // Resolve the super struct.
             match super_struct {
@@ -4129,7 +4167,7 @@ fn resolve_implementation(&mut self,
                               generics: &Generics,
                               opt_trait_reference: &Option<TraitRef>,
                               self_type: &Ty,
-                              methods: &[Gc<Method>]) {
+                              impl_items: &[ImplItem]) {
         // If applicable, create a rib for the type parameters.
         self.with_type_parameter_rib(HasTypeParameters(generics,
                                                        TypeSpace,
@@ -4138,6 +4176,7 @@ fn resolve_implementation(&mut self,
                                      |this| {
             // Resolve the type parameters.
             this.resolve_type_parameters(&generics.ty_params);
+            this.resolve_where_clause(&generics.where_clause);
 
             // Resolve the trait reference, if necessary.
             this.with_optional_trait_ref(id, opt_trait_reference, |this| {
@@ -4145,27 +4184,36 @@ fn resolve_implementation(&mut self,
                 this.resolve_type(self_type);
 
                 this.with_current_self_type(self_type, |this| {
-                    for method in methods.iter() {
-                        // If this is a trait impl, ensure the method exists in trait
-                        this.check_trait_method(&**method);
-
-                        // We also need a new scope for the method-specific type parameters.
-                        this.resolve_method(MethodRibKind(id, Provided(method.id)),
-                                            &**method);
+                    for impl_item in impl_items.iter() {
+                        match *impl_item {
+                            MethodImplItem(method) => {
+                                // If this is a trait impl, ensure the method
+                                // exists in trait
+                                this.check_trait_item(method.pe_ident(),
+                                                      method.span);
+
+                                // We also need a new scope for the method-
+                                // specific type parameters.
+                                this.resolve_method(
+                                    MethodRibKind(id,
+                                                  ProvidedMethod(method.id)),
+                                    &*method);
+                            }
+                        }
                     }
                 });
             });
         });
     }
 
-    fn check_trait_method(&self, method: &Method) {
+    fn check_trait_item(&self, ident: Ident, span: Span) {
         // If there is a TraitRef in scope for an impl, then the method must be in the trait.
         for &(did, ref trait_ref) in self.current_trait_ref.iter() {
-            let method_name = method.pe_ident().name;
+            let method_name = ident.name;
 
-            if self.method_map.borrow().find(&(method_name, did)).is_none() {
+            if self.trait_item_map.borrow().find(&(method_name, did)).is_none() {
                 let path_str = self.path_idents_to_string(&trait_ref.path);
-                self.resolve_error(method.span,
+                self.resolve_error(span,
                                     format!("method `{}` is not a member of trait `{}`",
                                             token::get_name(method_name),
                                             path_str).as_slice());
@@ -4845,8 +4893,8 @@ fn resolve_module_relative_path(&mut self,
             TraitModuleKind | ImplModuleKind => {
                 match containing_module.def_id.get() {
                     Some(def_id) => {
-                        match self.method_map.borrow().find(&(ident.name, def_id)) {
-                            Some(&MethodIsStatic) => (),
+                        match self.trait_item_map.borrow().find(&(ident.name, def_id)) {
+                            Some(&StaticMethodTraitItemKind) => (),
                             None => (),
                             _ => {
                                 debug!("containing module was a trait or impl \
@@ -5102,7 +5150,7 @@ fn get_module(this: &mut Resolver, span: Span, ident_path: &[ast::Ident])
                             }
                         }
                         Some(DefMethod(_, None)) if allowed == Everything => return Method,
-                        Some(DefMethod(_, Some(_))) => return TraitMethod,
+                        Some(DefMethod(_, Some(_))) => return TraitItem,
                         _ => ()
                     }
                 }
@@ -5112,14 +5160,14 @@ fn get_module(this: &mut Resolver, span: Span, ident_path: &[ast::Ident])
         }
 
         // Look for a method in the current trait.
-        let method_map = self.method_map.borrow();
+        let trait_item_map = self.trait_item_map.borrow();
         match self.current_trait_ref {
             Some((did, ref trait_ref)) => {
                 let path_str = self.path_idents_to_string(&trait_ref.path);
 
-                match method_map.find(&(name, did)) {
-                    Some(&MethodIsStatic) => return StaticTraitMethod(path_str),
-                    Some(_) => return TraitMethod,
+                match trait_item_map.find(&(name, did)) {
+                    Some(&StaticMethodTraitItemKind) => return StaticTraitMethod(path_str),
+                    Some(_) => return TraitItem,
                     None => {}
                 }
             }
@@ -5262,7 +5310,7 @@ fn resolve_expr(&mut self, expr: &Expr) {
                                         Field =>
                                             format!("`self.{}`", wrong_name),
                                         Method
-                                        | TraitMethod =>
+                                        | TraitItem =>
                                             format!("to call `self.{}`", wrong_name),
                                         StaticTraitMethod(path_str)
                                         | StaticMethod(path_str) =>
@@ -5287,9 +5335,9 @@ fn resolve_expr(&mut self, expr: &Expr) {
                 visit::walk_expr(self, expr, ());
             }
 
-            ExprFnBlock(fn_decl, block) |
+            ExprFnBlock(_, fn_decl, block) |
             ExprProc(fn_decl, block) |
-            ExprUnboxedFn(fn_decl, block) => {
+            ExprUnboxedFn(_, _, fn_decl, block) => {
                 self.resolve_function(FunctionRibKind(expr.id, block.id),
                                       Some(fn_decl), NoTypeParameters,
                                       block);
@@ -5437,9 +5485,9 @@ fn add_trait_info(found_traits: &mut Vec<DefId>,
             // Look for the current trait.
             match self.current_trait_ref {
                 Some((trait_def_id, _)) => {
-                    let method_map = self.method_map.borrow();
+                    let trait_item_map = self.trait_item_map.borrow();
 
-                    if method_map.contains_key(&(name, trait_def_id)) {
+                    if trait_item_map.contains_key(&(name, trait_def_id)) {
                         add_trait_info(&mut found_traits, trait_def_id, name);
                     }
                 }
@@ -5450,7 +5498,7 @@ fn add_trait_info(found_traits: &mut Vec<DefId>,
             self.populate_module_if_necessary(&search_module);
 
             {
-                let method_map = self.method_map.borrow();
+                let trait_item_map = self.trait_item_map.borrow();
                 for (_, child_names) in search_module.children.borrow().iter() {
                     let def = match child_names.def_for_namespace(TypeNS) {
                         Some(def) => def,
@@ -5460,7 +5508,7 @@ fn add_trait_info(found_traits: &mut Vec<DefId>,
                         DefTrait(trait_def_id) => trait_def_id,
                         _ => continue,
                     };
-                    if method_map.contains_key(&(name, trait_def_id)) {
+                    if trait_item_map.contains_key(&(name, trait_def_id)) {
                         add_trait_info(&mut found_traits, trait_def_id, name);
                     }
                 }
@@ -5476,7 +5524,7 @@ fn add_trait_info(found_traits: &mut Vec<DefId>,
                     Some(DefTrait(trait_def_id)) => trait_def_id,
                     Some(..) | None => continue,
                 };
-                if self.method_map.borrow().contains_key(&(name, did)) {
+                if self.trait_item_map.borrow().contains_key(&(name, did)) {
                     add_trait_info(&mut found_traits, did, name);
                     self.used_imports.insert((import.type_id, TypeNS));
                 }
index c4373a023ccb24044872da32aacd84c97118e570..11b16f1853379372999919fd9f45379af76bc5a8 100644 (file)
@@ -283,8 +283,8 @@ fn process_method(&mut self, method: &ast::Method, e:DxrVisitorEnv) {
                             let mut result = String::from_str("<");
                             result.push_str(ty_to_string(&*ty).as_slice());
 
-                            match ty::trait_of_method(&self.analysis.ty_cx,
-                                                      ast_util::local_def(method.id)) {
+                            match ty::trait_of_item(&self.analysis.ty_cx,
+                                                    ast_util::local_def(method.id)) {
                                 Some(def_id) => {
                                     result.push_str(" as ");
                                     result.push_str(
@@ -310,8 +310,8 @@ fn process_method(&mut self, method: &ast::Method, e:DxrVisitorEnv) {
                                               ).as_slice());
                 },
             },
-            None => match ty::trait_of_method(&self.analysis.ty_cx,
-                                              ast_util::local_def(method.id)) {
+            None => match ty::trait_of_item(&self.analysis.ty_cx,
+                                            ast_util::local_def(method.id)) {
                 Some(def_id) => {
                     scope_id = def_id.node;
                     match self.analysis.ty_cx.map.get(def_id.node) {
@@ -338,9 +338,19 @@ fn process_method(&mut self, method: &ast::Method, e:DxrVisitorEnv) {
         let qualname = qualname.as_slice();
 
         // record the decl for this def (if it has one)
-        let decl_id = ty::trait_method_of_method(&self.analysis.ty_cx,
-                                                 ast_util::local_def(method.id))
-            .filtered(|def_id| method.id != 0 && def_id.node == 0);
+        let decl_id = ty::trait_item_of_item(&self.analysis.ty_cx,
+                                             ast_util::local_def(method.id))
+            .filtered(|def_id| {
+                match *def_id {
+                    ty::MethodTraitItemId(def_id) => {
+                        method.id != 0 && def_id.node == 0
+                    }
+                }
+            });
+        let decl_id = match decl_id {
+            None => None,
+            Some(ty::MethodTraitItemId(def_id)) => Some(def_id),
+        };
 
         let sub_span = self.span.sub_span_after_keyword(method.span, keywords::Fn);
         self.fmt.method_str(method.span,
@@ -601,7 +611,7 @@ fn process_impl(&mut self,
                     type_parameters: &ast::Generics,
                     trait_ref: &Option<ast::TraitRef>,
                     typ: ast::P<ast::Ty>,
-                    methods: &Vec<Gc<ast::Method>>) {
+                    impl_items: &Vec<ast::ImplItem>) {
         match typ.node {
             ast::TyPath(ref path, _, id) => {
                 match self.lookup_type_ref(id) {
@@ -630,8 +640,12 @@ fn process_impl(&mut self,
         }
 
         self.process_generic_params(type_parameters, item.span, "", item.id, e);
-        for method in methods.iter() {
-            visit::walk_method_helper(self, &**method, e)
+        for impl_item in impl_items.iter() {
+            match *impl_item {
+                ast::MethodImplItem(method) => {
+                    visit::walk_method_helper(self, &*method, e)
+                }
+            }
         }
     }
 
@@ -640,7 +654,7 @@ fn process_trait(&mut self,
                      e: DxrVisitorEnv,
                      generics: &ast::Generics,
                      trait_refs: &Vec<ast::TraitRef>,
-                     methods: &Vec<ast::TraitMethod>) {
+                     methods: &Vec<ast::TraitItem>) {
         let qualname = self.analysis.ty_cx.map.path_to_string(item.id);
 
         let sub_span = self.span.sub_span_after_keyword(item.span, keywords::Trait);
@@ -672,7 +686,7 @@ fn process_trait(&mut self,
         // walk generics and methods
         self.process_generic_params(generics, item.span, qualname.as_slice(), item.id, e);
         for method in methods.iter() {
-            self.visit_trait_method(method, e)
+            self.visit_trait_item(method, e)
         }
     }
 
@@ -735,18 +749,44 @@ fn process_path(&mut self,
             def::DefStaticMethod(declid, provenence, _) => {
                 let sub_span = self.span.sub_span_for_meth_name(ex.span);
                 let defid = if declid.krate == ast::LOCAL_CRATE {
-                    let m = ty::method(&self.analysis.ty_cx, declid);
+                    let ti = ty::impl_or_trait_item(&self.analysis.ty_cx,
+                                                    declid);
                     match provenence {
-                        def::FromTrait(def_id) =>
-                            Some(ty::trait_methods(&self.analysis.ty_cx, def_id)
-                                .iter().find(|mr| mr.ident.name == m.ident.name).unwrap().def_id),
+                        def::FromTrait(def_id) => {
+                            Some(ty::trait_items(&self.analysis.ty_cx,
+                                                 def_id)
+                                    .iter()
+                                    .find(|mr| {
+                                        match **mr {
+                                            ty::MethodTraitItem(ref mr) => {
+                                                mr.ident.name == ti.ident()
+                                                                   .name
+                                            }
+                                        }
+                                    })
+                                    .unwrap()
+                                    .def_id())
+                        }
                         def::FromImpl(def_id) => {
-                            let impl_methods = self.analysis.ty_cx.impl_methods.borrow();
-                            Some(*impl_methods.get(&def_id)
-                                .iter().find(|mr|
-                                    ty::method(
-                                        &self.analysis.ty_cx, **mr).ident.name == m.ident.name)
-                                .unwrap())
+                            let impl_items = self.analysis
+                                                 .ty_cx
+                                                 .impl_items
+                                                 .borrow();
+                            Some(impl_items.get(&def_id)
+                                           .iter()
+                                           .find(|mr| {
+                                            match **mr {
+                                                ty::MethodTraitItemId(mr) => {
+                                                    ty::impl_or_trait_item(
+                                                            &self.analysis
+                                                                 .ty_cx,
+                                                            mr).ident()
+                                                               .name ==
+                                                        ti.ident().name
+                                                    }
+                                                }
+                                            }).unwrap()
+                                              .def_id())
                         }
                     }
                 } else {
@@ -845,27 +885,45 @@ fn process_method_call(&mut self,
             typeck::MethodStatic(def_id) |
             typeck::MethodStaticUnboxedClosure(def_id) => {
                 // method invoked on an object with a concrete type (not a static method)
-                let decl_id = ty::trait_method_of_method(&self.analysis.ty_cx, def_id);
+                let decl_id =
+                    match ty::trait_item_of_item(&self.analysis.ty_cx,
+                                                 def_id) {
+                        None => None,
+                        Some(ty::MethodTraitItemId(decl_id)) => Some(decl_id),
+                    };
 
-                // This incantation is required if the method referenced is a trait's
-                // default implementation.
-                let def_id = ty::method(&self.analysis.ty_cx, def_id).provided_source
-                                    .unwrap_or(def_id);
+                // This incantation is required if the method referenced is a
+                // trait's default implementation.
+                let def_id = match ty::impl_or_trait_item(&self.analysis
+                                                               .ty_cx,
+                                                          def_id) {
+                    ty::MethodTraitItem(method) => {
+                        method.provided_source.unwrap_or(def_id)
+                    }
+                };
                 (Some(def_id), decl_id)
             }
             typeck::MethodParam(mp) => {
                 // method invoked on a type parameter
-                let method = ty::trait_method(&self.analysis.ty_cx,
-                                              mp.trait_id,
-                                              mp.method_num);
-                (None, Some(method.def_id))
+                let trait_item = ty::trait_item(&self.analysis.ty_cx,
+                                                mp.trait_id,
+                                                mp.method_num);
+                match trait_item {
+                    ty::MethodTraitItem(method) => {
+                        (None, Some(method.def_id))
+                    }
+                }
             },
             typeck::MethodObject(mo) => {
                 // method invoked on a trait instance
-                let method = ty::trait_method(&self.analysis.ty_cx,
-                                              mo.trait_id,
-                                              mo.method_num);
-                (None, Some(method.def_id))
+                let trait_item = ty::trait_item(&self.analysis.ty_cx,
+                                                mo.trait_id,
+                                                mo.method_num);
+                match trait_item {
+                    ty::MethodTraitItem(method) => {
+                        (None, Some(method.def_id))
+                    }
+                }
             },
         };
         let sub_span = self.span.sub_span_for_meth_name(ex.span);
@@ -968,8 +1026,17 @@ fn visit_item(&mut self, item:&ast::Item, e: DxrVisitorEnv) {
                 self.process_static(item, e, typ, mt, &*expr),
             ast::ItemStruct(def, ref ty_params) => self.process_struct(item, e, &*def, ty_params),
             ast::ItemEnum(ref def, ref ty_params) => self.process_enum(item, e, def, ty_params),
-            ast::ItemImpl(ref ty_params, ref trait_ref, typ, ref methods) =>
-                self.process_impl(item, e, ty_params, trait_ref, typ, methods),
+            ast::ItemImpl(ref ty_params,
+                          ref trait_ref,
+                          typ,
+                          ref impl_items) => {
+                self.process_impl(item,
+                                  e,
+                                  ty_params,
+                                  trait_ref,
+                                  typ,
+                                  impl_items)
+            }
             ast::ItemTrait(ref generics, _, ref trait_refs, ref methods) =>
                 self.process_trait(item, e, generics, trait_refs, methods),
             ast::ItemMod(ref m) => self.process_mod(item, e, m),
@@ -1027,16 +1094,16 @@ fn visit_fn(&mut self,
         }
     }
 
-    fn visit_trait_method(&mut self, tm: &ast::TraitMethod, e: DxrVisitorEnv) {
+    fn visit_trait_item(&mut self, tm: &ast::TraitItem, e: DxrVisitorEnv) {
         match *tm {
-            ast::Required(ref method_type) => {
+            ast::RequiredMethod(ref method_type) => {
                 if generated_code(method_type.span) {
                     return;
                 }
 
-                let mut scope_id ;
-                let mut qualname = match ty::trait_of_method(&self.analysis.ty_cx,
-                                                             ast_util::local_def(method_type.id)) {
+                let mut scope_id;
+                let mut qualname = match ty::trait_of_item(&self.analysis.ty_cx,
+                                                           ast_util::local_def(method_type.id)) {
                     Some(def_id) => {
                         scope_id = def_id.node;
                         ty::item_path_str(&self.analysis.ty_cx, def_id).append("::")
@@ -1070,7 +1137,7 @@ fn visit_trait_method(&mut self, tm: &ast::TraitMethod, e: DxrVisitorEnv) {
                                             method_type.id,
                                             e);
             }
-            ast::Provided(method) => self.process_method(&*method, e),
+            ast::ProvidedMethod(method) => self.process_method(&*method, e),
         }
     }
 
@@ -1237,7 +1304,7 @@ fn visit_expr(&mut self, ex: &ast::Expr, e: DxrVisitorEnv) {
                                             "Expected struct type, but not ty_struct"),
                 }
             },
-            ast::ExprFnBlock(decl, body) => {
+            ast::ExprFnBlock(_, decl, body) => {
                 if generated_code(body.span) {
                     return
                 }
index a3fa5a5f85ba4cd5237d3d43d37ebb49bffbd148..e73d81d9bf5974923a14383547eb37ea6bb37da5 100644 (file)
@@ -16,7 +16,7 @@
 use syntax::{attr, visit};
 use syntax::ast;
 use syntax::ast::{Attribute, Block, Crate, DefId, FnDecl, NodeId, Variant};
-use syntax::ast::{Item, Required, Provided, TraitMethod, TypeMethod, Method};
+use syntax::ast::{Item, RequiredMethod, ProvidedMethod, TraitItem, TypeMethod, Method};
 use syntax::ast::{Generics, StructDef, StructField, Ident};
 use syntax::ast_util::is_local;
 use syntax::attr::Stability;
@@ -68,18 +68,18 @@ fn visit_fn(&mut self, fk: &FnKind, fd: &FnDecl, b: &Block,
         visit::walk_fn(self, fk, fd, b, s, stab)
     }
 
-    fn visit_trait_method(&mut self, t: &TraitMethod, parent: Option<Stability>) {
+    fn visit_trait_item(&mut self, t: &TraitItem, parent: Option<Stability>) {
         let stab = match *t {
-            Required(TypeMethod {attrs: ref attrs, id: id, ..}) =>
+            RequiredMethod(TypeMethod {attrs: ref attrs, id: id, ..}) =>
                 self.annotate(id, attrs.as_slice(), parent),
 
             // work around lack of pattern matching for @ types
-            Provided(method) => match *method {
+            ProvidedMethod(method) => match *method {
                 Method {attrs: ref attrs, id: id, ..} =>
                     self.annotate(id, attrs.as_slice(), parent)
             }
         };
-        visit::walk_trait_method(self, t, stab)
+        visit::walk_trait_item(self, t, stab)
     }
 
     fn visit_variant(&mut self, v: &Variant, g: &Generics, parent: Option<Stability>) {
@@ -116,10 +116,11 @@ pub fn build(krate: &Crate) -> Index {
 
 /// Lookup the stability for a node, loading external crate
 /// metadata as necessary.
-pub fn lookup(tcx: &ty::ctxt,  id: DefId) -> Option<Stability> {
+pub fn lookup(tcx: &ty::ctxt, id: DefId) -> Option<Stability> {
     // is this definition the implementation of a trait method?
-    match ty::trait_method_of_method(tcx, id) {
-        Some(trait_method_id) if trait_method_id != id => {
+    match ty::trait_item_of_item(tcx, id) {
+        Some(ty::MethodTraitItemId(trait_method_id))
+                if trait_method_id != id => {
             lookup(tcx, trait_method_id)
         }
         _ if is_local(id) => {
index 9ec0407b5c3fc48e2c2aa9f39b258dd73f674028..9c68631baa44c6f94a8032e6ebe3d0a2eda8ca26 100644 (file)
@@ -170,7 +170,7 @@ fn represent_type_uncached(cx: &CrateContext, t: ty::t) -> Repr {
 
             return Univariant(mk_struct(cx, ftys.as_slice(), packed), dtor)
         }
-        ty::ty_unboxed_closure(def_id) => {
+        ty::ty_unboxed_closure(def_id, _) => {
             let upvars = ty::unboxed_closure_upvars(cx.tcx(), def_id);
             let upvar_types = upvars.iter().map(|u| u.ty).collect::<Vec<_>>();
             return Univariant(mk_struct(cx, upvar_types.as_slice(), false),
index 0860f84dbef47a4375ab844e162ab7f061141090..896d37669e6f101a84ba9351a43063d47f6d3570 100644 (file)
@@ -45,8 +45,8 @@
 use middle::trans::build::*;
 use middle::trans::builder::{Builder, noname};
 use middle::trans::callee;
+use middle::trans::cleanup::{CleanupMethods, ScopeId};
 use middle::trans::cleanup;
-use middle::trans::cleanup::CleanupMethods;
 use middle::trans::common::*;
 use middle::trans::consts;
 use middle::trans::controlflow;
@@ -252,6 +252,31 @@ fn get_extern_rust_fn(ccx: &CrateContext, fn_ty: ty::t, name: &str, did: ast::De
     f
 }
 
+pub fn self_type_for_unboxed_closure(ccx: &CrateContext,
+                                     closure_id: ast::DefId)
+                                     -> ty::t {
+    let unboxed_closure_type = ty::mk_unboxed_closure(ccx.tcx(),
+                                                      closure_id,
+                                                      ty::ReStatic);
+    let unboxed_closures = ccx.tcx.unboxed_closures.borrow();
+    let unboxed_closure = unboxed_closures.get(&closure_id);
+    match unboxed_closure.kind {
+        ty::FnUnboxedClosureKind => {
+            ty::mk_imm_rptr(&ccx.tcx, ty::ReStatic, unboxed_closure_type)
+        }
+        ty::FnMutUnboxedClosureKind => {
+            ty::mk_mut_rptr(&ccx.tcx, ty::ReStatic, unboxed_closure_type)
+        }
+        ty::FnOnceUnboxedClosureKind => unboxed_closure_type,
+    }
+}
+
+pub fn kind_for_unboxed_closure(ccx: &CrateContext, closure_id: ast::DefId)
+                                -> ty::UnboxedClosureKind {
+    let unboxed_closures = ccx.tcx.unboxed_closures.borrow();
+    unboxed_closures.get(&closure_id).kind
+}
+
 pub fn decl_rust_fn(ccx: &CrateContext, fn_ty: ty::t, name: &str) -> ValueRef {
     let (inputs, output, abi, env) = match ty::get(fn_ty).sty {
         ty::ty_bare_fn(ref f) => {
@@ -260,12 +285,12 @@ pub fn decl_rust_fn(ccx: &CrateContext, fn_ty: ty::t, name: &str) -> ValueRef {
         ty::ty_closure(ref f) => {
             (f.sig.inputs.clone(), f.sig.output, f.abi, Some(Type::i8p(ccx)))
         }
-        ty::ty_unboxed_closure(closure_did) => {
-            let unboxed_closure_types = ccx.tcx
-                                           .unboxed_closure_types
-                                           .borrow();
-            let function_type = unboxed_closure_types.get(&closure_did);
-            let llenvironment_type = type_of(ccx, fn_ty).ptr_to();
+        ty::ty_unboxed_closure(closure_did, _) => {
+            let unboxed_closures = ccx.tcx.unboxed_closures.borrow();
+            let unboxed_closure = unboxed_closures.get(&closure_did);
+            let function_type = unboxed_closure.closure_type.clone();
+            let self_type = self_type_for_unboxed_closure(ccx, closure_did);
+            let llenvironment_type = type_of_explicit_arg(ccx, self_type);
             (function_type.sig.inputs.clone(),
              function_type.sig.output,
              RustCall,
@@ -691,7 +716,7 @@ fn iter_variant<'r,
               }
           })
       }
-      ty::ty_unboxed_closure(def_id) => {
+      ty::ty_unboxed_closure(def_id, _) => {
           let repr = adt::represent_type(cx.ccx(), t);
           let upvars = ty::unboxed_closure_upvars(cx.tcx(), def_id);
           for (i, upvar) in upvars.iter().enumerate() {
@@ -1274,9 +1299,9 @@ fn has_nested_returns(tcx: &ty::ctxt, id: ast::NodeId) -> bool {
                 _ => tcx.sess.bug("unexpected item variant in has_nested_returns")
             }
         }
-        Some(ast_map::NodeTraitMethod(trait_method)) => {
+        Some(ast_map::NodeTraitItem(trait_method)) => {
             match *trait_method {
-                ast::Provided(m) => {
+                ast::ProvidedMethod(m) => {
                     match m.node {
                         ast::MethDecl(_, _, _, _, _, _, blk, _) => {
                             let mut explicit = CheckForNestedReturnsVisitor { found: false };
@@ -1288,25 +1313,41 @@ fn has_nested_returns(tcx: &ty::ctxt, id: ast::NodeId) -> bool {
                         ast::MethMac(_) => tcx.sess.bug("unexpanded macro")
                     }
                 }
-                ast::Required(_) => tcx.sess.bug("unexpected variant: required trait method in \
-                                                  has_nested_returns")
+                ast::RequiredMethod(_) => {
+                    tcx.sess.bug("unexpected variant: required trait method \
+                                  in has_nested_returns")
+                }
             }
         }
-        Some(ast_map::NodeMethod(m)) => {
-            match m.node {
-                ast::MethDecl(_, _, _, _, _, _, blk, _) => {
-                    let mut explicit = CheckForNestedReturnsVisitor { found: false };
-                    let mut implicit = CheckForNestedReturnsVisitor { found: false };
-                    visit::walk_method_helper(&mut explicit, &*m, false);
-                    visit::walk_expr_opt(&mut implicit, blk.expr, true);
-                    explicit.found || implicit.found
+        Some(ast_map::NodeImplItem(ref ii)) => {
+            match **ii {
+                ast::MethodImplItem(ref m) => {
+                    match m.node {
+                        ast::MethDecl(_, _, _, _, _, _, blk, _) => {
+                            let mut explicit = CheckForNestedReturnsVisitor {
+                                found: false,
+                            };
+                            let mut implicit = CheckForNestedReturnsVisitor {
+                                found: false,
+                            };
+                            visit::walk_method_helper(&mut explicit,
+                                                      &**m,
+                                                      false);
+                            visit::walk_expr_opt(&mut implicit,
+                                                 blk.expr,
+                                                 true);
+                            explicit.found || implicit.found
+                        }
+                        ast::MethMac(_) => tcx.sess.bug("unexpanded macro")
+                    }
                 }
-                ast::MethMac(_) => tcx.sess.bug("unexpanded macro")
             }
         }
         Some(ast_map::NodeExpr(e)) => {
             match e.node {
-                ast::ExprFnBlock(_, blk) | ast::ExprProc(_, blk) | ast::ExprUnboxedFn(_, blk) => {
+                ast::ExprFnBlock(_, _, blk) |
+                ast::ExprProc(_, blk) |
+                ast::ExprUnboxedFn(_, _, _, blk) => {
                     let mut explicit = CheckForNestedReturnsVisitor { found: false };
                     let mut implicit = CheckForNestedReturnsVisitor { found: false };
                     visit::walk_expr(&mut explicit, &*e, false);
@@ -1343,8 +1384,7 @@ pub fn new_fn_ctxt<'a>(ccx: &'a CrateContext,
                        output_type: ty::t,
                        param_substs: &'a param_substs,
                        sp: Option<Span>,
-                       block_arena: &'a TypedArena<Block<'a>>,
-                       handle_items: HandleItemsFlag)
+                       block_arena: &'a TypedArena<Block<'a>>)
                        -> FunctionContext<'a> {
     param_substs.validate();
 
@@ -1379,8 +1419,7 @@ pub fn new_fn_ctxt<'a>(ccx: &'a CrateContext,
           block_arena: block_arena,
           ccx: ccx,
           debug_context: debug_context,
-          scopes: RefCell::new(Vec::new()),
-          handle_items: handle_items,
+          scopes: RefCell::new(Vec::new())
     };
 
     if has_env {
@@ -1460,6 +1499,8 @@ pub fn create_datums_for_fn_args(fcx: &FunctionContext,
 /// Creates rvalue datums for each of the incoming function arguments and
 /// tuples the arguments. These will later be stored into appropriate lvalue
 /// datums.
+///
+/// FIXME(pcwalton): Reduce the amount of code bloat this is responsible for.
 fn create_datums_for_fn_args_under_call_abi<
         'a>(
         mut bcx: &'a Block<'a>,
@@ -1708,8 +1749,8 @@ pub fn trans_closure(ccx: &CrateContext,
                      abi: Abi,
                      has_env: bool,
                      is_unboxed_closure: IsUnboxedClosureFlag,
-                     maybe_load_env: <'a> |&'a Block<'a>| -> &'a Block<'a>,
-                     handle_items: HandleItemsFlag) {
+                     maybe_load_env: <'a>|&'a Block<'a>, ScopeId|
+                                         -> &'a Block<'a>) {
     ccx.stats.n_closures.set(ccx.stats.n_closures.get() + 1);
 
     let _icx = push_ctxt("trans_closure");
@@ -1726,8 +1767,7 @@ pub fn trans_closure(ccx: &CrateContext,
                           output_type,
                           param_substs,
                           Some(body.span),
-                          &arena,
-                          handle_items);
+                          &arena);
     let mut bcx = init_function(&fcx, false, output_type);
 
     // cleanup scope for the incoming arguments
@@ -1775,7 +1815,7 @@ pub fn trans_closure(ccx: &CrateContext,
         }
     };
 
-    bcx = maybe_load_env(bcx);
+    bcx = maybe_load_env(bcx, cleanup::CustomScope(arg_scope));
 
     // Up until here, IR instructions for this function have explicitly not been annotated with
     // source code location, so we don't step into call setup code. From here on, source location
@@ -1836,8 +1876,7 @@ pub fn trans_fn(ccx: &CrateContext,
                 llfndecl: ValueRef,
                 param_substs: &param_substs,
                 id: ast::NodeId,
-                attrs: &[ast::Attribute],
-                handle_items: HandleItemsFlag) {
+                attrs: &[ast::Attribute]) {
     let _s = StatRecorder::new(ccx, ccx.tcx.map.path_to_string(id).to_string());
     debug!("trans_fn(param_substs={})", param_substs.repr(ccx.tcx()));
     let _icx = push_ctxt("trans_fn");
@@ -1857,8 +1896,7 @@ pub fn trans_fn(ccx: &CrateContext,
                   abi,
                   false,
                   NotUnboxedClosure,
-                  |bcx| bcx,
-                  handle_items);
+                  |bcx, _| bcx);
 }
 
 pub fn trans_enum_variant(ccx: &CrateContext,
@@ -1909,12 +1947,10 @@ pub fn trans_named_tuple_constructor<'a>(mut bcx: &'a Block<'a>,
     };
 
     if !type_is_zero_size(ccx, result_ty) {
-        let repr = adt::represent_type(ccx, result_ty);
-
         match args {
             callee::ArgExprs(exprs) => {
                 let fields = exprs.iter().map(|x| *x).enumerate().collect::<Vec<_>>();
-                bcx = expr::trans_adt(bcx, &*repr, disr, fields.as_slice(),
+                bcx = expr::trans_adt(bcx, result_ty, disr, fields.as_slice(),
                                       None, expr::SaveIn(llresult));
             }
             _ => ccx.sess().bug("expected expr as arguments for variant/struct tuple constructor")
@@ -1964,7 +2000,7 @@ fn trans_enum_variant_or_tuple_like_struct(ccx: &CrateContext,
 
     let arena = TypedArena::new();
     let fcx = new_fn_ctxt(ccx, llfndecl, ctor_id, false, result_ty,
-                          param_substs, None, &arena, TranslateItems);
+                          param_substs, None, &arena);
     let bcx = init_function(&fcx, false, result_ty);
 
     assert!(!fcx.needs_ret_allocas);
@@ -2066,8 +2102,7 @@ pub fn trans_item(ccx: &CrateContext, item: &ast::Item) {
                                                         llfn,
                                                         &param_substs::empty(),
                                                         item.id,
-                                                        None,
-                                                        TranslateItems);
+                                                        None);
             } else {
                 trans_fn(ccx,
                          &**decl,
@@ -2075,18 +2110,21 @@ pub fn trans_item(ccx: &CrateContext, item: &ast::Item) {
                          llfn,
                          &param_substs::empty(),
                          item.id,
-                         item.attrs.as_slice(),
-                         TranslateItems);
+                         item.attrs.as_slice());
             }
-        } else {
-            // Be sure to travel more than just one layer deep to catch nested
-            // items in blocks and such.
-            let mut v = TransItemVisitor{ ccx: ccx };
-            v.visit_block(&**body, ());
         }
+
+        // Be sure to travel more than just one layer deep to catch nested
+        // items in blocks and such.
+        let mut v = TransItemVisitor{ ccx: ccx };
+        v.visit_block(&**body, ());
       }
-      ast::ItemImpl(ref generics, _, _, ref ms) => {
-        meth::trans_impl(ccx, item.ident, ms.as_slice(), generics, item.id);
+      ast::ItemImpl(ref generics, _, _, ref impl_items) => {
+        meth::trans_impl(ccx,
+                         item.ident,
+                         impl_items.as_slice(),
+                         generics,
+                         item.id);
       }
       ast::ItemMod(ref m) => {
         trans_mod(ccx, m);
@@ -2194,11 +2232,11 @@ pub fn get_fn_llvm_attributes(ccx: &CrateContext, fn_ty: ty::t)
     let (fn_sig, abi, has_env) = match ty::get(fn_ty).sty {
         ty::ty_closure(ref f) => (f.sig.clone(), f.abi, true),
         ty::ty_bare_fn(ref f) => (f.sig.clone(), f.abi, false),
-        ty::ty_unboxed_closure(closure_did) => {
-            let unboxed_closure_types = ccx.tcx
-                                           .unboxed_closure_types
-                                           .borrow();
-            let function_type = unboxed_closure_types.get(&closure_did);
+        ty::ty_unboxed_closure(closure_did, _) => {
+            let unboxed_closures = ccx.tcx.unboxed_closures.borrow();
+            let function_type = unboxed_closures.get(&closure_did)
+                                                .closure_type
+                                                .clone();
             (function_type.sig.clone(), RustCall, true)
         }
         _ => fail!("expected closure or function.")
@@ -2593,21 +2631,23 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
             v
         }
 
-        ast_map::NodeTraitMethod(trait_method) => {
-            debug!("get_item_val(): processing a NodeTraitMethod");
+        ast_map::NodeTraitItem(trait_method) => {
+            debug!("get_item_val(): processing a NodeTraitItem");
             match *trait_method {
-                ast::Required(_) => {
+                ast::RequiredMethod(_) => {
                     ccx.sess().bug("unexpected variant: required trait method in \
                                    get_item_val()");
                 }
-                ast::Provided(m) => {
+                ast::ProvidedMethod(m) => {
                     register_method(ccx, id, &*m)
                 }
             }
         }
 
-        ast_map::NodeMethod(m) => {
-            register_method(ccx, id, &*m)
+        ast_map::NodeImplItem(ii) => {
+            match *ii {
+                ast::MethodImplItem(m) => register_method(ccx, id, &*m),
+            }
         }
 
         ast_map::NodeForeignItem(ni) => {
index 52461e3fdcb23d10fc23daf311e5dea74aa69b4f..d419a56ec148e3f7f27d0890bf30068692667c4a 100644 (file)
@@ -18,7 +18,7 @@
 use middle::trans::cabi_mips;
 use middle::trans::type_::Type;
 use syntax::abi::{X86, X86_64, Arm, Mips, Mipsel};
-use syntax::abi::{OsWin32};
+use syntax::abi::{OsWindows};
 
 #[deriving(Clone, PartialEq)]
 pub enum ArgKind {
@@ -110,7 +110,7 @@ pub fn compute_abi_info(ccx: &CrateContext,
     match ccx.sess().targ_cfg.arch {
         X86 => cabi_x86::compute_abi_info(ccx, atys, rty, ret_def),
         X86_64 =>
-            if ccx.sess().targ_cfg.os == OsWin32 {
+            if ccx.sess().targ_cfg.os == OsWindows {
                 cabi_x86_win64::compute_abi_info(ccx, atys, rty, ret_def)
             } else {
                 cabi_x86_64::compute_abi_info(ccx, atys, rty, ret_def)
index 6bb3d992f50c627a4745666c2072b4b729ff4694..d9812677d64cbec0975b429be362c21f171b723e 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 
-use syntax::abi::{OsWin32, OsMacos, OsiOS};
+use syntax::abi::{OsWindows, OsMacos, OsiOS};
 use llvm::*;
 use super::cabi::*;
 use super::common::*;
@@ -36,7 +36,7 @@ pub fn compute_abi_info(ccx: &CrateContext,
 
         enum Strategy { RetValue(Type), RetPointer }
         let strategy = match ccx.sess().targ_cfg.os {
-            OsWin32 | OsMacos | OsiOS => {
+            OsWindows | OsMacos | OsiOS => {
                 match llsize_of_alloc(ccx, rty) {
                     1 => RetValue(Type::i8(ccx)),
                     2 => RetValue(Type::i16(ccx)),
index 8e6ff0cdb3e115e61e0fa1742975a1d0f23a420e..56c1c66533133c222570fb8f173ca3fe70b88de1 100644 (file)
@@ -77,7 +77,7 @@ pub enum CalleeData {
 
     Intrinsic(ast::NodeId, subst::Substs),
 
-    TraitMethod(MethodData)
+    TraitItem(MethodData)
 }
 
 pub struct Callee<'a> {
@@ -339,8 +339,7 @@ pub fn trans_unboxing_shim(bcx: &Block,
                           return_type,
                           &empty_param_substs,
                           None,
-                          &block_arena,
-                          TranslateItems);
+                          &block_arena);
     let mut bcx = init_function(&fcx, false, return_type);
 
     // Create the substituted versions of the self type.
@@ -450,7 +449,7 @@ pub fn trans_fn_ref_with_vtables(
     assert!(substs.types.all(|t| !ty::type_needs_infer(*t)));
 
     // Load the info for the appropriate trait if necessary.
-    match ty::trait_of_method(tcx, def_id) {
+    match ty::trait_of_item(tcx, def_id) {
         None => {}
         Some(trait_id) => {
             ty::populate_implementations_for_trait_if_necessary(tcx, trait_id)
@@ -477,35 +476,43 @@ pub fn trans_fn_ref_with_vtables(
             // So, what we need to do is find this substitution and
             // compose it with the one we already have.
 
-            let impl_id = ty::method(tcx, def_id).container_id();
-            let method = ty::method(tcx, source_id);
-            let trait_ref = ty::impl_trait_ref(tcx, impl_id)
-                .expect("could not find trait_ref for impl with \
-                         default methods");
-
-            // Compute the first substitution
-            let first_subst = make_substs_for_receiver_types(
-                tcx, &*trait_ref, &*method);
-
-            // And compose them
-            let new_substs = first_subst.subst(tcx, &substs);
-
-            debug!("trans_fn_with_vtables - default method: \
-                    substs = {}, trait_subst = {}, \
-                    first_subst = {}, new_subst = {}, \
-                    vtables = {}",
-                   substs.repr(tcx), trait_ref.substs.repr(tcx),
-                   first_subst.repr(tcx), new_substs.repr(tcx),
-                   vtables.repr(tcx));
-
-            let param_vtables =
-                resolve_default_method_vtables(bcx, impl_id, &substs, vtables);
-
-            debug!("trans_fn_with_vtables - default method: \
-                    param_vtables = {}",
-                   param_vtables.repr(tcx));
-
-            (true, source_id, new_substs, param_vtables)
+            let impl_id = ty::impl_or_trait_item(tcx, def_id).container()
+                                                             .id();
+            let impl_or_trait_item = ty::impl_or_trait_item(tcx, source_id);
+            match impl_or_trait_item {
+                ty::MethodTraitItem(method) => {
+                    let trait_ref = ty::impl_trait_ref(tcx, impl_id)
+                        .expect("could not find trait_ref for impl with \
+                                 default methods");
+
+                    // Compute the first substitution
+                    let first_subst = make_substs_for_receiver_types(
+                        tcx, &*trait_ref, &*method);
+
+                    // And compose them
+                    let new_substs = first_subst.subst(tcx, &substs);
+
+                    debug!("trans_fn_with_vtables - default method: \
+                            substs = {}, trait_subst = {}, \
+                            first_subst = {}, new_subst = {}, \
+                            vtables = {}",
+                           substs.repr(tcx), trait_ref.substs.repr(tcx),
+                           first_subst.repr(tcx), new_substs.repr(tcx),
+                           vtables.repr(tcx));
+
+                    let param_vtables =
+                        resolve_default_method_vtables(bcx,
+                                                       impl_id,
+                                                       &substs,
+                                                       vtables);
+
+                    debug!("trans_fn_with_vtables - default method: \
+                            param_vtables = {}",
+                           param_vtables.repr(tcx));
+
+                    (true, source_id, new_substs, param_vtables)
+                }
+            }
         }
     };
 
@@ -743,7 +750,7 @@ pub fn trans_call_inner<'a>(
         Fn(llfn) => {
             (llfn, None, None)
         }
-        TraitMethod(d) => {
+        TraitItem(d) => {
             (d.llfn, None, Some(d.llself))
         }
         Closure(d) => {
index eeff0609a56dd2658f2071958762a982d40b5a36..17f1b6ca52669c07dfb0ec39b19358160f6cc48b 100644 (file)
@@ -19,6 +19,7 @@
 use middle::trans::adt;
 use middle::trans::base::*;
 use middle::trans::build::*;
+use middle::trans::cleanup::{CleanupMethods, ScopeId};
 use middle::trans::common::*;
 use middle::trans::datum::{Datum, DatumBlock, Expr, Lvalue, rvalue_scratch_datum};
 use middle::trans::debuginfo;
@@ -306,7 +307,9 @@ fn load_environment<'a>(bcx: &'a Block<'a>,
 
 fn load_unboxed_closure_environment<'a>(
                                     bcx: &'a Block<'a>,
-                                    freevars: &Vec<freevars::freevar_entry>)
+                                    arg_scope_id: ScopeId,
+                                    freevars: &Vec<freevars::freevar_entry>,
+                                    closure_id: ast::DefId)
                                     -> &'a Block<'a> {
     let _icx = push_ctxt("closure::load_environment");
 
@@ -314,11 +317,31 @@ fn load_unboxed_closure_environment<'a>(
         return bcx
     }
 
-    let llenv = bcx.fcx.llenv.unwrap();
+    // Special case for small by-value selfs.
+    let self_type = self_type_for_unboxed_closure(bcx.ccx(), closure_id);
+    let kind = kind_for_unboxed_closure(bcx.ccx(), closure_id);
+    let llenv = if kind == ty::FnOnceUnboxedClosureKind &&
+            !arg_is_indirect(bcx.ccx(), self_type) {
+        let datum = rvalue_scratch_datum(bcx,
+                                         self_type,
+                                         "unboxed_closure_env");
+        store_ty(bcx, bcx.fcx.llenv.unwrap(), datum.val, self_type);
+        assert!(freevars.len() <= 1);
+        datum.val
+    } else {
+        bcx.fcx.llenv.unwrap()
+    };
+
     for (i, freevar) in freevars.iter().enumerate() {
         let upvar_ptr = GEPi(bcx, llenv, [0, i]);
         let def_id = freevar.def.def_id();
         bcx.fcx.llupvars.borrow_mut().insert(def_id.node, upvar_ptr);
+
+        if kind == ty::FnOnceUnboxedClosureKind {
+            bcx.fcx.schedule_drop_mem(arg_scope_id,
+                                      upvar_ptr,
+                                      node_id_type(bcx, def_id.node))
+        }
     }
 
     bcx
@@ -394,8 +417,7 @@ pub fn trans_expr_fn<'a>(
                   ty::ty_fn_abi(fty),
                   true,
                   NotUnboxedClosure,
-                  |bcx| load_environment(bcx, cdata_ty, &freevars, store),
-                  bcx.fcx.handle_items);
+                  |bcx, _| load_environment(bcx, cdata_ty, &freevars, store));
     fill_fn_pair(bcx, dest_addr, llfn, llbox);
     bcx
 }
@@ -405,7 +427,7 @@ pub fn trans_expr_fn<'a>(
 pub fn get_or_create_declaration_if_unboxed_closure(ccx: &CrateContext,
                                                     closure_id: ast::DefId)
                                                     -> Option<ValueRef> {
-    if !ccx.tcx.unboxed_closure_types.borrow().contains_key(&closure_id) {
+    if !ccx.tcx.unboxed_closures.borrow().contains_key(&closure_id) {
         // Not an unboxed closure.
         return None
     }
@@ -419,7 +441,9 @@ pub fn get_or_create_declaration_if_unboxed_closure(ccx: &CrateContext,
         None => {}
     }
 
-    let function_type = ty::mk_unboxed_closure(&ccx.tcx, closure_id);
+    let function_type = ty::mk_unboxed_closure(&ccx.tcx,
+                                               closure_id,
+                                               ty::ReStatic);
     let symbol = ccx.tcx.map.with_path(closure_id.node, |path| {
         mangle_internal_name_by_path_and_seq(path, "unboxed_closure")
     });
@@ -454,19 +478,10 @@ pub fn trans_unboxed_closure<'a>(
         bcx.ccx(),
         closure_id).unwrap();
 
-    // Untuple the arguments.
-    let unboxed_closure_types = bcx.tcx().unboxed_closure_types.borrow();
-    let /*mut*/ function_type = (*unboxed_closure_types.get(&closure_id)).clone();
-    /*function_type.sig.inputs =
-        match ty::get(*function_type.sig.inputs.get(0)).sty {
-            ty::ty_tup(ref tuple_types) => {
-                tuple_types.iter().map(|x| (*x).clone()).collect()
-            }
-            _ => {
-                bcx.tcx().sess.span_bug(body.span,
-                                        "unboxed closure wasn't a tuple?!")
-            }
-        };*/
+    let unboxed_closures = bcx.tcx().unboxed_closures.borrow();
+    let function_type = unboxed_closures.get(&closure_id)
+                                        .closure_type
+                                        .clone();
     let function_type = ty::mk_closure(bcx.tcx(), function_type);
 
     let freevars: Vec<freevars::freevar_entry> =
@@ -487,8 +502,12 @@ pub fn trans_unboxed_closure<'a>(
                   ty::ty_fn_abi(function_type),
                   true,
                   IsUnboxedClosure,
-                  |bcx| load_unboxed_closure_environment(bcx, freevars_ptr),
-                  bcx.fcx.handle_items);
+                  |bcx, arg_scope| {
+                      load_unboxed_closure_environment(bcx,
+                                                       arg_scope,
+                                                       freevars_ptr,
+                                                       closure_id)
+                  });
 
     // Don't hoist this to the top of the function. It's perfectly legitimate
     // to have a zero-size unboxed closure (in which case dest will be
@@ -504,13 +523,13 @@ pub fn trans_unboxed_closure<'a>(
     let repr = adt::represent_type(bcx.ccx(), node_id_type(bcx, id));
 
     // Create the closure.
-    for freevar in freevars_ptr.iter() {
+    for (i, freevar) in freevars_ptr.iter().enumerate() {
         let datum = expr::trans_local_var(bcx, freevar.def);
         let upvar_slot_dest = adt::trans_field_ptr(bcx,
                                                    &*repr,
                                                    dest_addr,
                                                    0,
-                                                   0);
+                                                   i);
         bcx = datum.store_to(bcx, upvar_slot_dest);
     }
     adt::trans_set_discr(bcx, &*repr, dest_addr, 0);
@@ -575,7 +594,7 @@ pub fn get_wrapper_for_bare_fn(ccx: &CrateContext,
     let arena = TypedArena::new();
     let empty_param_substs = param_substs::empty();
     let fcx = new_fn_ctxt(ccx, llfn, ast::DUMMY_NODE_ID, true, f.sig.output,
-                          &empty_param_substs, None, &arena, TranslateItems);
+                          &empty_param_substs, None, &arena);
     let bcx = init_function(&fcx, true, f.sig.output);
 
     let args = create_datums_for_fn_args(&fcx,
index 5e46550eccba561191200c6d9c35f2fe8876c6af..300e7ecf81f43dfaaccd530d006cc65ec0991cce 100644 (file)
@@ -18,6 +18,7 @@
 use llvm::{True, False, Bool};
 use mc = middle::mem_categorization;
 use middle::def;
+use middle::freevars;
 use middle::lang_items::LangItem;
 use middle::subst;
 use middle::subst::Subst;
@@ -31,7 +32,7 @@
 use middle::ty;
 use middle::typeck;
 use util::ppaux::Repr;
-use util::nodemap::NodeMap;
+use util::nodemap::{DefIdMap, NodeMap};
 
 use arena::TypedArena;
 use std::collections::HashMap;
@@ -224,12 +225,6 @@ fn substp(&self, tcx: &ty::ctxt, substs: &param_substs) -> T {
 pub type RvalueDatum = datum::Datum<datum::Rvalue>;
 pub type LvalueDatum = datum::Datum<datum::Lvalue>;
 
-#[deriving(Clone, Eq, PartialEq)]
-pub enum HandleItemsFlag {
-    IgnoreItems,
-    TranslateItems,
-}
-
 // Function context.  Every LLVM function we create will have one of
 // these.
 pub struct FunctionContext<'a> {
@@ -303,9 +298,6 @@ pub struct FunctionContext<'a> {
 
     // Cleanup scopes.
     pub scopes: RefCell<Vec<cleanup::CleanupScope<'a>> >,
-
-    // How to handle items encountered during translation of this function.
-    pub handle_items: HandleItemsFlag,
 }
 
 impl<'a> FunctionContext<'a> {
@@ -522,9 +514,19 @@ fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option<ast::NodeId> {
         self.tcx().region_maps.temporary_scope(rvalue_id)
     }
 
+    fn unboxed_closures<'a>(&'a self)
+                        -> &'a RefCell<DefIdMap<ty::UnboxedClosure>> {
+        &self.tcx().unboxed_closures
+    }
+
     fn upvar_borrow(&self, upvar_id: ty::UpvarId) -> ty::UpvarBorrow {
         self.tcx().upvar_borrow_map.borrow().get_copy(&upvar_id)
     }
+
+    fn capture_mode(&self, closure_expr_id: ast::NodeId)
+                    -> freevars::CaptureMode {
+        self.tcx().capture_modes.borrow().get_copy(&closure_expr_id)
+    }
 }
 
 pub struct Result<'a> {
index 02a5f715ecb230e2132c08e5f2605ba2c54901c3..193303f4d1cd361e1f3b58ed04e7513fb19eb2ee 100644 (file)
@@ -69,12 +69,8 @@ pub fn trans_stmt<'a>(cx: &'a Block<'a>,
                         debuginfo::create_local_var_metadata(bcx, &**local);
                     }
                 }
-                ast::DeclItem(ref i) => {
-                    match fcx.handle_items {
-                        TranslateItems => trans_item(cx.fcx.ccx, &**i),
-                        IgnoreItems => {}
-                    }
-                }
+                // Inner items are visited by `trans_item`/`trans_meth`.
+                ast::DeclItem(_) => {},
             }
         }
         ast::StmtMac(..) => cx.tcx().sess.bug("unexpanded macro")
@@ -334,13 +330,12 @@ pub fn trans_for<'a>(
     // Check the discriminant; if the `None` case, exit the loop.
     let option_representation = adt::represent_type(loopback_bcx_out.ccx(),
                                                     method_result_type);
-    let i8_type = Type::i8(loopback_bcx_out.ccx());
     let lldiscriminant = adt::trans_get_discr(loopback_bcx_out,
                                               &*option_representation,
                                               option_datum.val,
-                                              Some(i8_type));
-    let llzero = C_u8(loopback_bcx_out.ccx(), 0);
-    let llcondition = ICmp(loopback_bcx_out, IntNE, lldiscriminant, llzero);
+                                              None);
+    let i1_type = Type::i1(loopback_bcx_out.ccx());
+    let llcondition = Trunc(loopback_bcx_out, lldiscriminant, i1_type);
     CondBr(loopback_bcx_out, llcondition, body_bcx_in.llbb, cleanup_llbb);
 
     // Now we're in the body. Unpack the `Option` value into the programmer-
index c27b0bb8cb1ebeac5eb625248a57800331d4bcfb..0c481b68f67fd5b24e42fd1a2ca917121b70c103 100644 (file)
@@ -208,7 +208,6 @@ struct List {
 use syntax::codemap::{Span, Pos};
 use syntax::{abi, ast, codemap, ast_util, ast_map};
 use syntax::ast_util::PostExpansionMethod;
-use syntax::owned_slice::OwnedSlice;
 use syntax::parse::token;
 use syntax::parse::token::special_idents;
 
@@ -1123,13 +1122,16 @@ pub fn create_function_debug_context(cx: &CrateContext,
         return FunctionDebugContext { repr: FunctionWithoutDebugInfo };
     }
 
-    let empty_generics = ast::Generics { lifetimes: Vec::new(),
-                                         ty_params: OwnedSlice::empty() };
+    let empty_generics = ast_util::empty_generics();
 
     let fnitem = cx.tcx.map.get(fn_ast_id);
 
     let (ident, fn_decl, generics, top_level_block, span, has_path) = match fnitem {
         ast_map::NodeItem(ref item) => {
+            if contains_nodebug_attribute(item.attrs.as_slice()) {
+                return FunctionDebugContext { repr: FunctionWithoutDebugInfo };
+            }
+
             match item.node {
                 ast::ItemFn(fn_decl, _, _, ref generics, top_level_block) => {
                     (item.ident, fn_decl, generics, top_level_block, item.span, true)
@@ -1140,19 +1142,29 @@ pub fn create_function_debug_context(cx: &CrateContext,
                 }
             }
         }
-        ast_map::NodeMethod(ref method) => {
-            (method.pe_ident(),
-             method.pe_fn_decl(),
-             method.pe_generics(),
-             method.pe_body(),
-             method.span,
-             true)
+        ast_map::NodeImplItem(ref item) => {
+            match **item {
+                ast::MethodImplItem(ref method) => {
+                    if contains_nodebug_attribute(method.attrs.as_slice()) {
+                        return FunctionDebugContext {
+                            repr: FunctionWithoutDebugInfo
+                        };
+                    }
+
+                    (method.pe_ident(),
+                     method.pe_fn_decl(),
+                     method.pe_generics(),
+                     method.pe_body(),
+                     method.span,
+                     true)
+                }
+            }
         }
         ast_map::NodeExpr(ref expr) => {
             match expr.node {
-                ast::ExprFnBlock(fn_decl, top_level_block) |
+                ast::ExprFnBlock(_, fn_decl, top_level_block) |
                 ast::ExprProc(fn_decl, top_level_block) |
-                ast::ExprUnboxedFn(fn_decl, top_level_block) => {
+                ast::ExprUnboxedFn(_, _, fn_decl, top_level_block) => {
                     let name = format!("fn{}", token::gensym("fn"));
                     let name = token::str_to_ident(name.as_slice());
                     (name, fn_decl,
@@ -1168,9 +1180,15 @@ pub fn create_function_debug_context(cx: &CrateContext,
                         "create_function_debug_context: expected an expr_fn_block here")
             }
         }
-        ast_map::NodeTraitMethod(ref trait_method) => {
+        ast_map::NodeTraitItem(ref trait_method) => {
             match **trait_method {
-                ast::Provided(ref method) => {
+                ast::ProvidedMethod(ref method) => {
+                    if contains_nodebug_attribute(method.attrs.as_slice()) {
+                        return FunctionDebugContext {
+                            repr: FunctionWithoutDebugInfo
+                        };
+                    }
+
                     (method.pe_ident(),
                      method.pe_fn_decl(),
                      method.pe_generics(),
@@ -3167,6 +3185,16 @@ fn set_debug_location(cx: &CrateContext, debug_location: DebugLocation) {
 //  Utility Functions
 //=-----------------------------------------------------------------------------
 
+fn contains_nodebug_attribute(attributes: &[ast::Attribute]) -> bool {
+    attributes.iter().any(|attr| {
+        let meta_item: &ast::MetaItem = &*attr.node.value;
+        match meta_item.node {
+            ast::MetaWord(ref value) => value.get() == "no_debug",
+            _ => false
+        }
+    })
+}
+
 /// Return codemap::Loc corresponding to the beginning of the span
 fn span_start(cx: &CrateContext, span: Span) -> codemap::Loc {
     cx.sess().codemap().lookup_char_pos(span.lo)
@@ -3618,9 +3646,9 @@ fn walk_expr(cx: &CrateContext,
                 })
             }
 
-            ast::ExprFnBlock(ref decl, ref block) |
+            ast::ExprFnBlock(_, ref decl, ref block) |
             ast::ExprProc(ref decl, ref block) |
-            ast::ExprUnboxedFn(ref decl, ref block) => {
+            ast::ExprUnboxedFn(_, _, ref decl, ref block) => {
                 with_new_scope(cx,
                                block.span,
                                scope_stack,
@@ -3895,7 +3923,7 @@ fn push_debuginfo_type_name(cx: &CrateContext,
                 push_debuginfo_type_name(cx, sig.output, true, output);
             }
         },
-        ty::ty_unboxed_closure(_) => {
+        ty::ty_unboxed_closure(..) => {
             output.push_str("closure");
         }
         ty::ty_err      |
index 1dad6e3cb18439684d0ae3301b2e96a0194657a9..748274b1201e58cc82a430bd33b43f58f5ce1ae1 100644 (file)
@@ -746,18 +746,17 @@ fn trans_rvalue_dps_unadjusted<'a>(bcx: &'a Block<'a>,
             controlflow::trans_block(bcx, &**blk, dest)
         }
         ast::ExprStruct(_, ref fields, base) => {
-            trans_rec_or_struct(bcx,
-                                fields.as_slice(),
-                                base,
-                                expr.span,
-                                expr.id,
-                                dest)
+            trans_struct(bcx,
+                         fields.as_slice(),
+                         base,
+                         expr.span,
+                         expr.id,
+                         dest)
         }
         ast::ExprTup(ref args) => {
-            let repr = adt::represent_type(bcx.ccx(), expr_ty(bcx, expr));
             let numbered_fields: Vec<(uint, Gc<ast::Expr>)> =
                 args.iter().enumerate().map(|(i, arg)| (i, *arg)).collect();
-            trans_adt(bcx, &*repr, 0, numbered_fields.as_slice(), None, dest)
+            trans_adt(bcx, expr_ty(bcx, expr), 0, numbered_fields.as_slice(), None, dest)
         }
         ast::ExprLit(lit) => {
             match lit.node {
@@ -782,7 +781,7 @@ fn trans_rvalue_dps_unadjusted<'a>(bcx: &'a Block<'a>,
         ast::ExprVec(..) | ast::ExprRepeat(..) => {
             tvec::trans_fixed_vstore(bcx, expr, expr, dest)
         }
-        ast::ExprFnBlock(ref decl, ref body) |
+        ast::ExprFnBlock(_, ref decl, ref body) |
         ast::ExprProc(ref decl, ref body) => {
             let expr_ty = expr_ty(bcx, expr);
             let store = ty::ty_closure_store(expr_ty);
@@ -790,7 +789,7 @@ fn trans_rvalue_dps_unadjusted<'a>(bcx: &'a Block<'a>,
                    expr_to_string(expr), expr_ty.repr(tcx));
             closure::trans_expr_fn(bcx, store, &**decl, &**body, expr.id, dest)
         }
-        ast::ExprUnboxedFn(decl, body) => {
+        ast::ExprUnboxedFn(_, _, decl, body) => {
             closure::trans_unboxed_closure(bcx, &*decl, &*body, expr.id, dest)
         }
         ast::ExprCall(ref f, ref args) => {
@@ -1042,16 +1041,13 @@ pub fn with_field_tys<R>(tcx: &ty::ctxt,
     }
 }
 
-fn trans_rec_or_struct<'a>(
-                       bcx: &'a Block<'a>,
-                       fields: &[ast::Field],
-                       base: Option<Gc<ast::Expr>>,
-                       expr_span: codemap::Span,
-                       id: ast::NodeId,
-                       dest: Dest)
-                       -> &'a Block<'a> {
+fn trans_struct<'a>(bcx: &'a Block<'a>,
+                    fields: &[ast::Field],
+                    base: Option<Gc<ast::Expr>>,
+                    expr_span: codemap::Span,
+                    id: ast::NodeId,
+                    dest: Dest) -> &'a Block<'a> {
     let _icx = push_ctxt("trans_rec");
-    let bcx = bcx;
 
     let ty = node_id_type(bcx, id);
     let tcx = bcx.tcx();
@@ -1092,8 +1088,7 @@ fn trans_rec_or_struct<'a>(
             }
         };
 
-        let repr = adt::represent_type(bcx.ccx(), ty);
-        trans_adt(bcx, &*repr, discr, numbered_fields.as_slice(), optbase, dest)
+        trans_adt(bcx, ty, discr, numbered_fields.as_slice(), optbase, dest)
     })
 }
 
@@ -1121,35 +1116,51 @@ pub struct StructBaseInfo {
  * - `optbase` contains information on the base struct (if any) from
  * which remaining fields are copied; see comments on `StructBaseInfo`.
  */
-pub fn trans_adt<'a>(bcx: &'a Block<'a>,
-                     repr: &adt::Repr,
+pub fn trans_adt<'a>(mut bcx: &'a Block<'a>,
+                     ty: ty::t,
                      discr: ty::Disr,
                      fields: &[(uint, Gc<ast::Expr>)],
                      optbase: Option<StructBaseInfo>,
                      dest: Dest) -> &'a Block<'a> {
     let _icx = push_ctxt("trans_adt");
     let fcx = bcx.fcx;
-    let mut bcx = bcx;
+    let repr = adt::represent_type(bcx.ccx(), ty);
+
+    // If we don't care about the result, just make a
+    // temporary stack slot
     let addr = match dest {
-        Ignore => {
-            for &(_i, ref e) in fields.iter() {
-                bcx = trans_into(bcx, &**e, Ignore);
-            }
-            for sbi in optbase.iter() {
-                // FIXME #7261: this moves entire base, not just certain fields
-                bcx = trans_into(bcx, &*sbi.expr, Ignore);
-            }
-            return bcx;
-        }
-        SaveIn(pos) => pos
+        SaveIn(pos) => pos,
+        Ignore => alloc_ty(bcx, ty, "temp"),
     };
 
     // This scope holds intermediates that must be cleaned should
     // failure occur before the ADT as a whole is ready.
     let custom_cleanup_scope = fcx.push_custom_cleanup_scope();
 
+    // First we trans the base, if we have one, to the dest
+    for base in optbase.iter() {
+        assert_eq!(discr, 0);
+
+        match ty::expr_kind(bcx.tcx(), &*base.expr) {
+            ty::LvalueExpr => {
+                let base_datum = unpack_datum!(bcx, trans_to_lvalue(bcx, &*base.expr, "base"));
+                for &(i, t) in base.fields.iter() {
+                    let datum = base_datum.get_element(
+                            t, |srcval| adt::trans_field_ptr(bcx, &*repr, srcval, discr, i));
+                    let dest = adt::trans_field_ptr(bcx, &*repr, addr, discr, i);
+                    bcx = datum.store_to(bcx, dest);
+                }
+            },
+            ty::RvalueDpsExpr | ty::RvalueDatumExpr => {
+                bcx = trans_into(bcx, &*base.expr, SaveIn(addr));
+            },
+            ty::RvalueStmtExpr => bcx.tcx().sess.bug("unexpected expr kind for struct base expr")
+        }
+    }
+
+    // Now, we just overwrite the fields we've explicity specified
     for &(i, ref e) in fields.iter() {
-        let dest = adt::trans_field_ptr(bcx, repr, addr, discr, i);
+        let dest = adt::trans_field_ptr(bcx, &*repr, addr, discr, i);
         let e_ty = expr_ty_adjusted(bcx, &**e);
         bcx = trans_into(bcx, &**e, SaveIn(dest));
         let scope = cleanup::CustomScope(custom_cleanup_scope);
@@ -1157,24 +1168,19 @@ pub fn trans_adt<'a>(bcx: &'a Block<'a>,
         fcx.schedule_drop_mem(scope, dest, e_ty);
     }
 
-    for base in optbase.iter() {
-        // FIXME #6573: is it sound to use the destination's repr on the base?
-        // And, would it ever be reasonable to be here with discr != 0?
-        let base_datum = unpack_datum!(bcx, trans_to_lvalue(bcx, &*base.expr, "base"));
-        for &(i, t) in base.fields.iter() {
-            let datum = base_datum.get_element(
-                t,
-                |srcval| adt::trans_field_ptr(bcx, repr, srcval, discr, i));
-            let dest = adt::trans_field_ptr(bcx, repr, addr, discr, i);
-            bcx = datum.store_to(bcx, dest);
-        }
-    }
-
-    adt::trans_set_discr(bcx, repr, addr, discr);
+    adt::trans_set_discr(bcx, &*repr, addr, discr);
 
     fcx.pop_custom_cleanup_scope(custom_cleanup_scope);
 
-    return bcx;
+    // If we don't care about the result drop the temporary we made
+    match dest {
+        SaveIn(_) => bcx,
+        Ignore => {
+            bcx = glue::drop_ty(bcx, addr, ty);
+            base::call_lifetime_end(bcx, addr);
+            bcx
+        }
+    }
 }
 
 
index 4ca2060ca866d41076fd201e6ec49ef81a47b20f..fe9b593c11c7e1dee174642f0bbf78db75c7dff9 100644 (file)
@@ -577,8 +577,7 @@ pub fn trans_rust_fn_with_foreign_abi(ccx: &CrateContext,
                                       llwrapfn: ValueRef,
                                       param_substs: &param_substs,
                                       id: ast::NodeId,
-                                      hash: Option<&str>,
-                                      handle_items: HandleItemsFlag) {
+                                      hash: Option<&str>) {
     let _icx = push_ctxt("foreign::build_foreign_fn");
 
     let fnty = ty::node_id_to_type(ccx.tcx(), id);
@@ -587,8 +586,7 @@ pub fn trans_rust_fn_with_foreign_abi(ccx: &CrateContext,
 
     unsafe { // unsafe because we call LLVM operations
         // Build up the Rust function (`foo0` above).
-        let llrustfn = build_rust_fn(ccx, decl, body, param_substs, attrs, id,
-                                     hash, handle_items);
+        let llrustfn = build_rust_fn(ccx, decl, body, param_substs, attrs, id, hash);
 
         // Build up the foreign wrapper (`foo` above).
         return build_wrap_fn(ccx, llrustfn, llwrapfn, &tys, mty);
@@ -600,8 +598,7 @@ fn build_rust_fn(ccx: &CrateContext,
                      param_substs: &param_substs,
                      attrs: &[ast::Attribute],
                      id: ast::NodeId,
-                     hash: Option<&str>,
-                     handle_items: HandleItemsFlag)
+                     hash: Option<&str>)
                      -> ValueRef {
         let _icx = push_ctxt("foreign::foreign::build_rust_fn");
         let tcx = ccx.tcx();
@@ -633,7 +630,7 @@ fn build_rust_fn(ccx: &CrateContext,
 
         let llfn = base::decl_internal_rust_fn(ccx, t, ps.as_slice());
         base::set_llvm_fn_attrs(attrs, llfn);
-        base::trans_fn(ccx, decl, body, llfn, param_substs, id, [], handle_items);
+        base::trans_fn(ccx, decl, body, llfn, param_substs, id, []);
         llfn
     }
 
@@ -744,6 +741,12 @@ unsafe fn build_wrap_fn(ccx: &CrateContext,
             let llforeign_arg_ty = *tys.fn_ty.arg_tys.get(i);
             let foreign_indirect = llforeign_arg_ty.is_indirect();
 
+            if llforeign_arg_ty.is_ignore() {
+                debug!("skipping ignored arg #{}", i);
+                llrust_args.push(C_undef(llrust_ty));
+                continue;
+            }
+
             // skip padding
             let foreign_index = next_foreign_arg(llforeign_arg_ty.pad.is_some());
             let mut llforeign_arg = get_param(llwrapfn, foreign_index);
index f3a8a39d9ec9cb819f1ecdacc7cb36cc59578e73..570f4d370425d9b70f2520eba58a158db1bd1f59 100644 (file)
@@ -469,7 +469,7 @@ fn make_generic_glue(ccx: &CrateContext,
     let arena = TypedArena::new();
     let empty_param_substs = param_substs::empty();
     let fcx = new_fn_ctxt(ccx, llfn, ast::DUMMY_NODE_ID, false, ty::mk_nil(),
-                          &empty_param_substs, None, &arena, TranslateItems);
+                          &empty_param_substs, None, &arena);
 
     let bcx = init_function(&fcx, false, ty::mk_nil());
 
index 877dd647c3b20bb32eb05fd46c96585e7984ca7d..4b1f37fcdc22afaf6cc1e1c401aab01d1bf6caec 100644 (file)
@@ -115,27 +115,42 @@ pub fn maybe_instantiate_inline(ccx: &CrateContext, fn_id: ast::DefId)
             ccx.sess().bug("maybe_get_item_ast returned a found_parent \
              with a non-item parent");
         }
-        csearch::found(ast::IIMethod(impl_did, is_provided, mth)) => {
-            ccx.external.borrow_mut().insert(fn_id, Some(mth.id));
-            ccx.external_srcs.borrow_mut().insert(mth.id, fn_id);
+        csearch::found(ast::IITraitItem(impl_did, impl_item)) => {
+            match impl_item {
+                ast::ProvidedInlinedTraitItem(mth) |
+                ast::RequiredInlinedTraitItem(mth) => {
+                    ccx.external.borrow_mut().insert(fn_id, Some(mth.id));
+                    ccx.external_srcs.borrow_mut().insert(mth.id, fn_id);
 
-            ccx.stats.n_inlines.set(ccx.stats.n_inlines.get() + 1);
-
-            // If this is a default method, we can't look up the
-            // impl type. But we aren't going to translate anyways, so don't.
-            if is_provided { return local_def(mth.id); }
+                    ccx.stats.n_inlines.set(ccx.stats.n_inlines.get() + 1);
+                }
+            }
 
-            let impl_tpt = ty::lookup_item_type(ccx.tcx(), impl_did);
-            let unparameterized =
-                impl_tpt.generics.types.is_empty() &&
-                mth.pe_generics().ty_params.is_empty();
+            match impl_item {
+                ast::ProvidedInlinedTraitItem(mth) => {
+                    // If this is a default method, we can't look up the
+                    // impl type. But we aren't going to translate anyways, so
+                    // don't.
+                    local_def(mth.id)
+                }
+                ast::RequiredInlinedTraitItem(mth) => {
+                    let impl_tpt = ty::lookup_item_type(ccx.tcx(), impl_did);
+                    let unparameterized = impl_tpt.generics.types.is_empty() &&
+                            mth.pe_generics().ty_params.is_empty();
 
-          if unparameterized {
-              let llfn = get_item_val(ccx, mth.id);
-                trans_fn(ccx, &*mth.pe_fn_decl(), &*mth.pe_body(), llfn,
-                       &param_substs::empty(), mth.id, [], TranslateItems);
-          }
-          local_def(mth.id)
+                    if unparameterized {
+                        let llfn = get_item_val(ccx, mth.id);
+                        trans_fn(ccx,
+                                 &*mth.pe_fn_decl(),
+                                 &*mth.pe_body(),
+                                 llfn,
+                                 &param_substs::empty(),
+                                 mth.id,
+                                 []);
+                    }
+                    local_def(mth.id)
+                }
+            }
         }
     };
 }
index 7f7b70e075d1d4876fad029c2a521bd05245f399..31f2a3df6620216a0f34156608fde051ca91c5d1 100644 (file)
@@ -35,7 +35,6 @@
 use util::ppaux::Repr;
 
 use std::c_str::ToCStr;
-use std::gc::Gc;
 use syntax::abi::{Rust, RustCall};
 use syntax::parse::token;
 use syntax::{ast, ast_map, visit};
@@ -49,7 +48,7 @@
 */
 pub fn trans_impl(ccx: &CrateContext,
                   name: ast::Ident,
-                  methods: &[Gc<ast::Method>],
+                  impl_items: &[ast::ImplItem],
                   generics: &ast::Generics,
                   id: ast::NodeId) {
     let _icx = push_ctxt("meth::trans_impl");
@@ -61,25 +60,33 @@ pub fn trans_impl(ccx: &CrateContext,
     // items that we need to translate.
     if !generics.ty_params.is_empty() {
         let mut v = TransItemVisitor{ ccx: ccx };
-        for method in methods.iter() {
-            visit::walk_method_helper(&mut v, &**method, ());
+        for impl_item in impl_items.iter() {
+            match *impl_item {
+                ast::MethodImplItem(method) => {
+                    visit::walk_method_helper(&mut v, &*method, ());
+                }
+            }
         }
         return;
     }
-    for method in methods.iter() {
-        if method.pe_generics().ty_params.len() == 0u {
-            let llfn = get_item_val(ccx, method.id);
-            trans_fn(ccx,
-                     &*method.pe_fn_decl(),
-                     &*method.pe_body(),
-                     llfn,
-                     &param_substs::empty(),
-                     method.id,
-                     [],
-                     TranslateItems);
-        } else {
-            let mut v = TransItemVisitor{ ccx: ccx };
-            visit::walk_method_helper(&mut v, &**method, ());
+    for impl_item in impl_items.iter() {
+        match *impl_item {
+            ast::MethodImplItem(method) => {
+                if method.pe_generics().ty_params.len() == 0u {
+                    let llfn = get_item_val(ccx, method.id);
+                    trans_fn(ccx,
+                             &*method.pe_fn_decl(),
+                             &*method.pe_body(),
+                             llfn,
+                             &param_substs::empty(),
+                             method.id,
+                             []);
+                }
+                let mut v = TransItemVisitor {
+                    ccx: ccx,
+                };
+                visit::walk_method_helper(&mut v, &*method, ());
+            }
         }
     }
 }
@@ -167,10 +174,10 @@ pub fn trans_static_method_callee(bcx: &Block,
 
     let mname = if method_id.krate == ast::LOCAL_CRATE {
         match bcx.tcx().map.get(method_id.node) {
-            ast_map::NodeTraitMethod(method) => {
+            ast_map::NodeTraitItem(method) => {
                 let ident = match *method {
-                    ast::Required(ref m) => m.ident,
-                    ast::Provided(ref m) => m.pe_ident()
+                    ast::RequiredMethod(ref m) => m.ident,
+                    ast::ProvidedMethod(ref m) => m.pe_ident()
                 };
                 ident.name
             }
@@ -215,22 +222,33 @@ pub fn trans_static_method_callee(bcx: &Block,
     }
 }
 
-fn method_with_name(ccx: &CrateContext,
-                    impl_id: ast::DefId,
-                    name: ast::Name) -> ast::DefId {
+fn method_with_name(ccx: &CrateContext, impl_id: ast::DefId, name: ast::Name)
+                    -> ast::DefId {
     match ccx.impl_method_cache.borrow().find_copy(&(impl_id, name)) {
         Some(m) => return m,
         None => {}
     }
 
-    let methods = ccx.tcx.impl_methods.borrow();
-    let methods = methods.find(&impl_id)
-                         .expect("could not find impl while translating");
-    let meth_did = methods.iter().find(|&did| ty::method(&ccx.tcx, *did).ident.name == name)
-                                 .expect("could not find method while translating");
-
-    ccx.impl_method_cache.borrow_mut().insert((impl_id, name), *meth_did);
-    *meth_did
+    let impl_items = ccx.tcx.impl_items.borrow();
+    let impl_items =
+        impl_items.find(&impl_id)
+                  .expect("could not find impl while translating");
+    let meth_did = impl_items.iter()
+                             .find(|&did| {
+                                match *did {
+                                    ty::MethodTraitItemId(did) => {
+                                        ty::impl_or_trait_item(&ccx.tcx,
+                                                               did).ident()
+                                                                   .name ==
+                                            name
+                                    }
+                                }
+                             }).expect("could not find method while \
+                                        translating");
+
+    ccx.impl_method_cache.borrow_mut().insert((impl_id, name),
+                                              meth_did.def_id());
+    meth_did.def_id()
 }
 
 fn trans_monomorphized_callee<'a>(
@@ -244,7 +262,9 @@ fn trans_monomorphized_callee<'a>(
     match vtbl {
       typeck::vtable_static(impl_did, rcvr_substs, rcvr_origins) => {
           let ccx = bcx.ccx();
-          let mname = ty::trait_method(ccx.tcx(), trait_id, n_method).ident;
+          let mname = match ty::trait_item(ccx.tcx(), trait_id, n_method) {
+              ty::MethodTraitItem(method) => method.ident,
+          };
           let mth_id = method_with_name(bcx.ccx(), impl_did, mname.name);
 
           // create a concatenated set of substitutions which includes
@@ -435,7 +455,7 @@ pub fn trans_trait_callee_from_llval<'a>(bcx: &'a Block<'a>,
 
     return Callee {
         bcx: bcx,
-        data: TraitMethod(MethodData {
+        data: TraitItem(MethodData {
             llfn: mptr,
             llself: llself,
         })
@@ -448,7 +468,7 @@ pub fn trans_trait_callee_from_llval<'a>(bcx: &'a Block<'a>,
 fn get_callee_substitutions_for_unboxed_closure(bcx: &Block,
                                                 def_id: ast::DefId)
                                                 -> subst::Substs {
-    let self_ty = ty::mk_unboxed_closure(bcx.tcx(), def_id);
+    let self_ty = ty::mk_unboxed_closure(bcx.tcx(), def_id, ty::ReStatic);
     subst::Substs::erased(
         VecPerParamSpace::new(Vec::new(),
                               vec![
@@ -554,35 +574,42 @@ fn emit_vtable_methods(bcx: &Block,
 
     ty::populate_implementations_for_trait_if_necessary(bcx.tcx(), trt_id);
 
-    let trait_method_def_ids = ty::trait_method_def_ids(tcx, trt_id);
-    trait_method_def_ids.iter().map(|method_def_id| {
-        let ident = ty::method(tcx, *method_def_id).ident;
+    let trait_item_def_ids = ty::trait_item_def_ids(tcx, trt_id);
+    trait_item_def_ids.iter().map(|method_def_id| {
+        let method_def_id = method_def_id.def_id();
+        let ident = ty::impl_or_trait_item(tcx, method_def_id).ident();
         // The substitutions we have are on the impl, so we grab
         // the method type from the impl to substitute into.
         let m_id = method_with_name(ccx, impl_id, ident.name);
-        let m = ty::method(tcx, m_id);
-        debug!("(making impl vtable) emitting method {} at subst {}",
-               m.repr(tcx),
-               substs.repr(tcx));
-        if m.generics.has_type_params(subst::FnSpace) ||
-           ty::type_has_self(ty::mk_bare_fn(tcx, m.fty.clone())) {
-            debug!("(making impl vtable) method has self or type params: {}",
-                   token::get_ident(ident));
-            C_null(Type::nil(ccx).ptr_to())
-        } else {
-            let mut fn_ref = trans_fn_ref_with_vtables(bcx,
-                                                       m_id,
-                                                       ExprId(0),
-                                                       substs.clone(),
-                                                       vtables.clone());
-            if m.explicit_self == ty::ByValueExplicitSelfCategory {
-                fn_ref = trans_unboxing_shim(bcx,
-                                             fn_ref,
-                                             &*m,
-                                             m_id,
-                                             substs.clone());
+        let ti = ty::impl_or_trait_item(tcx, m_id);
+        match ti {
+            ty::MethodTraitItem(m) => {
+                debug!("(making impl vtable) emitting method {} at subst {}",
+                       m.repr(tcx),
+                       substs.repr(tcx));
+                if m.generics.has_type_params(subst::FnSpace) ||
+                   ty::type_has_self(ty::mk_bare_fn(tcx, m.fty.clone())) {
+                    debug!("(making impl vtable) method has self or type \
+                            params: {}",
+                           token::get_ident(ident));
+                    C_null(Type::nil(ccx).ptr_to())
+                } else {
+                    let mut fn_ref = trans_fn_ref_with_vtables(
+                        bcx,
+                        m_id,
+                        ExprId(0),
+                        substs.clone(),
+                        vtables.clone());
+                    if m.explicit_self == ty::ByValueExplicitSelfCategory {
+                        fn_ref = trans_unboxing_shim(bcx,
+                                                     fn_ref,
+                                                     &*m,
+                                                     m_id,
+                                                     substs.clone());
+                    }
+                    fn_ref
+                }
             }
-            fn_ref
         }
     }).collect()
 }
index 070bd89d2896378e71c6c642c011907421a6693e..e19ee035a781e3a02169232b68c70b17caaa5783 100644 (file)
@@ -164,10 +164,9 @@ pub fn monomorphic_fn(ccx: &CrateContext,
                   if abi != abi::Rust {
                       foreign::trans_rust_fn_with_foreign_abi(
                           ccx, &**decl, &**body, [], d, &psubsts, fn_id.node,
-                          Some(hash.as_slice()), IgnoreItems);
+                          Some(hash.as_slice()));
                   } else {
-                      trans_fn(ccx, &**decl, &**body, d, &psubsts, fn_id.node, [],
-                               IgnoreItems);
+                      trans_fn(ccx, &**decl, &**body, d, &psubsts, fn_id.node, []);
                   }
 
                   d
@@ -198,20 +197,29 @@ pub fn monomorphic_fn(ccx: &CrateContext,
             }
             d
         }
-        ast_map::NodeMethod(mth) => {
-            let d = mk_lldecl(abi::Rust);
-            set_llvm_fn_attrs(mth.attrs.as_slice(), d);
-            trans_fn(ccx, &*mth.pe_fn_decl(), &*mth.pe_body(), d, &psubsts, mth.id, [],
-                     IgnoreItems);
-            d
+        ast_map::NodeImplItem(ii) => {
+            match *ii {
+                ast::MethodImplItem(mth) => {
+                    let d = mk_lldecl(abi::Rust);
+                    set_llvm_fn_attrs(mth.attrs.as_slice(), d);
+                    trans_fn(ccx,
+                             &*mth.pe_fn_decl(),
+                             &*mth.pe_body(),
+                             d,
+                             &psubsts,
+                             mth.id,
+                             []);
+                    d
+                }
+            }
         }
-        ast_map::NodeTraitMethod(method) => {
+        ast_map::NodeTraitItem(method) => {
             match *method {
-                ast::Provided(mth) => {
+                ast::ProvidedMethod(mth) => {
                     let d = mk_lldecl(abi::Rust);
                     set_llvm_fn_attrs(mth.attrs.as_slice(), d);
                     trans_fn(ccx, &*mth.pe_fn_decl(), &*mth.pe_body(), d,
-                             &psubsts, mth.id, [], IgnoreItems);
+                             &psubsts, mth.id, []);
                     d
                 }
                 _ => {
index e49d483e8d93d29b5608ae9f9369e25ce45b07b0..2aff12c2b68c5010a262a596a21942b3697fbf92 100644 (file)
@@ -25,7 +25,6 @@
 use middle::ty;
 use util::ppaux::ty_to_string;
 
-use std::rc::Rc;
 use arena::TypedArena;
 use libc::c_uint;
 use syntax::ast::DefId;
@@ -36,7 +35,7 @@
 
 pub struct Reflector<'a, 'b> {
     visitor_val: ValueRef,
-    visitor_methods: &'a [Rc<ty::Method>],
+    visitor_items: &'a [ty::ImplOrTraitItem],
     final_bcx: &'b Block<'b>,
     tydesc_ty: Type,
     bcx: &'b Block<'b>
@@ -87,13 +86,14 @@ pub fn c_mt(&mut self, mt: &ty::mt) -> Vec<ValueRef> {
     pub fn visit(&mut self, ty_name: &str, args: &[ValueRef]) {
         let fcx = self.bcx.fcx;
         let tcx = self.bcx.tcx();
-        let mth_idx = ty::method_idx(token::str_to_ident(format!(
+        let mth_idx = ty::impl_or_trait_item_idx(token::str_to_ident(format!(
                         "visit_{}", ty_name).as_slice()),
-                                     self.visitor_methods.as_slice()).expect(
+                                     self.visitor_items.as_slice()).expect(
                 format!("couldn't find visit method for {}", ty_name).as_slice());
-        let mth_ty =
-            ty::mk_bare_fn(tcx,
-                           self.visitor_methods[mth_idx].fty.clone());
+        let method = match self.visitor_items[mth_idx] {
+            ty::MethodTraitItem(ref method) => (*method).clone(),
+        };
+        let mth_ty = ty::mk_bare_fn(tcx, method.fty.clone());
         let v = self.visitor_val;
         debug!("passing {} args:", args.len());
         let mut bcx = self.bcx;
@@ -312,7 +312,7 @@ pub fn visit_ty(&mut self, t: ty::t) {
                 let empty_param_substs = param_substs::empty();
                 let fcx = new_fn_ctxt(ccx, llfdecl, ast::DUMMY_NODE_ID, false,
                                       ty::mk_u64(), &empty_param_substs,
-                                      None, &arena, TranslateItems);
+                                      None, &arena);
                 let bcx = init_function(&fcx, false, ty::mk_u64());
 
                 // we know the return type of llfdecl is an int here, so
@@ -397,10 +397,10 @@ pub fn emit_calls_to_trait_visit_ty<'a>(
     let final = fcx.new_temp_block("final");
     let tydesc_ty = ty::get_tydesc_ty(bcx.tcx()).unwrap();
     let tydesc_ty = type_of(bcx.ccx(), tydesc_ty);
-    let visitor_methods = ty::trait_methods(bcx.tcx(), visitor_trait_id);
+    let visitor_items = ty::trait_items(bcx.tcx(), visitor_trait_id);
     let mut r = Reflector {
         visitor_val: visitor_val,
-        visitor_methods: visitor_methods.as_slice(),
+        visitor_items: visitor_items.as_slice(),
         final_bcx: final,
         tydesc_ty: tydesc_ty,
         bcx: bcx
index 94c376c09c86a66a3257c0c455e1cfd11cea39db..8a445fc48398ee21feeb051de4e2ca587e33af0b 100644 (file)
@@ -273,7 +273,7 @@ pub fn type_of(cx: &CrateContext, t: ty::t) -> Type {
         let name = llvm_type_name(cx, an_enum, did, tps);
         adt::incomplete_type_of(cx, &*repr, name.as_slice())
       }
-      ty::ty_unboxed_closure(did) => {
+      ty::ty_unboxed_closure(did, _) => {
         // Only create the named struct, but don't fill it in. We
         // fill it in *after* placing it into the type cache.
         let repr = adt::represent_type(cx, t);
index a4588da1bd7dd7361a22669e54bfd057b0036f61..40c4d9682c4a3e8bf504bbcf63c9193e49543132 100644 (file)
 use middle::const_eval;
 use middle::def;
 use middle::dependency_format;
+use middle::freevars::CaptureModeMap;
+use middle::freevars;
 use middle::lang_items::{FnMutTraitLangItem, OpaqueStructLangItem};
 use middle::lang_items::{TyDescStructLangItem, TyVisitorTraitLangItem};
-use middle::freevars;
 use middle::resolve;
 use middle::resolve_lifetime;
-use middle::subst;
-use middle::subst::{Subst, Substs, VecPerParamSpace};
 use middle::stability;
+use middle::subst::{Subst, Substs, VecPerParamSpace};
+use middle::subst;
 use middle::ty;
 use middle::typeck;
 use middle::typeck::MethodCall;
@@ -75,11 +76,64 @@ pub struct field {
 }
 
 #[deriving(Clone)]
-pub enum MethodContainer {
+pub enum ImplOrTraitItemContainer {
     TraitContainer(ast::DefId),
     ImplContainer(ast::DefId),
 }
 
+impl ImplOrTraitItemContainer {
+    pub fn id(&self) -> ast::DefId {
+        match *self {
+            TraitContainer(id) => id,
+            ImplContainer(id) => id,
+        }
+    }
+}
+
+#[deriving(Clone)]
+pub enum ImplOrTraitItem {
+    MethodTraitItem(Rc<Method>),
+}
+
+impl ImplOrTraitItem {
+    fn id(&self) -> ImplOrTraitItemId {
+        match *self {
+            MethodTraitItem(ref method) => MethodTraitItemId(method.def_id),
+        }
+    }
+
+    pub fn def_id(&self) -> ast::DefId {
+        match *self {
+            MethodTraitItem(ref method) => method.def_id,
+        }
+    }
+
+    pub fn ident(&self) -> ast::Ident {
+        match *self {
+            MethodTraitItem(ref method) => method.ident,
+        }
+    }
+
+    pub fn container(&self) -> ImplOrTraitItemContainer {
+        match *self {
+            MethodTraitItem(ref method) => method.container,
+        }
+    }
+}
+
+#[deriving(Clone)]
+pub enum ImplOrTraitItemId {
+    MethodTraitItemId(ast::DefId),
+}
+
+impl ImplOrTraitItemId {
+    pub fn def_id(&self) -> ast::DefId {
+        match *self {
+            MethodTraitItemId(def_id) => def_id,
+        }
+    }
+}
+
 #[deriving(Clone)]
 pub struct Method {
     pub ident: ast::Ident,
@@ -88,7 +142,7 @@ pub struct Method {
     pub explicit_self: ExplicitSelfCategory,
     pub vis: ast::Visibility,
     pub def_id: ast::DefId,
-    pub container: MethodContainer,
+    pub container: ImplOrTraitItemContainer,
 
     // If this method is provided, we need to know where it came from
     pub provided_source: Option<ast::DefId>
@@ -101,7 +155,7 @@ pub fn new(ident: ast::Ident,
                explicit_self: ExplicitSelfCategory,
                vis: ast::Visibility,
                def_id: ast::DefId,
-               container: MethodContainer,
+               container: ImplOrTraitItemContainer,
                provided_source: Option<ast::DefId>)
                -> Method {
        Method {
@@ -273,14 +327,14 @@ pub struct ctxt {
     /// other items.
     pub item_substs: RefCell<NodeMap<ItemSubsts>>,
 
-    /// Maps from a method to the method "descriptor"
-    pub methods: RefCell<DefIdMap<Rc<Method>>>,
+    /// Maps from a trait item to the trait item "descriptor"
+    pub impl_or_trait_items: RefCell<DefIdMap<ImplOrTraitItem>>,
 
-    /// Maps from a trait def-id to a list of the def-ids of its methods
-    pub trait_method_def_ids: RefCell<DefIdMap<Rc<Vec<DefId>>>>,
+    /// Maps from a trait def-id to a list of the def-ids of its trait items
+    pub trait_item_def_ids: RefCell<DefIdMap<Rc<Vec<ImplOrTraitItemId>>>>,
 
-    /// A cache for the trait_methods() routine
-    pub trait_methods_cache: RefCell<DefIdMap<Rc<Vec<Rc<Method>>>>>,
+    /// A cache for the trait_items() routine
+    pub trait_items_cache: RefCell<DefIdMap<Rc<Vec<ImplOrTraitItem>>>>,
 
     pub impl_trait_cache: RefCell<DefIdMap<Option<Rc<ty::TraitRef>>>>,
 
@@ -331,11 +385,11 @@ pub struct ctxt {
     /// Methods in these implementations don't need to be exported.
     pub inherent_impls: RefCell<DefIdMap<Rc<RefCell<Vec<ast::DefId>>>>>,
 
-    /// Maps a DefId of an impl to a list of its methods.
+    /// Maps a DefId of an impl to a list of its items.
     /// Note that this contains all of the impls that we know about,
     /// including ones in other crates. It's not clear that this is the best
     /// way to do it.
-    pub impl_methods: RefCell<DefIdMap<Vec<ast::DefId>>>,
+    pub impl_items: RefCell<DefIdMap<Vec<ImplOrTraitItemId>>>,
 
     /// Set of used unsafe nodes (functions or blocks). Unsafe nodes not
     /// present in this set can be warned about.
@@ -372,7 +426,7 @@ pub struct ctxt {
 
     /// Records the type of each unboxed closure. The def ID is the ID of the
     /// expression defining the unboxed closure.
-    pub unboxed_closure_types: RefCell<DefIdMap<ClosureTy>>,
+    pub unboxed_closures: RefCell<DefIdMap<UnboxedClosure>>,
 
     pub node_lint_levels: RefCell<HashMap<(ast::NodeId, lint::LintId),
                                           lint::LevelSource>>,
@@ -384,6 +438,9 @@ pub struct ctxt {
 
     /// Maps any item's def-id to its stability index.
     pub stability: RefCell<stability::Index>,
+
+    /// Maps closures to their capture clauses.
+    pub capture_modes: RefCell<CaptureModeMap>,
 }
 
 pub enum tbox_flag {
@@ -741,7 +798,7 @@ pub enum sty {
     ty_closure(Box<ClosureTy>),
     ty_trait(Box<TyTrait>),
     ty_struct(DefId, Substs),
-    ty_unboxed_closure(DefId),
+    ty_unboxed_closure(DefId, Region),
     ty_tup(Vec<t>),
 
     ty_param(ParamTy), // type parameter
@@ -1052,11 +1109,27 @@ pub struct ItemSubsts {
 
 pub type node_type_table = RefCell<HashMap<uint,t>>;
 
+/// Records information about each unboxed closure.
+pub struct UnboxedClosure {
+    /// The type of the unboxed closure.
+    pub closure_type: ClosureTy,
+    /// The kind of unboxed closure this is.
+    pub kind: UnboxedClosureKind,
+}
+
+#[deriving(PartialEq, Eq)]
+pub enum UnboxedClosureKind {
+    FnUnboxedClosureKind,
+    FnMutUnboxedClosureKind,
+    FnOnceUnboxedClosureKind,
+}
+
 pub fn mk_ctxt(s: Session,
                dm: resolve::DefMap,
                named_region_map: resolve_lifetime::NamedRegionMap,
                map: ast_map::Map,
                freevars: freevars::freevar_map,
+               capture_modes: freevars::CaptureModeMap,
                region_maps: middle::region::RegionMaps,
                lang_items: middle::lang_items::LanguageItems,
                stability: stability::Index)
@@ -1084,9 +1157,9 @@ pub fn mk_ctxt(s: Session,
         tc_cache: RefCell::new(HashMap::new()),
         ast_ty_to_ty_cache: RefCell::new(NodeMap::new()),
         enum_var_cache: RefCell::new(DefIdMap::new()),
-        methods: RefCell::new(DefIdMap::new()),
-        trait_method_def_ids: RefCell::new(DefIdMap::new()),
-        trait_methods_cache: RefCell::new(DefIdMap::new()),
+        impl_or_trait_items: RefCell::new(DefIdMap::new()),
+        trait_item_def_ids: RefCell::new(DefIdMap::new()),
+        trait_items_cache: RefCell::new(DefIdMap::new()),
         impl_trait_cache: RefCell::new(DefIdMap::new()),
         ty_param_defs: RefCell::new(NodeMap::new()),
         adjustments: RefCell::new(NodeMap::new()),
@@ -1100,7 +1173,7 @@ pub fn mk_ctxt(s: Session,
         destructors: RefCell::new(DefIdSet::new()),
         trait_impls: RefCell::new(DefIdMap::new()),
         inherent_impls: RefCell::new(DefIdMap::new()),
-        impl_methods: RefCell::new(DefIdMap::new()),
+        impl_items: RefCell::new(DefIdMap::new()),
         used_unsafe: RefCell::new(NodeSet::new()),
         used_mut_nodes: RefCell::new(NodeSet::new()),
         impl_vtables: RefCell::new(DefIdMap::new()),
@@ -1112,10 +1185,11 @@ pub fn mk_ctxt(s: Session,
         method_map: RefCell::new(FnvHashMap::new()),
         vtable_map: RefCell::new(FnvHashMap::new()),
         dependency_formats: RefCell::new(HashMap::new()),
-        unboxed_closure_types: RefCell::new(DefIdMap::new()),
+        unboxed_closures: RefCell::new(DefIdMap::new()),
         node_lint_levels: RefCell::new(HashMap::new()),
         transmute_restrictions: RefCell::new(Vec::new()),
-        stability: RefCell::new(stability)
+        stability: RefCell::new(stability),
+        capture_modes: RefCell::new(capture_modes),
     }
 }
 
@@ -1171,7 +1245,7 @@ fn sflags(substs: &Substs) -> uint {
     }
     match &st {
       &ty_nil | &ty_bool | &ty_char | &ty_int(_) | &ty_float(_) | &ty_uint(_) |
-      &ty_str | &ty_unboxed_closure(_) => {}
+      &ty_str => {}
       // You might think that we could just return ty_err for
       // any type containing ty_err as a component, and get
       // rid of the has_ty_err flag -- likewise for ty_bot (with
@@ -1188,6 +1262,7 @@ fn sflags(substs: &Substs) -> uint {
               flags |= has_params as uint;
           }
       }
+      &ty_unboxed_closure(_, ref region) => flags |= rflags(*region),
       &ty_infer(_) => flags |= needs_infer as uint,
       &ty_enum(_, ref substs) | &ty_struct(_, ref substs) => {
           flags |= sflags(substs);
@@ -1436,8 +1511,9 @@ pub fn mk_struct(cx: &ctxt, struct_id: ast::DefId, substs: Substs) -> t {
     mk_t(cx, ty_struct(struct_id, substs))
 }
 
-pub fn mk_unboxed_closure(cx: &ctxt, closure_id: ast::DefId) -> t {
-    mk_t(cx, ty_unboxed_closure(closure_id))
+pub fn mk_unboxed_closure(cx: &ctxt, closure_id: ast::DefId, region: Region)
+                          -> t {
+    mk_t(cx, ty_unboxed_closure(closure_id, region))
 }
 
 pub fn mk_var(cx: &ctxt, v: TyVid) -> t { mk_infer(cx, TyVar(v)) }
@@ -1470,8 +1546,8 @@ pub fn maybe_walk_ty(ty: t, f: |t| -> bool) {
     }
     match get(ty).sty {
         ty_nil | ty_bot | ty_bool | ty_char | ty_int(_) | ty_uint(_) | ty_float(_) |
-        ty_str | ty_infer(_) | ty_param(_) | ty_unboxed_closure(_) | ty_err => {
-        }
+        ty_str | ty_infer(_) | ty_param(_) | ty_unboxed_closure(..) |
+        ty_err => {}
         ty_box(ty) | ty_uniq(ty) => maybe_walk_ty(ty, f),
         ty_ptr(ref tm) | ty_rptr(_, ref tm) | ty_vec(ref tm, _) => {
             maybe_walk_ty(tm.ty, f);
@@ -1578,7 +1654,7 @@ pub fn type_is_vec(ty: t) -> bool {
 pub fn type_is_structural(ty: t) -> bool {
     match get(ty).sty {
       ty_struct(..) | ty_tup(_) | ty_enum(..) | ty_closure(_) |
-      ty_vec(_, Some(_)) | ty_unboxed_closure(_) => true,
+      ty_vec(_, Some(_)) | ty_unboxed_closure(..) => true,
       _ => type_is_slice(ty) | type_is_trait(ty)
     }
 }
@@ -2093,10 +2169,13 @@ fn tc_ty(cx: &ctxt,
                 apply_lang_items(cx, did, res)
             }
 
-            ty_unboxed_closure(did) => {
+            ty_unboxed_closure(did, r) => {
+                // FIXME(#14449): `borrowed_contents` below assumes `&mut`
+                // unboxed closure.
                 let upvars = unboxed_closure_upvars(cx, did);
                 TypeContents::union(upvars.as_slice(),
-                                    |f| tc_ty(cx, f.ty, cache))
+                                    |f| tc_ty(cx, f.ty, cache)) |
+                    borrowed_contents(r, MutMutable)
             }
 
             ty_tup(ref tys) => {
@@ -2343,7 +2422,7 @@ fn subtypes_require(cx: &ctxt, seen: &mut Vec<DefId>,
                 r
             }
 
-            ty_unboxed_closure(did) => {
+            ty_unboxed_closure(did, _) => {
                 let upvars = unboxed_closure_upvars(cx, did);
                 upvars.iter().any(|f| type_requires(cx, seen, r_ty, f.ty))
             }
@@ -2471,7 +2550,7 @@ fn type_structurally_recursive(cx: &ctxt, sp: Span, seen: &mut Vec<DefId>,
                 r
             }
 
-            ty_unboxed_closure(did) => {
+            ty_unboxed_closure(did, _) => {
                 let upvars = unboxed_closure_upvars(cx, did);
                 find_nonrepresentable(cx,
                                       sp,
@@ -2712,7 +2791,7 @@ pub fn ty_fn_args(fty: t) -> Vec<t> {
 pub fn ty_closure_store(fty: t) -> TraitStore {
     match get(fty).sty {
         ty_closure(ref f) => f.store,
-        ty_unboxed_closure(_) => {
+        ty_unboxed_closure(..) => {
             // Close enough for the purposes of all the callers of this
             // function (which is soon to be deprecated anyhow).
             UniqTraitStore
@@ -3049,11 +3128,19 @@ pub fn method_call_type_param_defs(tcx: &ctxt, origin: typeck::MethodOrigin)
                 Err(s) => tcx.sess.fatal(s.as_slice()),
             }
         }
-        typeck::MethodParam(typeck::MethodParam{trait_id: trt_id,
-                                                method_num: n_mth, ..}) |
-        typeck::MethodObject(typeck::MethodObject{trait_id: trt_id,
-                                                  method_num: n_mth, ..}) => {
-            ty::trait_method(tcx, trt_id, n_mth).generics.types.clone()
+        typeck::MethodParam(typeck::MethodParam{
+            trait_id: trt_id,
+            method_num: n_mth,
+            ..
+        }) |
+        typeck::MethodObject(typeck::MethodObject{
+                trait_id: trt_id,
+                method_num: n_mth,
+                ..
+        }) => {
+            match ty::trait_item(tcx, trt_id, n_mth) {
+                ty::MethodTraitItem(method) => method.generics.types.clone(),
+            }
         }
     }
 }
@@ -3271,8 +3358,9 @@ pub fn field_idx_strict(tcx: &ctxt, name: ast::Name, fields: &[field])
               .collect::<Vec<String>>()).as_slice());
 }
 
-pub fn method_idx(id: ast::Ident, meths: &[Rc<Method>]) -> Option<uint> {
-    meths.iter().position(|m| m.ident == id)
+pub fn impl_or_trait_item_idx(id: ast::Ident, trait_items: &[ImplOrTraitItem])
+                              -> Option<uint> {
+    trait_items.iter().position(|m| m.ident() == id)
 }
 
 /// Returns a vector containing the indices of all type parameters that appear
@@ -3312,7 +3400,7 @@ pub fn ty_sort_string(cx: &ctxt, t: t) -> String {
         ty_struct(id, _) => {
             format!("struct {}", item_path_str(cx, id))
         }
-        ty_unboxed_closure(_) => "closure".to_string(),
+        ty_unboxed_closure(..) => "closure".to_string(),
         ty_tup(_) => "tuple".to_string(),
         ty_infer(TyVar(_)) => "inferred type".to_string(),
         ty_infer(IntVar(_)) => "integral variable".to_string(),
@@ -3514,7 +3602,15 @@ pub fn provided_trait_methods(cx: &ctxt, id: ast::DefId) -> Vec<Rc<Method>> {
                 match item.node {
                     ItemTrait(_, _, _, ref ms) => {
                         let (_, p) = ast_util::split_trait_methods(ms.as_slice());
-                        p.iter().map(|m| method(cx, ast_util::local_def(m.id))).collect()
+                        p.iter()
+                         .map(|m| {
+                            match impl_or_trait_item(
+                                    cx,
+                                    ast_util::local_def(m.id)) {
+                                MethodTraitItem(m) => m,
+                            }
+                         })
+                         .collect()
                     }
                     _ => {
                         cx.sess.bug(format!("provided_trait_methods: `{}` is \
@@ -3566,7 +3662,7 @@ fn lookup_locally_or_in_crate_store<V:Clone>(
     /*!
      * Helper for looking things up in the various maps
      * that are populated during typeck::collect (e.g.,
-     * `cx.methods`, `cx.tcache`, etc).  All of these share
+     * `cx.impl_or_trait_items`, `cx.tcache`, etc).  All of these share
      * the pattern that if the id is local, it should have
      * been loaded into the map by the `typeck::collect` phase.
      * If the def-id is external, then we have to go consult
@@ -3586,40 +3682,47 @@ fn lookup_locally_or_in_crate_store<V:Clone>(
     v
 }
 
-pub fn trait_method(cx: &ctxt, trait_did: ast::DefId, idx: uint) -> Rc<Method> {
-    let method_def_id = *ty::trait_method_def_ids(cx, trait_did).get(idx);
-    ty::method(cx, method_def_id)
+pub fn trait_item(cx: &ctxt, trait_did: ast::DefId, idx: uint)
+                  -> ImplOrTraitItem {
+    let method_def_id = ty::trait_item_def_ids(cx, trait_did).get(idx)
+                                                             .def_id();
+    impl_or_trait_item(cx, method_def_id)
 }
 
-
-pub fn trait_methods(cx: &ctxt, trait_did: ast::DefId) -> Rc<Vec<Rc<Method>>> {
-    let mut trait_methods = cx.trait_methods_cache.borrow_mut();
-    match trait_methods.find_copy(&trait_did) {
-        Some(methods) => methods,
+pub fn trait_items(cx: &ctxt, trait_did: ast::DefId)
+                   -> Rc<Vec<ImplOrTraitItem>> {
+    let mut trait_items = cx.trait_items_cache.borrow_mut();
+    match trait_items.find_copy(&trait_did) {
+        Some(trait_items) => trait_items,
         None => {
-            let def_ids = ty::trait_method_def_ids(cx, trait_did);
-            let methods: Rc<Vec<Rc<Method>>> = Rc::new(def_ids.iter().map(|d| {
-                ty::method(cx, *d)
-            }).collect());
-            trait_methods.insert(trait_did, methods.clone());
-            methods
+            let def_ids = ty::trait_item_def_ids(cx, trait_did);
+            let items: Rc<Vec<ImplOrTraitItem>> =
+                Rc::new(def_ids.iter()
+                               .map(|d| impl_or_trait_item(cx, d.def_id()))
+                               .collect());
+            trait_items.insert(trait_did, items.clone());
+            items
         }
     }
 }
 
-pub fn method(cx: &ctxt, id: ast::DefId) -> Rc<Method> {
-    lookup_locally_or_in_crate_store("methods", id,
-                                     &mut *cx.methods.borrow_mut(), || {
-        Rc::new(csearch::get_method(cx, id))
+pub fn impl_or_trait_item(cx: &ctxt, id: ast::DefId) -> ImplOrTraitItem {
+    lookup_locally_or_in_crate_store("impl_or_trait_items",
+                                     id,
+                                     &mut *cx.impl_or_trait_items
+                                             .borrow_mut(),
+                                     || {
+        csearch::get_impl_or_trait_item(cx, id)
     })
 }
 
-pub fn trait_method_def_ids(cx: &ctxt, id: ast::DefId) -> Rc<Vec<DefId>> {
-    lookup_locally_or_in_crate_store("trait_method_def_ids",
+pub fn trait_item_def_ids(cx: &ctxt, id: ast::DefId)
+                          -> Rc<Vec<ImplOrTraitItemId>> {
+    lookup_locally_or_in_crate_store("trait_item_def_ids",
                                      id,
-                                     &mut *cx.trait_method_def_ids.borrow_mut(),
+                                     &mut *cx.trait_item_def_ids.borrow_mut(),
                                      || {
-        Rc::new(csearch::get_trait_method_def_ids(&cx.sess.cstore, id))
+        Rc::new(csearch::get_trait_item_def_ids(&cx.sess.cstore, id))
     })
 }
 
@@ -3681,7 +3784,7 @@ pub fn ty_to_def_id(ty: t) -> Option<ast::DefId> {
         ty_trait(box TyTrait { def_id: id, .. }) |
         ty_struct(id, _) |
         ty_enum(id, _) |
-        ty_unboxed_closure(id) => Some(id),
+        ty_unboxed_closure(id, _) => Some(id),
         _ => None
     }
 }
@@ -4433,7 +4536,8 @@ pub fn populate_implementations_for_type_if_necessary(tcx: &ctxt,
 
     csearch::each_implementation_for_type(&tcx.sess.cstore, type_id,
             |impl_def_id| {
-        let methods = csearch::get_impl_methods(&tcx.sess.cstore, impl_def_id);
+        let impl_items = csearch::get_impl_items(&tcx.sess.cstore,
+                                                 impl_def_id);
 
         // Record the trait->implementation mappings, if applicable.
         let associated_traits = csearch::get_impl_trait(tcx, impl_def_id);
@@ -4443,14 +4547,21 @@ pub fn populate_implementations_for_type_if_necessary(tcx: &ctxt,
 
         // For any methods that use a default implementation, add them to
         // the map. This is a bit unfortunate.
-        for &method_def_id in methods.iter() {
-            for &source in ty::method(tcx, method_def_id).provided_source.iter() {
-                tcx.provided_method_sources.borrow_mut().insert(method_def_id, source);
+        for impl_item_def_id in impl_items.iter() {
+            let method_def_id = impl_item_def_id.def_id();
+            match impl_or_trait_item(tcx, method_def_id) {
+                MethodTraitItem(method) => {
+                    for &source in method.provided_source.iter() {
+                        tcx.provided_method_sources
+                           .borrow_mut()
+                           .insert(method_def_id, source);
+                    }
+                }
             }
         }
 
         // Store the implementation info.
-        tcx.impl_methods.borrow_mut().insert(impl_def_id, methods);
+        tcx.impl_items.borrow_mut().insert(impl_def_id, impl_items);
 
         // If this is an inherent implementation, record it.
         if associated_traits.is_none() {
@@ -4483,21 +4594,28 @@ pub fn populate_implementations_for_trait_if_necessary(
 
     csearch::each_implementation_for_trait(&tcx.sess.cstore, trait_id,
             |implementation_def_id| {
-        let methods = csearch::get_impl_methods(&tcx.sess.cstore, implementation_def_id);
+        let impl_items = csearch::get_impl_items(&tcx.sess.cstore, implementation_def_id);
 
         // Record the trait->implementation mapping.
         record_trait_implementation(tcx, trait_id, implementation_def_id);
 
         // For any methods that use a default implementation, add them to
         // the map. This is a bit unfortunate.
-        for &method_def_id in methods.iter() {
-            for &source in ty::method(tcx, method_def_id).provided_source.iter() {
-                tcx.provided_method_sources.borrow_mut().insert(method_def_id, source);
+        for impl_item_def_id in impl_items.iter() {
+            let method_def_id = impl_item_def_id.def_id();
+            match impl_or_trait_item(tcx, method_def_id) {
+                MethodTraitItem(method) => {
+                    for &source in method.provided_source.iter() {
+                        tcx.provided_method_sources
+                           .borrow_mut()
+                           .insert(method_def_id, source);
+                    }
+                }
             }
         }
 
         // Store the implementation info.
-        tcx.impl_methods.borrow_mut().insert(implementation_def_id, methods);
+        tcx.impl_items.borrow_mut().insert(implementation_def_id, impl_items);
     });
 
     tcx.populated_external_traits.borrow_mut().insert(trait_id);
@@ -4529,14 +4647,15 @@ pub fn trait_id_of_impl(tcx: &ctxt,
 pub fn impl_of_method(tcx: &ctxt, def_id: ast::DefId)
                        -> Option<ast::DefId> {
     if def_id.krate != LOCAL_CRATE {
-        return match csearch::get_method(tcx, def_id).container {
+        return match csearch::get_impl_or_trait_item(tcx,
+                                                     def_id).container() {
             TraitContainer(_) => None,
             ImplContainer(def_id) => Some(def_id),
         };
     }
-    match tcx.methods.borrow().find_copy(&def_id) {
-        Some(method) => {
-            match method.container {
+    match tcx.impl_or_trait_items.borrow().find_copy(&def_id) {
+        Some(trait_item) => {
+            match trait_item.container() {
                 TraitContainer(_) => None,
                 ImplContainer(def_id) => Some(def_id),
             }
@@ -4545,17 +4664,16 @@ pub fn impl_of_method(tcx: &ctxt, def_id: ast::DefId)
     }
 }
 
-/// If the given def ID describes a method belonging to a trait (either a
+/// If the given def ID describes an item belonging to a trait (either a
 /// default method or an implementation of a trait method), return the ID of
 /// the trait that the method belongs to. Otherwise, return `None`.
-pub fn trait_of_method(tcx: &ctxt, def_id: ast::DefId)
-                       -> Option<ast::DefId> {
+pub fn trait_of_item(tcx: &ctxt, def_id: ast::DefId) -> Option<ast::DefId> {
     if def_id.krate != LOCAL_CRATE {
-        return csearch::get_trait_of_method(&tcx.sess.cstore, def_id, tcx);
+        return csearch::get_trait_of_item(&tcx.sess.cstore, def_id, tcx);
     }
-    match tcx.methods.borrow().find_copy(&def_id) {
-        Some(method) => {
-            match method.container {
+    match tcx.impl_or_trait_items.borrow().find_copy(&def_id) {
+        Some(impl_or_trait_item) => {
+            match impl_or_trait_item.container() {
                 TraitContainer(def_id) => Some(def_id),
                 ImplContainer(def_id) => trait_id_of_impl(tcx, def_id),
             }
@@ -4564,25 +4682,27 @@ pub fn trait_of_method(tcx: &ctxt, def_id: ast::DefId)
     }
 }
 
-/// If the given def ID describes a method belonging to a trait, (either a
+/// If the given def ID describes an item belonging to a trait, (either a
 /// default method or an implementation of a trait method), return the ID of
 /// the method inside trait definition (this means that if the given def ID
 /// is already that of the original trait method, then the return value is
 /// the same).
 /// Otherwise, return `None`.
-pub fn trait_method_of_method(tcx: &ctxt,
-                              def_id: ast::DefId) -> Option<ast::DefId> {
-    let method = match tcx.methods.borrow().find(&def_id) {
+pub fn trait_item_of_item(tcx: &ctxt, def_id: ast::DefId)
+                          -> Option<ImplOrTraitItemId> {
+    let impl_item = match tcx.impl_or_trait_items.borrow().find(&def_id) {
         Some(m) => m.clone(),
         None => return None,
     };
-    let name = method.ident.name;
-    match trait_of_method(tcx, def_id) {
+    let name = match impl_item {
+        MethodTraitItem(method) => method.ident.name,
+    };
+    match trait_of_item(tcx, def_id) {
         Some(trait_did) => {
-            let trait_methods = ty::trait_methods(tcx, trait_did);
-            trait_methods.iter()
-                .position(|m| m.ident.name == name)
-                .map(|idx| ty::trait_method(tcx, trait_did, idx).def_id)
+            let trait_items = ty::trait_items(tcx, trait_did);
+            trait_items.iter()
+                .position(|m| m.ident().name == name)
+                .map(|idx| ty::trait_item(tcx, trait_did, idx).id())
         }
         None => None
     }
@@ -4711,9 +4831,10 @@ pub fn hash_crate_independent(tcx: &ctxt, t: t, svh: &Svh) -> u64 {
             }
             ty_infer(_) => unreachable!(),
             ty_err => byte!(23),
-            ty_unboxed_closure(d) => {
+            ty_unboxed_closure(d, r) => {
                 byte!(24);
                 did(&mut state, d);
+                region(&mut state, r);
             }
         }
     });
@@ -4862,6 +4983,16 @@ fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option<ast::NodeId> {
     fn upvar_borrow(&self, upvar_id: ty::UpvarId) -> ty::UpvarBorrow {
         self.upvar_borrow_map.borrow().get_copy(&upvar_id)
     }
+
+    fn capture_mode(&self, closure_expr_id: ast::NodeId)
+                    -> freevars::CaptureMode {
+        self.capture_modes.borrow().get_copy(&closure_expr_id)
+    }
+
+    fn unboxed_closures<'a>(&'a self)
+                        -> &'a RefCell<DefIdMap<UnboxedClosure>> {
+        &self.unboxed_closures
+    }
 }
 
 /// The category of explicit self.
@@ -4903,6 +5034,7 @@ pub fn accumulate_lifetimes_in_type(accumulator: &mut Vec<ty::Region>,
                     UniqTraitStore => {}
                 }
             }
+            ty_unboxed_closure(_, ref region) => accumulator.push(*region),
             ty_nil |
             ty_bot |
             ty_bool |
@@ -4919,7 +5051,6 @@ pub fn accumulate_lifetimes_in_type(accumulator: &mut Vec<ty::Region>,
             ty_tup(_) |
             ty_param(_) |
             ty_infer(_) |
-            ty_unboxed_closure(_) |
             ty_err => {}
         }
     })
index e2b984959060c2b270e9536b509fbcaaa67e512b..9f475bfd9d5d06dbba4ec703350517e0311ecba5 100644 (file)
@@ -392,8 +392,8 @@ pub fn super_fold_sty<T:TypeFolder>(this: &mut T,
         ty::ty_struct(did, ref substs) => {
             ty::ty_struct(did, substs.fold_with(this))
         }
-        ty::ty_unboxed_closure(did) => {
-            ty::ty_unboxed_closure(did)
+        ty::ty_unboxed_closure(did, ref region) => {
+            ty::ty_unboxed_closure(did, region.fold_with(this))
         }
         ty::ty_nil | ty::ty_bot | ty::ty_bool | ty::ty_char | ty::ty_str |
         ty::ty_int(_) | ty::ty_uint(_) | ty::ty_float(_) |
index 5e7426f3ae749ccddeba3f06a56c000c71409e5b..c317f98a25afef408b00a99abf6d67227d4851c0 100644 (file)
@@ -51,7 +51,8 @@
 
 use middle::const_eval;
 use middle::def;
-use middle::lang_items::FnMutTraitLangItem;
+use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem};
+use middle::lang_items::{FnOnceTraitLangItem};
 use middle::subst::{FnSpace, TypeSpace, SelfSpace, Subst, Substs};
 use middle::subst::{VecPerParamSpace};
 use middle::ty;
@@ -544,16 +545,17 @@ fn ast_ty_to_mt<AC:AstConv, RS:RegionScope>(this: &AC,
 
 pub fn trait_ref_for_unboxed_function<AC:AstConv,
                                       RS:RegionScope>(
-                                          this: &AC,
-                                          rscope: &RS,
-                                          unboxed_function: &ast::UnboxedFnTy,
-                                          self_ty: Option<ty::t>)
-    -> ty::TraitRef
-{
-    let fn_mut_trait_did = this.tcx()
-                               .lang_items
-                               .require(FnMutTraitLangItem)
-                               .unwrap();
+                                      this: &AC,
+                                      rscope: &RS,
+                                      unboxed_function: &ast::UnboxedFnTy,
+                                      self_ty: Option<ty::t>)
+                                      -> ty::TraitRef {
+    let lang_item = match unboxed_function.kind {
+        ast::FnUnboxedClosureKind => FnTraitLangItem,
+        ast::FnMutUnboxedClosureKind => FnMutTraitLangItem,
+        ast::FnOnceUnboxedClosureKind => FnOnceTraitLangItem,
+    };
+    let trait_did = this.tcx().lang_items.require(lang_item).unwrap();
     let input_types =
         unboxed_function.decl
                         .inputs
@@ -574,7 +576,7 @@ pub fn trait_ref_for_unboxed_function<AC:AstConv,
     }
 
     ty::TraitRef {
-        def_id: fn_mut_trait_did,
+        def_id: trait_did,
         substs: substs,
     }
 }
@@ -810,7 +812,7 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:RegionScope>(
                                             None);
                 ty::mk_closure(tcx, fn_decl)
             }
-            ast::TyUnboxedFn(_) => {
+            ast::TyUnboxedFn(..) => {
                 tcx.sess.span_err(ast_ty.span,
                                   "cannot use unboxed functions here");
                 ty::mk_err()
index 1805c18eaf10c9771011e12430b51e488b52e210..1e3ea095704bf167057eccb365205b7c4fee6015 100644 (file)
@@ -220,9 +220,15 @@ fn get_method_index(tcx: &ty::ctxt,
     // methods from them.
     let mut method_count = 0;
     ty::each_bound_trait_and_supertraits(tcx, &[subtrait], |bound_ref| {
-        if bound_ref.def_id == trait_ref.def_id { false }
-            else {
-            method_count += ty::trait_methods(tcx, bound_ref.def_id).len();
+        if bound_ref.def_id == trait_ref.def_id {
+            false
+        } else {
+            let trait_items = ty::trait_items(tcx, bound_ref.def_id);
+            for trait_item in trait_items.iter() {
+                match *trait_item {
+                    ty::MethodTraitItem(_) => method_count += 1,
+                }
+            }
             true
         }
     });
@@ -444,7 +450,7 @@ fn push_inherent_candidates(&mut self, self_ty: ty::t) {
                 },
                 ty_enum(did, _) |
                 ty_struct(did, _) |
-                ty_unboxed_closure(did) => {
+                ty_unboxed_closure(did, _) => {
                     if self.check_traits == CheckTraitsAndInherentMethods {
                         self.push_inherent_impl_candidates_for_type(did);
                     }
@@ -468,7 +474,7 @@ fn push_bound_candidates(&mut self, self_ty: ty::t, restrict_to: Option<DefId>)
                 ty_param(p) => {
                     self.push_inherent_candidates_from_param(self_ty, restrict_to, p);
                 }
-                ty_unboxed_closure(closure_did) => {
+                ty_unboxed_closure(closure_did, _) => {
                     self.push_unboxed_closure_call_candidates_if_applicable(
                         closure_did);
                 }
@@ -488,11 +494,13 @@ fn push_extension_candidate(&mut self, trait_did: DefId) {
         ty::populate_implementations_for_trait_if_necessary(self.tcx(), trait_did);
 
         // Look for explicit implementations.
-        let impl_methods = self.tcx().impl_methods.borrow();
+        let impl_items = self.tcx().impl_items.borrow();
         for impl_infos in self.tcx().trait_impls.borrow().find(&trait_did).iter() {
             for impl_did in impl_infos.borrow().iter() {
-                let methods = impl_methods.get(impl_did);
-                self.push_candidates_from_impl(*impl_did, methods.as_slice(), true);
+                let items = impl_items.get(impl_did);
+                self.push_candidates_from_impl(*impl_did,
+                                               items.as_slice(),
+                                               true);
             }
         }
     }
@@ -520,8 +528,11 @@ fn push_unboxed_closure_call_candidate_if_applicable(
             trait_did: DefId,
             closure_did: DefId,
             closure_function_type: &ClosureTy) {
-        let method =
-            ty::trait_methods(self.tcx(), trait_did).get(0).clone();
+        let trait_item = ty::trait_items(self.tcx(), trait_did).get(0)
+                                                               .clone();
+        let method = match trait_item {
+            ty::MethodTraitItem(method) => method,
+        };
 
         let vcx = self.fcx.vtable_context();
         let region_params =
@@ -531,8 +542,11 @@ fn push_unboxed_closure_call_candidate_if_applicable(
         let arguments_type = *closure_function_type.sig.inputs.get(0);
         let return_type = closure_function_type.sig.output;
 
+        let closure_region =
+            vcx.infcx.next_region_var(MiscVariable(self.span));
         let unboxed_closure_type = ty::mk_unboxed_closure(self.tcx(),
-                                                          closure_did);
+                                                          closure_did,
+                                                          closure_region);
         self.extension_candidates.push(Candidate {
             rcvr_match_condition:
                 RcvrMatchesIfSubtype(unboxed_closure_type),
@@ -548,39 +562,38 @@ fn push_unboxed_closure_call_candidate_if_applicable(
     fn push_unboxed_closure_call_candidates_if_applicable(
             &mut self,
             closure_did: DefId) {
-        // FIXME(pcwalton): Try `Fn` and `FnOnce` too.
-        let trait_did = match self.tcx().lang_items.fn_mut_trait() {
-            Some(trait_did) => trait_did,
-            None => return,
-        };
-
-        match self.tcx()
-                  .unboxed_closure_types
-                  .borrow()
-                  .find(&closure_did) {
-            None => {}  // Fall through to try inherited.
-            Some(closure_function_type) => {
-                self.push_unboxed_closure_call_candidate_if_applicable(
-                    trait_did,
-                    closure_did,
-                    closure_function_type);
-                return
+        let trait_dids = [
+            self.tcx().lang_items.fn_trait(),
+            self.tcx().lang_items.fn_mut_trait(),
+            self.tcx().lang_items.fn_once_trait()
+        ];
+        for optional_trait_did in trait_dids.iter() {
+            let trait_did = match *optional_trait_did {
+                Some(trait_did) => trait_did,
+                None => continue,
+            };
+
+            match self.tcx().unboxed_closures.borrow().find(&closure_did) {
+                None => {}  // Fall through to try inherited.
+                Some(closure) => {
+                    self.push_unboxed_closure_call_candidate_if_applicable(
+                        trait_did,
+                        closure_did,
+                        &closure.closure_type);
+                    return
+                }
             }
-        }
 
-        match self.fcx
-                  .inh
-                  .unboxed_closure_types
-                  .borrow()
-                  .find(&closure_did) {
-            Some(closure_function_type) => {
-                self.push_unboxed_closure_call_candidate_if_applicable(
-                    trait_did,
-                    closure_did,
-                    closure_function_type);
-                return
+            match self.fcx.inh.unboxed_closures.borrow().find(&closure_did) {
+                Some(closure) => {
+                    self.push_unboxed_closure_call_candidate_if_applicable(
+                        trait_did,
+                        closure_did,
+                        &closure.closure_type);
+                    return
+                }
+                None => {}
             }
-            None => {}
         }
 
         self.tcx().sess.bug("didn't find unboxed closure type in tcx map or \
@@ -699,14 +712,24 @@ fn push_inherent_candidates_from_bounds_inner(&mut self,
             let this_bound_idx = next_bound_idx;
             next_bound_idx += 1;
 
-            let trait_methods = ty::trait_methods(tcx, bound_trait_ref.def_id);
-            match trait_methods.iter().position(|m| {
-                m.explicit_self != ty::StaticExplicitSelfCategory &&
-                m.ident.name == self.m_name }) {
+            let trait_items = ty::trait_items(tcx, bound_trait_ref.def_id);
+            match trait_items.iter().position(|ti| {
+                match *ti {
+                    ty::MethodTraitItem(ref m) => {
+                        m.explicit_self != ty::StaticExplicitSelfCategory &&
+                        m.ident.name == self.m_name
+                    }
+                }
+            }) {
                 Some(pos) => {
-                    let method = trait_methods.get(pos).clone();
-
-                    match mk_cand(bound_trait_ref, method, pos, this_bound_idx) {
+                    let method = match *trait_items.get(pos) {
+                        ty::MethodTraitItem(ref method) => (*method).clone(),
+                    };
+
+                    match mk_cand(bound_trait_ref,
+                                  method,
+                                  pos,
+                                  this_bound_idx) {
                         Some(cand) => {
                             debug!("pushing inherent candidate for param: {}",
                                    cand.repr(self.tcx()));
@@ -731,18 +754,20 @@ fn push_inherent_impl_candidates_for_type(&mut self, did: DefId) {
         // metadata if necessary.
         ty::populate_implementations_for_type_if_necessary(self.tcx(), did);
 
-        let impl_methods = self.tcx().impl_methods.borrow();
+        let impl_items = self.tcx().impl_items.borrow();
         for impl_infos in self.tcx().inherent_impls.borrow().find(&did).iter() {
             for impl_did in impl_infos.borrow().iter() {
-                let methods = impl_methods.get(impl_did);
-                self.push_candidates_from_impl(*impl_did, methods.as_slice(), false);
+                let items = impl_items.get(impl_did);
+                self.push_candidates_from_impl(*impl_did,
+                                               items.as_slice(),
+                                               false);
             }
         }
     }
 
     fn push_candidates_from_impl(&mut self,
                                  impl_did: DefId,
-                                 impl_methods: &[DefId],
+                                 impl_items: &[ImplOrTraitItemId],
                                  is_extension: bool) {
         let did = if self.report_statics == ReportStaticMethods {
             // we only want to report each base trait once
@@ -760,13 +785,23 @@ fn push_candidates_from_impl(&mut self,
 
         debug!("push_candidates_from_impl: {} {}",
                token::get_name(self.m_name),
-               impl_methods.iter().map(|&did| ty::method(self.tcx(), did).ident)
-                                 .collect::<Vec<ast::Ident>>()
-                                 .repr(self.tcx()));
-
-        let method = match impl_methods.iter().map(|&did| ty::method(self.tcx(), did))
-                                              .find(|m| m.ident.name == self.m_name) {
-            Some(method) => method,
+               impl_items.iter()
+                         .map(|&did| {
+                             ty::impl_or_trait_item(self.tcx(),
+                                                    did.def_id()).ident()
+                         })
+                         .collect::<Vec<ast::Ident>>()
+                         .repr(self.tcx()));
+
+        let method = match impl_items.iter()
+                                     .map(|&did| {
+                                         ty::impl_or_trait_item(self.tcx(),
+                                                                did.def_id())
+                                     })
+                                     .find(|m| {
+                                         m.ident().name == self.m_name
+                                     }) {
+            Some(ty::MethodTraitItem(method)) => method,
             None => { return; } // No method with the right name.
         };
 
@@ -1484,9 +1519,16 @@ fn report_candidate(&self, idx: uint, origin: &MethodOrigin) {
                 let did = if self.report_statics == ReportStaticMethods {
                     // If we're reporting statics, we want to report the trait
                     // definition if possible, rather than an impl
-                    match ty::trait_method_of_method(self.tcx(), impl_did) {
-                        None => {debug!("(report candidate) No trait method found"); impl_did},
-                        Some(trait_did) => {debug!("(report candidate) Found trait ref"); trait_did}
+                    match ty::trait_item_of_item(self.tcx(), impl_did) {
+                        None => {
+                            debug!("(report candidate) No trait method \
+                                    found");
+                            impl_did
+                        }
+                        Some(MethodTraitItemId(trait_did)) => {
+                            debug!("(report candidate) Found trait ref");
+                            trait_did
+                        }
                     }
                 } else {
                     // If it is an instantiated default method, use the original
index aa38ff68f24e6c901ed3510b14dbf1a7a7fe824f..3403a51610cff082d618de0e22d5c566e020178e 100644 (file)
 use std::rc::Rc;
 use std::gc::Gc;
 use syntax::abi;
-use syntax::ast::{Provided, Required};
+use syntax::ast::{ProvidedMethod, RequiredMethod};
 use syntax::ast;
 use syntax::ast_map;
 use syntax::ast_util::{local_def, PostExpansionMethod};
@@ -168,7 +168,7 @@ pub struct Inherited<'a> {
     method_map: MethodMap,
     vtable_map: vtable_map,
     upvar_borrow_map: RefCell<ty::UpvarBorrowMap>,
-    unboxed_closure_types: RefCell<DefIdMap<ty::ClosureTy>>,
+    unboxed_closures: RefCell<DefIdMap<ty::UnboxedClosure>>,
 }
 
 /// When type-checking an expression, we propagate downward
@@ -275,7 +275,7 @@ fn new(tcx: &'a ty::ctxt,
             method_map: RefCell::new(FnvHashMap::new()),
             vtable_map: RefCell::new(FnvHashMap::new()),
             upvar_borrow_map: RefCell::new(HashMap::new()),
-            unboxed_closure_types: RefCell::new(DefIdMap::new()),
+            unboxed_closures: RefCell::new(DefIdMap::new()),
         }
     }
 }
@@ -680,23 +680,27 @@ pub fn check_item(ccx: &CrateCtxt, it: &ast::Item) {
 
         check_bare_fn(ccx, &**decl, &**body, it.id, fn_pty.ty, param_env);
       }
-      ast::ItemImpl(_, ref opt_trait_ref, _, ref ms) => {
+      ast::ItemImpl(_, ref opt_trait_ref, _, ref impl_items) => {
         debug!("ItemImpl {} with id {}", token::get_ident(it.ident), it.id);
 
         let impl_pty = ty::lookup_item_type(ccx.tcx, ast_util::local_def(it.id));
-        for m in ms.iter() {
-            check_method_body(ccx, &impl_pty.generics, &**m);
+        for impl_item in impl_items.iter() {
+            match *impl_item {
+                ast::MethodImplItem(m) => {
+                    check_method_body(ccx, &impl_pty.generics, &*m);
+                }
+            }
         }
 
         match *opt_trait_ref {
             Some(ref ast_trait_ref) => {
                 let impl_trait_ref =
                     ty::node_id_to_trait_ref(ccx.tcx, ast_trait_ref.ref_id);
-                check_impl_methods_against_trait(ccx,
-                                             it.span,
-                                             ast_trait_ref,
-                                             &*impl_trait_ref,
-                                             ms.as_slice());
+                check_impl_items_against_trait(ccx,
+                                               it.span,
+                                               ast_trait_ref,
+                                               &*impl_trait_ref,
+                                               impl_items.as_slice());
                 vtable::resolve_impl(ccx.tcx, it, &impl_pty.generics, &*impl_trait_ref);
             }
             None => { }
@@ -707,11 +711,11 @@ pub fn check_item(ccx: &CrateCtxt, it: &ast::Item) {
         let trait_def = ty::lookup_trait_def(ccx.tcx, local_def(it.id));
         for trait_method in (*trait_methods).iter() {
             match *trait_method {
-                Required(..) => {
+                RequiredMethod(..) => {
                     // Nothing to do, since required methods don't have
                     // bodies to check.
                 }
-                Provided(m) => {
+                ProvidedMethod(m) => {
                     check_method_body(ccx, &trait_def.generics, &*m);
                 }
             }
@@ -770,7 +774,9 @@ fn check_method_body(ccx: &CrateCtxt,
             item_generics.repr(ccx.tcx),
             method.id);
     let method_def_id = local_def(method.id);
-    let method_ty = ty::method(ccx.tcx, method_def_id);
+    let method_ty = match ty::impl_or_trait_item(ccx.tcx, method_def_id) {
+        ty::MethodTraitItem(ref method_ty) => (*method_ty).clone(),
+    };
     let method_generics = &method_ty.generics;
 
     let param_env = ty::construct_parameter_environment(ccx.tcx,
@@ -787,43 +793,58 @@ fn check_method_body(ccx: &CrateCtxt,
                   param_env);
 }
 
-fn check_impl_methods_against_trait(ccx: &CrateCtxt,
-                                    impl_span: Span,
-                                    ast_trait_ref: &ast::TraitRef,
-                                    impl_trait_ref: &ty::TraitRef,
-                                    impl_methods: &[Gc<ast::Method>]) {
+fn check_impl_items_against_trait(ccx: &CrateCtxt,
+                                  impl_span: Span,
+                                  ast_trait_ref: &ast::TraitRef,
+                                  impl_trait_ref: &ty::TraitRef,
+                                  impl_items: &[ast::ImplItem]) {
     // Locate trait methods
     let tcx = ccx.tcx;
-    let trait_methods = ty::trait_methods(tcx, impl_trait_ref.def_id);
+    let trait_items = ty::trait_items(tcx, impl_trait_ref.def_id);
 
     // Check existing impl methods to see if they are both present in trait
     // and compatible with trait signature
-    for impl_method in impl_methods.iter() {
-        let impl_method_def_id = local_def(impl_method.id);
-        let impl_method_ty = ty::method(ccx.tcx, impl_method_def_id);
-
-        // If this is an impl of a trait method, find the corresponding
-        // method definition in the trait.
-        let opt_trait_method_ty =
-            trait_methods.iter().
-            find(|tm| tm.ident.name == impl_method_ty.ident.name);
-        match opt_trait_method_ty {
-            Some(trait_method_ty) => {
-                compare_impl_method(ccx.tcx,
-                                    &*impl_method_ty,
-                                    impl_method.span,
-                                    impl_method.pe_body().id,
-                                    &**trait_method_ty,
-                                    &impl_trait_ref.substs);
-            }
-            None => {
-                // This is span_bug as it should have already been caught in resolve.
-                tcx.sess.span_bug(
-                    impl_method.span,
-                    format!(
-                        "method `{}` is not a member of trait `{}`",
-                        token::get_ident(impl_method_ty.ident),
-                        pprust::path_to_string(&ast_trait_ref.path)).as_slice());
+    for impl_item in impl_items.iter() {
+        match *impl_item {
+            ast::MethodImplItem(impl_method) => {
+                let impl_method_def_id = local_def(impl_method.id);
+                let impl_item_ty = ty::impl_or_trait_item(ccx.tcx,
+                                                          impl_method_def_id);
+
+                // If this is an impl of a trait method, find the
+                // corresponding method definition in the trait.
+                let opt_trait_method_ty =
+                    trait_items.iter()
+                               .find(|ti| {
+                                   ti.ident().name == impl_item_ty.ident()
+                                                                  .name
+                               });
+                match opt_trait_method_ty {
+                    Some(trait_method_ty) => {
+                        match (trait_method_ty, &impl_item_ty) {
+                            (&ty::MethodTraitItem(ref trait_method_ty),
+                             &ty::MethodTraitItem(ref impl_method_ty)) => {
+                                compare_impl_method(ccx.tcx,
+                                                    &**impl_method_ty,
+                                                    impl_method.span,
+                                                    impl_method.pe_body().id,
+                                                    &**trait_method_ty,
+                                                    &impl_trait_ref.substs);
+                            }
+                        }
+                    }
+                    None => {
+                        // This is span_bug as it should have already been
+                        // caught in resolve.
+                        tcx.sess.span_bug(
+                            impl_method.span,
+                            format!(
+                                "method `{}` is not a member of trait `{}`",
+                                token::get_ident(impl_item_ty.ident()),
+                                pprust::path_to_string(
+                                    &ast_trait_ref.path)).as_slice());
+                    }
+                }
             }
         }
     }
@@ -832,16 +853,26 @@ fn check_impl_methods_against_trait(ccx: &CrateCtxt,
     let provided_methods = ty::provided_trait_methods(tcx,
                                                       impl_trait_ref.def_id);
     let mut missing_methods = Vec::new();
-    for trait_method in trait_methods.iter() {
-        let is_implemented =
-            impl_methods.iter().any(
-                |m| m.pe_ident().name == trait_method.ident.name);
-        let is_provided =
-            provided_methods.iter().any(
-                |m| m.ident.name == trait_method.ident.name);
-        if !is_implemented && !is_provided {
-            missing_methods.push(
-                format!("`{}`", token::get_ident(trait_method.ident)));
+    for trait_item in trait_items.iter() {
+        match *trait_item {
+            ty::MethodTraitItem(ref trait_method) => {
+                let is_implemented =
+                    impl_items.iter().any(|ii| {
+                        match *ii {
+                            ast::MethodImplItem(m) => {
+                                m.pe_ident().name == trait_method.ident.name
+                            }
+                        }
+                    });
+                let is_provided =
+                    provided_methods.iter().any(
+                        |m| m.ident.name == trait_method.ident.name);
+                if !is_implemented && !is_provided {
+                    missing_methods.push(
+                        format!("`{}`",
+                                token::get_ident(trait_method.ident)));
+                }
+            }
         }
     }
 
@@ -853,7 +884,7 @@ fn check_impl_methods_against_trait(ccx: &CrateCtxt,
 }
 
 /**
- * Checks that a method from an impl/class conforms to the signature of
+ * Checks that a method from an impl conforms to the signature of
  * the same method as declared in the trait.
  *
  * # Parameters
@@ -1271,7 +1302,7 @@ pub fn vtable_context<'a>(&'a self) -> VtableContext<'a> {
         VtableContext {
             infcx: self.infcx(),
             param_env: &self.inh.param_env,
-            unboxed_closure_types: &self.inh.unboxed_closure_types,
+            unboxed_closures: &self.inh.unboxed_closures,
         }
     }
 }
@@ -2618,6 +2649,7 @@ fn check_user_unop(fcx: &FnCtxt,
 
     fn check_unboxed_closure(fcx: &FnCtxt,
                              expr: &ast::Expr,
+                             kind: ast::UnboxedClosureKind,
                              decl: &ast::FnDecl,
                              body: ast::P<ast::Block>) {
         // The `RegionTraitStore` is a lie, but we ignore it so it doesn't
@@ -2635,8 +2667,16 @@ fn check_unboxed_closure(fcx: &FnCtxt,
             abi::RustCall,
             None);
 
+        let region = match fcx.infcx().anon_regions(expr.span, 1) {
+            Err(_) => {
+                fcx.ccx.tcx.sess.span_bug(expr.span,
+                                          "can't make anon regions here?!")
+            }
+            Ok(regions) => *regions.get(0),
+        };
         let closure_type = ty::mk_unboxed_closure(fcx.ccx.tcx,
-                                                  local_def(expr.id));
+                                                  local_def(expr.id),
+                                                  region);
         fcx.write_ty(expr.id, closure_type);
 
         check_fn(fcx.ccx,
@@ -2648,13 +2688,24 @@ fn check_unboxed_closure(fcx: &FnCtxt,
                  fcx.inh);
 
         // Tuple up the arguments and insert the resulting function type into
-        // the `unboxed_closure_types` table.
+        // the `unboxed_closures` table.
         fn_ty.sig.inputs = vec![ty::mk_tup(fcx.tcx(), fn_ty.sig.inputs)];
 
+        let kind = match kind {
+            ast::FnUnboxedClosureKind => ty::FnUnboxedClosureKind,
+            ast::FnMutUnboxedClosureKind => ty::FnMutUnboxedClosureKind,
+            ast::FnOnceUnboxedClosureKind => ty::FnOnceUnboxedClosureKind,
+        };
+
+        let unboxed_closure = ty::UnboxedClosure {
+            closure_type: fn_ty,
+            kind: kind,
+        };
+
         fcx.inh
-           .unboxed_closure_types
+           .unboxed_closures
            .borrow_mut()
-           .insert(local_def(expr.id), fn_ty);
+           .insert(local_def(expr.id), unboxed_closure);
     }
 
     fn check_expr_fn(fcx: &FnCtxt,
@@ -3390,7 +3441,7 @@ fn check_fn_for_vec_elements_expected(fcx: &FnCtxt,
       ast::ExprMatch(ref discrim, ref arms) => {
         _match::check_match(fcx, expr, &**discrim, arms.as_slice());
       }
-      ast::ExprFnBlock(ref decl, ref body) => {
+      ast::ExprFnBlock(_, ref decl, ref body) => {
         let region = astconv::opt_ast_region_to_region(fcx,
                                                        fcx.infcx(),
                                                        expr.span,
@@ -3402,9 +3453,10 @@ fn check_fn_for_vec_elements_expected(fcx: &FnCtxt,
                       body.clone(),
                       expected);
       }
-      ast::ExprUnboxedFn(ref decl, ref body) => {
+      ast::ExprUnboxedFn(_, kind, ref decl, ref body) => {
         check_unboxed_closure(fcx,
                               expr,
+                              kind,
                               &**decl,
                               *body);
       }
index d0431de81a359543d4daa30baca6952bacd0024d..0acf6e91831641a71bfa10e095e3c2189992e0d8 100644 (file)
@@ -132,7 +132,7 @@ fn get_i(x: &'a Bar) -> &'a int {
 use middle::typeck::infer;
 use middle::typeck::MethodCall;
 use middle::pat_util;
-use util::nodemap::NodeMap;
+use util::nodemap::{DefIdMap, NodeMap};
 use util::ppaux::{ty_to_string, region_to_string, Repr};
 
 use syntax::ast;
@@ -290,6 +290,16 @@ fn temporary_scope(&self, id: ast::NodeId) -> Option<ast::NodeId> {
     fn upvar_borrow(&self, id: ty::UpvarId) -> ty::UpvarBorrow {
         self.fcx.inh.upvar_borrow_map.borrow().get_copy(&id)
     }
+
+    fn capture_mode(&self, closure_expr_id: ast::NodeId)
+                    -> freevars::CaptureMode {
+        self.tcx().capture_modes.borrow().get_copy(&closure_expr_id)
+    }
+
+    fn unboxed_closures<'a>(&'a self)
+                        -> &'a RefCell<DefIdMap<ty::UnboxedClosure>> {
+        &self.fcx.inh.unboxed_closures
+    }
 }
 
 pub fn regionck_expr(fcx: &FnCtxt, e: &ast::Expr) {
@@ -587,9 +597,9 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
             visit::walk_expr(rcx, expr, ());
         }
 
-        ast::ExprFnBlock(_, ref body) |
+        ast::ExprFnBlock(_, _, ref body) |
         ast::ExprProc(_, ref body) |
-        ast::ExprUnboxedFn(_, ref body) => {
+        ast::ExprUnboxedFn(_, _, _, ref body) => {
             check_expr_fn_block(rcx, expr, &**body);
         }
 
@@ -655,6 +665,17 @@ fn check_expr_fn_block(rcx: &mut Rcx,
                 }
             });
         }
+        ty::ty_unboxed_closure(_, region) => {
+            freevars::with_freevars(tcx, expr.id, |freevars| {
+                // No free variables means that there is no environment and
+                // hence the closure has static lifetime. Otherwise, the
+                // closure must not outlive the variables it closes over
+                // by-reference.
+                if !freevars.is_empty() {
+                    constrain_free_variables(rcx, region, expr, freevars);
+                }
+            })
+        }
         _ => ()
     }
 
index 565b88b74939b9505e6f42a02a6bf9f30684e7a4..850d5c5a8f07d03a110608fdd7db132f8fd5abcd 100644 (file)
@@ -71,7 +71,7 @@
 pub struct VtableContext<'a> {
     pub infcx: &'a infer::InferCtxt<'a>,
     pub param_env: &'a ty::ParameterEnvironment,
-    pub unboxed_closure_types: &'a RefCell<DefIdMap<ty::ClosureTy>>,
+    pub unboxed_closures: &'a RefCell<DefIdMap<ty::UnboxedClosure>>,
 }
 
 impl<'a> VtableContext<'a> {
@@ -309,31 +309,42 @@ fn search_for_unboxed_closure_vtable(vcx: &VtableContext,
                                      -> Option<vtable_origin> {
     let tcx = vcx.tcx();
     let closure_def_id = match ty::get(ty).sty {
-        ty::ty_unboxed_closure(closure_def_id) => closure_def_id,
+        ty::ty_unboxed_closure(closure_def_id, _) => closure_def_id,
         _ => return None,
     };
 
     let fn_traits = [
-        tcx.lang_items.fn_trait(),
-        tcx.lang_items.fn_mut_trait(),
-        tcx.lang_items.fn_once_trait()
+        (ty::FnUnboxedClosureKind, tcx.lang_items.fn_trait()),
+        (ty::FnMutUnboxedClosureKind, tcx.lang_items.fn_mut_trait()),
+        (ty::FnOnceUnboxedClosureKind, tcx.lang_items.fn_once_trait()),
     ];
-    for fn_trait in fn_traits.iter() {
-        match *fn_trait {
-            Some(ref fn_trait) if *fn_trait == trait_ref.def_id => {}
+    for tuple in fn_traits.iter() {
+        let kind = match tuple {
+            &(kind, Some(ref fn_trait)) if *fn_trait == trait_ref.def_id => {
+                kind
+            }
             _ => continue,
         };
 
         // Check to see whether the argument and return types match.
-        let unboxed_closure_types = tcx.unboxed_closure_types.borrow();
-        let closure_type = match unboxed_closure_types.find(&closure_def_id) {
-            Some(closure_type) => (*closure_type).clone(),
+        let unboxed_closures = tcx.unboxed_closures.borrow();
+        let closure_type = match unboxed_closures.find(&closure_def_id) {
+            Some(closure) => {
+                if closure.kind != kind {
+                    continue
+                }
+                closure.closure_type.clone()
+            }
             None => {
                 // Try the inherited unboxed closure type map.
-                let unboxed_closure_types = vcx.unboxed_closure_types
-                                               .borrow();
-                match unboxed_closure_types.find(&closure_def_id) {
-                    Some(closure_type) => (*closure_type).clone(),
+                let unboxed_closures = vcx.unboxed_closures.borrow();
+                match unboxed_closures.find(&closure_def_id) {
+                    Some(closure) => {
+                        if closure.kind != kind {
+                            continue
+                        }
+                        closure.closure_type.clone()
+                    }
                     None => {
                         tcx.sess.span_bug(span,
                                           "didn't find unboxed closure type \
@@ -881,11 +892,11 @@ pub fn resolve_impl(tcx: &ty::ctxt,
     debug!("impl_trait_ref={}", impl_trait_ref.repr(tcx));
 
     let infcx = &infer::new_infer_ctxt(tcx);
-    let unboxed_closure_types = RefCell::new(DefIdMap::new());
+    let unboxed_closures = RefCell::new(DefIdMap::new());
     let vcx = VtableContext {
         infcx: infcx,
         param_env: &param_env,
-        unboxed_closure_types: &unboxed_closure_types,
+        unboxed_closures: &unboxed_closures,
     };
 
     // Resolve the vtables for the trait reference on the impl.  This
@@ -934,11 +945,11 @@ pub fn resolve_impl(tcx: &ty::ctxt,
 pub fn trans_resolve_method(tcx: &ty::ctxt, id: ast::NodeId,
                             substs: &subst::Substs) -> vtable_res {
     let generics = ty::lookup_item_type(tcx, ast_util::local_def(id)).generics;
-    let unboxed_closure_types = RefCell::new(DefIdMap::new());
+    let unboxed_closures = RefCell::new(DefIdMap::new());
     let vcx = VtableContext {
         infcx: &infer::new_infer_ctxt(tcx),
         param_env: &ty::construct_parameter_environment(tcx, &ty::Generics::empty(), id),
-        unboxed_closure_types: &unboxed_closure_types,
+        unboxed_closures: &unboxed_closures,
     };
 
     lookup_vtables(&vcx,
index d94ac103ceb731ed37f18d15a5e80f5c5c68fcfb..892a62249ac3b5aa47b8e4778aca710783a3ca96 100644 (file)
@@ -43,7 +43,7 @@ pub fn resolve_type_vars_in_expr(fcx: &FnCtxt, e: &ast::Expr) {
     let mut wbcx = WritebackCx::new(fcx);
     wbcx.visit_expr(e, ());
     wbcx.visit_upvar_borrow_map();
-    wbcx.visit_unboxed_closure_types();
+    wbcx.visit_unboxed_closures();
 }
 
 pub fn resolve_type_vars_in_fn(fcx: &FnCtxt,
@@ -62,7 +62,7 @@ pub fn resolve_type_vars_in_fn(fcx: &FnCtxt,
         }
     }
     wbcx.visit_upvar_borrow_map();
-    wbcx.visit_unboxed_closure_types();
+    wbcx.visit_unboxed_closures();
 }
 
 pub fn resolve_impl_res(infcx: &infer::InferCtxt,
@@ -132,9 +132,9 @@ fn visit_expr(&mut self, e:&ast::Expr, _: ()) {
                                     MethodCall::expr(e.id));
 
         match e.node {
-            ast::ExprFnBlock(ref decl, _) |
+            ast::ExprFnBlock(_, ref decl, _) |
             ast::ExprProc(ref decl, _) |
-            ast::ExprUnboxedFn(ref decl, _) => {
+            ast::ExprUnboxedFn(_, _, ref decl, _) => {
                 for input in decl.inputs.iter() {
                     let _ = self.visit_node_id(ResolvingExpr(e.span),
                                                input.id);
@@ -211,23 +211,27 @@ fn visit_upvar_borrow_map(&self) {
         }
     }
 
-    fn visit_unboxed_closure_types(&self) {
+    fn visit_unboxed_closures(&self) {
         if self.fcx.writeback_errors.get() {
             return
         }
 
-        for (def_id, closure_ty) in self.fcx
-                                        .inh
-                                        .unboxed_closure_types
-                                        .borrow()
-                                        .iter() {
-            let closure_ty = self.resolve(closure_ty,
+        for (def_id, unboxed_closure) in self.fcx
+                                             .inh
+                                             .unboxed_closures
+                                             .borrow()
+                                             .iter() {
+            let closure_ty = self.resolve(&unboxed_closure.closure_type,
                                           ResolvingUnboxedClosure(*def_id));
+            let unboxed_closure = ty::UnboxedClosure {
+                closure_type: closure_ty,
+                kind: unboxed_closure.kind,
+            };
             self.fcx
                 .tcx()
-                .unboxed_closure_types
+                .unboxed_closures
                 .borrow_mut()
-                .insert(*def_id, closure_ty);
+                .insert(*def_id, unboxed_closure);
         }
     }
 
index fdf9125e6e14d2cca5a46993ff394bf9d93569c8..3dee787b6c9064edea7f3507a25dd933427dcf7e 100644 (file)
@@ -20,7 +20,8 @@
 use middle::subst;
 use middle::subst::{Substs};
 use middle::ty::get;
-use middle::ty::{ImplContainer, lookup_item_type};
+use middle::ty::{ImplContainer, ImplOrTraitItemId, MethodTraitItemId};
+use middle::ty::{lookup_item_type};
 use middle::ty::{t, ty_bool, ty_char, ty_bot, ty_box, ty_enum, ty_err};
 use middle::ty::{ty_str, ty_vec, ty_float, ty_infer, ty_int, ty_nil};
 use middle::ty::{ty_param, Polytype, ty_ptr};
@@ -109,7 +110,7 @@ fn type_is_defined_in_local_crate(tcx: &ty::ctxt, original_type: t) -> bool {
         match get(t).sty {
             ty_enum(def_id, _) |
             ty_struct(def_id, _) |
-            ty_unboxed_closure(def_id) => {
+            ty_unboxed_closure(def_id, _) => {
                 if def_id.krate == ast::LOCAL_CRATE {
                     found_nominal = true;
                 }
@@ -153,7 +154,7 @@ fn get_base_type_def_id(inference_context: &InferCtxt,
             match get(base_type).sty {
                 ty_enum(def_id, _) |
                 ty_struct(def_id, _) |
-                ty_unboxed_closure(def_id) => {
+                ty_unboxed_closure(def_id, _) => {
                     Some(def_id)
                 }
                 ty_rptr(_, ty::mt {ty, ..}) | ty_uniq(ty) => match ty::get(ty).sty {
@@ -308,7 +309,7 @@ fn check_implementation(&self, item: &Item,
             }
         }
 
-        let impl_methods = self.create_impl_from_item(item);
+        let impl_items = self.create_impl_from_item(item);
 
         for associated_trait in associated_traits.iter() {
             let trait_ref = ty::node_id_to_trait_ref(
@@ -337,16 +338,17 @@ fn check_implementation(&self, item: &Item,
             }
         }
 
-        tcx.impl_methods.borrow_mut().insert(impl_did, impl_methods);
+        tcx.impl_items.borrow_mut().insert(impl_did, impl_items);
     }
 
     // Creates default method IDs and performs type substitutions for an impl
     // and trait pair. Then, for each provided method in the trait, inserts a
     // `ProvidedMethodInfo` instance into the `provided_method_sources` map.
-    fn instantiate_default_methods(&self,
-                                   impl_id: DefId,
-                                   trait_ref: &ty::TraitRef,
-                                   all_methods: &mut Vec<DefId>) {
+    fn instantiate_default_methods(
+            &self,
+            impl_id: DefId,
+            trait_ref: &ty::TraitRef,
+            all_impl_items: &mut Vec<ImplOrTraitItemId>) {
         let tcx = self.crate_context.tcx;
         debug!("instantiate_default_methods(impl_id={:?}, trait_ref={})",
                impl_id, trait_ref.repr(tcx));
@@ -373,7 +375,7 @@ fn instantiate_default_methods(&self,
                     Some(trait_method.def_id)));
 
             debug!("new_method_ty={}", new_method_ty.repr(tcx));
-            all_methods.push(new_did);
+            all_impl_items.push(MethodTraitItemId(new_did));
 
             // construct the polytype for the method based on the
             // method_ty.  it will have all the generics from the
@@ -385,7 +387,9 @@ fn instantiate_default_methods(&self,
             debug!("new_polytype={}", new_polytype.repr(tcx));
 
             tcx.tcache.borrow_mut().insert(new_did, new_polytype);
-            tcx.methods.borrow_mut().insert(new_did, new_method_ty);
+            tcx.impl_or_trait_items
+               .borrow_mut()
+               .insert(new_did, ty::MethodTraitItem(new_method_ty));
 
             // Pair the new synthesized ID up with the
             // ID of the method.
@@ -576,13 +580,20 @@ fn ast_type_is_defined_in_local_crate(&self, original_type: &ast::Ty) -> bool {
         }
     }
 
-    // Converts an implementation in the AST to a vector of methods.
-    fn create_impl_from_item(&self, item: &Item) -> Vec<DefId> {
+    // Converts an implementation in the AST to a vector of items.
+    fn create_impl_from_item(&self, item: &Item) -> Vec<ImplOrTraitItemId> {
         match item.node {
-            ItemImpl(_, ref trait_refs, _, ref ast_methods) => {
-                let mut methods: Vec<DefId> = ast_methods.iter().map(|ast_method| {
-                    local_def(ast_method.id)
-                }).collect();
+            ItemImpl(_, ref trait_refs, _, ref ast_items) => {
+                let mut items: Vec<ImplOrTraitItemId> =
+                        ast_items.iter()
+                                 .map(|ast_item| {
+                            match *ast_item {
+                                ast::MethodImplItem(ast_method) => {
+                                    MethodTraitItemId(
+                                        local_def(ast_method.id))
+                                }
+                            }
+                        }).collect();
 
                 for trait_ref in trait_refs.iter() {
                     let ty_trait_ref = ty::node_id_to_trait_ref(
@@ -591,10 +602,10 @@ fn create_impl_from_item(&self, item: &Item) -> Vec<DefId> {
 
                     self.instantiate_default_methods(local_def(item.id),
                                                      &*ty_trait_ref,
-                                                     &mut methods);
+                                                     &mut items);
                 }
 
-                methods
+                items
             }
             _ => {
                 self.crate_context.tcx.sess.span_bug(item.span,
@@ -614,7 +625,8 @@ fn add_external_impl(&self,
                          impls_seen: &mut HashSet<DefId>,
                          impl_def_id: DefId) {
         let tcx = self.crate_context.tcx;
-        let methods = csearch::get_impl_methods(&tcx.sess.cstore, impl_def_id);
+        let impl_items = csearch::get_impl_items(&tcx.sess.cstore,
+                                                 impl_def_id);
 
         // Make sure we don't visit the same implementation multiple times.
         if !impls_seen.insert(impl_def_id) {
@@ -629,20 +641,27 @@ fn add_external_impl(&self,
         // Do a sanity check.
         assert!(associated_traits.is_some());
 
-        // Record all the trait methods.
+        // Record all the trait items.
         for trait_ref in associated_traits.iter() {
             self.add_trait_impl(trait_ref.def_id, impl_def_id);
         }
 
         // For any methods that use a default implementation, add them to
         // the map. This is a bit unfortunate.
-        for &method_def_id in methods.iter() {
-            for &source in ty::method(tcx, method_def_id).provided_source.iter() {
-                tcx.provided_method_sources.borrow_mut().insert(method_def_id, source);
+        for item_def_id in impl_items.iter() {
+            let impl_item = ty::impl_or_trait_item(tcx, item_def_id.def_id());
+            match impl_item {
+                ty::MethodTraitItem(ref method) => {
+                    for &source in method.provided_source.iter() {
+                        tcx.provided_method_sources
+                           .borrow_mut()
+                           .insert(item_def_id.def_id(), source);
+                    }
+                }
             }
         }
 
-        tcx.impl_methods.borrow_mut().insert(impl_def_id, methods);
+        tcx.impl_items.borrow_mut().insert(impl_def_id, impl_items);
     }
 
     // Adds implementations and traits from external crates to the coherence
@@ -669,28 +688,31 @@ fn populate_destructor_table(&self) {
             Some(id) => id, None => { return }
         };
 
-        let impl_methods = tcx.impl_methods.borrow();
+        let impl_items = tcx.impl_items.borrow();
         let trait_impls = match tcx.trait_impls.borrow().find_copy(&drop_trait) {
             None => return, // No types with (new-style) dtors present.
             Some(found_impls) => found_impls
         };
 
         for &impl_did in trait_impls.borrow().iter() {
-            let methods = impl_methods.get(&impl_did);
-            if methods.len() < 1 {
+            let items = impl_items.get(&impl_did);
+            if items.len() < 1 {
                 // We'll error out later. For now, just don't ICE.
                 continue;
             }
-            let method_def_id = *methods.get(0);
+            let method_def_id = *items.get(0);
 
             let self_type = self.get_self_type_for_implementation(impl_did);
             match ty::get(self_type.ty).sty {
                 ty::ty_enum(type_def_id, _) |
                 ty::ty_struct(type_def_id, _) |
-                ty::ty_unboxed_closure(type_def_id) => {
-                    tcx.destructor_for_type.borrow_mut().insert(type_def_id,
-                                                                method_def_id);
-                    tcx.destructors.borrow_mut().insert(method_def_id);
+                ty::ty_unboxed_closure(type_def_id, _) => {
+                    tcx.destructor_for_type
+                       .borrow_mut()
+                       .insert(type_def_id, method_def_id.def_id());
+                    tcx.destructors
+                       .borrow_mut()
+                       .insert(method_def_id.def_id());
                 }
                 _ => {
                     // Destructors only work on nominal types.
index a81c6344cc9c6014002af35656940c1511cbd1d6..0c5d58ae930b694f83b62e9ecde5352b838028d6 100644 (file)
@@ -37,7 +37,7 @@
 use middle::resolve_lifetime;
 use middle::subst;
 use middle::subst::{Substs};
-use middle::ty::{ImplContainer, MethodContainer, TraitContainer};
+use middle::ty::{ImplContainer, ImplOrTraitItemContainer, TraitContainer};
 use middle::ty::{Polytype};
 use middle::ty;
 use middle::ty_fold::TypeFolder;
@@ -200,64 +200,74 @@ pub fn ensure_trait_methods(ccx: &CrateCtxt,
     match tcx.map.get(trait_id) {
         ast_map::NodeItem(item) => {
             match item.node {
-                ast::ItemTrait(_, _, _, ref ms) => {
+                ast::ItemTrait(_, _, _, ref trait_items) => {
                     // For each method, construct a suitable ty::Method and
-                    // store it into the `tcx.methods` table:
-                    for m in ms.iter() {
-                        let ty_method = Rc::new(match m {
-                            &ast::Required(ref m) => {
-                                ty_method_of_trait_method(
-                                    ccx,
-                                    trait_id,
-                                    &trait_def.generics,
-                                    &m.id,
-                                    &m.ident,
-                                    &m.explicit_self,
-                                    m.abi,
-                                    &m.generics,
-                                    &m.fn_style,
-                                    &*m.decl)
-                            }
+                    // store it into the `tcx.impl_or_trait_items` table:
+                    for trait_item in trait_items.iter() {
+                        match *trait_item {
+                            ast::RequiredMethod(_) |
+                            ast::ProvidedMethod(_) => {
+                                let ty_method = Rc::new(match *trait_item {
+                                    ast::RequiredMethod(ref m) => {
+                                        ty_method_of_trait_method(
+                                            ccx,
+                                            trait_id,
+                                            &trait_def.generics,
+                                            &m.id,
+                                            &m.ident,
+                                            &m.explicit_self,
+                                            m.abi,
+                                            &m.generics,
+                                            &m.fn_style,
+                                            &*m.decl)
+                                    }
+                                    ast::ProvidedMethod(ref m) => {
+                                        ty_method_of_trait_method(
+                                            ccx,
+                                            trait_id,
+                                            &trait_def.generics,
+                                            &m.id,
+                                            &m.pe_ident(),
+                                            m.pe_explicit_self(),
+                                            m.pe_abi(),
+                                            m.pe_generics(),
+                                            &m.pe_fn_style(),
+                                            &*m.pe_fn_decl())
+                                    }
+                                });
 
-                            &ast::Provided(ref m) => {
-                                ty_method_of_trait_method(
-                                    ccx,
-                                    trait_id,
-                                    &trait_def.generics,
-                                    &m.id,
-                                    &m.pe_ident(),
-                                    m.pe_explicit_self(),
-                                    m.pe_abi(),
-                                    m.pe_generics(),
-                                    &m.pe_fn_style(),
-                                    &*m.pe_fn_decl())
-                            }
-                        });
+                                if ty_method.explicit_self ==
+                                        ty::StaticExplicitSelfCategory {
+                                    make_static_method_ty(ccx, &*ty_method);
+                                }
 
-                        if ty_method.explicit_self ==
-                                ty::StaticExplicitSelfCategory {
-                            make_static_method_ty(ccx, &*ty_method);
+                                tcx.impl_or_trait_items
+                                   .borrow_mut()
+                                   .insert(ty_method.def_id,
+                                           ty::MethodTraitItem(ty_method));
+                            }
                         }
-
-                        tcx.methods.borrow_mut().insert(ty_method.def_id,
-                                                        ty_method);
                     }
 
                     // Add an entry mapping
-                    let method_def_ids = Rc::new(ms.iter().map(|m| {
-                        match m {
-                            &ast::Required(ref ty_method) => {
-                                local_def(ty_method.id)
+                    let trait_item_def_ids =
+                        Rc::new(trait_items.iter()
+                                           .map(|ti| {
+                            match *ti {
+                                ast::RequiredMethod(ref ty_method) => {
+                                    ty::MethodTraitItemId(local_def(
+                                            ty_method.id))
+                                }
+                                ast::ProvidedMethod(ref method) => {
+                                    ty::MethodTraitItemId(local_def(
+                                            method.id))
+                                }
                             }
-                            &ast::Provided(ref method) => {
-                                local_def(method.id)
-                            }
-                        }
-                    }).collect());
+                        }).collect());
 
                     let trait_def_id = local_def(trait_id);
-                    tcx.trait_method_def_ids.borrow_mut()
-                        .insert(trait_def_id, method_def_ids);
+                    tcx.trait_item_def_ids.borrow_mut()
+                        .insert(trait_def_id, trait_item_def_ids);
                 }
                 _ => {} // Ignore things that aren't traits.
             }
@@ -346,12 +356,11 @@ pub fn convert_field(ccx: &CrateCtxt,
 }
 
 fn convert_methods(ccx: &CrateCtxt,
-                   container: MethodContainer,
+                   container: ImplOrTraitItemContainer,
                    ms: &[Gc<ast::Method>],
                    untransformed_rcvr_ty: ty::t,
                    rcvr_ty_generics: &ty::Generics,
-                   rcvr_visibility: ast::Visibility)
-{
+                   rcvr_visibility: ast::Visibility) {
     let tcx = ccx.tcx;
     let mut seen_methods = HashSet::new();
     for m in ms.iter() {
@@ -379,11 +388,13 @@ fn convert_methods(ccx: &CrateCtxt,
 
         write_ty_to_tcx(tcx, m.id, fty);
 
-        tcx.methods.borrow_mut().insert(mty.def_id, mty);
+        tcx.impl_or_trait_items
+           .borrow_mut()
+           .insert(mty.def_id, ty::MethodTraitItem(mty));
     }
 
     fn ty_of_method(ccx: &CrateCtxt,
-                    container: MethodContainer,
+                    container: ImplOrTraitItemContainer,
                     m: &ast::Method,
                     untransformed_rcvr_ty: ty::t,
                     rcvr_ty_generics: &ty::Generics,
@@ -459,7 +470,10 @@ pub fn convert(ccx: &CrateCtxt, it: &ast::Item) {
                                    enum_definition.variants.as_slice(),
                                    generics);
         },
-        ast::ItemImpl(ref generics, ref opt_trait_ref, selfty, ref ms) => {
+        ast::ItemImpl(ref generics,
+                      ref opt_trait_ref,
+                      selfty,
+                      ref impl_items) => {
             let ty_generics = ty_generics_for_type(ccx, generics);
             let selfty = ccx.to_ty(&ExplicitRscope, &*selfty);
             write_ty_to_tcx(tcx, it.id, selfty);
@@ -480,16 +494,22 @@ pub fn convert(ccx: &CrateCtxt, it: &ast::Item) {
                 it.vis
             };
 
-            for method in ms.iter() {
-                check_method_self_type(ccx,
-                                       &BindingRscope::new(method.id),
-                                       selfty,
-                                       method.pe_explicit_self())
+            let mut methods = Vec::new();
+            for impl_item in impl_items.iter() {
+                match *impl_item {
+                    ast::MethodImplItem(ref method) => {
+                        check_method_self_type(ccx,
+                                               &BindingRscope::new(method.id),
+                                               selfty,
+                                               method.pe_explicit_self());
+                        methods.push(*method);
+                    }
+                }
             }
 
             convert_methods(ccx,
                             ImplContainer(local_def(it.id)),
-                            ms.as_slice(),
+                            methods.as_slice(),
                             selfty,
                             &ty_generics,
                             parent_visibility);
@@ -507,14 +527,14 @@ pub fn convert(ccx: &CrateCtxt, it: &ast::Item) {
                                              0,
                                              local_def(it.id));
                 match *trait_method {
-                    ast::Required(ref type_method) => {
+                    ast::RequiredMethod(ref type_method) => {
                         let rscope = BindingRscope::new(type_method.id);
                         check_method_self_type(ccx,
                                                &rscope,
                                                self_type,
                                                &type_method.explicit_self)
                     }
-                    ast::Provided(ref method) => {
+                    ast::ProvidedMethod(ref method) => {
                         check_method_self_type(ccx,
                                                &BindingRscope::new(method.id),
                                                self_type,
@@ -967,20 +987,26 @@ pub fn ty_of_foreign_item(ccx: &CrateCtxt,
 
 fn ty_generics_for_type(ccx: &CrateCtxt,
                         generics: &ast::Generics)
-                        -> ty::Generics
-{
-    ty_generics(ccx, subst::TypeSpace, &generics.lifetimes,
-                &generics.ty_params, ty::Generics::empty())
+                        -> ty::Generics {
+    ty_generics(ccx,
+                subst::TypeSpace,
+                &generics.lifetimes,
+                &generics.ty_params,
+                ty::Generics::empty(),
+                &generics.where_clause)
 }
 
 fn ty_generics_for_trait(ccx: &CrateCtxt,
                          trait_id: ast::NodeId,
                          substs: &subst::Substs,
                          generics: &ast::Generics)
-                         -> ty::Generics
-{
-    let mut generics = ty_generics(ccx, subst::TypeSpace, &generics.lifetimes,
-                                   &generics.ty_params, ty::Generics::empty());
+                         -> ty::Generics {
+    let mut generics = ty_generics(ccx,
+                                   subst::TypeSpace,
+                                   &generics.lifetimes,
+                                   &generics.ty_params,
+                                   ty::Generics::empty(),
+                                   &generics.where_clause);
 
     // Something of a hack: use the node id for the trait, also as
     // the node id for the Self type parameter.
@@ -1012,11 +1038,14 @@ fn ty_generics_for_trait(ccx: &CrateCtxt,
 fn ty_generics_for_fn_or_method(ccx: &CrateCtxt,
                                 generics: &ast::Generics,
                                 base_generics: ty::Generics)
-                                -> ty::Generics
-{
+                                -> ty::Generics {
     let early_lifetimes = resolve_lifetime::early_bound_lifetimes(generics);
-    ty_generics(ccx, subst::FnSpace, &early_lifetimes,
-                &generics.ty_params, base_generics)
+    ty_generics(ccx,
+                subst::FnSpace,
+                &early_lifetimes,
+                &generics.ty_params,
+                base_generics,
+                &generics.where_clause)
 }
 
 // Add the Sized bound, unless the type parameter is marked as `Sized?`.
@@ -1060,9 +1089,9 @@ fn ty_generics(ccx: &CrateCtxt,
                space: subst::ParamSpace,
                lifetimes: &Vec<ast::LifetimeDef>,
                types: &OwnedSlice<ast::TyParam>,
-               base_generics: ty::Generics)
-               -> ty::Generics
-{
+               base_generics: ty::Generics,
+               where_clause: &ast::WhereClause)
+               -> ty::Generics {
     let mut result = base_generics;
 
     for (i, l) in lifetimes.iter().enumerate() {
@@ -1075,7 +1104,11 @@ fn ty_generics(ccx: &CrateCtxt,
     }
 
     for (i, param) in types.iter().enumerate() {
-        let def = get_or_create_type_parameter_def(ccx, space, param, i);
+        let def = get_or_create_type_parameter_def(ccx,
+                                                   space,
+                                                   param,
+                                                   i,
+                                                   where_clause);
         debug!("ty_generics: def for type param: {}", def.repr(ccx.tcx));
         result.types.push(space, def);
     }
@@ -1085,9 +1118,9 @@ fn ty_generics(ccx: &CrateCtxt,
     fn get_or_create_type_parameter_def(ccx: &CrateCtxt,
                                         space: subst::ParamSpace,
                                         param: &ast::TyParam,
-                                        index: uint)
-                                        -> ty::TypeParameterDef
-    {
+                                        index: uint,
+                                        where_clause: &ast::WhereClause)
+                                        -> ty::TypeParameterDef {
         match ccx.tcx.ty_param_defs.borrow().find(&param.id) {
             Some(d) => { return (*d).clone(); }
             None => { }
@@ -1101,7 +1134,8 @@ fn get_or_create_type_parameter_def(ccx: &CrateCtxt,
                                             &param.bounds,
                                             &param.unbound,
                                             param.ident,
-                                            param.span));
+                                            param.span,
+                                            where_clause));
         let default = param.default.map(|path| {
             let ty = ast_ty_to_ty(ccx, &ExplicitRscope, &*path);
             let cur_idx = param_ty.idx;
@@ -1134,14 +1168,14 @@ fn get_or_create_type_parameter_def(ccx: &CrateCtxt,
         def
     }
 
-    fn compute_bounds(
-        ccx: &CrateCtxt,
-        param_ty: ty::ParamTy,
-        ast_bounds: &OwnedSlice<ast::TyParamBound>,
-        unbound: &Option<ast::TyParamBound>,
-        ident: ast::Ident,
-        span: Span) -> ty::ParamBounds
-    {
+    fn compute_bounds(ccx: &CrateCtxt,
+                      param_ty: ty::ParamTy,
+                      ast_bounds: &OwnedSlice<ast::TyParamBound>,
+                      unbound: &Option<ast::TyParamBound>,
+                      ident: ast::Ident,
+                      span: Span,
+                      where_clause: &ast::WhereClause)
+                      -> ty::ParamBounds {
         /*!
          * Translate the AST's notion of ty param bounds (which are an
          * enum consisting of a newtyped Ty or a region) to ty's
@@ -1154,44 +1188,23 @@ fn compute_bounds(
             trait_bounds: Vec::new()
         };
         for ast_bound in ast_bounds.iter() {
-            match *ast_bound {
-                TraitTyParamBound(ref b) => {
-                    let ty = ty::mk_param(ccx.tcx, param_ty.space,
-                                          param_ty.idx, param_ty.def_id);
-                    let trait_ref = instantiate_trait_ref(ccx, b, ty);
-                    if !ty::try_add_builtin_trait(
-                            ccx.tcx, trait_ref.def_id,
-                            &mut param_bounds.builtin_bounds) {
-                        // Must be a user-defined trait
-                        param_bounds.trait_bounds.push(trait_ref);
-                    }
-                }
-
-                StaticRegionTyParamBound => {
-                    param_bounds.builtin_bounds.add(ty::BoundStatic);
-                }
-
-                UnboxedFnTyParamBound(ref unboxed_function) => {
-                    let rscope = ExplicitRscope;
-                    let self_ty = ty::mk_param(ccx.tcx,
-                                               param_ty.space,
-                                               param_ty.idx,
-                                               param_ty.def_id);
-                    let trait_ref =
-                        astconv::trait_ref_for_unboxed_function(ccx,
-                                                                &rscope,
-                                                                unboxed_function,
-                                                                Some(self_ty));
-                    param_bounds.trait_bounds.push(Rc::new(trait_ref));
-                }
-
-                OtherRegionTyParamBound(span) => {
-                    if !ccx.tcx.sess.features.issue_5723_bootstrap.get() {
-                        ccx.tcx.sess.span_err(
-                            span,
-                            "only the 'static lifetime is accepted here.");
-                    }
-                }
+            compute_bound(ccx, &mut param_bounds, param_ty, ast_bound);
+        }
+        for predicate in where_clause.predicates.iter() {
+            let predicate_param_id = ccx.tcx
+                                        .def_map
+                                        .borrow()
+                                        .find(&predicate.id)
+                                        .expect("compute_bounds(): resolve \
+                                                 didn't resolve the type \
+                                                 parameter identifier in a \
+                                                 `where` clause")
+                                        .def_id();
+            if param_ty.def_id != predicate_param_id {
+                continue
+            }
+            for bound in predicate.bounds.iter() {
+                compute_bound(ccx, &mut param_bounds, param_ty, bound);
             }
         }
 
@@ -1208,6 +1221,54 @@ fn compute_bounds(
         param_bounds
     }
 
+    /// Translates the AST's notion of a type parameter bound to
+    /// typechecking's notion of the same, and pushes the resulting bound onto
+    /// the appropriate section of `param_bounds`.
+    fn compute_bound(ccx: &CrateCtxt,
+                     param_bounds: &mut ty::ParamBounds,
+                     param_ty: ty::ParamTy,
+                     ast_bound: &ast::TyParamBound) {
+        match *ast_bound {
+            TraitTyParamBound(ref b) => {
+                let ty = ty::mk_param(ccx.tcx, param_ty.space,
+                                      param_ty.idx, param_ty.def_id);
+                let trait_ref = instantiate_trait_ref(ccx, b, ty);
+                if !ty::try_add_builtin_trait(
+                        ccx.tcx, trait_ref.def_id,
+                        &mut param_bounds.builtin_bounds) {
+                    // Must be a user-defined trait
+                    param_bounds.trait_bounds.push(trait_ref);
+                }
+            }
+
+            StaticRegionTyParamBound => {
+                param_bounds.builtin_bounds.add(ty::BoundStatic);
+            }
+
+            UnboxedFnTyParamBound(ref unboxed_function) => {
+                let rscope = ExplicitRscope;
+                let self_ty = ty::mk_param(ccx.tcx,
+                                           param_ty.space,
+                                           param_ty.idx,
+                                           param_ty.def_id);
+                let trait_ref =
+                    astconv::trait_ref_for_unboxed_function(ccx,
+                                                            &rscope,
+                                                            unboxed_function,
+                                                            Some(self_ty));
+                param_bounds.trait_bounds.push(Rc::new(trait_ref));
+            }
+
+            OtherRegionTyParamBound(span) => {
+                if !ccx.tcx.sess.features.issue_5723_bootstrap.get() {
+                    ccx.tcx.sess.span_err(
+                        span,
+                        "only the 'static lifetime is accepted here.");
+                }
+            }
+        }
+    }
+
     fn check_bounds_compatible(tcx: &ty::ctxt,
                                param_bounds: &ty::ParamBounds,
                                ident: ast::Ident,
index 1aae97d3d83e9266a68d0b2a536dbcdb77772829..d99d55d4d873dfba386a001b099dd1092af61b74 100644 (file)
@@ -492,9 +492,11 @@ fn check_ptr_to_unsized<C:Combine>(this: &C,
             Ok(ty::mk_struct(tcx, a_id, substs))
       }
 
-      (&ty::ty_unboxed_closure(a_id), &ty::ty_unboxed_closure(b_id))
+      (&ty::ty_unboxed_closure(a_id, a_region),
+       &ty::ty_unboxed_closure(b_id, b_region))
       if a_id == b_id => {
-          Ok(ty::mk_unboxed_closure(tcx, a_id))
+          let region = if_ok!(this.regions(a_region, b_region));
+          Ok(ty::mk_unboxed_closure(tcx, a_id, region))
       }
 
       (&ty::ty_box(a_inner), &ty::ty_box(b_inner)) => {
index e191fb343b53a3dce42980c527ec3891c2590da1..beaf81409a38b39c91ad8dd6c37d1d7ae17817ac 100644 (file)
@@ -305,7 +305,8 @@ fn free_regions_from_same_fn(tcx: &ty::ctxt,
                         },
                         _ => None
                     },
-                    ast_map::NodeMethod(..) => {
+                    ast_map::NodeImplItem(..) |
+                    ast_map::NodeTraitItem(..) => {
                         Some(FreeRegionsFromSameFn::new(fr1, fr2, scope_id))
                     },
                     _ => None
@@ -699,9 +700,17 @@ fn give_suggestion(&self, same_regions: &[SameRegions]) {
                         _ => None
                     }
                 }
-                ast_map::NodeMethod(ref m) => {
-                    Some((m.pe_fn_decl(), m.pe_generics(), m.pe_fn_style(),
-                          m.pe_ident(), Some(m.pe_explicit_self().node), m.span))
+                ast_map::NodeImplItem(ref item) => {
+                    match **item {
+                        ast::MethodImplItem(ref m) => {
+                            Some((m.pe_fn_decl(),
+                                  m.pe_generics(),
+                                  m.pe_fn_style(),
+                                  m.pe_ident(),
+                                  Some(m.pe_explicit_self().node),
+                                  m.span))
+                        }
+                    }
                 },
                 _ => None
             },
@@ -772,6 +781,7 @@ fn rebuild(&self)
         let mut inputs = self.fn_decl.inputs.clone();
         let mut output = self.fn_decl.output;
         let mut ty_params = self.generics.ty_params.clone();
+        let where_clause = self.generics.where_clause.clone();
         let mut kept_lifetimes = HashSet::new();
         for sr in self.same_regions.iter() {
             self.cur_anon.set(0);
@@ -798,7 +808,8 @@ fn rebuild(&self)
                                              &fresh_lifetimes,
                                              &kept_lifetimes,
                                              &all_region_names,
-                                             ty_params);
+                                             ty_params,
+                                             where_clause);
         let new_fn_decl = ast::FnDecl {
             inputs: inputs,
             output: output,
@@ -972,7 +983,8 @@ fn rebuild_generics(&self,
                         add: &Vec<ast::Lifetime>,
                         keep: &HashSet<ast::Name>,
                         remove: &HashSet<ast::Name>,
-                        ty_params: OwnedSlice<ast::TyParam>)
+                        ty_params: OwnedSlice<ast::TyParam>,
+                        where_clause: ast::WhereClause)
                         -> ast::Generics {
         let mut lifetimes = Vec::new();
         for lt in add.iter() {
@@ -981,14 +993,14 @@ fn rebuild_generics(&self,
         }
         for lt in generics.lifetimes.iter() {
             if keep.contains(&lt.lifetime.name) ||
-                !remove.contains(&lt.lifetime.name)
-            {
+                !remove.contains(&lt.lifetime.name) {
                 lifetimes.push((*lt).clone());
             }
         }
         ast::Generics {
             lifetimes: lifetimes,
-            ty_params: ty_params
+            ty_params: ty_params,
+            where_clause: where_clause,
         }
     }
 
@@ -1454,10 +1466,14 @@ fn lifetimes_in_scope(tcx: &ty::ctxt,
                 },
                 _ => None
             },
-            ast_map::NodeMethod(m) => {
-                taken.push_all(m.pe_generics().lifetimes.as_slice());
-                Some(m.id)
-            },
+            ast_map::NodeImplItem(ii) => {
+                match *ii {
+                    ast::MethodImplItem(m) => {
+                        taken.push_all(m.pe_generics().lifetimes.as_slice());
+                        Some(m.id)
+                    }
+                }
+            }
             _ => None
         },
         None => None
index 637af96b6321ab23cb2e0521922e89a8e345ff5d..dd00fc62079813c31e3dbc6985ef4709f866f6b8 100644 (file)
@@ -124,12 +124,20 @@ fn test_env(_test_name: &str,
     let lang_items = lang_items::collect_language_items(&krate, &sess);
     let resolve::CrateMap { def_map: def_map, .. } =
         resolve::resolve_crate(&sess, &lang_items, &krate);
-    let freevars_map = freevars::annotate_freevars(&def_map, &krate);
+    let (freevars_map, captures_map) = freevars::annotate_freevars(&def_map,
+                                                                   &krate);
     let named_region_map = resolve_lifetime::krate(&sess, &krate);
     let region_map = region::resolve_crate(&sess, &krate);
     let stability_index = stability::Index::build(&krate);
-    let tcx = ty::mk_ctxt(sess, def_map, named_region_map, ast_map,
-                          freevars_map, region_map, lang_items, stability_index);
+    let tcx = ty::mk_ctxt(sess,
+                          def_map,
+                          named_region_map,
+                          ast_map,
+                          freevars_map,
+                          captures_map,
+                          region_map,
+                          lang_items,
+                          stability_index);
     let infcx = infer::new_infer_ctxt(&tcx);
     let env = Env {krate: krate,
                    tcx: &tcx,
index be9ae0cc719f2966bacae5be17c17c04cbcf463c..e0fab95a04529435a9c039aceeba218e3bf073b5 100644 (file)
@@ -515,10 +515,14 @@ fn visit_item(&mut self, item: &ast::Item, _: ()) {
             }
 
             ast::ItemTrait(..) => {
-                let methods = ty::trait_methods(tcx, did);
-                for method in methods.iter() {
-                    self.add_constraints_from_sig(
-                        &method.fty.sig, self.covariant);
+                let trait_items = ty::trait_items(tcx, did);
+                for trait_item in trait_items.iter() {
+                    match *trait_item {
+                        ty::MethodTraitItem(ref method) => {
+                            self.add_constraints_from_sig(&method.fty.sig,
+                                                          self.covariant);
+                        }
+                    }
                 }
             }
 
@@ -609,8 +613,8 @@ macro_rules! cannot_happen { () => { {
                         _                    => cannot_happen!(),
                     }
                 }
-                ast_map::NodeTraitMethod(..) => is_inferred = false,
-                ast_map::NodeMethod(_)       => is_inferred = false,
+                ast_map::NodeTraitItem(..)   => is_inferred = false,
+                ast_map::NodeImplItem(..)    => is_inferred = false,
                 _                            => cannot_happen!(),
             }
 
@@ -722,10 +726,15 @@ fn add_constraints_from_ty(&mut self,
         match ty::get(ty).sty {
             ty::ty_nil | ty::ty_bot | ty::ty_bool |
             ty::ty_char | ty::ty_int(_) | ty::ty_uint(_) |
-            ty::ty_float(_) | ty::ty_str | ty::ty_unboxed_closure(..) => {
+            ty::ty_float(_) | ty::ty_str => {
                 /* leaf type -- noop */
             }
 
+            ty::ty_unboxed_closure(_, region) => {
+                let contra = self.contravariant(variance);
+                self.add_constraints_from_region(region, contra);
+            }
+
             ty::ty_rptr(region, ref mt) => {
                 let contra = self.contravariant(variance);
                 self.add_constraints_from_region(region, contra);
index 4e193f0f1d952f816ce290d7a97883fe0c2b733f..301143e5045509c941b3bfc2320a8fcc5a2a50c2 100644 (file)
@@ -762,8 +762,8 @@ fn repr(&self, tcx: &ctxt) -> String {
                 match tcx.map.find(self.node) {
                     Some(ast_map::NodeItem(..)) |
                     Some(ast_map::NodeForeignItem(..)) |
-                    Some(ast_map::NodeMethod(..)) |
-                    Some(ast_map::NodeTraitMethod(..)) |
+                    Some(ast_map::NodeImplItem(..)) |
+                    Some(ast_map::NodeTraitItem(..)) |
                     Some(ast_map::NodeVariant(..)) |
                     Some(ast_map::NodeStructCtor(..)) => {
                         return format!(
index 85e0f2f10d8dcae4c0f6a0096c1ef696737a3ff5..6e606f3336180380a6c2a08761cbff9f36de06c4 100644 (file)
@@ -98,7 +98,7 @@ fn run_ar(handler: &ErrorHandler, maybe_ar_prog: &Option<String>,
 pub fn find_library(name: &str, os: abi::Os, search_paths: &[Path],
                     handler: &ErrorHandler) -> Path {
     let (osprefix, osext) = match os {
-        abi::OsWin32 => ("", "lib"), _ => ("lib", "a"),
+        abi::OsWindows => ("", "lib"), _ => ("lib", "a"),
     };
     // On Windows, static libraries sometimes show up as libfoo.a and other
     // times show up as foo.lib
index 9bb90427e7ccf24127a290115ab18369654a05e2..134f7105ea76eddfc0726814eeaac726d66061a5 100644 (file)
@@ -37,7 +37,7 @@ pub fn get_target_strs(target_triple: String, target_os: abi::Os) -> target_strs
                 -a0:0:64-n32".to_string()
           }
 
-          abi::OsWin32 => {
+          abi::OsWindows => {
             "e-p:32:32:32\
                 -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
                 -f32:32:32-f64:64:64\
index 43bf3e8e4af385efeb1ad5b1553f86ce98d8e277..322f001c31e1b9dfb3df084f459f11153147c642 100644 (file)
@@ -32,7 +32,7 @@ pub fn get_target_strs(target_triple: String, target_os: abi::Os) -> target_strs
                 -a0:0:64-n32".to_string()
           }
 
-          abi::OsWin32 => {
+          abi::OsWindows => {
             "E-p:32:32:32\
                 -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
                 -f32:32:32-f64:64:64\
index 87f74e72504ac01dec6d411f04466e67355b2e73..e7ce5b0a429bc4023ad1143647af8c19c15cc69a 100644 (file)
@@ -32,7 +32,7 @@ pub fn get_target_strs(target_triple: String, target_os: abi::Os) -> target_strs
                 -a0:0:64-n32".to_string()
           }
 
-          abi::OsWin32 => {
+          abi::OsWindows => {
             "e-p:32:32:32\
                 -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
                 -f32:32:32-f64:64:64\
index 94d197ad06a8d23c6e9f84402657400aeb3e797d..98fdd5a7fd7db4dcebe2f0f7e2d72bc1d4b8961f 100644 (file)
@@ -26,7 +26,7 @@ pub struct RPathConfig<'a> {
 pub fn get_rpath_flags(config: RPathConfig) -> Vec<String> {
 
     // No rpath on windows
-    if config.os == abi::OsWin32 {
+    if config.os == abi::OsWindows {
         return Vec::new();
     }
 
@@ -107,14 +107,14 @@ fn get_rpath_relative_to_output(config: &mut RPathConfig,
                                 lib: &Path) -> String {
     use std::os;
 
-    assert!(config.os != abi::OsWin32);
+    assert!(config.os != abi::OsWindows);
 
     // Mac doesn't appear to support $ORIGIN
     let prefix = match config.os {
         abi::OsAndroid | abi::OsLinux | abi::OsFreebsd | abi::OsDragonfly
                           => "$ORIGIN",
         abi::OsMacos => "@loader_path",
-        abi::OsWin32 | abi::OsiOS => unreachable!()
+        abi::OsWindows | abi::OsiOS => unreachable!()
     };
 
     let mut lib = (config.realpath)(&os::make_absolute(lib)).unwrap();
index d45ebb3858e9f703ed2671563535f59570e9fe06..29668795ed7ba429e3d30c42c60fedb976237218 100644 (file)
@@ -480,8 +480,8 @@ fn visit_ty_method(&mut self, t: &TypeMethod, e: E) {
             SawTyMethod.hash(self.st); visit::walk_ty_method(self, t, e)
         }
 
-        fn visit_trait_method(&mut self, t: &TraitMethod, e: E) {
-            SawTraitMethod.hash(self.st); visit::walk_trait_method(self, t, e)
+        fn visit_trait_item(&mut self, t: &TraitItem, e: E) {
+            SawTraitMethod.hash(self.st); visit::walk_trait_item(self, t, e)
         }
 
         fn visit_struct_field(&mut self, s: &StructField, e: E) {
index 3c444806e13e55c45b113b54b2d9f33702053a52..21c4fd424748f2f21dfc0b08ebd158708e573d01 100644 (file)
@@ -34,7 +34,7 @@ pub fn get_target_strs(target_triple: String, target_os: abi::Os)
                 -n8:16:32".to_string()
           }
 
-          abi::OsWin32 => {
+          abi::OsWindows => {
             "e-p:32:32-f64:64:64-i64:64:64-f80:32:32-n8:16:32".to_string()
           }
 
index b4b5765986bab3b3533bd22fe6b5254984485620..43c4d646ec940c76425c8c3c58990cea90784292 100644 (file)
@@ -29,7 +29,7 @@ pub fn get_target_strs(target_triple: String, target_os: abi::Os) -> target_strs
                 s0:64:64-f80:128:128-n8:16:32:64".to_string()
           }
 
-          abi::OsWin32 => {
+          abi::OsWindows => {
             // FIXME: Test this. Copied from linux (#2398)
             "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-\
                 f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-\
index 3c942d0791e77fb6e5db6ff7cb36c21d1d584c4c..0e87be1c241b91a1e02de8ab1a4456f042fc30cb 100644 (file)
@@ -157,13 +157,13 @@ pub fn record_extern_fqn(cx: &core::DocContext,
 
 pub fn build_external_trait(tcx: &ty::ctxt, did: ast::DefId) -> clean::Trait {
     let def = ty::lookup_trait_def(tcx, did);
-    let methods = ty::trait_methods(tcx, did).clean();
+    let trait_items = ty::trait_items(tcx, did).clean();
     let provided = ty::provided_trait_methods(tcx, did);
-    let mut methods = methods.move_iter().map(|meth| {
-        if provided.iter().any(|a| a.def_id == meth.def_id) {
-            clean::Provided(meth)
+    let mut items = trait_items.move_iter().map(|trait_item| {
+        if provided.iter().any(|a| a.def_id == trait_item.def_id) {
+            clean::ProvidedMethod(trait_item)
         } else {
-            clean::Required(meth)
+            clean::RequiredMethod(trait_item)
         }
     });
     let supertraits = ty::trait_supertraits(tcx, did);
@@ -176,7 +176,7 @@ pub fn build_external_trait(tcx: &ty::ctxt, did: ast::DefId) -> clean::Trait {
 
     clean::Trait {
         generics: (&def.generics, subst::TypeSpace).clean(),
-        methods: methods.collect(),
+        items: items.collect(),
         parents: parents.collect()
     }
 }
@@ -303,27 +303,33 @@ fn build_impl(cx: &core::DocContext,
 
     let attrs = load_attrs(tcx, did);
     let ty = ty::lookup_item_type(tcx, did);
-    let methods = csearch::get_impl_methods(&tcx.sess.cstore,
-                                            did).iter().filter_map(|did| {
-        let method = ty::method(tcx, *did);
-        if method.vis != ast::Public && associated_trait.is_none() {
-            return None
-        }
-        let mut item = ty::method(tcx, *did).clean();
-        item.inner = match item.inner.clone() {
-            clean::TyMethodItem(clean::TyMethod {
-                fn_style, decl, self_, generics
-            }) => {
-                clean::MethodItem(clean::Method {
-                    fn_style: fn_style,
-                    decl: decl,
-                    self_: self_,
-                    generics: generics,
-                })
+    let trait_items = csearch::get_impl_items(&tcx.sess.cstore, did)
+            .iter()
+            .filter_map(|did| {
+        let did = did.def_id();
+        let impl_item = ty::impl_or_trait_item(tcx, did);
+        match impl_item {
+            ty::MethodTraitItem(method) => {
+                if method.vis != ast::Public && associated_trait.is_none() {
+                    return None
+                }
+                let mut item = method.clean();
+                item.inner = match item.inner.clone() {
+                    clean::TyMethodItem(clean::TyMethod {
+                        fn_style, decl, self_, generics
+                    }) => {
+                        clean::MethodItem(clean::Method {
+                            fn_style: fn_style,
+                            decl: decl,
+                            self_: self_,
+                            generics: generics,
+                        })
+                    }
+                    _ => fail!("not a tymethod"),
+                };
+                Some(item)
             }
-            _ => fail!("not a tymethod"),
-        };
-        Some(item)
+        }
     }).collect();
     return Some(clean::Item {
         inner: clean::ImplItem(clean::Impl {
@@ -336,7 +342,7 @@ fn build_impl(cx: &core::DocContext,
             }),
             for_: ty.ty.clean(),
             generics: (&ty.generics, subst::TypeSpace).clean(),
-            methods: methods,
+            items: trait_items,
         }),
         source: clean::Span::empty(),
         name: None,
index a1f486b3b31b81a92f14fabccda514d6c0632a9f..68e1529fb1770f343903ecfa66e2c773a0c05cca 100644 (file)
@@ -363,7 +363,7 @@ fn clean(&self) -> Item {
 
         // determine if we should display the inner contents or
         // the outer `mod` item for the source code.
-        let where = {
+        let whence = {
             let ctxt = super::ctxtkey.get().unwrap();
             let cm = ctxt.sess().codemap();
             let outer = cm.lookup_char_pos(self.where_outer.lo);
@@ -380,7 +380,7 @@ fn clean(&self) -> Item {
         Item {
             name: Some(name),
             attrs: self.attrs.clean(),
-            source: where.clean(),
+            source: whence.clean(),
             visibility: self.vis.clean(),
             stability: self.stab.clean(),
             def_id: ast_util::local_def(self.id),
@@ -781,7 +781,7 @@ fn clean(&self) -> Item {
         Item {
             name: Some(self.name.clean()),
             attrs: self.attrs.clean(),
-            source: self.where.clean(),
+            source: self.whence.clean(),
             visibility: self.vis.clean(),
             stability: self.stab.clean(),
             def_id: ast_util::local_def(self.id),
@@ -907,7 +907,7 @@ fn clean(&self) -> RetStyle {
 
 #[deriving(Clone, Encodable, Decodable)]
 pub struct Trait {
-    pub methods: Vec<TraitMethod>,
+    pub items: Vec<TraitItem>,
     pub generics: Generics,
     pub parents: Vec<Type>,
 }
@@ -917,12 +917,12 @@ fn clean(&self) -> Item {
         Item {
             name: Some(self.name.clean()),
             attrs: self.attrs.clean(),
-            source: self.where.clean(),
+            source: self.whence.clean(),
             def_id: ast_util::local_def(self.id),
             visibility: self.vis.clean(),
             stability: self.stab.clean(),
             inner: TraitItem(Trait {
-                methods: self.methods.clean(),
+                items: self.items.clean(),
                 generics: self.generics.clean(),
                 parents: self.parents.clean(),
             }),
@@ -937,37 +937,50 @@ fn clean(&self) -> Type {
 }
 
 #[deriving(Clone, Encodable, Decodable)]
-pub enum TraitMethod {
-    Required(Item),
-    Provided(Item),
+pub enum TraitItem {
+    RequiredMethod(Item),
+    ProvidedMethod(Item),
 }
 
-impl TraitMethod {
+impl TraitItem {
     pub fn is_req(&self) -> bool {
         match self {
-            &Required(..) => true,
+            &RequiredMethod(..) => true,
             _ => false,
         }
     }
     pub fn is_def(&self) -> bool {
         match self {
-            &Provided(..) => true,
+            &ProvidedMethod(..) => true,
             _ => false,
         }
     }
     pub fn item<'a>(&'a self) -> &'a Item {
         match *self {
-            Required(ref item) => item,
-            Provided(ref item) => item,
+            RequiredMethod(ref item) => item,
+            ProvidedMethod(ref item) => item,
         }
     }
 }
 
-impl Clean<TraitMethod> for ast::TraitMethod {
-    fn clean(&self) -> TraitMethod {
+impl Clean<TraitItem> for ast::TraitItem {
+    fn clean(&self) -> TraitItem {
         match self {
-            &ast::Required(ref t) => Required(t.clean()),
-            &ast::Provided(ref t) => Provided(t.clean()),
+            &ast::RequiredMethod(ref t) => RequiredMethod(t.clean()),
+            &ast::ProvidedMethod(ref t) => ProvidedMethod(t.clean()),
+        }
+    }
+}
+
+#[deriving(Clone, Encodable, Decodable)]
+pub enum ImplItem {
+    MethodImplItem(Item),
+}
+
+impl Clean<ImplItem> for ast::ImplItem {
+    fn clean(&self) -> ImplItem {
+        match self {
+            &ast::MethodImplItem(ref t) => MethodImplItem(t.clean()),
         }
     }
 }
@@ -1019,6 +1032,14 @@ fn clean(&self) -> Item {
     }
 }
 
+impl Clean<Item> for ty::ImplOrTraitItem {
+    fn clean(&self) -> Item {
+        match *self {
+            ty::MethodTraitItem(ref mti) => mti.clean(),
+        }
+    }
+}
+
 /// A representation of a Type suitable for hyperlinking purposes. Ideally one can get the original
 /// type out of the AST/ty::ctxt given one of these, if more information is needed. Most importantly
 /// it does not preserve mutability or boxes.
@@ -1376,7 +1397,7 @@ fn clean(&self) -> Item {
         Item {
             name: Some(self.name.clean()),
             attrs: self.attrs.clean(),
-            source: self.where.clean(),
+            source: self.whence.clean(),
             def_id: ast_util::local_def(self.id),
             visibility: self.vis.clean(),
             stability: self.stab.clean(),
@@ -1422,7 +1443,7 @@ fn clean(&self) -> Item {
         Item {
             name: Some(self.name.clean()),
             attrs: self.attrs.clean(),
-            source: self.where.clean(),
+            source: self.whence.clean(),
             def_id: ast_util::local_def(self.id),
             visibility: self.vis.clean(),
             stability: self.stab.clean(),
@@ -1445,7 +1466,7 @@ fn clean(&self) -> Item {
         Item {
             name: Some(self.name.clean()),
             attrs: self.attrs.clean(),
-            source: self.where.clean(),
+            source: self.whence.clean(),
             visibility: self.vis.clean(),
             stability: self.stab.clean(),
             def_id: ast_util::local_def(self.id),
@@ -1631,7 +1652,7 @@ fn clean(&self) -> Item {
         Item {
             name: Some(self.name.clean()),
             attrs: self.attrs.clean(),
-            source: self.where.clean(),
+            source: self.whence.clean(),
             def_id: ast_util::local_def(self.id.clone()),
             visibility: self.vis.clean(),
             stability: self.stab.clean(),
@@ -1681,7 +1702,7 @@ fn clean(&self) -> Item {
         Item {
             name: Some(self.name.clean()),
             attrs: self.attrs.clean(),
-            source: self.where.clean(),
+            source: self.whence.clean(),
             def_id: ast_util::local_def(self.id),
             visibility: self.vis.clean(),
             stability: self.stab.clean(),
@@ -1714,7 +1735,7 @@ pub struct Impl {
     pub generics: Generics,
     pub trait_: Option<Type>,
     pub for_: Type,
-    pub methods: Vec<Item>,
+    pub items: Vec<Item>,
     pub derived: bool,
 }
 
@@ -1727,7 +1748,7 @@ fn clean(&self) -> Item {
         Item {
             name: None,
             attrs: self.attrs.clean(),
-            source: self.where.clean(),
+            source: self.whence.clean(),
             def_id: ast_util::local_def(self.id),
             visibility: self.vis.clean(),
             stability: self.stab.clean(),
@@ -1735,7 +1756,11 @@ fn clean(&self) -> Item {
                 generics: self.generics.clean(),
                 trait_: self.trait_.clean(),
                 for_: self.for_.clean(),
-                methods: self.methods.clean(),
+                items: self.items.clean().move_iter().map(|ti| {
+                        match ti {
+                            MethodImplItem(i) => i,
+                        }
+                    }).collect(),
                 derived: detect_derived(self.attrs.as_slice()),
             }),
         }
@@ -2090,12 +2115,12 @@ fn clean(&self) -> Item {
         Item {
             name: Some(format!("{}!", self.name.clean())),
             attrs: self.attrs.clean(),
-            source: self.where.clean(),
+            source: self.whence.clean(),
             visibility: ast::Public.clean(),
             stability: self.stab.clean(),
             def_id: ast_util::local_def(self.id),
             inner: MacroItem(Macro {
-                source: self.where.to_src(),
+                source: self.whence.to_src(),
             }),
         }
     }
index 313f1c81c79e81ba8df55f0d5af5fb24b11cd01a..da45321e7fd98819ee6b296c21ef14b9003e786f 100644 (file)
@@ -93,7 +93,7 @@ pub struct Struct {
     pub generics: ast::Generics,
     pub attrs: Vec<ast::Attribute>,
     pub fields: Vec<ast::StructField>,
-    pub where: Span,
+    pub whence: Span,
 }
 
 pub struct Enum {
@@ -103,7 +103,7 @@ pub struct Enum {
     pub generics: ast::Generics,
     pub attrs: Vec<ast::Attribute>,
     pub id: NodeId,
-    pub where: Span,
+    pub whence: Span,
     pub name: Ident,
 }
 
@@ -114,7 +114,7 @@ pub struct Variant {
     pub id: ast::NodeId,
     pub vis: ast::Visibility,
     pub stab: Option<attr::Stability>,
-    pub where: Span,
+    pub whence: Span,
 }
 
 pub struct Function {
@@ -125,7 +125,7 @@ pub struct Function {
     pub vis: ast::Visibility,
     pub stab: Option<attr::Stability>,
     pub fn_style: ast::FnStyle,
-    pub where: Span,
+    pub whence: Span,
     pub generics: ast::Generics,
 }
 
@@ -135,7 +135,7 @@ pub struct Typedef {
     pub name: Ident,
     pub id: ast::NodeId,
     pub attrs: Vec<ast::Attribute>,
-    pub where: Span,
+    pub whence: Span,
     pub vis: ast::Visibility,
     pub stab: Option<attr::Stability>,
 }
@@ -149,17 +149,17 @@ pub struct Static {
     pub vis: ast::Visibility,
     pub stab: Option<attr::Stability>,
     pub id: ast::NodeId,
-    pub where: Span,
+    pub whence: Span,
 }
 
 pub struct Trait {
     pub name: Ident,
-    pub methods: Vec<ast::TraitMethod>, //should be TraitMethod
+    pub items: Vec<ast::TraitItem>, //should be TraitItem
     pub generics: ast::Generics,
     pub parents: Vec<ast::TraitRef>,
     pub attrs: Vec<ast::Attribute>,
     pub id: ast::NodeId,
-    pub where: Span,
+    pub whence: Span,
     pub vis: ast::Visibility,
     pub stab: Option<attr::Stability>,
 }
@@ -168,9 +168,9 @@ pub struct Impl {
     pub generics: ast::Generics,
     pub trait_: Option<ast::TraitRef>,
     pub for_: ast::P<ast::Ty>,
-    pub methods: Vec<Gc<ast::Method>>,
+    pub items: Vec<ast::ImplItem>,
     pub attrs: Vec<ast::Attribute>,
-    pub where: Span,
+    pub whence: Span,
     pub vis: ast::Visibility,
     pub stab: Option<attr::Stability>,
     pub id: ast::NodeId,
@@ -180,7 +180,7 @@ pub struct Macro {
     pub name: Ident,
     pub id: ast::NodeId,
     pub attrs: Vec<ast::Attribute>,
-    pub where: Span,
+    pub whence: Span,
     pub stab: Option<attr::Stability>,
 }
 
index 60853f450ab329dcb0a5d3ad5a5bedaf5d33a509..f0082f8900e6ae3414a92b802490d06786c8f33c 100644 (file)
@@ -40,29 +40,31 @@ fn fold_item_recur(&mut self, item: Item) -> Option<Item> {
                 EnumItem(i)
             },
             TraitItem(mut i) => {
-                fn vtrm<T: DocFolder>(this: &mut T, trm: TraitMethod) -> Option<TraitMethod> {
+                fn vtrm<T: DocFolder>(this: &mut T, trm: TraitItem)
+                        -> Option<TraitItem> {
                     match trm {
-                        Required(it) => {
+                        RequiredMethod(it) => {
                             match this.fold_item(it) {
-                                Some(x) => return Some(Required(x)),
+                                Some(x) => return Some(RequiredMethod(x)),
                                 None => return None,
                             }
                         },
-                        Provided(it) => {
+                        ProvidedMethod(it) => {
                             match this.fold_item(it) {
-                                Some(x) => return Some(Provided(x)),
+                                Some(x) => return Some(ProvidedMethod(x)),
                                 None => return None,
                             }
                         },
                     }
                 }
-                let mut foo = Vec::new(); swap(&mut foo, &mut i.methods);
-                i.methods.extend(foo.move_iter().filter_map(|x| vtrm(self, x)));
+                let mut foo = Vec::new(); swap(&mut foo, &mut i.items);
+                i.items.extend(foo.move_iter().filter_map(|x| vtrm(self, x)));
                 TraitItem(i)
             },
             ImplItem(mut i) => {
-                let mut foo = Vec::new(); swap(&mut foo, &mut i.methods);
-                i.methods.extend(foo.move_iter().filter_map(|x| self.fold_item(x)));
+                let mut foo = Vec::new(); swap(&mut foo, &mut i.items);
+                i.items.extend(foo.move_iter()
+                                  .filter_map(|x| self.fold_item(x)));
                 ImplItem(i)
             },
             VariantItem(i) => {
index 4f511e390ff98650100a3ae13a56c833fda05f49..bb68c6536a00d3ab676b3c506de65b87be9ad5df 100644 (file)
@@ -1624,10 +1624,24 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
                   it.name.get_ref().as_slice(),
                   t.generics,
                   parents));
-    let required = t.methods.iter().filter(|m| m.is_req()).collect::<Vec<&clean::TraitMethod>>();
-    let provided = t.methods.iter().filter(|m| !m.is_req()).collect::<Vec<&clean::TraitMethod>>();
-
-    if t.methods.len() == 0 {
+    let required = t.items.iter()
+                          .filter(|m| {
+                              match **m {
+                                  clean::RequiredMethod(_) => true,
+                                  _ => false,
+                              }
+                          })
+                          .collect::<Vec<&clean::TraitItem>>();
+    let provided = t.items.iter()
+                          .filter(|m| {
+                              match **m {
+                                  clean::ProvidedMethod(_) => true,
+                                  _ => false,
+                              }
+                          })
+                          .collect::<Vec<&clean::TraitItem>>();
+
+    if t.items.len() == 0 {
         try!(write!(w, "{{ }}"));
     } else {
         try!(write!(w, "{{\n"));
@@ -1651,7 +1665,8 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
     // Trait documentation
     try!(document(w, it));
 
-    fn meth(w: &mut fmt::Formatter, m: &clean::TraitMethod) -> fmt::Result {
+    fn trait_item(w: &mut fmt::Formatter, m: &clean::TraitItem)
+                  -> fmt::Result {
         try!(write!(w, "<h3 id='{}.{}' class='method'>{}<code>",
                     shortty(m.item()),
                     *m.item().name.get_ref(),
@@ -1669,7 +1684,7 @@ fn meth(w: &mut fmt::Formatter, m: &clean::TraitMethod) -> fmt::Result {
             <div class='methods'>
         "));
         for m in required.iter() {
-            try!(meth(w, *m));
+            try!(trait_item(w, *m));
         }
         try!(write!(w, "</div>"));
     }
@@ -1679,7 +1694,7 @@ fn meth(w: &mut fmt::Formatter, m: &clean::TraitMethod) -> fmt::Result {
             <div class='methods'>
         "));
         for m in provided.iter() {
-            try!(meth(w, *m));
+            try!(trait_item(w, *m));
         }
         try!(write!(w, "</div>"));
     }
@@ -1991,8 +2006,8 @@ fn render_impl(w: &mut fmt::Formatter, i: &Impl) -> fmt::Result {
         None => {}
     }
 
-    fn docmeth(w: &mut fmt::Formatter, item: &clean::Item,
-               dox: bool) -> fmt::Result {
+    fn doctraititem(w: &mut fmt::Formatter, item: &clean::Item, dox: bool)
+                    -> fmt::Result {
         try!(write!(w, "<h4 id='method.{}' class='method'>{}<code>",
                     *item.name.get_ref(),
                     ConciseStability(&item.stability)));
@@ -2008,21 +2023,21 @@ fn docmeth(w: &mut fmt::Formatter, item: &clean::Item,
     }
 
     try!(write!(w, "<div class='impl-methods'>"));
-    for meth in i.impl_.methods.iter() {
-        try!(docmeth(w, meth, true));
+    for trait_item in i.impl_.items.iter() {
+        try!(doctraititem(w, trait_item, true));
     }
 
     fn render_default_methods(w: &mut fmt::Formatter,
                               t: &clean::Trait,
                               i: &clean::Impl) -> fmt::Result {
-        for method in t.methods.iter() {
-            let n = method.item().name.clone();
-            match i.methods.iter().find(|m| { m.name == n }) {
+        for trait_item in t.items.iter() {
+            let n = trait_item.item().name.clone();
+            match i.items.iter().find(|m| { m.name == n }) {
                 Some(..) => continue,
                 None => {}
             }
 
-            try!(docmeth(w, method.item(), false));
+            try!(doctraititem(w, trait_item.item(), false));
         }
         Ok(())
     }
index 6c254b621775cf5d93886a1965d23979991497dc..fb1666bef0d2f467d8757c6b8d6bf244a0e7f596 100644 (file)
@@ -328,7 +328,7 @@ fn acquire_input(input: &str,
 fn parse_externs(matches: &getopts::Matches) -> Result<core::Externs, String> {
     let mut externs = HashMap::new();
     for arg in matches.opt_strs("extern").iter() {
-        let mut parts = arg.as_slice().splitn('=', 1);
+        let mut parts = arg.as_slice().splitn(1, '=');
         let name = match parts.next() {
             Some(s) => s,
             None => {
index cc5bc5cb7c170de7265e18f3ab14bc8ad234e937..eeccc3303ebfec7e000f307dc9c6744e65288062 100644 (file)
@@ -202,7 +202,7 @@ fn fold_item(&mut self, i: Item) -> Option<Item> {
                     clean::ModuleItem(ref m)
                         if m.items.len() == 0 &&
                            i.doc_value().is_none() => None,
-                    clean::ImplItem(ref i) if i.methods.len() == 0 => None,
+                    clean::ImplItem(ref i) if i.items.len() == 0 => None,
                     _ => {
                         self.retained.insert(i.def_id.node);
                         Some(i)
index 9ac366655636cca447ce9c4a00895cb99e06521b..c5ac9416fa06d9d2ca8413e48f7a5247e2553160 100644 (file)
@@ -73,7 +73,8 @@ pub fn run_plugins(&self, krate: clean::Crate) -> (clean::Crate, Vec<PluginJson>
     }
 }
 
-#[cfg(target_os="win32")]
+#[cfg(target_os = "windows")]
+#[cfg(stage0, target_os = "win32")] // NOTE: Remove after snapshot
 fn libname(mut n: String) -> String {
     n.push_str(".dll");
     n
@@ -85,7 +86,8 @@ fn libname(mut n: String) -> String {
     n
 }
 
-#[cfg(not(target_os="win32"), not(target_os="macos"))]
+#[cfg(not(stage0), not(target_os="windows"), not(target_os="macos"))]
+#[cfg(stage0, not(target_os="win32"), not(target_os="macos"))] // NOTE: Remove after snapshot
 fn libname(n: String) -> String {
     let mut i = String::from_str("lib");
     i.push_str(n.as_slice());
index 60db4fda05190098046ed477101d521a98276680..bbcf38f4955715604cb30f0bab593c41f09d5a52 100644 (file)
@@ -21,7 +21,7 @@
 use syntax::ast::Public;
 
 use clean::{Crate, Item, ModuleItem, Module, StructItem, Struct, EnumItem, Enum};
-use clean::{ImplItem, Impl, TraitItem, Trait, TraitMethod, Provided, Required};
+use clean::{ImplItem, Impl, Trait, TraitItem, ProvidedMethod, RequiredMethod};
 use clean::{ViewItemItem, PrimitiveItem};
 
 #[deriving(Zero, Encodable, Decodable, PartialEq, Eq)]
@@ -110,7 +110,7 @@ fn summarize_item(item: &Item) -> (Counts, Option<ModuleSummary>) {
     match item.inner {
         // Require explicit `pub` to be visible
         StructItem(Struct { fields: ref subitems, .. }) |
-        ImplItem(Impl { methods: ref subitems, trait_: None, .. }) => {
+        ImplItem(Impl { items: ref subitems, trait_: None, .. }) => {
             let subcounts = subitems.iter().filter(|i| visible(*i))
                                            .map(summarize_item)
                                            .map(|s| s.val0())
@@ -124,16 +124,21 @@ fn summarize_item(item: &Item) -> (Counts, Option<ModuleSummary>) {
                                            .sum();
             (item_counts + subcounts, None)
         }
-        TraitItem(Trait { methods: ref methods, .. }) => {
-            fn extract_item<'a>(meth: &'a TraitMethod) -> &'a Item {
-                match *meth {
-                    Provided(ref item) | Required(ref item) => item
+        TraitItem(Trait {
+            items: ref trait_items,
+            ..
+        }) => {
+            fn extract_item<'a>(trait_item: &'a TraitItem) -> &'a Item {
+                match *trait_item {
+                    ProvidedMethod(ref item) |
+                    RequiredMethod(ref item) => item
                 }
             }
-            let subcounts = methods.iter().map(extract_item)
-                                          .map(summarize_item)
-                                          .map(|s| s.val0())
-                                          .sum();
+            let subcounts = trait_items.iter()
+                                       .map(extract_item)
+                                       .map(summarize_item)
+                                       .map(|s| s.val0())
+                                       .sum();
             (item_counts + subcounts, None)
         }
         ModuleItem(Module { items: ref items, .. }) => {
index 5b2a542ca9664b308ab707eef25c843438e36c7f..b67b3c394d6f4bf766404ac601ccefcbe1bb7feb 100644 (file)
@@ -91,7 +91,7 @@ pub fn visit_struct_def(&mut self, item: &ast::Item, sd: Gc<ast::StructDef>,
             attrs: item.attrs.iter().map(|x| *x).collect(),
             generics: generics.clone(),
             fields: sd.fields.iter().map(|x| (*x).clone()).collect(),
-            where: item.span
+            whence: item.span
         }
     }
 
@@ -107,7 +107,7 @@ pub fn visit_enum_def(&mut self, it: &ast::Item, def: &ast::EnumDef,
                 stab: self.stability(x.node.id),
                 id: x.node.id,
                 kind: x.node.kind.clone(),
-                where: x.span,
+                whence: x.span,
             });
         }
         Enum {
@@ -118,7 +118,7 @@ pub fn visit_enum_def(&mut self, it: &ast::Item, def: &ast::EnumDef,
             generics: params.clone(),
             attrs: it.attrs.iter().map(|x| *x).collect(),
             id: it.id,
-            where: it.span,
+            whence: it.span,
         }
     }
 
@@ -133,7 +133,7 @@ pub fn visit_fn(&mut self, item: &ast::Item, fd: &ast::FnDecl,
             attrs: item.attrs.iter().map(|x| *x).collect(),
             decl: fd.clone(),
             name: item.ident,
-            where: item.span,
+            whence: item.span,
             generics: gen.clone(),
             fn_style: *fn_style,
         }
@@ -297,7 +297,7 @@ pub fn visit_item(&mut self, item: &ast::Item, om: &mut Module) {
                     name: item.ident,
                     id: item.id,
                     attrs: item.attrs.iter().map(|x| *x).collect(),
-                    where: item.span,
+                    whence: item.span,
                     vis: item.vis,
                     stab: self.stability(item.id),
                 };
@@ -311,35 +311,35 @@ pub fn visit_item(&mut self, item: &ast::Item, om: &mut Module) {
                     id: item.id,
                     name: item.ident,
                     attrs: item.attrs.iter().map(|x| *x).collect(),
-                    where: item.span,
+                    whence: item.span,
                     vis: item.vis,
                     stab: self.stability(item.id),
                 };
                 om.statics.push(s);
             },
-            ast::ItemTrait(ref gen, _, ref tr, ref met) => {
+            ast::ItemTrait(ref gen, _, ref tr, ref items) => {
                 let t = Trait {
                     name: item.ident,
-                    methods: met.iter().map(|x| (*x).clone()).collect(),
+                    items: items.iter().map(|x| (*x).clone()).collect(),
                     generics: gen.clone(),
                     parents: tr.iter().map(|x| (*x).clone()).collect(),
                     id: item.id,
                     attrs: item.attrs.iter().map(|x| *x).collect(),
-                    where: item.span,
+                    whence: item.span,
                     vis: item.vis,
                     stab: self.stability(item.id),
                 };
                 om.traits.push(t);
             },
-            ast::ItemImpl(ref gen, ref tr, ty, ref meths) => {
+            ast::ItemImpl(ref gen, ref tr, ty, ref items) => {
                 let i = Impl {
                     generics: gen.clone(),
                     trait_: tr.clone(),
                     for_: ty,
-                    methods: meths.iter().map(|x| *x).collect(),
+                    items: items.iter().map(|x| *x).collect(),
                     attrs: item.attrs.iter().map(|x| *x).collect(),
                     id: item.id,
-                    where: item.span,
+                    whence: item.span,
                     vis: item.vis,
                     stab: self.stability(item.id),
                 };
@@ -360,7 +360,7 @@ fn visit_macro(&self, item: &ast::Item) -> Macro {
             id: item.id,
             attrs: item.attrs.iter().map(|x| *x).collect(),
             name: item.ident,
-            where: item.span,
+            whence: item.span,
             stab: self.stability(item.id),
         }
     }
index 531bbe038fcbbc5664097ced27680ad9bb3f377c..453a9307579d4681aa6abeb53ee9e6a26e224731 100644 (file)
@@ -147,7 +147,8 @@ fn smoke_test() {
 
 #[cfg(target_os = "macos")]
 #[cfg(target_os = "ios")]
-#[cfg(target_os = "win32")]
+#[cfg(target_os = "windows")]
+#[cfg(stage0, target_os = "win32")] // NOTE: Remove after snapshot
 mod imp {
     use core::prelude::*;
     use collections::vec::Vec;
index db6308c10dcf2b547cd76472d259047a27531ce6..72d78d84aa3e69bcdf079ab2d63f629e184b5b49 100644 (file)
@@ -86,7 +86,8 @@ pub enum _Unwind_Context {}
 
 #[cfg(target_os = "linux")]
 #[cfg(target_os = "freebsd")]
-#[cfg(target_os = "win32")]
+#[cfg(target_os = "windows")]
+#[cfg(stage0, target_os = "win32")] // NOTE: Remove after snapshot
 #[link(name = "gcc_s")]
 extern {}
 
index c941107d7e81ae66cf23689078d9b5f37ba6bc81..772b5da8cd5b809c12b28d235673d3c6ac71f44a 100644 (file)
@@ -199,7 +199,8 @@ unsafe fn target_record_sp_limit(limit: uint) {
     unsafe fn target_record_sp_limit(limit: uint) {
         asm!("movq $0, %fs:112" :: "r"(limit) :: "volatile")
     }
-    #[cfg(target_arch = "x86_64", target_os = "win32")] #[inline(always)]
+    #[cfg(target_arch = "x86_64", target_os = "windows")] #[inline(always)]
+    #[cfg(stage0, target_arch = "x86_64", target_os = "win32")] // NOTE: Remove after snapshot
     unsafe fn target_record_sp_limit(limit: uint) {
         // see: http://en.wikipedia.org/wiki/Win32_Thread_Information_Block
         // store this inside of the "arbitrary data slot", but double the size
@@ -227,7 +228,8 @@ unsafe fn target_record_sp_limit(limit: uint) {
     unsafe fn target_record_sp_limit(limit: uint) {
         asm!("movl $0, %gs:48" :: "r"(limit) :: "volatile")
     }
-    #[cfg(target_arch = "x86", target_os = "win32")] #[inline(always)]
+    #[cfg(target_arch = "x86", target_os = "windows")] #[inline(always)]
+    #[cfg(stage0, target_arch = "x86", target_os = "win32")] // NOTE: Remove after snapshot
     unsafe fn target_record_sp_limit(limit: uint) {
         // see: http://en.wikipedia.org/wiki/Win32_Thread_Information_Block
         // store this inside of the "arbitrary data slot"
@@ -280,7 +282,8 @@ unsafe fn target_get_sp_limit() -> uint {
         asm!("movq %fs:112, $0" : "=r"(limit) ::: "volatile");
         return limit;
     }
-    #[cfg(target_arch = "x86_64", target_os = "win32")] #[inline(always)]
+    #[cfg(target_arch = "x86_64", target_os = "windows")] #[inline(always)]
+    #[cfg(stage0, target_arch = "x86_64", target_os = "win32")] // NOTE: Remove after snapshot
     unsafe fn target_get_sp_limit() -> uint {
         let limit;
         asm!("movq %gs:0x28, $0" : "=r"(limit) ::: "volatile");
@@ -316,7 +319,8 @@ unsafe fn target_get_sp_limit() -> uint {
         asm!("movl %gs:48, $0" : "=r"(limit) ::: "volatile");
         return limit;
     }
-    #[cfg(target_arch = "x86", target_os = "win32")] #[inline(always)]
+    #[cfg(target_arch = "x86", target_os = "windows")] #[inline(always)]
+    #[cfg(stage0, target_arch = "x86", target_os = "win32")] // NOTE: Remove after snapshot
     unsafe fn target_get_sp_limit() -> uint {
         let limit;
         asm!("movl %fs:0x14, $0" : "=r"(limit) ::: "volatile");
index 6fb45339ba699c85465fc3f6775053b49533eb80..b06065659bda1b7bb1544960cfa77749ae108801 100644 (file)
@@ -727,7 +727,8 @@ pub fn uv_signal_start(h: *mut uv_signal_t, cb: uv_signal_cb,
 #[link(name = "rt")]
 extern {}
 
-#[cfg(target_os = "win32")]
+#[cfg(target_os = "windows")]
+#[cfg(stage0, target_os = "win32")] // NOTE: Remove after snapshot
 #[link(name = "ws2_32")]
 #[link(name = "psapi")]
 #[link(name = "iphlpapi")]
index e8352dcd40cdc29fcfc9099e4706990de89c85dd..e5f42bd65a30071d21dae7840c6f761cebb8edfe 100644 (file)
@@ -19,7 +19,7 @@
 use iter::Iterator;
 use mem;
 use option::{Option, Some, None};
-use slice::{ImmutableVector, MutableVector, Vector};
+use slice::{ImmutableSlice, MutableSlice, Slice};
 use str::{Str, StrSlice};
 use str;
 use string::String;
index 80fe05fcea5cdf99f1cdc14179c4af21dfd3324d..5f52c0ada5d62d2d4077ab21864a905d839a885d 100644 (file)
@@ -43,7 +43,7 @@
 use ptr::RawPtr;
 use ptr;
 use raw;
-use slice::Vector;
+use slice::Slice;
 
 /// The type representing a foreign chunk of memory
 pub struct CVec<T> {
@@ -145,7 +145,7 @@ pub unsafe fn unwrap(mut self) -> *mut T {
     }
 }
 
-impl<T> Vector<T> for CVec<T> {
+impl<T> Slice<T> for CVec<T> {
     /// View the stored data as a slice.
     fn as_slice<'a>(&'a self) -> &'a [T] {
         unsafe {
index 2de9db1cc93e33ddee3bfd9f5b3f64cc2af27847..b8f8bd41a2d9dacb24121c4376433ac3c1e5eb7c 100644 (file)
@@ -2743,7 +2743,7 @@ mod test_set {
     use prelude::*;
 
     use super::HashSet;
-    use slice::ImmutableEqVector;
+    use slice::ImmutablePartialEqSlice;
     use collections::Collection;
 
     #[test]
index 1ac37458e2493acd1b6f0f95b274187933d7a227..fb951d45c42112aa849891c750884dcd10a2b608 100644 (file)
@@ -29,7 +29,7 @@
 use os;
 use path::{Path,GenericPath};
 use result::*;
-use slice::{Vector,ImmutableVector};
+use slice::{Slice,ImmutableSlice};
 use str;
 use string::String;
 use vec::Vec;
@@ -278,7 +278,8 @@ fn dlsym(handle: *mut libc::c_void,
     }
 }
 
-#[cfg(target_os = "win32")]
+#[cfg(target_os = "windows")]
+#[cfg(stage0, target_os = "win32")] // NOTE: Remove after snapshot
 pub mod dl {
     use c_str::ToCStr;
     use iter::Iterator;
index 71ec524211824dcad77dc4d52f01ce1a293d5be8..a9b0b33c59ad9ae3b2ef066b0ab8a08c431fab62 100644 (file)
@@ -19,7 +19,7 @@
 use ops::Drop;
 use option::{Some, None, Option};
 use result::{Ok, Err};
-use slice::{ImmutableVector, MutableVector};
+use slice::{ImmutableSlice, MutableSlice};
 use slice;
 use vec::Vec;
 
index cd5887b7add0011d6ebf96cae8caad21019922a6..53b5fbe3894edc099bd9e36ea109b6b4ab76eca9 100644 (file)
@@ -15,7 +15,7 @@
 use io;
 use option::{None, Option, Some};
 use result::{Ok, Err};
-use slice::{bytes, MutableVector, ImmutableVector};
+use slice::{bytes, MutableSlice, ImmutableSlice};
 use str::StrSlice;
 use super::{Reader, Writer, IoResult};
 use vec::Vec;
index 5215aec5dfbfa6e314bd481a22169e3f978cea25..12caa7158658e28693df873b74ab099b4e6505c0 100644 (file)
@@ -21,7 +21,7 @@
 use result::{Ok, Err};
 use io;
 use io::{IoError, IoResult, Reader};
-use slice::{ImmutableVector, Vector};
+use slice::{ImmutableSlice, Slice};
 use ptr::RawPtr;
 
 /// An iterator that reads a single byte on each iteration,
@@ -153,7 +153,7 @@ pub fn u64_to_be_bytes<T>(n: u64, size: uint, f: |v: &[u8]| -> T) -> T {
 pub fn u64_from_be_bytes(data: &[u8], start: uint, size: uint) -> u64 {
     use ptr::{copy_nonoverlapping_memory};
     use mem::from_be64;
-    use slice::MutableVector;
+    use slice::MutableSlice;
 
     assert!(size <= 8u);
 
index 7335511ed857e42781339027bf7a530b7ddd06bd..f95f41509a0f50b9158538476765560b4f265447 100644 (file)
@@ -70,7 +70,7 @@
 use result::{Err, Ok};
 use rt::rtio::LocalIo;
 use rt::rtio;
-use slice::ImmutableVector;
+use slice::ImmutableSlice;
 use string::String;
 use vec::Vec;
 
index 8879f7e25063cb56890d5f57daee1d5cb8717e55..ea9d08171e6cef2794753ab83d141915cd2d0b93 100644 (file)
@@ -19,7 +19,7 @@
 use io;
 use io::{Reader, Writer, Seek, Buffer, IoError, SeekStyle, IoResult};
 use slice;
-use slice::{Vector, ImmutableVector, MutableVector};
+use slice::{Slice, ImmutableSlice, MutableSlice};
 use vec::Vec;
 
 static BUF_CAPACITY: uint = 128;
index d098f9a6479146016bfab81ee7d1c53e82580ca2..c95dd8618ed10a7648e14f8f07939117a3a3d9ad 100644 (file)
@@ -235,7 +235,7 @@ fn file_product(p: &Path) -> IoResult<u32> {
 use boxed::Box;
 use result::{Ok, Err, Result};
 use rt::rtio;
-use slice::{Vector, MutableVector, ImmutableVector};
+use slice::{Slice, MutableSlice, ImmutableSlice};
 use str::{Str, StrSlice};
 use str;
 use string::String;
index 0f864c7be5e274e5a1b754e74bea8e5b6e8d1267..ed76cdc276ba62e8488f284fd2eb98fa2f5fb51c 100644 (file)
@@ -21,7 +21,7 @@
 use iter::Iterator;
 use option::{Option, None, Some};
 use str::StrSlice;
-use slice::{MutableCloneableVector, ImmutableVector, MutableVector};
+use slice::{MutableCloneableSlice, ImmutableSlice, MutableSlice};
 
 pub type Port = u16;
 
index 0b0c22ed88799f3efccb362e12793d42ed6a8d59..7055b9d7a473887c5680905eb889372428f047ca 100644 (file)
 use collections::MutableSeq;
 use io::IoResult;
 use iter::Iterator;
-use slice::ImmutableVector;
+use slice::ImmutableSlice;
 use result::{Ok,Err};
 use io::net::addrinfo::get_host_addresses;
 use io::net::ip::SocketAddr;
 use io::{IoError, ConnectionFailed, InvalidInput};
 use io::{Reader, Writer, Listener, Acceptor};
+use io::{standard_error, TimedOut};
 use from_str::FromStr;
 use kinds::Send;
 use option::{None, Some, Option};
@@ -34,6 +35,7 @@
 use rt::rtio::{IoFactory, LocalIo, RtioSocket, RtioTcpListener};
 use rt::rtio::{RtioTcpAcceptor, RtioTcpStream};
 use rt::rtio;
+use time::Duration;
 
 /// A structure which represents a TCP stream between a local socket and a
 /// remote socket.
@@ -92,7 +94,7 @@ pub fn connect(host: &str, port: u16) -> IoResult<TcpStream> {
     }
 
     /// Creates a TCP connection to a remote socket address, timing out after
-    /// the specified number of milliseconds.
+    /// the specified duration.
     ///
     /// This is the same as the `connect` method, except that if the timeout
     /// specified (in milliseconds) elapses before a connection is made an error
@@ -100,13 +102,20 @@ pub fn connect(host: &str, port: u16) -> IoResult<TcpStream> {
     ///
     /// Note that the `addr` argument may one day be split into a separate host
     /// and port, similar to the API seen in `connect`.
+    ///
+    /// If a `timeout` with zero or negative duration is specified then
+    /// the function returns `Err`, with the error kind set to `TimedOut`.
     #[experimental = "the timeout argument may eventually change types"]
     pub fn connect_timeout(addr: SocketAddr,
-                           timeout_ms: u64) -> IoResult<TcpStream> {
+                           timeout: Duration) -> IoResult<TcpStream> {
+        if timeout <= Duration::milliseconds(0) {
+            return Err(standard_error(TimedOut));
+        }
+
         let SocketAddr { ip, port } = addr;
         let addr = rtio::SocketAddr { ip: super::to_rtio(ip), port: port };
         LocalIo::maybe_raise(|io| {
-            io.tcp_connect(addr, Some(timeout_ms)).map(TcpStream::new)
+            io.tcp_connect(addr, Some(timeout.num_milliseconds() as u64)).map(TcpStream::new)
         }).map_err(IoError::from_rtio_error)
     }
 
@@ -164,13 +173,14 @@ pub fn set_keepalive(&mut self, delay_in_seconds: Option<uint>) -> IoResult<()>
     /// # #![allow(unused_must_use)]
     /// use std::io::timer;
     /// use std::io::TcpStream;
+    /// use std::time::Duration;
     ///
     /// let mut stream = TcpStream::connect("127.0.0.1", 34254).unwrap();
     /// let stream2 = stream.clone();
     ///
     /// spawn(proc() {
     ///     // close this stream after one second
-    ///     timer::sleep(1000);
+    ///     timer::sleep(Duration::seconds(1));
     ///     let mut stream = stream2;
     ///     stream.close_read();
     /// });
index 5e7c421497772faa7f7244326a6a238c3ee10b4e..d88af8dd30aa36ae4e0df1e75a820a923d87ed89 100644 (file)
 use c_str::ToCStr;
 use clone::Clone;
 use io::{Listener, Acceptor, Reader, Writer, IoResult, IoError};
+use io::{standard_error, TimedOut};
 use kinds::Send;
 use boxed::Box;
 use rt::rtio::{IoFactory, LocalIo, RtioUnixListener};
 use rt::rtio::{RtioUnixAcceptor, RtioPipe};
+use time::Duration;
 
 /// A stream which communicates over a named pipe.
 pub struct UnixStream {
@@ -66,11 +68,18 @@ pub fn connect<P: ToCStr>(path: &P) -> IoResult<UnixStream> {
     ///
     /// This function is similar to `connect`, except that if `timeout_ms`
     /// elapses the function will return an error of kind `TimedOut`.
+    ///
+    /// If a `timeout` with zero or negative duration is specified then
+    /// the function returns `Err`, with the error kind set to `TimedOut`.
     #[experimental = "the timeout argument is likely to change types"]
     pub fn connect_timeout<P: ToCStr>(path: &P,
-                                      timeout_ms: u64) -> IoResult<UnixStream> {
+                                      timeout: Duration) -> IoResult<UnixStream> {
+        if timeout <= Duration::milliseconds(0) {
+            return Err(standard_error(TimedOut));
+        }
+
         LocalIo::maybe_raise(|io| {
-            let s = io.unix_connect(&path.to_c_str(), Some(timeout_ms));
+            let s = io.unix_connect(&path.to_c_str(), Some(timeout.num_milliseconds() as u64));
             s.map(|p| UnixStream { obj: p })
         }).map_err(IoError::from_rtio_error)
     }
@@ -499,13 +508,25 @@ pub fn smalltest(server: proc(UnixStream):Send, client: proc(UnixStream):Send) {
 
     iotest!(fn connect_timeout_error() {
         let addr = next_test_unix();
-        assert!(UnixStream::connect_timeout(&addr, 100).is_err());
+        assert!(UnixStream::connect_timeout(&addr, Duration::milliseconds(100)).is_err());
     })
 
     iotest!(fn connect_timeout_success() {
         let addr = next_test_unix();
         let _a = UnixListener::bind(&addr).unwrap().listen().unwrap();
-        assert!(UnixStream::connect_timeout(&addr, 100).is_ok());
+        assert!(UnixStream::connect_timeout(&addr, Duration::milliseconds(100)).is_ok());
+    })
+
+    iotest!(fn connect_timeout_zero() {
+        let addr = next_test_unix();
+        let _a = UnixListener::bind(&addr).unwrap().listen().unwrap();
+        assert!(UnixStream::connect_timeout(&addr, Duration::milliseconds(0)).is_err());
+    })
+
+    iotest!(fn connect_timeout_negative() {
+        let addr = next_test_unix();
+        let _a = UnixListener::bind(&addr).unwrap().listen().unwrap();
+        assert!(UnixStream::connect_timeout(&addr, Duration::milliseconds(-1)).is_err());
     })
 
     iotest!(fn close_readwrite_smoke() {
index 1eee69834948fb24db130a6550d8f9acdef6d6a1..3dd4343c5f4fcd4070f05f720ec91f45ac0fc468 100644 (file)
@@ -378,7 +378,8 @@ pub enum StdioContainer {
     Ignored,
 
     /// The specified file descriptor is inherited for the stream which it is
-    /// specified for.
+    /// specified for. Ownership of the file descriptor is *not* taken, so the
+    /// caller must clean it up.
     InheritFd(libc::c_int),
 
     /// Creates a pipe for the specified file descriptor which will be created
@@ -605,6 +606,7 @@ fn drop(&mut self) {
 
 #[cfg(test)]
 mod tests {
+    extern crate native;
     use io::process::{Command, Process};
     use prelude::*;
 
@@ -974,7 +976,7 @@ pub fn sleeper() -> Process {
                 assert!(!p.wait().unwrap().success());
                 return
             }
-            timer::sleep(100);
+            timer::sleep(Duration::milliseconds(100));
         }
         fail!("never saw the child go away");
     })
@@ -1017,4 +1019,25 @@ pub fn sleeper() -> Process {
         assert!(Process::kill(id, 0).is_ok());
         assert!(Process::kill(id, PleaseExitSignal).is_ok());
     })
+
+    iotest!(fn dont_close_fd_on_command_spawn() {
+        use std::rt::rtio::{Truncate, Write};
+        use native::io::file;
+
+        let path = if cfg!(windows) {
+            Path::new("NUL")
+        } else {
+            Path::new("/dev/null")
+        };
+
+        let mut fdes = match file::open(&path.to_c_str(), Truncate, Write) {
+            Ok(f) => f,
+            Err(_) => fail!("failed to open file descriptor"),
+        };
+
+        let mut cmd = pwd_cmd();
+        let _ = cmd.stdout(InheritFd(fdes.fd()));
+        assert!(cmd.status().unwrap().success());
+        assert!(fdes.inner_write("extra write\n".as_bytes()).is_ok());
+    })
 }
index c126866e7159ae67f1d33f84af6bbd25923912df..1d882bdc0ad9e0fddd53ff318921029f8c43f265 100644 (file)
@@ -30,7 +30,7 @@
 use boxed::Box;
 use result::{Ok, Err};
 use rt::rtio::{IoFactory, LocalIo, RtioSignal, Callback};
-use slice::ImmutableVector;
+use slice::ImmutableSlice;
 use vec::Vec;
 
 /// Signals that can be sent and received
@@ -167,6 +167,7 @@ mod test_unix {
     use comm::Empty;
     use io::timer;
     use super::{Listener, Interrupt};
+    use time::Duration;
 
     fn sigint() {
         unsafe {
@@ -179,7 +180,7 @@ fn test_io_signal_smoketest() {
         let mut signal = Listener::new();
         signal.register(Interrupt).unwrap();
         sigint();
-        timer::sleep(10);
+        timer::sleep(Duration::milliseconds(10));
         match signal.rx.recv() {
             Interrupt => (),
             s => fail!("Expected Interrupt, got {:?}", s),
@@ -193,7 +194,7 @@ fn test_io_signal_two_signal_one_signum() {
         s1.register(Interrupt).unwrap();
         s2.register(Interrupt).unwrap();
         sigint();
-        timer::sleep(10);
+        timer::sleep(Duration::milliseconds(10));
         match s1.rx.recv() {
             Interrupt => (),
             s => fail!("Expected Interrupt, got {:?}", s),
@@ -212,7 +213,7 @@ fn test_io_signal_unregister() {
         s2.register(Interrupt).unwrap();
         s2.unregister(Interrupt);
         sigint();
-        timer::sleep(10);
+        timer::sleep(Duration::milliseconds(10));
         assert_eq!(s2.rx.try_recv(), Err(Empty));
     }
 }
index 5b33c3671b48849a561fd70a7c272119415a45d9..fea161c426a2e1a15a22fc5876fc052cd99cab16 100644 (file)
@@ -41,7 +41,7 @@
 use rt::local::Local;
 use rt::task::Task;
 use rt::rtio::{DontClose, IoFactory, LocalIo, RtioFileStream, RtioTTY};
-use slice::ImmutableVector;
+use slice::ImmutableSlice;
 use str::StrSlice;
 use uint;
 
index 331cfa1a59ef9e5de8570c9cbf042f764533006b..079a9aef648aa77e7480eaf57bbfbe1d80c7959d 100644 (file)
@@ -39,6 +39,7 @@ mod $name {
             use io::process::*;
             use rt::running_on_valgrind;
             use str;
+            use time::Duration;
 
             fn f() $b
 
index 1c9e428dcad82e897897ddcc4f40ba6c2c3a913b..39c6c74e45eef62c59028409b2f1875bd3d0d449 100644 (file)
 
 */
 
+// FIXME: These functions take Durations but only pass ms to the backend impls.
+
 use comm::{Receiver, Sender, channel};
+use time::Duration;
 use io::{IoResult, IoError};
 use kinds::Send;
 use boxed::Box;
 /// # fn main() {}
 /// # fn foo() {
 /// use std::io::Timer;
+/// use std::time::Duration;
 ///
 /// let mut timer = Timer::new().unwrap();
-/// timer.sleep(10); // block the task for awhile
+/// timer.sleep(Duration::milliseconds(10)); // block the task for awhile
 ///
-/// let timeout = timer.oneshot(10);
+/// let timeout = timer.oneshot(Duration::milliseconds(10));
 /// // do some work
 /// timeout.recv(); // wait for the timeout to expire
 ///
-/// let periodic = timer.periodic(10);
+/// let periodic = timer.periodic(Duration::milliseconds(10));
 /// loop {
 ///     periodic.recv();
 ///     // this loop is only executed once every 10ms
 /// # fn main() {}
 /// # fn foo() {
 /// use std::io::timer;
+/// use std::time::Duration;
 ///
 /// // Put this task to sleep for 5 seconds
-/// timer::sleep(5000);
+/// timer::sleep(Duration::seconds(5));
 /// # }
 /// ```
 pub struct Timer {
@@ -69,12 +74,15 @@ pub struct Timer {
 
 struct TimerCallback { tx: Sender<()> }
 
-/// Sleep the current task for `msecs` milliseconds.
-pub fn sleep(msecs: u64) {
+/// Sleep the current task for the specified duration.
+///
+/// When provided a zero or negative `duration`, the function will
+/// return immediately.
+pub fn sleep(duration: Duration) {
     let timer = Timer::new();
     let mut timer = timer.ok().expect("timer::sleep: could not create a Timer");
 
-    timer.sleep(msecs)
+    timer.sleep(duration)
 }
 
 impl Timer {
@@ -87,16 +95,22 @@ pub fn new() -> IoResult<Timer> {
         }).map_err(IoError::from_rtio_error)
     }
 
-    /// Blocks the current task for `msecs` milliseconds.
+    /// Blocks the current task for the specified duration.
     ///
     /// Note that this function will cause any other receivers for this timer to
     /// be invalidated (the other end will be closed).
-    pub fn sleep(&mut self, msecs: u64) {
-        self.obj.sleep(msecs);
+    ///
+    /// When provided a zero or negative `duration`, the function will
+    /// return immediately.
+    pub fn sleep(&mut self, duration: Duration) {
+        // Short-circuit the timer backend for 0 duration
+        let ms = in_ms_u64(duration);
+        if ms == 0 { return }
+        self.obj.sleep(ms);
     }
 
     /// Creates a oneshot receiver which will have a notification sent when
-    /// `msecs` milliseconds has elapsed.
+    /// the specified duration has elapsed.
     ///
     /// This does *not* block the current task, but instead returns immediately.
     ///
@@ -111,9 +125,10 @@ pub fn sleep(&mut self, msecs: u64) {
     ///
     /// ```rust
     /// use std::io::Timer;
+    /// use std::time::Duration;
     ///
     /// let mut timer = Timer::new().unwrap();
-    /// let ten_milliseconds = timer.oneshot(10);
+    /// let ten_milliseconds = timer.oneshot(Duration::milliseconds(10));
     ///
     /// for _ in range(0u, 100) { /* do work */ }
     ///
@@ -123,24 +138,33 @@ pub fn sleep(&mut self, msecs: u64) {
     ///
     /// ```rust
     /// use std::io::Timer;
+    /// use std::time::Duration;
     ///
     /// // Incorrect, method chaining-style:
-    /// let mut five_ms = Timer::new().unwrap().oneshot(5);
+    /// let mut five_ms = Timer::new().unwrap().oneshot(Duration::milliseconds(5));
     /// // The timer object was destroyed, so this will always fail:
     /// // five_ms.recv()
     /// ```
-    pub fn oneshot(&mut self, msecs: u64) -> Receiver<()> {
+    ///
+    /// When provided a zero or negative `duration`, the message will
+    /// be sent immediately.
+    pub fn oneshot(&mut self, duration: Duration) -> Receiver<()> {
         let (tx, rx) = channel();
-        self.obj.oneshot(msecs, box TimerCallback { tx: tx });
+        // Short-circuit the timer backend for 0 duration
+        if in_ms_u64(duration) != 0 {
+            self.obj.oneshot(in_ms_u64(duration), box TimerCallback { tx: tx });
+        } else {
+            tx.send(());
+        }
         return rx
     }
 
     /// Creates a receiver which will have a continuous stream of notifications
-    /// being sent every `msecs` milliseconds.
+    /// being sent each time the specified duration has elapsed.
     ///
     /// This does *not* block the current task, but instead returns
     /// immediately. The first notification will not be received immediately,
-    /// but rather after `msec` milliseconds have passed.
+    /// but rather after the first duration.
     ///
     /// Note that this invalidates any previous receiver which has been created
     /// by this timer, and that the returned receiver will be invalidated once
@@ -153,9 +177,10 @@ pub fn oneshot(&mut self, msecs: u64) -> Receiver<()> {
     ///
     /// ```rust
     /// use std::io::Timer;
+    /// use std::time::Duration;
     ///
     /// let mut timer = Timer::new().unwrap();
-    /// let ten_milliseconds = timer.periodic(10);
+    /// let ten_milliseconds = timer.periodic(Duration::milliseconds(10));
     ///
     /// for _ in range(0u, 100) { /* do work */ }
     ///
@@ -171,15 +196,24 @@ pub fn oneshot(&mut self, msecs: u64) -> Receiver<()> {
     ///
     /// ```rust
     /// use std::io::Timer;
+    /// use std::time::Duration;
     ///
     /// // Incorrect, method chaining-style.
-    /// let mut five_ms = Timer::new().unwrap().periodic(5);
+    /// let mut five_ms = Timer::new().unwrap().periodic(Duration::milliseconds(5));
     /// // The timer object was destroyed, so this will always fail:
     /// // five_ms.recv()
     /// ```
-    pub fn periodic(&mut self, msecs: u64) -> Receiver<()> {
+    ///
+    /// When provided a zero or negative `duration`, the messages will
+    /// be sent without delay.
+    pub fn periodic(&mut self, duration: Duration) -> Receiver<()> {
+        let ms = in_ms_u64(duration);
+        // FIXME: The backend implementations don't ever send a message
+        // if given a 0 ms duration. Temporarily using 1ms. It's
+        // not clear what use a 0ms period is anyway...
+        let ms = if ms == 0 { 1 } else { ms };
         let (tx, rx) = channel();
-        self.obj.period(msecs, box TimerCallback { tx: tx });
+        self.obj.period(ms, box TimerCallback { tx: tx });
         return rx
     }
 }
@@ -190,42 +224,48 @@ fn call(&mut self) {
     }
 }
 
+fn in_ms_u64(d: Duration) -> u64 {
+    let ms = d.num_milliseconds();
+    if ms < 0 { return 0 };
+    return ms as u64;
+}
+
 #[cfg(test)]
 mod test {
     iotest!(fn test_io_timer_sleep_simple() {
         let mut timer = Timer::new().unwrap();
-        timer.sleep(1);
+        timer.sleep(Duration::milliseconds(1));
     })
 
     iotest!(fn test_io_timer_sleep_oneshot() {
         let mut timer = Timer::new().unwrap();
-        timer.oneshot(1).recv();
+        timer.oneshot(Duration::milliseconds(1)).recv();
     })
 
     iotest!(fn test_io_timer_sleep_oneshot_forget() {
         let mut timer = Timer::new().unwrap();
-        timer.oneshot(100000000000);
+        timer.oneshot(Duration::milliseconds(100000000));
     })
 
     iotest!(fn oneshot_twice() {
         let mut timer = Timer::new().unwrap();
-        let rx1 = timer.oneshot(10000);
-        let rx = timer.oneshot(1);
+        let rx1 = timer.oneshot(Duration::milliseconds(10000));
+        let rx = timer.oneshot(Duration::milliseconds(1));
         rx.recv();
         assert_eq!(rx1.recv_opt(), Err(()));
     })
 
     iotest!(fn test_io_timer_oneshot_then_sleep() {
         let mut timer = Timer::new().unwrap();
-        let rx = timer.oneshot(100000000000);
-        timer.sleep(1); // this should invalidate rx
+        let rx = timer.oneshot(Duration::milliseconds(100000000));
+        timer.sleep(Duration::milliseconds(1)); // this should invalidate rx
 
         assert_eq!(rx.recv_opt(), Err(()));
     })
 
     iotest!(fn test_io_timer_sleep_periodic() {
         let mut timer = Timer::new().unwrap();
-        let rx = timer.periodic(1);
+        let rx = timer.periodic(Duration::milliseconds(1));
         rx.recv();
         rx.recv();
         rx.recv();
@@ -233,60 +273,60 @@ mod test {
 
     iotest!(fn test_io_timer_sleep_periodic_forget() {
         let mut timer = Timer::new().unwrap();
-        timer.periodic(100000000000);
+        timer.periodic(Duration::milliseconds(100000000));
     })
 
     iotest!(fn test_io_timer_sleep_standalone() {
-        sleep(1)
+        sleep(Duration::milliseconds(1))
     })
 
     iotest!(fn oneshot() {
         let mut timer = Timer::new().unwrap();
 
-        let rx = timer.oneshot(1);
+        let rx = timer.oneshot(Duration::milliseconds(1));
         rx.recv();
         assert!(rx.recv_opt().is_err());
 
-        let rx = timer.oneshot(1);
+        let rx = timer.oneshot(Duration::milliseconds(1));
         rx.recv();
         assert!(rx.recv_opt().is_err());
     })
 
     iotest!(fn override() {
         let mut timer = Timer::new().unwrap();
-        let orx = timer.oneshot(100);
-        let prx = timer.periodic(100);
-        timer.sleep(1);
+        let orx = timer.oneshot(Duration::milliseconds(100));
+        let prx = timer.periodic(Duration::milliseconds(100));
+        timer.sleep(Duration::milliseconds(1));
         assert_eq!(orx.recv_opt(), Err(()));
         assert_eq!(prx.recv_opt(), Err(()));
-        timer.oneshot(1).recv();
+        timer.oneshot(Duration::milliseconds(1)).recv();
     })
 
     iotest!(fn period() {
         let mut timer = Timer::new().unwrap();
-        let rx = timer.periodic(1);
+        let rx = timer.periodic(Duration::milliseconds(1));
         rx.recv();
         rx.recv();
-        let rx2 = timer.periodic(1);
+        let rx2 = timer.periodic(Duration::milliseconds(1));
         rx2.recv();
         rx2.recv();
     })
 
     iotest!(fn sleep() {
         let mut timer = Timer::new().unwrap();
-        timer.sleep(1);
-        timer.sleep(1);
+        timer.sleep(Duration::milliseconds(1));
+        timer.sleep(Duration::milliseconds(1));
     })
 
     iotest!(fn oneshot_fail() {
         let mut timer = Timer::new().unwrap();
-        let _rx = timer.oneshot(1);
+        let _rx = timer.oneshot(Duration::milliseconds(1));
         fail!();
     } #[should_fail])
 
     iotest!(fn period_fail() {
         let mut timer = Timer::new().unwrap();
-        let _rx = timer.periodic(1);
+        let _rx = timer.periodic(Duration::milliseconds(1));
         fail!();
     } #[should_fail])
 
@@ -298,7 +338,7 @@ mod test {
     iotest!(fn closing_channel_during_drop_doesnt_kill_everything() {
         // see issue #10375
         let mut timer = Timer::new().unwrap();
-        let timer_rx = timer.periodic(1000);
+        let timer_rx = timer.periodic(Duration::milliseconds(1000));
 
         spawn(proc() {
             let _ = timer_rx.recv_opt();
@@ -311,31 +351,31 @@ mod test {
     iotest!(fn reset_doesnt_switch_tasks() {
         // similar test to the one above.
         let mut timer = Timer::new().unwrap();
-        let timer_rx = timer.periodic(1000);
+        let timer_rx = timer.periodic(Duration::milliseconds(1000));
 
         spawn(proc() {
             let _ = timer_rx.recv_opt();
         });
 
-        timer.oneshot(1);
+        timer.oneshot(Duration::milliseconds(1));
     })
 
     iotest!(fn reset_doesnt_switch_tasks2() {
         // similar test to the one above.
         let mut timer = Timer::new().unwrap();
-        let timer_rx = timer.periodic(1000);
+        let timer_rx = timer.periodic(Duration::milliseconds(1000));
 
         spawn(proc() {
             let _ = timer_rx.recv_opt();
         });
 
-        timer.sleep(1);
+        timer.sleep(Duration::milliseconds(1));
     })
 
     iotest!(fn sender_goes_away_oneshot() {
         let rx = {
             let mut timer = Timer::new().unwrap();
-            timer.oneshot(1000)
+            timer.oneshot(Duration::milliseconds(1000))
         };
         assert_eq!(rx.recv_opt(), Err(()));
     })
@@ -343,26 +383,67 @@ mod test {
     iotest!(fn sender_goes_away_period() {
         let rx = {
             let mut timer = Timer::new().unwrap();
-            timer.periodic(1000)
+            timer.periodic(Duration::milliseconds(1000))
         };
         assert_eq!(rx.recv_opt(), Err(()));
     })
 
     iotest!(fn receiver_goes_away_oneshot() {
         let mut timer1 = Timer::new().unwrap();
-        timer1.oneshot(1);
+        timer1.oneshot(Duration::milliseconds(1));
         let mut timer2 = Timer::new().unwrap();
         // while sleeping, the previous timer should fire and not have its
         // callback do something terrible.
-        timer2.sleep(2);
+        timer2.sleep(Duration::milliseconds(2));
     })
 
     iotest!(fn receiver_goes_away_period() {
         let mut timer1 = Timer::new().unwrap();
-        timer1.periodic(1);
+        timer1.periodic(Duration::milliseconds(1));
         let mut timer2 = Timer::new().unwrap();
         // while sleeping, the previous timer should fire and not have its
         // callback do something terrible.
-        timer2.sleep(2);
+        timer2.sleep(Duration::milliseconds(2));
+    })
+
+    iotest!(fn sleep_zero() {
+        let mut timer = Timer::new().unwrap();
+        timer.sleep(Duration::milliseconds(0));
+    })
+
+    iotest!(fn sleep_negative() {
+        let mut timer = Timer::new().unwrap();
+        timer.sleep(Duration::milliseconds(-1000000));
+    })
+
+    iotest!(fn oneshot_zero() {
+        let mut timer = Timer::new().unwrap();
+        let rx = timer.oneshot(Duration::milliseconds(0));
+        rx.recv();
+    })
+
+    iotest!(fn oneshot_negative() {
+        let mut timer = Timer::new().unwrap();
+        let rx = timer.oneshot(Duration::milliseconds(-1000000));
+        rx.recv();
+    })
+
+    iotest!(fn periodic_zero() {
+        let mut timer = Timer::new().unwrap();
+        let rx = timer.periodic(Duration::milliseconds(0));
+        rx.recv();
+        rx.recv();
+        rx.recv();
+        rx.recv();
     })
+
+    iotest!(fn periodic_negative() {
+        let mut timer = Timer::new().unwrap();
+        let rx = timer.periodic(Duration::milliseconds(-1000000));
+        rx.recv();
+        rx.recv();
+        rx.recv();
+        rx.recv();
+    })
+
 }
index 20fc7efeb574f15d4a7a0884286e082dc1504d8e..103cd574e7381d0634b842b30c780cc02d5b2b88 100644 (file)
@@ -233,6 +233,8 @@ fn start(argc: int, argv: *const *const u8) -> int {
 #[cfg(not(test))]
 pub mod gc;
 
+pub mod time;
+
 /* Common traits */
 
 pub mod from_str;
index 9b97513935c80dc87e5d6fdabe48a7d475649264..f5b2f31a127d603f25fc09ea5d8513e885d3380a 100644 (file)
@@ -17,7 +17,7 @@
 use num::{ToStrRadix, FromStrRadix};
 use num::strconv;
 use option::Option;
-use slice::ImmutableVector;
+use slice::ImmutableSlice;
 use string::String;
 
 pub use core::i16::{BITS, BYTES, MIN, MAX};
index 03dcbb0f6d671927aec39d3e0c3cd6941c788b5c..623a10725c826387d8c942b9c0f79efd3e416658 100644 (file)
@@ -17,7 +17,7 @@
 use num::{ToStrRadix, FromStrRadix};
 use num::strconv;
 use option::Option;
-use slice::ImmutableVector;
+use slice::ImmutableSlice;
 use string::String;
 
 pub use core::i32::{BITS, BYTES, MIN, MAX};
index 347b5b4b93ce7f6a14d1ed51b6a1df26f7bd8dfc..ffb1307908c90821941ee8721d7a7ed8c20989f2 100644 (file)
@@ -17,7 +17,7 @@
 use num::{ToStrRadix, FromStrRadix};
 use num::strconv;
 use option::Option;
-use slice::ImmutableVector;
+use slice::ImmutableSlice;
 use string::String;
 
 pub use core::i64::{BITS, BYTES, MIN, MAX};
index fd6f96a0f97be8a9b6b16c24331bcdf69c0cd1d1..4fbb7381238dc77569a6a05aafd84e20d1f9ac45 100644 (file)
@@ -17,7 +17,7 @@
 use num::{ToStrRadix, FromStrRadix};
 use num::strconv;
 use option::Option;
-use slice::ImmutableVector;
+use slice::ImmutableSlice;
 use string::String;
 
 pub use core::i8::{BITS, BYTES, MIN, MAX};
index 1888d6a519e398e727f157a8740fd3970a52387f..7821306f5fc3da122ee4d2f4d027a6920272b1c8 100644 (file)
@@ -17,7 +17,7 @@
 use num::{ToStrRadix, FromStrRadix};
 use num::strconv;
 use option::Option;
-use slice::ImmutableVector;
+use slice::ImmutableSlice;
 use string::String;
 
 pub use core::int::{BITS, BYTES, MIN, MAX};
index 37378518dc8e123b98688ab042bb73734dd94462..407c8ea61d9146eeef1b061eb3ac96d6871586cd 100644 (file)
@@ -20,7 +20,7 @@
 use num;
 use ops::{Add, Sub, Mul, Div, Rem, Neg};
 use option::{None, Option, Some};
-use slice::{ImmutableVector, MutableVector};
+use slice::{ImmutableSlice, MutableSlice};
 use std::cmp::{PartialOrd, PartialEq};
 use str::StrSlice;
 use string::String;
index 727d756106276acb409bbf6551247ace868109fd..0f00f99e980a2a6c387555fd8ca36bbb7b3cdd33 100644 (file)
@@ -17,7 +17,7 @@
 use num::{ToStrRadix, FromStrRadix};
 use num::strconv;
 use option::Option;
-use slice::ImmutableVector;
+use slice::ImmutableSlice;
 use string::String;
 
 pub use core::u16::{BITS, BYTES, MIN, MAX};
index d18bfdf9fbac0e110330f9acefca44fed673fae6..e6c6bc377b7aa304d51cb468c93f06ac091b6768 100644 (file)
@@ -17,7 +17,7 @@
 use num::{ToStrRadix, FromStrRadix};
 use num::strconv;
 use option::Option;
-use slice::ImmutableVector;
+use slice::ImmutableSlice;
 use string::String;
 
 pub use core::u32::{BITS, BYTES, MIN, MAX};
index 53e88a96f332d0ce1fe944474289cafda2a71f35..7eb9e1a082fe872abb009e326cc94657d7048a41 100644 (file)
@@ -17,7 +17,7 @@
 use num::{ToStrRadix, FromStrRadix};
 use num::strconv;
 use option::Option;
-use slice::ImmutableVector;
+use slice::ImmutableSlice;
 use string::String;
 
 pub use core::u64::{BITS, BYTES, MIN, MAX};
index e6cbd14bf417ddf9bd57b78c8aa1ac6dce6751f8..300dd3bcc01a4cfc69f2f7965bb0f614a024f7ec 100644 (file)
@@ -17,7 +17,7 @@
 use num::{ToStrRadix, FromStrRadix};
 use num::strconv;
 use option::Option;
-use slice::ImmutableVector;
+use slice::ImmutableSlice;
 use string::String;
 
 pub use core::u8::{BITS, BYTES, MIN, MAX};
index 41c4caf4006f1403e88fb7d655429698253a9df2..0adc22e321406ebdce3ef58c05d77dec808c8521 100644 (file)
@@ -17,7 +17,7 @@
 use num::{ToStrRadix, FromStrRadix};
 use num::strconv;
 use option::Option;
-use slice::ImmutableVector;
+use slice::ImmutableSlice;
 use string::String;
 
 pub use core::uint::{BITS, BYTES, MIN, MAX};
index 85445e49139352e706f437ca5309af01d20bcfe8..d8eb0979190d447baf11d44d3b8f120c82bcde30 100644 (file)
@@ -45,7 +45,7 @@
 use ptr::RawPtr;
 use ptr;
 use result::{Err, Ok, Result};
-use slice::{Vector, ImmutableVector, MutableVector, ImmutableEqVector};
+use slice::{Slice, ImmutableSlice, MutableSlice, ImmutablePartialEqSlice};
 use str::{Str, StrSlice, StrAllocating};
 use string::String;
 use sync::atomic::{AtomicInt, INIT_ATOMIC_INT, SeqCst};
@@ -145,7 +145,7 @@ pub mod win32 {
     use option::{None, Option};
     use option;
     use os::TMPBUF_SZ;
-    use slice::{MutableVector, ImmutableVector};
+    use slice::{MutableSlice, ImmutableSlice};
     use string::String;
     use str::StrSlice;
     use vec::Vec;
@@ -1842,7 +1842,8 @@ pub mod consts {
     pub static EXE_EXTENSION: &'static str = "";
 }
 
-#[cfg(target_os = "win32")]
+#[cfg(target_os = "windows")]
+#[cfg(stage0, target_os = "win32")] // NOTE: Remove after snapshot
 pub mod consts {
     pub use os::arch_consts::ARCH;
 
@@ -1850,7 +1851,7 @@ pub mod consts {
 
     /// A string describing the specific operating system in use: in this
     /// case, `win32`.
-    pub static SYSNAME: &'static str = "win32";
+    pub static SYSNAME: &'static str = "windows";
 
     /// Specifies the filename prefix used for shared libraries on this
     /// platform: in this case, the empty string.
index d290a5f8c63c758d12113b5ddf923e844f118838..d24c2e2266d4c68ae5165be33821b77612692fab 100644 (file)
@@ -74,8 +74,8 @@
 use str;
 use str::{MaybeOwned, Str, StrSlice};
 use string::String;
-use slice::Vector;
-use slice::{ImmutableEqVector, ImmutableVector};
+use slice::Slice;
+use slice::{ImmutablePartialEqSlice, ImmutableSlice};
 use vec::Vec;
 
 /// Typedef for POSIX file paths.
index 9a4bc11f5c03a8fd78eef3204c11e497d8937561..0a7817c3e0047dd71c73d79b03f288e18e5cf95c 100644 (file)
@@ -21,8 +21,8 @@
 use option::{Option, None, Some};
 use str::Str;
 use str;
-use slice::{CloneableVector, Splits, Vector, VectorVector,
-            ImmutableEqVector, ImmutableVector};
+use slice::{CloneableVector, Splits, Slice, VectorVector,
+            ImmutablePartialEqSlice, ImmutableSlice};
 use vec::Vec;
 
 use super::{BytesContainer, GenericPath, GenericPathUnsafe};
@@ -367,7 +367,7 @@ pub fn new_opt<T: BytesContainer>(path: T) -> Option<Path> {
 
     /// Returns a normalized byte vector representation of a path, by removing all empty
     /// components, and unnecessary . and .. components.
-    fn normalize<V: Vector<u8>+CloneableVector<u8>>(v: V) -> Vec<u8> {
+    fn normalize<V: Slice<u8>+CloneableVector<u8>>(v: V) -> Vec<u8> {
         // borrowck is being very picky
         let val = {
             let is_abs = !v.as_slice().is_empty() && v.as_slice()[0] == SEP_BYTE;
index c3a217bf940f3a3b716b0e4cb6f89f3a4d103fb3..8402d751bf2c81f54d1e5cfee784325ee1dd4cc8 100644 (file)
@@ -23,7 +23,7 @@
 use iter::{AdditiveIterator, DoubleEndedIterator, Extendable, Iterator, Map};
 use mem;
 use option::{Option, Some, None};
-use slice::{Vector, ImmutableVector};
+use slice::{Slice, ImmutableSlice};
 use str::{CharSplits, Str, StrAllocating, StrVector, StrSlice};
 use string::String;
 use unicode::char::UnicodeChar;
index aa407ce8e0ccbb9de5d5e2637dab8b898ad10bb7..eb6dcc1f1a586d250600d8b3fbfd39fa4a97532d 100644 (file)
 #[doc(no_inline)] pub use tuple::{Tuple5, Tuple6, Tuple7, Tuple8};
 #[doc(no_inline)] pub use tuple::{Tuple9, Tuple10, Tuple11, Tuple12};
 #[doc(no_inline)] pub use slice::{CloneableVector, ImmutableCloneableVector};
-#[doc(no_inline)] pub use slice::{MutableCloneableVector, MutableOrdVector};
-#[doc(no_inline)] pub use slice::{ImmutableVector, MutableVector};
-#[doc(no_inline)] pub use slice::{ImmutableEqVector, ImmutableOrdVector};
-#[doc(no_inline)] pub use slice::{Vector, VectorVector};
-#[doc(no_inline)] pub use slice::MutableVectorAllocating;
+#[doc(no_inline)] pub use slice::{MutableCloneableSlice, MutableOrdSlice};
+#[doc(no_inline)] pub use slice::{ImmutableSlice, MutableSlice};
+#[doc(no_inline)] pub use slice::{ImmutablePartialEqSlice, ImmutableOrdSlice};
+#[doc(no_inline)] pub use slice::{Slice, VectorVector};
+#[doc(no_inline)] pub use slice::MutableSliceAllocating;
 #[doc(no_inline)] pub use string::String;
 #[doc(no_inline)] pub use vec::Vec;
 
index ffe8e539ffba13b9b07516eb393fce74d3354a0a..2be4129883f7421aa9ee966140e7a03adc4bac4b 100644 (file)
@@ -70,7 +70,7 @@ mod imp {
     use rand::Rng;
     use result::{Ok};
     use self::libc::{c_int, size_t};
-    use slice::MutableVector;
+    use slice::MutableSlice;
 
     /// A random number generator that retrieves randomness straight from
     /// the operating system. Platform sources:
@@ -138,7 +138,7 @@ mod imp {
     use rt::stack;
     use self::libc::{DWORD, BYTE, LPCSTR, BOOL};
     use self::libc::types::os::arch::extra::{LONG_PTR};
-    use slice::MutableVector;
+    use slice::MutableSlice;
 
     type HCRYPTPROV = LONG_PTR;
 
index b86937e4213014a69bda32dd68eeaaaff93bb5bd..a4491b2ab1d4695f3e467205c1d8e31694c11d70 100644 (file)
@@ -258,7 +258,7 @@ mod imp {
     pub fn write(w: &mut Writer) -> IoResult<()> {
         use iter::{Iterator, range};
         use result;
-        use slice::{MutableVector};
+        use slice::{MutableSlice};
 
         extern {
             fn backtrace(buf: *mut *mut libc::c_void,
@@ -398,7 +398,7 @@ fn print(w: &mut Writer, idx: int, addr: *mut libc::c_void) -> IoResult<()> {
         use path::GenericPath;
         use ptr::RawPtr;
         use ptr;
-        use slice::{ImmutableVector, MutableVector};
+        use slice::{ImmutableSlice, MutableSlice};
 
         ////////////////////////////////////////////////////////////////////////
         // libbacktrace.h API
@@ -670,7 +670,7 @@ mod imp {
     use path::Path;
     use result::{Ok, Err};
     use rt::mutex::{StaticNativeMutex, NATIVE_MUTEX_INIT};
-    use slice::ImmutableVector;
+    use slice::ImmutableSlice;
     use str::StrSlice;
     use dynamic_lib::DynamicLibrary;
 
index 19ad81a04834d606ebaa613928f281f6bf8a220f..9cace9c80ef5ad1a5dd60f1a7dcd923c32bb38c0 100644 (file)
@@ -664,10 +664,11 @@ fn test_stdout() {
 #[test]
 fn task_abort_no_kill_runtime() {
     use std::io::timer;
+    use time::Duration;
     use mem;
 
     let tb = TaskBuilder::new();
     let rx = tb.try_future(proc() {});
     mem::drop(rx);
-    timer::sleep(1000);
+    timer::sleep(Duration::milliseconds(1000));
 }
diff --git a/src/libstd/time/duration.rs b/src/libstd/time/duration.rs
new file mode 100644 (file)
index 0000000..545d1f2
--- /dev/null
@@ -0,0 +1,634 @@
+// 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.
+//
+// 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.
+
+//! Temporal quantification
+
+#![experimental]
+
+use {fmt, i32};
+use ops::{Add, Sub, Mul, Div, Neg};
+use option::{Option, Some, None};
+use num;
+use num::{CheckedAdd, CheckedMul};
+use result::{Result, Ok, Err};
+
+
+/// `Duration`'s `days` component should have no more than this value.
+static MIN_DAYS: i32 = i32::MIN;
+/// `Duration`'s `days` component should have no less than this value.
+static MAX_DAYS: i32 = i32::MAX;
+
+/// The number of nanoseconds in seconds.
+static NANOS_PER_SEC: i32 = 1_000_000_000;
+/// The number of (non-leap) seconds in days.
+static SECS_PER_DAY: i32 = 86400;
+
+macro_rules! try_opt(
+    ($e:expr) => (match $e { Some(v) => v, None => return None })
+)
+
+
+// FIXME #16466: This could be represented as (i64 seconds, u32 nanos)
+/// ISO 8601 time duration with nanosecond precision.
+/// This also allows for the negative duration; see individual methods for details.
+#[deriving(PartialEq, Eq, PartialOrd, Ord)]
+pub struct Duration {
+    days: i32,
+    secs: u32,  // Always < SECS_PER_DAY
+    nanos: u32, // Always < NANOS_PR_SECOND
+}
+
+/// The minimum possible `Duration`.
+pub static MIN: Duration = Duration { days: MIN_DAYS, secs: 0, nanos: 0 };
+/// The maximum possible `Duration`.
+pub static MAX: Duration = Duration { days: MAX_DAYS, secs: SECS_PER_DAY as u32 - 1,
+                                      nanos: NANOS_PER_SEC as u32 - 1 };
+
+impl Duration {
+    /// Makes a new `Duration` with given number of weeks.
+    /// Equivalent to `Duration::new(weeks * 7, 0, 0)` with overflow checks.
+    ///
+    /// Fails when the duration is out of bounds.
+    #[inline]
+    pub fn weeks(weeks: i32) -> Duration {
+        let days = weeks.checked_mul(&7).expect("Duration::weeks out of bounds");
+        Duration::days(days)
+    }
+
+    /// Makes a new `Duration` with given number of days.
+    /// Equivalent to `Duration::new(days, 0, 0)`.
+    #[inline]
+    pub fn days(days: i32) -> Duration {
+        Duration { days: days, secs: 0, nanos: 0 }
+    }
+
+    /// Makes a new `Duration` with given number of hours.
+    /// Equivalent to `Duration::new(0, hours * 3600, 0)` with overflow checks.
+    #[inline]
+    pub fn hours(hours: i32) -> Duration {
+        let (days, hours) = div_mod_floor(hours, (SECS_PER_DAY / 3600));
+        let secs = hours * 3600;
+        Duration { secs: secs as u32, ..Duration::days(days) }
+    }
+
+    /// Makes a new `Duration` with given number of minutes.
+    /// Equivalent to `Duration::new(0, mins * 60, 0)` with overflow checks.
+    #[inline]
+    pub fn minutes(mins: i32) -> Duration {
+        let (days, mins) = div_mod_floor(mins, (SECS_PER_DAY / 60));
+        let secs = mins * 60;
+        Duration { secs: secs as u32, ..Duration::days(days) }
+    }
+
+    /// Makes a new `Duration` with given number of seconds.
+    /// Equivalent to `Duration::new(0, secs, 0)`.
+    #[inline]
+    pub fn seconds(secs: i32) -> Duration {
+        let (days, secs) = div_mod_floor(secs, SECS_PER_DAY);
+        Duration { secs: secs as u32, ..Duration::days(days) }
+    }
+
+    /// Makes a new `Duration` with given number of milliseconds.
+    /// Equivalent to `Duration::new(0, 0, millis * 1_000_000)` with overflow checks.
+    #[inline]
+    pub fn milliseconds(millis: i32) -> Duration {
+        let (secs, millis) = div_mod_floor(millis, (NANOS_PER_SEC / 1_000_000));
+        let nanos = millis * 1_000_000;
+        Duration { nanos: nanos as u32, ..Duration::seconds(secs) }
+    }
+
+    /// Makes a new `Duration` with given number of microseconds.
+    /// Equivalent to `Duration::new(0, 0, micros * 1_000)` with overflow checks.
+    #[inline]
+    pub fn microseconds(micros: i32) -> Duration {
+        let (secs, micros) = div_mod_floor(micros, (NANOS_PER_SEC / 1_000));
+        let nanos = micros * 1_000;
+        Duration { nanos: nanos as u32, ..Duration::seconds(secs) }
+    }
+
+    /// Makes a new `Duration` with given number of nanoseconds.
+    /// Equivalent to `Duration::new(0, 0, nanos)`.
+    #[inline]
+    pub fn nanoseconds(nanos: i32) -> Duration {
+        let (secs, nanos) = div_mod_floor(nanos, NANOS_PER_SEC);
+        Duration { nanos: nanos as u32, ..Duration::seconds(secs) }
+    }
+
+    /// Returns a tuple of the number of days, (non-leap) seconds and
+    /// nanoseconds in the duration.  Note that the number of seconds
+    /// and nanoseconds are always positive, so that for example
+    /// `-Duration::seconds(3)` has -1 days and 86,397 seconds.
+    #[inline]
+    fn to_tuple_64(&self) -> (i64, u32, u32) {
+        (self.days as i64, self.secs, self.nanos)
+    }
+
+    /// Negates the duration and returns a tuple like `to_tuple`.
+    /// This does not overflow and thus is internally used for several methods.
+    fn to_negated_tuple_64(&self) -> (i64, u32, u32) {
+        let mut days = -(self.days as i64);
+        let mut secs = -(self.secs as i32);
+        let mut nanos = -(self.nanos as i32);
+        if nanos < 0 {
+            nanos += NANOS_PER_SEC;
+            secs -= 1;
+        }
+        if secs < 0 {
+            secs += SECS_PER_DAY;
+            days -= 1;
+        }
+        (days, secs as u32, nanos as u32)
+    }
+
+    /// Returns the total number of whole weeks in the duration.
+    #[inline]
+    pub fn num_weeks(&self) -> i32 {
+        self.num_days() / 7
+    }
+
+    /// Returns the total number of whole days in the duration.
+    pub fn num_days(&self) -> i32 {
+        if self.days < 0 {
+            let negated = -*self;
+            -negated.days
+        } else {
+            self.days
+        }
+    }
+
+    /// Returns the total number of whole hours in the duration.
+    #[inline]
+    pub fn num_hours(&self) -> i64 {
+        self.num_seconds() / 3600
+    }
+
+    /// Returns the total number of whole minutes in the duration.
+    #[inline]
+    pub fn num_minutes(&self) -> i64 {
+        self.num_seconds() / 60
+    }
+
+    /// Returns the total number of whole seconds in the duration.
+    pub fn num_seconds(&self) -> i64 {
+        // cannot overflow, 2^32 * 86400 < 2^64
+        fn secs((days, secs, _): (i64, u32, u32)) -> i64 {
+            days as i64 * SECS_PER_DAY as i64 + secs as i64
+        }
+        if self.days < 0 {-secs(self.to_negated_tuple_64())} else {secs(self.to_tuple_64())}
+    }
+
+    /// Returns the total number of whole milliseconds in the duration.
+    pub fn num_milliseconds(&self) -> i64 {
+        // cannot overflow, 2^32 * 86400 * 1000 < 2^64
+        fn millis((days, secs, nanos): (i64, u32, u32)) -> i64 {
+            static MILLIS_PER_SEC: i64 = 1_000;
+            static NANOS_PER_MILLI: i64 = 1_000_000;
+            (days as i64 * MILLIS_PER_SEC * SECS_PER_DAY as i64 +
+             secs as i64 * MILLIS_PER_SEC +
+             nanos as i64 / NANOS_PER_MILLI)
+        }
+        if self.days < 0 {-millis(self.to_negated_tuple_64())} else {millis(self.to_tuple_64())}
+    }
+
+    /// Returns the total number of whole microseconds in the duration,
+    /// or `None` on the overflow (exceeding 2^63 microseconds in either directions).
+    pub fn num_microseconds(&self) -> Option<i64> {
+        fn micros((days, secs, nanos): (i64, u32, u32)) -> Option<i64> {
+            static MICROS_PER_SEC: i64 = 1_000_000;
+            static MICROS_PER_DAY: i64 = MICROS_PER_SEC * SECS_PER_DAY as i64;
+            static NANOS_PER_MICRO: i64 = 1_000;
+            let nmicros = try_opt!((days as i64).checked_mul(&MICROS_PER_DAY));
+            let nmicros = try_opt!(nmicros.checked_add(&(secs as i64 * MICROS_PER_SEC)));
+            let nmicros = try_opt!(nmicros.checked_add(&(nanos as i64 / NANOS_PER_MICRO as i64)));
+            Some(nmicros)
+        }
+        if self.days < 0 {
+            // the final negation won't overflow since we start with positive numbers.
+            micros(self.to_negated_tuple_64()).map(|micros| -micros)
+        } else {
+            micros(self.to_tuple_64())
+        }
+    }
+
+    /// Returns the total number of whole nanoseconds in the duration,
+    /// or `None` on the overflow (exceeding 2^63 nanoseconds in either directions).
+    pub fn num_nanoseconds(&self) -> Option<i64> {
+        fn nanos((days, secs, nanos): (i64, u32, u32)) -> Option<i64> {
+            static NANOS_PER_DAY: i64 = NANOS_PER_SEC as i64 * SECS_PER_DAY as i64;
+            let nnanos = try_opt!((days as i64).checked_mul(&NANOS_PER_DAY));
+            let nnanos = try_opt!(nnanos.checked_add(&(secs as i64 * NANOS_PER_SEC as i64)));
+            let nnanos = try_opt!(nnanos.checked_add(&(nanos as i64)));
+            Some(nnanos)
+        }
+        if self.days < 0 {
+            // the final negation won't overflow since we start with positive numbers.
+            nanos(self.to_negated_tuple_64()).map(|micros| -micros)
+        } else {
+            nanos(self.to_tuple_64())
+        }
+    }
+}
+
+impl num::Bounded for Duration {
+    #[inline] fn min_value() -> Duration { MIN }
+    #[inline] fn max_value() -> Duration { MAX }
+}
+
+impl num::Zero for Duration {
+    #[inline]
+    fn zero() -> Duration {
+        Duration { days: 0, secs: 0, nanos: 0 }
+    }
+
+    #[inline]
+    fn is_zero(&self) -> bool {
+        self.days == 0 && self.secs == 0 && self.nanos == 0
+    }
+}
+
+impl Neg<Duration> for Duration {
+    #[inline]
+    fn neg(&self) -> Duration {
+        let (days, secs, nanos) = self.to_negated_tuple_64();
+        Duration { days: days as i32, secs: secs, nanos: nanos } // FIXME can overflow
+    }
+}
+
+impl Add<Duration,Duration> for Duration {
+    fn add(&self, rhs: &Duration) -> Duration {
+        let mut days = self.days + rhs.days;
+        let mut secs = self.secs + rhs.secs;
+        let mut nanos = self.nanos + rhs.nanos;
+        if nanos >= NANOS_PER_SEC as u32 {
+            nanos -= NANOS_PER_SEC as u32;
+            secs += 1;
+        }
+        if secs >= SECS_PER_DAY as u32 {
+            secs -= SECS_PER_DAY as u32;
+            days += 1;
+        }
+        Duration { days: days, secs: secs, nanos: nanos }
+    }
+}
+
+impl num::CheckedAdd for Duration {
+    fn checked_add(&self, rhs: &Duration) -> Option<Duration> {
+        let mut days = try_opt!(self.days.checked_add(&rhs.days));
+        let mut secs = self.secs + rhs.secs;
+        let mut nanos = self.nanos + rhs.nanos;
+        if nanos >= NANOS_PER_SEC as u32 {
+            nanos -= NANOS_PER_SEC as u32;
+            secs += 1;
+        }
+        if secs >= SECS_PER_DAY as u32 {
+            secs -= SECS_PER_DAY as u32;
+            days = try_opt!(days.checked_add(&1));
+        }
+        Some(Duration { days: days, secs: secs, nanos: nanos })
+    }
+}
+
+impl Sub<Duration,Duration> for Duration {
+    fn sub(&self, rhs: &Duration) -> Duration {
+        let mut days = self.days - rhs.days;
+        let mut secs = self.secs as i32 - rhs.secs as i32;
+        let mut nanos = self.nanos as i32 - rhs.nanos as i32;
+        if nanos < 0 {
+            nanos += NANOS_PER_SEC;
+            secs -= 1;
+        }
+        if secs < 0 {
+            secs += SECS_PER_DAY;
+            days -= 1;
+        }
+        Duration { days: days, secs: secs as u32, nanos: nanos as u32 }
+    }
+}
+
+impl num::CheckedSub for Duration {
+    fn checked_sub(&self, rhs: &Duration) -> Option<Duration> {
+        let mut days = try_opt!(self.days.checked_sub(&rhs.days));
+        let mut secs = self.secs as i32 - rhs.secs as i32;
+        let mut nanos = self.nanos as i32 - rhs.nanos as i32;
+        if nanos < 0 {
+            nanos += NANOS_PER_SEC;
+            secs -= 1;
+        }
+        if secs < 0 {
+            secs += SECS_PER_DAY;
+            days = try_opt!(days.checked_sub(&1));
+        }
+        Some(Duration { days: days, secs: secs as u32, nanos: nanos as u32 })
+    }
+}
+
+impl Mul<i32,Duration> for Duration {
+    fn mul(&self, rhs: &i32) -> Duration {
+        /// Given `0 <= y < limit <= 2^30`,
+        /// returns `(h,l)` such that `x * y = h * limit + l` where `0 <= l < limit`.
+        fn mul_i64_u32_limit(x: i64, y: u32, limit: u32) -> (i64,u32) {
+            let y = y as i64;
+            let limit = limit as i64;
+            let (xh, xl) = div_mod_floor_64(x, limit);
+            let (h, l) = (xh * y, xl * y);
+            let (h_, l) = div_rem_64(l, limit);
+            (h + h_, l as u32)
+        }
+
+        let rhs = *rhs as i64;
+        let (secs1, nanos) = mul_i64_u32_limit(rhs, self.nanos, NANOS_PER_SEC as u32);
+        let (days1, secs1) = div_mod_floor_64(secs1, (SECS_PER_DAY as i64));
+        let (days2, secs2) = mul_i64_u32_limit(rhs, self.secs, SECS_PER_DAY as u32);
+        let mut days = self.days as i64 * rhs + days1 + days2;
+        let mut secs = secs1 as u32 + secs2;
+        if secs >= SECS_PER_DAY as u32 {
+            secs -= 1;
+            days += 1;
+        }
+        Duration { days: days as i32, secs: secs, nanos: nanos }
+    }
+}
+
+impl Div<i32,Duration> for Duration {
+    fn div(&self, rhs: &i32) -> Duration {
+        let (rhs, days, secs, nanos) = if *rhs < 0 {
+            let (days, secs, nanos) = self.to_negated_tuple_64();
+            (-(*rhs as i64), days, secs as i64, nanos as i64)
+        } else {
+            (*rhs as i64, self.days as i64, self.secs as i64, self.nanos as i64)
+        };
+
+        let (days, carry) = div_mod_floor_64(days, rhs);
+        let secs = secs + carry * SECS_PER_DAY as i64;
+        let (secs, carry) = div_mod_floor_64(secs, rhs);
+        let nanos = nanos + carry * NANOS_PER_SEC as i64;
+        let nanos = nanos / rhs;
+        Duration { days: days as i32, secs: secs as u32, nanos: nanos as u32 }
+    }
+}
+
+impl fmt::Show for Duration {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        let hasdate = self.days != 0;
+        let hastime = (self.secs != 0 || self.nanos != 0) || !hasdate;
+
+        try!(write!(f, "P"));
+        if hasdate {
+            // technically speaking the negative part is not the valid ISO 8601,
+            // but we need to print it anyway.
+            try!(write!(f, "{}D", self.days));
+        }
+        if hastime {
+            if self.nanos == 0 {
+                try!(write!(f, "T{}S", self.secs));
+            } else if self.nanos % 1_000_000 == 0 {
+                try!(write!(f, "T{}.{:03}S", self.secs, self.nanos / 1_000_000));
+            } else if self.nanos % 1_000 == 0 {
+                try!(write!(f, "T{}.{:06}S", self.secs, self.nanos / 1_000));
+            } else {
+                try!(write!(f, "T{}.{:09}S", self.secs, self.nanos));
+            }
+        }
+        Ok(())
+    }
+}
+
+// Copied from libnum
+#[inline]
+fn div_mod_floor(this: i32, other: i32) -> (i32, i32) {
+    (div_floor(this, other), mod_floor(this, other))
+}
+
+#[inline]
+fn div_floor(this: i32, other: i32) -> i32 {
+    match div_rem(this, other) {
+        (d, r) if (r > 0 && other < 0)
+               || (r < 0 && other > 0) => d - 1,
+        (d, _)                         => d,
+    }
+}
+
+#[inline]
+fn mod_floor(this: i32, other: i32) -> i32 {
+    match this % other {
+        r if (r > 0 && other < 0)
+          || (r < 0 && other > 0) => r + other,
+        r                         => r,
+    }
+}
+
+#[inline]
+fn div_rem(this: i32, other: i32) -> (i32, i32) {
+    (this / other, this % other)
+}
+
+#[inline]
+fn div_mod_floor_64(this: i64, other: i64) -> (i64, i64) {
+    (div_floor_64(this, other), mod_floor_64(this, other))
+}
+
+#[inline]
+fn div_floor_64(this: i64, other: i64) -> i64 {
+    match div_rem_64(this, other) {
+        (d, r) if (r > 0 && other < 0)
+               || (r < 0 && other > 0) => d - 1,
+        (d, _)                         => d,
+    }
+}
+
+#[inline]
+fn mod_floor_64(this: i64, other: i64) -> i64 {
+    match this % other {
+        r if (r > 0 && other < 0)
+          || (r < 0 && other > 0) => r + other,
+        r                         => r,
+    }
+}
+
+#[inline]
+fn div_rem_64(this: i64, other: i64) -> (i64, i64) {
+    (this / other, this % other)
+}
+
+#[cfg(test)]
+mod tests {
+    use super::{Duration, MIN_DAYS, MAX_DAYS, MIN, MAX};
+    use {i32, i64};
+    use num::{Zero, CheckedAdd, CheckedSub};
+    use option::{Some, None};
+    use to_string::ToString;
+
+    #[test]
+    fn test_duration() {
+        let d: Duration = Zero::zero();
+        assert_eq!(d, Zero::zero());
+        assert!(Duration::seconds(1) != Zero::zero());
+        assert_eq!(Duration::seconds(1) + Duration::seconds(2), Duration::seconds(3));
+        assert_eq!(Duration::seconds(86399) + Duration::seconds(4),
+                   Duration::days(1) + Duration::seconds(3));
+        assert_eq!(Duration::days(10) - Duration::seconds(1000), Duration::seconds(863000));
+        assert_eq!(Duration::days(10) - Duration::seconds(1000000), Duration::seconds(-136000));
+        assert_eq!(Duration::days(2) + Duration::seconds(86399) + Duration::nanoseconds(1234567890),
+                   Duration::days(3) + Duration::nanoseconds(234567890));
+        assert_eq!(-Duration::days(3), Duration::days(-3));
+        assert_eq!(-(Duration::days(3) + Duration::seconds(70)),
+                   Duration::days(-4) + Duration::seconds(86400-70));
+    }
+
+    #[test]
+    fn test_duration_num_days() {
+        let d: Duration = Zero::zero();
+        assert_eq!(d.num_days(), 0);
+        assert_eq!(Duration::days(1).num_days(), 1);
+        assert_eq!(Duration::days(-1).num_days(), -1);
+        assert_eq!(Duration::seconds(86399).num_days(), 0);
+        assert_eq!(Duration::seconds(86401).num_days(), 1);
+        assert_eq!(Duration::seconds(-86399).num_days(), 0);
+        assert_eq!(Duration::seconds(-86401).num_days(), -1);
+        assert_eq!(Duration::days(i32::MAX).num_days(), i32::MAX);
+        assert_eq!(Duration::days(i32::MIN).num_days(), i32::MIN);
+        assert_eq!(MAX.num_days(), MAX_DAYS);
+        assert_eq!(MIN.num_days(), MIN_DAYS);
+    }
+
+    #[test]
+    fn test_duration_num_seconds() {
+        let d: Duration = Zero::zero();
+        assert_eq!(d.num_seconds(), 0);
+        assert_eq!(Duration::seconds(1).num_seconds(), 1);
+        assert_eq!(Duration::seconds(-1).num_seconds(), -1);
+        assert_eq!(Duration::milliseconds(999).num_seconds(), 0);
+        assert_eq!(Duration::milliseconds(1001).num_seconds(), 1);
+        assert_eq!(Duration::milliseconds(-999).num_seconds(), 0);
+        assert_eq!(Duration::milliseconds(-1001).num_seconds(), -1);
+        assert_eq!(Duration::seconds(i32::MAX).num_seconds(), i32::MAX as i64);
+        assert_eq!(Duration::seconds(i32::MIN).num_seconds(), i32::MIN as i64);
+        assert_eq!(MAX.num_seconds(), (MAX_DAYS as i64 + 1) * 86400 - 1);
+        assert_eq!(MIN.num_seconds(), MIN_DAYS as i64 * 86400);
+    }
+
+    #[test]
+    fn test_duration_num_milliseconds() {
+        let d: Duration = Zero::zero();
+        assert_eq!(d.num_milliseconds(), 0);
+        assert_eq!(Duration::milliseconds(1).num_milliseconds(), 1);
+        assert_eq!(Duration::milliseconds(-1).num_milliseconds(), -1);
+        assert_eq!(Duration::microseconds(999).num_milliseconds(), 0);
+        assert_eq!(Duration::microseconds(1001).num_milliseconds(), 1);
+        assert_eq!(Duration::microseconds(-999).num_milliseconds(), 0);
+        assert_eq!(Duration::microseconds(-1001).num_milliseconds(), -1);
+        assert_eq!(Duration::milliseconds(i32::MAX).num_milliseconds(), i32::MAX as i64);
+        assert_eq!(Duration::milliseconds(i32::MIN).num_milliseconds(), i32::MIN as i64);
+        assert_eq!(MAX.num_milliseconds(), (MAX_DAYS as i64 + 1) * 86400_000 - 1);
+        assert_eq!(MIN.num_milliseconds(), MIN_DAYS as i64 * 86400_000);
+    }
+
+    #[test]
+    fn test_duration_num_microseconds() {
+        let d: Duration = Zero::zero();
+        assert_eq!(d.num_microseconds(), Some(0));
+        assert_eq!(Duration::microseconds(1).num_microseconds(), Some(1));
+        assert_eq!(Duration::microseconds(-1).num_microseconds(), Some(-1));
+        assert_eq!(Duration::nanoseconds(999).num_microseconds(), Some(0));
+        assert_eq!(Duration::nanoseconds(1001).num_microseconds(), Some(1));
+        assert_eq!(Duration::nanoseconds(-999).num_microseconds(), Some(0));
+        assert_eq!(Duration::nanoseconds(-1001).num_microseconds(), Some(-1));
+        assert_eq!(Duration::microseconds(i32::MAX).num_microseconds(), Some(i32::MAX as i64));
+        assert_eq!(Duration::microseconds(i32::MIN).num_microseconds(), Some(i32::MIN as i64));
+        assert_eq!(MAX.num_microseconds(), None);
+        assert_eq!(MIN.num_microseconds(), None);
+
+        // overflow checks
+        static MICROS_PER_DAY: i64 = 86400_000_000;
+        assert_eq!(Duration::days((i64::MAX / MICROS_PER_DAY) as i32).num_microseconds(),
+                   Some(i64::MAX / MICROS_PER_DAY * MICROS_PER_DAY));
+        assert_eq!(Duration::days((i64::MIN / MICROS_PER_DAY) as i32).num_microseconds(),
+                   Some(i64::MIN / MICROS_PER_DAY * MICROS_PER_DAY));
+        assert_eq!(Duration::days((i64::MAX / MICROS_PER_DAY + 1) as i32).num_microseconds(), None);
+        assert_eq!(Duration::days((i64::MIN / MICROS_PER_DAY - 1) as i32).num_microseconds(), None);
+    }
+
+    #[test]
+    fn test_duration_num_nanoseconds() {
+        let d: Duration = Zero::zero();
+        assert_eq!(d.num_nanoseconds(), Some(0));
+        assert_eq!(Duration::nanoseconds(1).num_nanoseconds(), Some(1));
+        assert_eq!(Duration::nanoseconds(-1).num_nanoseconds(), Some(-1));
+        assert_eq!(Duration::nanoseconds(i32::MAX).num_nanoseconds(), Some(i32::MAX as i64));
+        assert_eq!(Duration::nanoseconds(i32::MIN).num_nanoseconds(), Some(i32::MIN as i64));
+        assert_eq!(MAX.num_nanoseconds(), None);
+        assert_eq!(MIN.num_nanoseconds(), None);
+
+        // overflow checks
+        static NANOS_PER_DAY: i64 = 86400_000_000_000;
+        assert_eq!(Duration::days((i64::MAX / NANOS_PER_DAY) as i32).num_nanoseconds(),
+                   Some(i64::MAX / NANOS_PER_DAY * NANOS_PER_DAY));
+        assert_eq!(Duration::days((i64::MIN / NANOS_PER_DAY) as i32).num_nanoseconds(),
+                   Some(i64::MIN / NANOS_PER_DAY * NANOS_PER_DAY));
+        assert_eq!(Duration::days((i64::MAX / NANOS_PER_DAY + 1) as i32).num_nanoseconds(), None);
+        assert_eq!(Duration::days((i64::MIN / NANOS_PER_DAY - 1) as i32).num_nanoseconds(), None);
+    }
+
+    #[test]
+    fn test_duration_checked_ops() {
+        assert_eq!(Duration::days(MAX_DAYS).checked_add(&Duration::seconds(86399)),
+                   Some(Duration::days(MAX_DAYS - 1) + Duration::seconds(86400+86399)));
+        assert!(Duration::days(MAX_DAYS).checked_add(&Duration::seconds(86400)).is_none());
+
+        assert_eq!(Duration::days(MIN_DAYS).checked_sub(&Duration::seconds(0)),
+                   Some(Duration::days(MIN_DAYS)));
+        assert!(Duration::days(MIN_DAYS).checked_sub(&Duration::seconds(1)).is_none());
+    }
+
+    #[test]
+    fn test_duration_mul() {
+        let d: Duration = Zero::zero();
+        assert_eq!(d * i32::MAX, d);
+        assert_eq!(d * i32::MIN, d);
+        assert_eq!(Duration::nanoseconds(1) * 0, Zero::zero());
+        assert_eq!(Duration::nanoseconds(1) * 1, Duration::nanoseconds(1));
+        assert_eq!(Duration::nanoseconds(1) * 1_000_000_000, Duration::seconds(1));
+        assert_eq!(Duration::nanoseconds(1) * -1_000_000_000, -Duration::seconds(1));
+        assert_eq!(-Duration::nanoseconds(1) * 1_000_000_000, -Duration::seconds(1));
+        assert_eq!(Duration::nanoseconds(30) * 333_333_333,
+                   Duration::seconds(10) - Duration::nanoseconds(10));
+        assert_eq!((Duration::nanoseconds(1) + Duration::seconds(1) + Duration::days(1)) * 3,
+                   Duration::nanoseconds(3) + Duration::seconds(3) + Duration::days(3));
+    }
+
+    #[test]
+    fn test_duration_div() {
+        let d: Duration = Zero::zero();
+        assert_eq!(d / i32::MAX, d);
+        assert_eq!(d / i32::MIN, d);
+        assert_eq!(Duration::nanoseconds(123_456_789) / 1, Duration::nanoseconds(123_456_789));
+        assert_eq!(Duration::nanoseconds(123_456_789) / -1, -Duration::nanoseconds(123_456_789));
+        assert_eq!(-Duration::nanoseconds(123_456_789) / -1, Duration::nanoseconds(123_456_789));
+        assert_eq!(-Duration::nanoseconds(123_456_789) / 1, -Duration::nanoseconds(123_456_789));
+    }
+
+    #[test]
+    fn test_duration_fmt() {
+        let d: Duration = Zero::zero();
+        assert_eq!(d.to_string(), "PT0S".to_string());
+        assert_eq!(Duration::days(42).to_string(), "P42D".to_string());
+        assert_eq!(Duration::days(-42).to_string(), "P-42D".to_string());
+        assert_eq!(Duration::seconds(42).to_string(), "PT42S".to_string());
+        assert_eq!(Duration::milliseconds(42).to_string(), "PT0.042S".to_string());
+        assert_eq!(Duration::microseconds(42).to_string(), "PT0.000042S".to_string());
+        assert_eq!(Duration::nanoseconds(42).to_string(), "PT0.000000042S".to_string());
+        assert_eq!((Duration::days(7) + Duration::milliseconds(6543)).to_string(),
+                   "P7DT6.543S".to_string());
+
+        // the format specifier should have no effect on `Duration`
+        assert_eq!(format!("{:30}", Duration::days(1) + Duration::milliseconds(2345)),
+                   "P1DT2.345S".to_string());
+    }
+}
diff --git a/src/libstd/time/mod.rs b/src/libstd/time/mod.rs
new file mode 100644 (file)
index 0000000..436fa5e
--- /dev/null
@@ -0,0 +1,15 @@
+// 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.
+//
+// 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.
+
+//! Temporal quantification.
+
+pub use self::duration::Duration;
+
+pub mod duration;
index 45016b97566ceab20dbbf8d46302fdecd0ed90d0..e4df661b56201946dc852f7e75144b8357e12da5 100644 (file)
 //!
 //! ```no_run
 //! use std::io::timer::Timer;
+//! use std::time::Duration;
 //!
 //! let (tx, rx) = channel::<int>();
 //! let mut timer = Timer::new().unwrap();
-//! let timeout = timer.oneshot(10000);
+//! let timeout = timer.oneshot(Duration::seconds(10));
 //!
 //! loop {
 //!     select! {
 //!
 //! ```no_run
 //! use std::io::timer::Timer;
+//! use std::time::Duration;
 //!
 //! let (tx, rx) = channel::<int>();
 //! let mut timer = Timer::new().unwrap();
 //!
 //! loop {
-//!     let timeout = timer.oneshot(5000);
+//!     let timeout = timer.oneshot(Duration::seconds(5));
 //!
 //!     select! {
 //!         val = rx.recv() => println!("Received {}", val),
index c50a5661973f5ed69f109388032e13ab01a6f385..3280829f958352d781785ea693d72a0d7ee8427f 100644 (file)
@@ -11,7 +11,7 @@
 use std::fmt;
 
 #[deriving(PartialEq)]
-pub enum Os { OsWin32, OsMacos, OsLinux, OsAndroid, OsFreebsd, OsiOS,
+pub enum Os { OsWindows, OsMacos, OsLinux, OsAndroid, OsFreebsd, OsiOS,
               OsDragonfly }
 
 #[deriving(PartialEq, Eq, Hash, Encodable, Decodable, Clone)]
@@ -124,7 +124,7 @@ pub fn for_target(&self, os: Os, arch: Architecture) -> Option<Abi> {
         // Transform this ABI as appropriate for the requested os/arch
         // combination.
         Some(match (*self, os, arch) {
-            (System, OsWin32, X86) => Stdcall,
+            (System, OsWindows, X86) => Stdcall,
             (System, _, _) => C,
             (me, _, _) => me,
         })
@@ -147,7 +147,7 @@ impl fmt::Show for Os {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match *self {
             OsLinux => "linux".fmt(f),
-            OsWin32 => "win32".fmt(f),
+            OsWindows => "windows".fmt(f),
             OsMacos => "macos".fmt(f),
             OsiOS => "ios".fmt(f),
             OsAndroid => "android".fmt(f),
@@ -195,9 +195,9 @@ fn pick_uniplatform() {
     assert_eq!(Stdcall.for_target(OsLinux, X86), Some(Stdcall));
     assert_eq!(Stdcall.for_target(OsLinux, Arm), None);
     assert_eq!(System.for_target(OsLinux, X86), Some(C));
-    assert_eq!(System.for_target(OsWin32, X86), Some(Stdcall));
-    assert_eq!(System.for_target(OsWin32, X86_64), Some(C));
-    assert_eq!(System.for_target(OsWin32, Arm), Some(C));
-    assert_eq!(Stdcall.for_target(OsWin32, X86), Some(Stdcall));
-    assert_eq!(Stdcall.for_target(OsWin32, X86_64), Some(Stdcall));
+    assert_eq!(System.for_target(OsWindows, X86), Some(Stdcall));
+    assert_eq!(System.for_target(OsWindows, X86_64), Some(C));
+    assert_eq!(System.for_target(OsWindows, Arm), Some(C));
+    assert_eq!(Stdcall.for_target(OsWindows, X86), Some(Stdcall));
+    assert_eq!(Stdcall.for_target(OsWindows, X86_64), Some(Stdcall));
 }
index 629b21875c9b61b37904f3e65f52e2c5e35009e8..d0adc75e5c8448d4e1f565867f03dda5a4d15bae 100644 (file)
@@ -55,6 +55,12 @@ pub fn new(name: Name) -> Ident { Ident {name: name, ctxt: EMPTY_CTXT}}
     pub fn as_str<'a>(&'a self) -> &'a str {
         self.name.as_str()
     }
+
+    pub fn encode_with_hygiene(&self) -> String {
+        format!("\x00name_{:u},ctxt_{:u}\x00",
+                self.name.uint(),
+                self.ctxt)
+    }
 }
 
 impl Show for Ident {
@@ -239,6 +245,7 @@ pub struct TyParam {
 pub struct Generics {
     pub lifetimes: Vec<LifetimeDef>,
     pub ty_params: OwnedSlice<TyParam>,
+    pub where_clause: WhereClause,
 }
 
 impl Generics {
@@ -253,9 +260,23 @@ pub fn is_type_parameterized(&self) -> bool {
     }
 }
 
+#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
+pub struct WhereClause {
+    pub id: NodeId,
+    pub predicates: Vec<WherePredicate>,
+}
+
+#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
+pub struct WherePredicate {
+    pub id: NodeId,
+    pub span: Span,
+    pub ident: Ident,
+    pub bounds: OwnedSlice<TyParamBound>,
+}
+
 /// The set of MetaItems that define the compilation environment of the crate,
 /// used to drive conditional compilation
-pub type CrateConfig = Vec<Gc<MetaItem>> ;
+pub type CrateConfig = Vec<Gc<MetaItem>>;
 
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
 pub struct Crate {
@@ -520,9 +541,9 @@ pub enum Expr_ {
     // FIXME #6993: change to Option<Name> ... or not, if these are hygienic.
     ExprLoop(P<Block>, Option<Ident>),
     ExprMatch(Gc<Expr>, Vec<Arm>),
-    ExprFnBlock(P<FnDecl>, P<Block>),
+    ExprFnBlock(CaptureClause, P<FnDecl>, P<Block>),
     ExprProc(P<FnDecl>, P<Block>),
-    ExprUnboxedFn(P<FnDecl>, P<Block>),
+    ExprUnboxedFn(CaptureClause, UnboxedClosureKind, P<FnDecl>, P<Block>),
     ExprBlock(P<Block>),
 
     ExprAssign(Gc<Expr>, Gc<Expr>),
@@ -553,6 +574,12 @@ pub enum Expr_ {
     ExprParen(Gc<Expr>)
 }
 
+#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
+pub enum CaptureClause {
+    CaptureByValue,
+    CaptureByRef,
+}
+
 /// When the main rust parser encounters a syntax-extension invocation, it
 /// parses the arguments to the invocation as a token-tree. This is a very
 /// loose structure, such that all sorts of different AST-fragments can
@@ -755,9 +782,14 @@ pub struct TypeMethod {
 /// doesn't have an implementation, just a signature) or provided (meaning it
 /// has a default implementation).
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
-pub enum TraitMethod {
-    Required(TypeMethod),
-    Provided(Gc<Method>),
+pub enum TraitItem {
+    RequiredMethod(TypeMethod),
+    ProvidedMethod(Gc<Method>),
+}
+
+#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
+pub enum ImplItem {
+    MethodImplItem(Gc<Method>),
 }
 
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
@@ -888,6 +920,7 @@ pub struct BareFnTy {
 
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
 pub struct UnboxedFnTy {
+    pub kind: UnboxedClosureKind,
     pub decl: P<FnDecl>,
 }
 
@@ -1101,11 +1134,11 @@ pub fn id(&self) -> NodeId {
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
 pub enum ViewPath_ {
 
-    /// `quux = foo::bar::baz`
+    /// `foo::bar::baz as quux`
     ///
     /// or just
     ///
-    /// `foo::bar::baz ` (with 'baz =' implicitly on the left)
+    /// `foo::bar::baz` (with `as baz` implicitly on the right)
     ViewPathSimple(Ident, Path, NodeId),
 
     /// `foo::bar::*`
@@ -1260,11 +1293,11 @@ pub enum Item_ {
               Option<TyParamBound>, // (optional) default bound not required for Self.
                                     // Currently, only Sized makes sense here.
               Vec<TraitRef> ,
-              Vec<TraitMethod>),
+              Vec<TraitItem>),
     ItemImpl(Generics,
              Option<TraitRef>, // (optional) trait this impl implements
              P<Ty>, // self
-             Vec<Gc<Method>>),
+             Vec<ImplItem>),
     /// A macro invocation (which includes macro definition)
     ItemMac(Mac),
 }
@@ -1285,16 +1318,29 @@ pub enum ForeignItem_ {
     ForeignItemStatic(P<Ty>, /* is_mutbl */ bool),
 }
 
+#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
+pub enum UnboxedClosureKind {
+    FnUnboxedClosureKind,
+    FnMutUnboxedClosureKind,
+    FnOnceUnboxedClosureKind,
+}
+
 /// The data we save and restore about an inlined item or method.  This is not
 /// part of the AST that we parse from a file, but it becomes part of the tree
 /// that we trans.
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
 pub enum InlinedItem {
     IIItem(Gc<Item>),
-    IIMethod(DefId /* impl id */, bool /* is provided */, Gc<Method>),
+    IITraitItem(DefId /* impl id */, InlinedTraitItem),
     IIForeign(Gc<ForeignItem>),
 }
 
+#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
+pub enum InlinedTraitItem {
+    ProvidedInlinedTraitItem(Gc<Method>),
+    RequiredInlinedTraitItem(Gc<Method>),
+}
+
 #[cfg(test)]
 mod test {
     use serialize::json;
index a522f80554327f89a297c2c6107c821923cad6bb..b00c6ce14b5b85f58dfdc9d225b4e8b0c34e89a5 100644 (file)
@@ -60,9 +60,9 @@ fn is_fn_like(&self) -> bool {
     }
 }
 
-impl MaybeFnLike for ast::TraitMethod {
+impl MaybeFnLike for ast::TraitItem {
     fn is_fn_like(&self) -> bool {
-        match *self { ast::Provided(_) => true, _ => false, }
+        match *self { ast::ProvidedMethod(_) => true, _ => false, }
     }
 }
 
@@ -97,9 +97,9 @@ fn new(node: Node) -> FnLikeNode { FnLikeNode { node: node } }
         match node {
             ast_map::NodeItem(item) if item.is_fn_like() =>
                 Some(FnLikeCode(new(node))),
-            ast_map::NodeTraitMethod(tm) if tm.is_fn_like() =>
+            ast_map::NodeTraitItem(tm) if tm.is_fn_like() =>
                 Some(FnLikeCode(new(node))),
-            ast_map::NodeMethod(_) =>
+            ast_map::NodeImplItem(_) =>
                 Some(FnLikeCode(new(node))),
             ast_map::NodeExpr(e) if e.is_fn_like() =>
                 Some(FnLikeCode(new(node))),
@@ -200,13 +200,17 @@ fn handle<'a, A>(&'a self,
                     }),
                 _ => fail!("item FnLikeNode that is not fn-like"),
             },
-            ast_map::NodeTraitMethod(ref t) => match **t {
-                ast::Provided(ref m) => method(&**m),
+            ast_map::NodeTraitItem(ref t) => match **t {
+                ast::ProvidedMethod(ref m) => method(&**m),
                 _ => fail!("trait method FnLikeNode that is not fn-like"),
             },
-            ast_map::NodeMethod(ref m) => method(&**m),
+            ast_map::NodeImplItem(ref ii) => {
+                match **ii {
+                    ast::MethodImplItem(ref m) => method(&**m),
+                }
+            }
             ast_map::NodeExpr(ref e) => match e.node {
-                ast::ExprFnBlock(ref decl, ref block) =>
+                ast::ExprFnBlock(_, ref decl, ref block) =>
                     closure(ClosureParts::new(*decl, *block, e.id, e.span)),
                 ast::ExprProc(ref decl, ref block) =>
                     closure(ClosureParts::new(*decl, *block, e.id, e.span)),
index 881ee4fd8d13e664d5ebbfcaa317fb4fcd4f56c9..5fccf6cc3f025bbdf1a10e7d121e958a7852ee51 100644 (file)
@@ -99,8 +99,8 @@ pub fn path_to_string<PI: Iterator<PathElem>>(mut path: PI) -> String {
 pub enum Node {
     NodeItem(Gc<Item>),
     NodeForeignItem(Gc<ForeignItem>),
-    NodeTraitMethod(Gc<TraitMethod>),
-    NodeMethod(Gc<Method>),
+    NodeTraitItem(Gc<TraitItem>),
+    NodeImplItem(Gc<ImplItem>),
     NodeVariant(P<Variant>),
     NodeExpr(Gc<Expr>),
     NodeStmt(Gc<Stmt>),
@@ -125,8 +125,8 @@ enum MapEntry {
     /// All the node types, with a parent ID.
     EntryItem(NodeId, Gc<Item>),
     EntryForeignItem(NodeId, Gc<ForeignItem>),
-    EntryTraitMethod(NodeId, Gc<TraitMethod>),
-    EntryMethod(NodeId, Gc<Method>),
+    EntryTraitItem(NodeId, Gc<TraitItem>),
+    EntryImplItem(NodeId, Gc<ImplItem>),
     EntryVariant(NodeId, P<Variant>),
     EntryExpr(NodeId, Gc<Expr>),
     EntryStmt(NodeId, Gc<Stmt>),
@@ -144,7 +144,7 @@ enum MapEntry {
 
 struct InlinedParent {
     path: Vec<PathElem> ,
-    /// Required by NodeTraitMethod and NodeMethod.
+    /// RequiredMethod by NodeTraitItem and NodeImplItem.
     def_id: DefId
 }
 
@@ -153,8 +153,8 @@ fn parent(&self) -> Option<NodeId> {
         Some(match *self {
             EntryItem(id, _) => id,
             EntryForeignItem(id, _) => id,
-            EntryTraitMethod(id, _) => id,
-            EntryMethod(id, _) => id,
+            EntryTraitItem(id, _) => id,
+            EntryImplItem(id, _) => id,
             EntryVariant(id, _) => id,
             EntryExpr(id, _) => id,
             EntryStmt(id, _) => id,
@@ -172,8 +172,8 @@ fn to_node(&self) -> Option<Node> {
         Some(match *self {
             EntryItem(_, p) => NodeItem(p),
             EntryForeignItem(_, p) => NodeForeignItem(p),
-            EntryTraitMethod(_, p) => NodeTraitMethod(p),
-            EntryMethod(_, p) => NodeMethod(p),
+            EntryTraitItem(_, p) => NodeTraitItem(p),
+            EntryImplItem(_, p) => NodeImplItem(p),
             EntryVariant(_, p) => NodeVariant(p),
             EntryExpr(_, p) => NodeExpr(p),
             EntryStmt(_, p) => NodeStmt(p),
@@ -324,13 +324,23 @@ pub fn get_path_elem(&self, id: NodeId) -> PathElem {
                 }
             }
             NodeForeignItem(i) => PathName(i.ident.name),
-            NodeMethod(m) => match m.node {
-                MethDecl(ident, _, _, _, _, _, _, _) => PathName(ident.name),
-                MethMac(_) => fail!("no path elem for {:?}", node)
+            NodeImplItem(ii) => {
+                match *ii {
+                    MethodImplItem(ref m) => {
+                        match m.node {
+                            MethDecl(ident, _, _, _, _, _, _, _) => {
+                                PathName(ident.name)
+                            }
+                            MethMac(_) => {
+                                fail!("no path elem for {:?}", node)
+                            }
+                        }
+                    }
+                }
             },
-            NodeTraitMethod(tm) => match *tm {
-                Required(ref m) => PathName(m.ident.name),
-                Provided(m) => match m.node {
+            NodeTraitItem(tm) => match *tm {
+                RequiredMethod(ref m) => PathName(m.ident.name),
+                ProvidedMethod(m) => match m.node {
                     MethDecl(ident, _, _, _, _, _, _, _) => {
                         PathName(ident.name)
                     }
@@ -393,11 +403,15 @@ pub fn with_attrs<T>(&self, id: NodeId, f: |Option<&[Attribute]>| -> T) -> T {
         let attrs = match node {
             NodeItem(ref i) => Some(i.attrs.as_slice()),
             NodeForeignItem(ref fi) => Some(fi.attrs.as_slice()),
-            NodeTraitMethod(ref tm) => match **tm {
-                Required(ref type_m) => Some(type_m.attrs.as_slice()),
-                Provided(ref m) => Some(m.attrs.as_slice())
+            NodeTraitItem(ref tm) => match **tm {
+                RequiredMethod(ref type_m) => Some(type_m.attrs.as_slice()),
+                ProvidedMethod(ref m) => Some(m.attrs.as_slice())
             },
-            NodeMethod(ref m) => Some(m.attrs.as_slice()),
+            NodeImplItem(ref ii) => {
+                match **ii {
+                    MethodImplItem(ref m) => Some(m.attrs.as_slice()),
+                }
+            }
             NodeVariant(ref v) => Some(v.node.attrs.as_slice()),
             // unit/tuple structs take the attributes straight from
             // the struct definition.
@@ -417,24 +431,31 @@ pub fn with_attrs<T>(&self, id: NodeId, f: |Option<&[Attribute]>| -> T) -> T {
     /// the iterator will produce node id's for items with paths
     /// such as `foo::bar::quux`, `bar::quux`, `other::bar::quux`, and
     /// any other such items it can find in the map.
-    pub fn nodes_matching_suffix<'a, S:Str>(&'a self, parts: &'a [S]) -> NodesMatchingSuffix<'a,S> {
-        NodesMatchingSuffix { map: self,
-                              item_name: parts.last().unwrap(),
-                              where: parts.slice_to(parts.len() - 1),
-                              idx: 0 }
+    pub fn nodes_matching_suffix<'a, S:Str>(&'a self, parts: &'a [S])
+                                 -> NodesMatchingSuffix<'a,S> {
+        NodesMatchingSuffix {
+            map: self,
+            item_name: parts.last().unwrap(),
+            in_which: parts.slice_to(parts.len() - 1),
+            idx: 0,
+        }
     }
 
     pub fn opt_span(&self, id: NodeId) -> Option<Span> {
         let sp = match self.find(id) {
             Some(NodeItem(item)) => item.span,
             Some(NodeForeignItem(foreign_item)) => foreign_item.span,
-            Some(NodeTraitMethod(trait_method)) => {
+            Some(NodeTraitItem(trait_method)) => {
                 match *trait_method {
-                    Required(ref type_method) => type_method.span,
-                    Provided(ref method) => method.span,
+                    RequiredMethod(ref type_method) => type_method.span,
+                    ProvidedMethod(ref method) => method.span,
+                }
+            }
+            Some(NodeImplItem(ref impl_item)) => {
+                match **impl_item {
+                    MethodImplItem(ref method) => method.span,
                 }
             }
-            Some(NodeMethod(method)) => method.span,
             Some(NodeVariant(variant)) => variant.span,
             Some(NodeExpr(expr)) => expr.span,
             Some(NodeStmt(stmt)) => stmt.span,
@@ -460,20 +481,20 @@ pub fn node_to_string(&self, id: NodeId) -> String {
 pub struct NodesMatchingSuffix<'a, S> {
     map: &'a Map,
     item_name: &'a S,
-    where: &'a [S],
+    in_which: &'a [S],
     idx: NodeId,
 }
 
 impl<'a,S:Str> NodesMatchingSuffix<'a,S> {
     /// Returns true only if some suffix of the module path for parent
-    /// matches `self.where`.
+    /// matches `self.in_which`.
     ///
-    /// In other words: let `[x_0,x_1,...,x_k]` be `self.where`;
+    /// In other words: let `[x_0,x_1,...,x_k]` be `self.in_which`;
     /// returns true if parent's path ends with the suffix
     /// `x_0::x_1::...::x_k`.
     fn suffix_matches(&self, parent: NodeId) -> bool {
         let mut cursor = parent;
-        for part in self.where.iter().rev() {
+        for part in self.in_which.iter().rev() {
             let (mod_id, mod_name) = match find_first_mod_parent(self.map, cursor) {
                 None => return false,
                 Some((node_id, name)) => (node_id, name),
@@ -532,8 +553,8 @@ fn next(&mut self) -> Option<NodeId> {
             let (p, name) = match self.map.find_entry(idx) {
                 Some(EntryItem(p, n))        => (p, n.name()),
                 Some(EntryForeignItem(p, n)) => (p, n.name()),
-                Some(EntryTraitMethod(p, n)) => (p, n.name()),
-                Some(EntryMethod(p, n))      => (p, n.name()),
+                Some(EntryTraitItem(p, n))   => (p, n.name()),
+                Some(EntryImplItem(p, n))    => (p, n.name()),
                 Some(EntryVariant(p, n))     => (p, n.name()),
                 _ => continue,
             };
@@ -553,11 +574,18 @@ impl<T:Named> Named for Spanned<T> { fn name(&self) -> Name { self.node.name() }
 impl Named for Item { fn name(&self) -> Name { self.ident.name } }
 impl Named for ForeignItem { fn name(&self) -> Name { self.ident.name } }
 impl Named for Variant_ { fn name(&self) -> Name { self.name.name } }
-impl Named for TraitMethod {
+impl Named for TraitItem {
     fn name(&self) -> Name {
         match *self {
-            Required(ref tm) => tm.ident.name,
-            Provided(m) => m.name(),
+            RequiredMethod(ref tm) => tm.ident.name,
+            ProvidedMethod(m) => m.name(),
+        }
+    }
+}
+impl Named for ImplItem {
+    fn name(&self) -> Name {
+        match *self {
+            MethodImplItem(ref m) => m.name(),
         }
     }
 }
@@ -616,9 +644,15 @@ fn fold_item(&mut self, i: Gc<Item>) -> SmallVector<Gc<Item>> {
         assert_eq!(self.parent, i.id);
 
         match i.node {
-            ItemImpl(_, _, _, ref ms) => {
-                for &m in ms.iter() {
-                    self.insert(m.id, EntryMethod(self.parent, m));
+            ItemImpl(_, _, _, ref impl_items) => {
+                for impl_item in impl_items.iter() {
+                    match *impl_item {
+                        MethodImplItem(m) => {
+                            self.insert(m.id,
+                                        EntryImplItem(self.parent,
+                                                      box(GC) *impl_item));
+                        }
+                    }
                 }
             }
             ItemEnum(ref enum_definition, _) => {
@@ -649,13 +683,13 @@ fn fold_item(&mut self, i: Gc<Item>) -> SmallVector<Gc<Item>> {
 
                 for tm in methods.iter() {
                     match *tm {
-                        Required(ref m) => {
-                            self.insert(m.id, EntryTraitMethod(self.parent,
+                        RequiredMethod(ref m) => {
+                            self.insert(m.id, EntryTraitItem(self.parent,
                                                                box(GC) (*tm).clone()));
                         }
-                        Provided(m) => {
-                            self.insert(m.id, EntryTraitMethod(self.parent,
-                                                               box(GC) Provided(m)));
+                        ProvidedMethod(m) => {
+                            self.insert(m.id, EntryTraitItem(self.parent,
+                                                               box(GC) ProvidedMethod(m)));
                         }
                     }
                 }
@@ -798,13 +832,18 @@ pub fn map_decoded_item<F: FoldOps>(map: &Map,
     let ii = fold(&mut cx);
     match ii {
         IIItem(_) => {}
-        IIMethod(impl_did, is_provided, m) => {
-            let entry = if is_provided {
-                EntryTraitMethod(cx.parent, box(GC) Provided(m))
-            } else {
-                EntryMethod(cx.parent, m)
+        IITraitItem(impl_did, inlined_trait_item) => {
+            let (trait_item_id, entry) = match inlined_trait_item {
+                ProvidedInlinedTraitItem(m) => {
+                    (m.id,
+                     EntryTraitItem(cx.parent, box(GC) ProvidedMethod(m)))
+                }
+                RequiredInlinedTraitItem(m) => {
+                    (m.id,
+                     EntryImplItem(cx.parent, box(GC) MethodImplItem(m)))
+                }
             };
-            cx.insert(m.id, entry);
+            cx.insert(trait_item_id, entry);
             def_id = impl_did;
         }
         IIForeign(i) => {
@@ -829,8 +868,8 @@ fn print_node(&mut self, node: &Node) -> IoResult<()> {
         match *node {
             NodeItem(a)        => self.print_item(&*a),
             NodeForeignItem(a) => self.print_foreign_item(&*a),
-            NodeTraitMethod(a) => self.print_trait_method(&*a),
-            NodeMethod(a)      => self.print_method(&*a),
+            NodeTraitItem(a)   => self.print_trait_method(&*a),
+            NodeImplItem(a)    => self.print_impl_item(&*a),
             NodeVariant(a)     => self.print_variant(&*a),
             NodeExpr(a)        => self.print_expr(&*a),
             NodeStmt(a)        => self.print_stmt(&*a),
@@ -870,17 +909,23 @@ fn node_id_to_string(map: &Map, id: NodeId) -> String {
             let path_str = map.path_to_str_with_ident(id, item.ident);
             format!("foreign item {} (id={})", path_str, id)
         }
-        Some(NodeMethod(m)) => match m.node {
-            MethDecl(ident, _, _, _, _, _, _, _) =>
-                format!("method {} in {} (id={})",
-                        token::get_ident(ident),
-                        map.path_to_string(id), id),
-            MethMac(ref mac) =>
-                format!("method macro {} (id={})",
-                        pprust::mac_to_string(mac), id)
-        },
-        Some(NodeTraitMethod(ref tm)) => {
-            let m = ast_util::trait_method_to_ty_method(&**tm);
+        Some(NodeImplItem(ref ii)) => {
+            match **ii {
+                MethodImplItem(ref m) => {
+                    match m.node {
+                        MethDecl(ident, _, _, _, _, _, _, _) =>
+                            format!("method {} in {} (id={})",
+                                    token::get_ident(ident),
+                                    map.path_to_string(id), id),
+                        MethMac(ref mac) =>
+                            format!("method macro {} (id={})",
+                                    pprust::mac_to_string(mac), id)
+                    }
+                }
+            }
+        }
+        Some(NodeTraitItem(ref tm)) => {
+            let m = ast_util::trait_item_to_ty_method(&**tm);
             format!("method {} in {} (id={})",
                     token::get_ident(m.ident),
                     map.path_to_string(id), id)
index cf2b5bc406373759a5376b8cb71668cb8f89b587..5674c6675f96362bec27e655b90b3e403d79d42b 100644 (file)
@@ -241,51 +241,52 @@ pub fn impl_pretty_name(trait_ref: &Option<TraitRef>, ty: &Ty) -> Ident {
     token::gensym_ident(pretty.as_slice())
 }
 
-/// extract a TypeMethod from a TraitMethod. if the TraitMethod is
+pub fn trait_method_to_ty_method(method: &Method) -> TypeMethod {
+    match method.node {
+        MethDecl(ident,
+                 ref generics,
+                 abi,
+                 explicit_self,
+                 fn_style,
+                 decl,
+                 _,
+                 vis) => {
+            TypeMethod {
+                ident: ident,
+                attrs: method.attrs.clone(),
+                fn_style: fn_style,
+                decl: decl,
+                generics: generics.clone(),
+                explicit_self: explicit_self,
+                id: method.id,
+                span: method.span,
+                vis: vis,
+                abi: abi,
+            }
+        },
+        MethMac(_) => fail!("expected non-macro method declaration")
+    }
+}
+
+/// extract a TypeMethod from a TraitItem. if the TraitItem is
 /// a default, pull out the useful fields to make a TypeMethod
 //
 // NB: to be used only after expansion is complete, and macros are gone.
-pub fn trait_method_to_ty_method(method: &TraitMethod) -> TypeMethod {
+pub fn trait_item_to_ty_method(method: &TraitItem) -> TypeMethod {
     match *method {
-        Required(ref m) => (*m).clone(),
-        Provided(m) => {
-            match m.node {
-                MethDecl(ident,
-                         ref generics,
-                         abi,
-                         explicit_self,
-                         fn_style,
-                         decl,
-                         _,
-                         vis) => {
-                    TypeMethod {
-                        ident: ident,
-                        attrs: m.attrs.clone(),
-                        fn_style: fn_style,
-                        decl: decl,
-                        generics: generics.clone(),
-                        explicit_self: explicit_self,
-                        id: m.id,
-                        span: m.span,
-                        vis: vis,
-                        abi: abi,
-                    }
-                },
-                MethMac(_) => fail!("expected non-macro method declaration")
-            }
-
-        }
+        RequiredMethod(ref m) => (*m).clone(),
+        ProvidedMethod(ref m) => trait_method_to_ty_method(&**m),
     }
 }
 
-pub fn split_trait_methods(trait_methods: &[TraitMethod])
+pub fn split_trait_methods(trait_methods: &[TraitItem])
     -> (Vec<TypeMethod> , Vec<Gc<Method>> ) {
     let mut reqd = Vec::new();
     let mut provd = Vec::new();
     for trt_method in trait_methods.iter() {
         match *trt_method {
-            Required(ref tm) => reqd.push((*tm).clone()),
-            Provided(m) => provd.push(m)
+            RequiredMethod(ref tm) => reqd.push((*tm).clone()),
+            ProvidedMethod(m) => provd.push(m)
         }
     };
     (reqd, provd)
@@ -319,8 +320,14 @@ pub fn operator_prec(op: ast::BinOp) -> uint {
 pub static as_prec: uint = 12u;
 
 pub fn empty_generics() -> Generics {
-    Generics {lifetimes: Vec::new(),
-              ty_params: OwnedSlice::empty()}
+    Generics {
+        lifetimes: Vec::new(),
+        ty_params: OwnedSlice::empty(),
+        where_clause: WhereClause {
+            id: DUMMY_NODE_ID,
+            predicates: Vec::new(),
+        }
+    }
 }
 
 // ______________________________________________________________________
@@ -543,12 +550,12 @@ fn visit_struct_def(&mut self,
         visit::walk_struct_def(self, struct_def, ());
     }
 
-    fn visit_trait_method(&mut self, tm: &ast::TraitMethod, _: ()) {
+    fn visit_trait_item(&mut self, tm: &ast::TraitItem, _: ()) {
         match *tm {
-            ast::Required(ref m) => self.operation.visit_id(m.id),
-            ast::Provided(ref m) => self.operation.visit_id(m.id),
+            ast::RequiredMethod(ref m) => self.operation.visit_id(m.id),
+            ast::ProvidedMethod(ref m) => self.operation.visit_id(m.id),
         }
-        visit::walk_trait_method(self, tm, ());
+        visit::walk_trait_item(self, tm, ());
     }
 }
 
index b9298cca4f87d8c53e79ec65e96fceb36292429f..67605360a48cb665d1b4621aca5650012f4b174f 100644 (file)
@@ -51,7 +51,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 
 impl FromStr for CrateId {
     fn from_str(s: &str) -> Option<CrateId> {
-        let pieces: Vec<&str> = s.splitn('#', 1).collect();
+        let pieces: Vec<&str> = s.splitn(1, '#').collect();
         let path = pieces.get(0).to_string();
 
         if path.as_slice().starts_with("/") || path.as_slice().ends_with("/") ||
@@ -60,7 +60,7 @@ fn from_str(s: &str) -> Option<CrateId> {
         }
 
         let path_pieces: Vec<&str> = path.as_slice()
-                                         .rsplitn('/', 1)
+                                         .rsplitn(1, '/')
                                          .collect();
         let inferred_name = *path_pieces.get(0);
 
@@ -68,7 +68,7 @@ fn from_str(s: &str) -> Option<CrateId> {
             (inferred_name.to_string(), None)
         } else {
             let hash_pieces: Vec<&str> = pieces.get(1)
-                                               .splitn(':', 1)
+                                               .splitn(1, ':')
                                                .collect();
             let (hash_name, hash_version) = if hash_pieces.len() == 1 {
                 ("", *hash_pieces.get(0))
index 0e687c02c1daf080c678316a4d28e51027522471..f7eddca4b7aed4d25c2ffd39aed3a5eab2edb537 100644 (file)
@@ -876,14 +876,14 @@ fn expr_loop(&self, span: Span, block: P<ast::Block>) -> Gc<ast::Expr> {
 
     fn lambda_fn_decl(&self, span: Span,
                       fn_decl: P<ast::FnDecl>, blk: P<ast::Block>) -> Gc<ast::Expr> {
-        self.expr(span, ast::ExprFnBlock(fn_decl, blk))
+        self.expr(span, ast::ExprFnBlock(ast::CaptureByRef, fn_decl, blk))
     }
     fn lambda(&self, span: Span, ids: Vec<ast::Ident> , blk: P<ast::Block>) -> Gc<ast::Expr> {
         let fn_decl = self.fn_decl(
             ids.iter().map(|id| self.arg(span, *id, self.ty_infer(span))).collect(),
             self.ty_infer(span));
 
-        self.expr(span, ast::ExprFnBlock(fn_decl, blk))
+        self.expr(span, ast::ExprFnBlock(ast::CaptureByRef, fn_decl, blk))
     }
     fn lambda0(&self, span: Span, blk: P<ast::Block>) -> Gc<ast::Expr> {
         self.lambda(span, Vec::new(), blk)
index 5842ca4a0d54d05ecb22af4396f22771aa16e260..f9f2a86d18249799789ec54e10389166930237ef 100644 (file)
@@ -390,7 +390,7 @@ fn create_derived_impl(&self,
                            methods: Vec<Gc<ast::Method>> ) -> Gc<ast::Item> {
         let trait_path = self.path.to_path(cx, self.span, type_ident, generics);
 
-        let Generics { mut lifetimes, ty_params } =
+        let Generics { mut lifetimes, ty_params, where_clause: _ } =
             self.generics.to_generics(cx, self.span, type_ident, generics);
         let mut ty_params = ty_params.into_vec();
 
@@ -418,7 +418,11 @@ fn create_derived_impl(&self,
         }));
         let trait_generics = Generics {
             lifetimes: lifetimes,
-            ty_params: OwnedSlice::from_vec(ty_params)
+            ty_params: OwnedSlice::from_vec(ty_params),
+            where_clause: ast::WhereClause {
+                id: ast::DUMMY_NODE_ID,
+                predicates: Vec::new(),
+            },
         };
 
         // Create the reference to the trait.
@@ -452,8 +456,13 @@ fn create_derived_impl(&self,
             self.span,
             ident,
             (vec!(attr)).append(self.attributes.as_slice()),
-            ast::ItemImpl(trait_generics, opt_trait_ref,
-                          self_type, methods))
+            ast::ItemImpl(trait_generics,
+                          opt_trait_ref,
+                          self_type,
+                          methods.move_iter()
+                                 .map(|method| {
+                                     ast::MethodImplItem(method)
+                                 }).collect()))
     }
 
     fn expand_struct_def(&self,
index 2130b6f4e9dbc9f16a90b875b7bd9317ecb67134..f4a9b85f75d23d62fff86fb8bbc53d72bc7c5e6e 100644 (file)
@@ -202,10 +202,15 @@ fn mk_ty_param(cx: &ExtCtxt, span: Span, name: &str,
     cx.typaram(span, cx.ident_of(name), bounds, unbound, None)
 }
 
-fn mk_generics(lifetimes: Vec<ast::LifetimeDef>, ty_params: Vec<ast::TyParam> ) -> Generics {
+fn mk_generics(lifetimes: Vec<ast::LifetimeDef>, ty_params: Vec<ast::TyParam>)
+               -> Generics {
     Generics {
         lifetimes: lifetimes,
-        ty_params: OwnedSlice::from_vec(ty_params)
+        ty_params: OwnedSlice::from_vec(ty_params),
+        where_clause: ast::WhereClause {
+            id: ast::DUMMY_NODE_ID,
+            predicates: Vec::new(),
+        },
     }
 }
 
index 808532d55bb2e924ead563cadc2a41d4fd9464c1..d918b28d4dc8f31cf8a8625e7bcf326e4dce35ad 100644 (file)
@@ -74,10 +74,12 @@ fn expand_expr(e: Gc<ast::Expr>, fld: &mut MacroExpander) -> Gc<ast::Expr> {
             fld.cx.expr(e.span, ast::ExprForLoop(pat, head, body, opt_ident))
         }
 
-        ast::ExprFnBlock(fn_decl, block) => {
+        ast::ExprFnBlock(capture_clause, fn_decl, block) => {
             let (rewritten_fn_decl, rewritten_block)
                 = expand_and_rename_fn_decl_and_block(&*fn_decl, block, fld);
-            let new_node = ast::ExprFnBlock(rewritten_fn_decl, rewritten_block);
+            let new_node = ast::ExprFnBlock(capture_clause,
+                                            rewritten_fn_decl,
+                                            rewritten_block);
             box(GC) ast::Expr{id:e.id, node: new_node, span: fld.new_span(e.span)}
         }
 
index cc07b5312589f84b05c314014f2e441397a372c2..d7d6c20b475a688a2bebc48a57100fcc2124db19 100644 (file)
@@ -97,6 +97,15 @@ pub trait ToSource {
         fn to_source(&self) -> String;
     }
 
+    // FIXME (Issue #16472): This should go away after ToToken impls
+    // are revised to go directly to token-trees.
+    trait ToSourceWithHygiene : ToSource {
+        // Takes a thing and generates a string containing rust code
+        // for it, encoding Idents as special byte sequences to
+        // maintain hygiene across serialization and deserialization.
+        fn to_source_with_hygiene(&self) -> String;
+    }
+
     macro_rules! impl_to_source(
         (Gc<$t:ty>, $pp:ident) => (
             impl ToSource for Gc<$t> {
@@ -104,6 +113,11 @@ fn to_source(&self) -> String {
                     pprust::$pp(&**self)
                 }
             }
+            impl ToSourceWithHygiene for Gc<$t> {
+                fn to_source_with_hygiene(&self) -> String {
+                    pprust::with_hygiene::$pp(&**self)
+                }
+            }
         );
         ($t:ty, $pp:ident) => (
             impl ToSource for $t {
@@ -111,6 +125,11 @@ fn to_source(&self) -> String {
                     pprust::$pp(self)
                 }
             }
+            impl ToSourceWithHygiene for $t {
+                fn to_source_with_hygiene(&self) -> String {
+                    pprust::with_hygiene::$pp(self)
+                }
+            }
         );
     )
 
@@ -122,6 +141,15 @@ fn slice_to_source<'a, T: ToSource>(sep: &'static str, xs: &'a [T]) -> String {
             .to_string()
     }
 
+    fn slice_to_source_with_hygiene<'a, T: ToSourceWithHygiene>(
+        sep: &'static str, xs: &'a [T]) -> String {
+        xs.iter()
+            .map(|i| i.to_source_with_hygiene())
+            .collect::<Vec<String>>()
+            .connect(sep)
+            .to_string()
+    }
+
     macro_rules! impl_to_source_slice(
         ($t:ty, $sep:expr) => (
             impl<'a> ToSource for &'a [$t] {
@@ -129,6 +157,12 @@ fn to_source(&self) -> String {
                     slice_to_source($sep, *self)
                 }
             }
+
+            impl<'a> ToSourceWithHygiene for &'a [$t] {
+                fn to_source_with_hygiene(&self) -> String {
+                    slice_to_source_with_hygiene($sep, *self)
+                }
+            }
         )
     )
 
@@ -138,6 +172,12 @@ fn to_source(&self) -> String {
         }
     }
 
+    impl ToSourceWithHygiene for ast::Ident {
+        fn to_source_with_hygiene(&self) -> String {
+            self.encode_with_hygiene()
+        }
+    }
+
     impl_to_source!(ast::Ty, ty_to_string)
     impl_to_source!(ast::Block, block_to_string)
     impl_to_source!(ast::Arg, arg_to_string)
@@ -156,6 +196,11 @@ fn to_source(&self) -> String {
             pprust::attribute_to_string(&dummy_spanned(*self))
         }
     }
+    impl ToSourceWithHygiene for ast::Attribute_ {
+        fn to_source_with_hygiene(&self) -> String {
+            self.to_source()
+        }
+    }
 
     impl<'a> ToSource for &'a str {
         fn to_source(&self) -> String {
@@ -164,12 +209,22 @@ fn to_source(&self) -> String {
             pprust::lit_to_string(&lit)
         }
     }
+    impl<'a> ToSourceWithHygiene for &'a str {
+        fn to_source_with_hygiene(&self) -> String {
+            self.to_source()
+        }
+    }
 
     impl ToSource for () {
         fn to_source(&self) -> String {
             "()".to_string()
         }
     }
+    impl ToSourceWithHygiene for () {
+        fn to_source_with_hygiene(&self) -> String {
+            self.to_source()
+        }
+    }
 
     impl ToSource for bool {
         fn to_source(&self) -> String {
@@ -177,6 +232,11 @@ fn to_source(&self) -> String {
             pprust::lit_to_string(&lit)
         }
     }
+    impl ToSourceWithHygiene for bool {
+        fn to_source_with_hygiene(&self) -> String {
+            self.to_source()
+        }
+    }
 
     impl ToSource for char {
         fn to_source(&self) -> String {
@@ -184,6 +244,11 @@ fn to_source(&self) -> String {
             pprust::lit_to_string(&lit)
         }
     }
+    impl ToSourceWithHygiene for char {
+        fn to_source_with_hygiene(&self) -> String {
+            self.to_source()
+        }
+    }
 
     macro_rules! impl_to_source_int(
         (signed, $t:ty, $tag:ident) => (
@@ -194,6 +259,11 @@ fn to_source(&self) -> String {
                     pprust::lit_to_string(&dummy_spanned(lit))
                 }
             }
+            impl ToSourceWithHygiene for $t {
+                fn to_source_with_hygiene(&self) -> String {
+                    self.to_source()
+                }
+            }
         );
         (unsigned, $t:ty, $tag:ident) => (
             impl ToSource for $t {
@@ -202,6 +272,11 @@ fn to_source(&self) -> String {
                     pprust::lit_to_string(&dummy_spanned(lit))
                 }
             }
+            impl ToSourceWithHygiene for $t {
+                fn to_source_with_hygiene(&self) -> String {
+                    self.to_source()
+                }
+            }
         );
     )
 
@@ -223,7 +298,7 @@ macro_rules! impl_to_tokens(
         ($t:ty) => (
             impl ToTokens for $t {
                 fn to_tokens(&self, cx: &ExtCtxt) -> Vec<TokenTree> {
-                    cx.parse_tts(self.to_source())
+                    cx.parse_tts_with_hygiene(self.to_source_with_hygiene())
                 }
             }
         )
@@ -233,7 +308,7 @@ macro_rules! impl_to_tokens_lifetime(
         ($t:ty) => (
             impl<'a> ToTokens for $t {
                 fn to_tokens(&self, cx: &ExtCtxt) -> Vec<TokenTree> {
-                    cx.parse_tts(self.to_source())
+                    cx.parse_tts_with_hygiene(self.to_source_with_hygiene())
                 }
             }
         )
@@ -272,7 +347,13 @@ pub trait ExtParseUtils {
         fn parse_item(&self, s: String) -> Gc<ast::Item>;
         fn parse_expr(&self, s: String) -> Gc<ast::Expr>;
         fn parse_stmt(&self, s: String) -> Gc<ast::Stmt>;
-        fn parse_tts(&self, s: String) -> Vec<ast::TokenTree> ;
+        fn parse_tts(&self, s: String) -> Vec<ast::TokenTree>;
+    }
+
+    trait ExtParseUtilsWithHygiene {
+        // FIXME (Issue #16472): This should go away after ToToken impls
+        // are revised to go directly to token-trees.
+        fn parse_tts_with_hygiene(&self, s: String) -> Vec<ast::TokenTree>;
     }
 
     impl<'a> ExtParseUtils for ExtCtxt<'a> {
@@ -315,6 +396,18 @@ fn parse_tts(&self, s: String) -> Vec<ast::TokenTree> {
         }
     }
 
+    impl<'a> ExtParseUtilsWithHygiene for ExtCtxt<'a> {
+
+        fn parse_tts_with_hygiene(&self, s: String) -> Vec<ast::TokenTree> {
+            use parse::with_hygiene::parse_tts_from_source_str;
+            parse_tts_from_source_str("<quote expansion>".to_string(),
+                                      s,
+                                      self.cfg(),
+                                      self.parse_sess())
+        }
+
+    }
+
 }
 
 pub fn expand_quote_tokens(cx: &mut ExtCtxt,
index 80325c64349e8414cc6b72b2b5d871715017d54c..9ad28f02e8034813f9e5fb76bcc4d43f273be3e8 100644 (file)
@@ -244,6 +244,16 @@ fn fold_field(&mut self, field: Field) -> Field {
         noop_fold_field(field, self)
     }
 
+    fn fold_where_clause(&mut self, where_clause: &WhereClause)
+                         -> WhereClause {
+        noop_fold_where_clause(where_clause, self)
+    }
+
+    fn fold_where_predicate(&mut self, where_predicate: &WherePredicate)
+                            -> WherePredicate {
+        noop_fold_where_predicate(where_predicate, self)
+    }
+
 // Helper methods:
 
     fn map_exprs(&self, f: |Gc<Expr>| -> Gc<Expr>,
@@ -368,6 +378,7 @@ pub fn noop_fold_ty<T: Folder>(t: P<Ty>, fld: &mut T) -> P<Ty> {
         TyUnboxedFn(ref f) => {
             TyUnboxedFn(box(GC) UnboxedFnTy {
                 decl: fld.fold_fn_decl(&*f.decl),
+                kind: f.kind,
             })
         }
         TyTup(ref tys) => TyTup(tys.iter().map(|&ty| fld.fold_ty(ty)).collect()),
@@ -641,6 +652,7 @@ pub fn noop_fold_ty_param_bound<T: Folder>(tpb: &TyParamBound, fld: &mut T)
         UnboxedFnTyParamBound(ref unboxed_function_type) => {
             UnboxedFnTyParamBound(UnboxedFnTy {
                 decl: fld.fold_fn_decl(&*unboxed_function_type.decl),
+                kind: unboxed_function_type.kind,
             })
         }
         OtherRegionTyParamBound(s) => OtherRegionTyParamBound(s)
@@ -696,8 +708,37 @@ pub fn noop_fold_opt_lifetime<T: Folder>(o_lt: &Option<Lifetime>, fld: &mut T)
 }
 
 pub fn noop_fold_generics<T: Folder>(generics: &Generics, fld: &mut T) -> Generics {
-    Generics {ty_params: fld.fold_ty_params(generics.ty_params.as_slice()),
-              lifetimes: fld.fold_lifetime_defs(generics.lifetimes.as_slice())}
+    Generics {
+        ty_params: fld.fold_ty_params(generics.ty_params.as_slice()),
+        lifetimes: fld.fold_lifetime_defs(generics.lifetimes.as_slice()),
+        where_clause: fld.fold_where_clause(&generics.where_clause),
+    }
+}
+
+pub fn noop_fold_where_clause<T: Folder>(
+                              where_clause: &WhereClause,
+                              fld: &mut T)
+                              -> WhereClause {
+    WhereClause {
+        id: fld.new_id(where_clause.id),
+        predicates: where_clause.predicates.iter().map(|predicate| {
+            fld.fold_where_predicate(predicate)
+        }).collect(),
+    }
+}
+
+pub fn noop_fold_where_predicate<T: Folder>(
+                                 predicate: &WherePredicate,
+                                 fld: &mut T)
+                                 -> WherePredicate {
+    WherePredicate {
+        id: fld.new_id(predicate.id),
+        span: fld.new_span(predicate.span),
+        ident: fld.fold_ident(predicate.ident),
+        bounds: predicate.bounds.map(|x| {
+            fld.fold_ty_param_bound(x)
+        }),
+    }
 }
 
 pub fn noop_fold_struct_def<T: Folder>(struct_def: Gc<StructDef>,
@@ -832,26 +873,37 @@ pub fn noop_fold_item_underscore<T: Folder>(i: &Item_, folder: &mut T) -> Item_
             let struct_def = folder.fold_struct_def(*struct_def);
             ItemStruct(struct_def, folder.fold_generics(generics))
         }
-        ItemImpl(ref generics, ref ifce, ty, ref methods) => {
+        ItemImpl(ref generics, ref ifce, ty, ref impl_items) => {
             ItemImpl(folder.fold_generics(generics),
                      ifce.as_ref().map(|p| folder.fold_trait_ref(p)),
                      folder.fold_ty(ty),
-                     methods.iter().flat_map(|x| folder.fold_method(*x).move_iter()).collect()
+                     impl_items.iter()
+                               .flat_map(|impl_item| {
+                                    match *impl_item {
+                                        MethodImplItem(x) => {
+                                            folder.fold_method(x)
+                                                  .move_iter()
+                                                  .map(|x| MethodImplItem(x))
+                                        }
+                                    }
+                               }).collect()
             )
         }
         ItemTrait(ref generics, ref unbound, ref traits, ref methods) => {
             let methods = methods.iter().flat_map(|method| {
                 let r = match *method {
-                    Required(ref m) =>
-                            SmallVector::one(Required(folder.fold_type_method(m))).move_iter(),
-                    Provided(method) => {
+                    RequiredMethod(ref m) => {
+                            SmallVector::one(RequiredMethod(
+                                    folder.fold_type_method(m))).move_iter()
+                    }
+                    ProvidedMethod(method) => {
                             // the awkward collect/iter idiom here is because
                             // even though an iter and a map satisfy the same trait bound,
                             // they're not actually the same type, so the method arms
                             // don't unify.
-                            let methods : SmallVector<ast::TraitMethod> =
+                            let methods : SmallVector<ast::TraitItem> =
                                 folder.fold_method(method).move_iter()
-                                .map(|m| Provided(m)).collect();
+                                .map(|m| ProvidedMethod(m)).collect();
                             methods.move_iter()
                         }
                 };
@@ -1094,16 +1146,19 @@ pub fn noop_fold_expr<T: Folder>(e: Gc<Expr>, folder: &mut T) -> Gc<Expr> {
             ExprMatch(folder.fold_expr(expr),
                       arms.iter().map(|x| folder.fold_arm(x)).collect())
         }
-        ExprFnBlock(ref decl, ref body) => {
-            ExprFnBlock(folder.fold_fn_decl(&**decl),
+        ExprFnBlock(capture_clause, ref decl, ref body) => {
+            ExprFnBlock(capture_clause,
+                        folder.fold_fn_decl(&**decl),
                         folder.fold_block(body.clone()))
         }
         ExprProc(ref decl, ref body) => {
             ExprProc(folder.fold_fn_decl(&**decl),
                      folder.fold_block(body.clone()))
         }
-        ExprUnboxedFn(ref decl, ref body) => {
-            ExprUnboxedFn(folder.fold_fn_decl(&**decl),
+        ExprUnboxedFn(capture_clause, kind, ref decl, ref body) => {
+            ExprUnboxedFn(capture_clause,
+                          kind,
+                          folder.fold_fn_decl(&**decl),
                           folder.fold_block(*body))
         }
         ExprBlock(ref blk) => ExprBlock(folder.fold_block(*blk)),
index 625c03ec13db941025fa6940cd4e6a059ef4a675..1724962898978d74bcff3a721020d899dd86e553 100644 (file)
@@ -17,7 +17,9 @@
 use parse::token::{str_to_ident};
 
 use std::char;
+use std::fmt;
 use std::mem::replace;
+use std::num;
 use std::rc::Rc;
 use std::str;
 
@@ -55,6 +57,11 @@ pub struct StringReader<'a> {
     /* cached: */
     pub peek_tok: token::Token,
     pub peek_span: Span,
+
+    // FIXME (Issue #16472): This field should go away after ToToken impls
+    // are revised to go directly to token-trees.
+    /// Is \x00<name>,<ctxt>\x00 is interpreted as encoded ast::Ident?
+    read_embedded_ident: bool,
 }
 
 impl<'a> Reader for StringReader<'a> {
@@ -106,6 +113,17 @@ fn peek(&self) -> TokenAndSpan {
     }
 }
 
+// FIXME (Issue #16472): This function should go away after
+// ToToken impls are revised to go directly to token-trees.
+pub fn make_reader_with_embedded_idents<'b>(span_diagnostic: &'b SpanHandler,
+                                            filemap: Rc<codemap::FileMap>)
+                                            -> StringReader<'b> {
+    let mut sr = StringReader::new_raw(span_diagnostic, filemap);
+    sr.read_embedded_ident = true;
+    sr.advance_token();
+    sr
+}
+
 impl<'a> StringReader<'a> {
     /// For comments.rs, which hackily pokes into pos and curr
     pub fn new_raw<'b>(span_diagnostic: &'b SpanHandler,
@@ -120,6 +138,7 @@ pub fn new_raw<'b>(span_diagnostic: &'b SpanHandler,
             /* dummy values; not read */
             peek_tok: token::EOF,
             peek_span: codemap::DUMMY_SP,
+            read_embedded_ident: false,
         };
         sr.bump();
         sr
@@ -512,6 +531,81 @@ fn scan_block_comment(&mut self) -> Option<TokenAndSpan> {
         })
     }
 
+    // FIXME (Issue #16472): The scan_embedded_hygienic_ident function
+    // should go away after we revise the syntax::ext::quote::ToToken
+    // impls to go directly to token-trees instead of thing -> string
+    // -> token-trees.  (The function is currently used to resolve
+    // Issues #15750 and #15962.)
+    //
+    // Since this function is only used for certain internal macros,
+    // and the functionality it provides is not exposed to end user
+    // programs, pnkfelix deliberately chose to write it in a way that
+    // favors rustc debugging effectiveness over runtime efficiency.
+
+    /// Scan through input of form \x00name_NNNNNN,ctxt_CCCCCCC\x00
+    /// whence: `NNNNNN` is a string of characters forming an integer
+    /// (the name) and `CCCCCCC` is a string of characters forming an
+    /// integer (the ctxt), separate by a comma and delimited by a
+    /// `\x00` marker.
+    #[inline(never)]
+    fn scan_embedded_hygienic_ident(&mut self) -> ast::Ident {
+        fn bump_expecting_char<'a,D:fmt::Show>(r: &mut StringReader<'a>,
+                                               c: char,
+                                               described_c: D,
+                                               whence: &str) {
+            match r.curr {
+                Some(r_c) if r_c == c => r.bump(),
+                Some(r_c) => fail!("expected {}, hit {}, {}", described_c, r_c, whence),
+                None      => fail!("expected {}, hit EOF, {}", described_c, whence),
+            }
+        }
+
+        let whence = "while scanning embedded hygienic ident";
+
+        // skip over the leading `\x00`
+        bump_expecting_char(self, '\x00', "nul-byte", whence);
+
+        // skip over the "name_"
+        for c in "name_".chars() {
+            bump_expecting_char(self, c, c, whence);
+        }
+
+        let start_bpos = self.last_pos;
+        let base = 10;
+
+        // find the integer representing the name
+        self.scan_digits(base);
+        let encoded_name : u32 = self.with_str_from(start_bpos, |s| {
+            num::from_str_radix(s, 10).unwrap_or_else(|| {
+                fail!("expected digits representing a name, got `{}`, {}, range [{},{}]",
+                      s, whence, start_bpos, self.last_pos);
+            })
+        });
+
+        // skip over the `,`
+        bump_expecting_char(self, ',', "comma", whence);
+
+        // skip over the "ctxt_"
+        for c in "ctxt_".chars() {
+            bump_expecting_char(self, c, c, whence);
+        }
+
+        // find the integer representing the ctxt
+        let start_bpos = self.last_pos;
+        self.scan_digits(base);
+        let encoded_ctxt : ast::SyntaxContext = self.with_str_from(start_bpos, |s| {
+            num::from_str_radix(s, 10).unwrap_or_else(|| {
+                fail!("expected digits representing a ctxt, got `{}`, {}", s, whence);
+            })
+        });
+
+        // skip over the `\x00`
+        bump_expecting_char(self, '\x00', "nul-byte", whence);
+
+        ast::Ident { name: ast::Name(encoded_name),
+                     ctxt: encoded_ctxt, }
+    }
+
     /// Scan through any digits (base `radix`) or underscores, and return how
     /// many digits there were.
     fn scan_digits(&mut self, radix: uint) -> uint {
@@ -839,6 +933,17 @@ fn next_token_inner(&mut self) -> token::Token {
             return self.scan_number(c.unwrap());
         }
 
+        if self.read_embedded_ident {
+            match (c.unwrap(), self.nextch(), self.nextnextch()) {
+                ('\x00', Some('n'), Some('a')) => {
+                    let ast_ident = self.scan_embedded_hygienic_ident();
+                    let is_mod_name = self.curr_is(':') && self.nextch_is(':');
+                    return token::IDENT(ast_ident, is_mod_name);
+                }
+                _ => {}
+            }
+        }
+
         match c.expect("next_token_inner called at EOF") {
           // One-byte tokens.
           ';' => { self.bump(); return token::SEMI; }
index 5b70ed609d98f05ff06ca31cb2901a57107a1796..271cefeaf038fcd260a515abd58edd2df249d517 100644 (file)
@@ -144,6 +144,8 @@ pub fn parse_stmt_from_source_str(name: String,
     maybe_aborted(p.parse_stmt(attrs),p)
 }
 
+// Note: keep in sync with `with_hygiene::parse_tts_from_source_str`
+// until #16472 is resolved.
 pub fn parse_tts_from_source_str(name: String,
                                  source: String,
                                  cfg: ast::CrateConfig,
@@ -160,6 +162,8 @@ pub fn parse_tts_from_source_str(name: String,
     maybe_aborted(p.parse_all_token_trees(),p)
 }
 
+// Note: keep in sync with `with_hygiene::new_parser_from_source_str`
+// until #16472 is resolved.
 // Create a new parser from a source string
 pub fn new_parser_from_source_str<'a>(sess: &'a ParseSess,
                                       cfg: ast::CrateConfig,
@@ -192,6 +196,8 @@ pub fn new_sub_parser_from_file<'a>(sess: &'a ParseSess,
     p
 }
 
+// Note: keep this in sync with `with_hygiene::filemap_to_parser` until
+// #16472 is resolved.
 /// Given a filemap and config, return a parser
 pub fn filemap_to_parser<'a>(sess: &'a ParseSess,
                              filemap: Rc<FileMap>,
@@ -248,6 +254,8 @@ pub fn string_to_filemap(sess: &ParseSess, source: String, path: String)
     sess.span_diagnostic.cm.new_filemap(path, source)
 }
 
+// Note: keep this in sync with `with_hygiene::filemap_to_tts` (apart
+// from the StringReader constructor), until #16472 is resolved.
 /// Given a filemap, produce a sequence of token-trees
 pub fn filemap_to_tts(sess: &ParseSess, filemap: Rc<FileMap>)
     -> Vec<ast::TokenTree> {
@@ -267,6 +275,67 @@ pub fn tts_to_parser<'a>(sess: &'a ParseSess,
     Parser::new(sess, cfg, box trdr)
 }
 
+// FIXME (Issue #16472): The `with_hygiene` mod should go away after
+// ToToken impls are revised to go directly to token-trees.
+pub mod with_hygiene {
+    use ast;
+    use codemap::FileMap;
+    use parse::parser::Parser;
+    use std::rc::Rc;
+    use super::ParseSess;
+    use super::{maybe_aborted, string_to_filemap, tts_to_parser};
+
+    // Note: keep this in sync with `super::parse_tts_from_source_str` until
+    // #16472 is resolved.
+    pub fn parse_tts_from_source_str(name: String,
+                                     source: String,
+                                     cfg: ast::CrateConfig,
+                                     sess: &ParseSess) -> Vec<ast::TokenTree> {
+        let mut p = new_parser_from_source_str(
+            sess,
+            cfg,
+            name,
+            source
+        );
+        p.quote_depth += 1u;
+        // right now this is re-creating the token trees from ... token trees.
+        maybe_aborted(p.parse_all_token_trees(),p)
+    }
+
+    // Note: keep this in sync with `super::new_parser_from_source_str` until
+    // #16472 is resolved.
+    // Create a new parser from a source string
+    fn new_parser_from_source_str<'a>(sess: &'a ParseSess,
+                                      cfg: ast::CrateConfig,
+                                      name: String,
+                                      source: String) -> Parser<'a> {
+        filemap_to_parser(sess, string_to_filemap(sess, source, name), cfg)
+    }
+
+    // Note: keep this in sync with `super::filemap_to_parserr` until
+    // #16472 is resolved.
+    /// Given a filemap and config, return a parser
+    fn filemap_to_parser<'a>(sess: &'a ParseSess,
+                             filemap: Rc<FileMap>,
+                             cfg: ast::CrateConfig) -> Parser<'a> {
+        tts_to_parser(sess, filemap_to_tts(sess, filemap), cfg)
+    }
+
+    // Note: keep this in sync with `super::filemap_to_tts` until
+    // #16472 is resolved.
+    /// Given a filemap, produce a sequence of token-trees
+    fn filemap_to_tts(sess: &ParseSess, filemap: Rc<FileMap>)
+                      -> Vec<ast::TokenTree> {
+        // it appears to me that the cfg doesn't matter here... indeed,
+        // parsing tt's probably shouldn't require a parser at all.
+        use make_reader = super::lexer::make_reader_with_embedded_idents;
+        let cfg = Vec::new();
+        let srdr = make_reader(&sess.span_diagnostic, filemap);
+        let mut p1 = Parser::new(sess, cfg, box srdr);
+        p1.parse_all_token_trees()
+    }
+}
+
 /// Abort if necessary
 pub fn maybe_aborted<T>(result: T, mut p: Parser) -> T {
     p.abort_if_errors();
@@ -984,6 +1053,10 @@ fn parser_done(p: Parser){
                                     ast::Generics{ // no idea on either of these:
                                         lifetimes: Vec::new(),
                                         ty_params: OwnedSlice::empty(),
+                                        where_clause: ast::WhereClause {
+                                            id: ast::DUMMY_NODE_ID,
+                                            predicates: Vec::new(),
+                                        }
                                     },
                                     ast::P(ast::Block {
                                         view_items: Vec::new(),
index 08d96f5b0086d590dd2b0aae2999df4d35a987a1..80b852111a2e47ee9d363a8f230e0c344831d844 100644 (file)
 use abi;
 use ast::{BareFnTy, ClosureTy};
 use ast::{StaticRegionTyParamBound, OtherRegionTyParamBound, TraitTyParamBound};
-use ast::{Provided, Public, FnStyle};
+use ast::{ProvidedMethod, Public, FnStyle};
 use ast::{Mod, BiAdd, Arg, Arm, Attribute, BindByRef, BindByValue};
 use ast::{BiBitAnd, BiBitOr, BiBitXor, Block};
 use ast::{BlockCheckMode, UnBox};
+use ast::{CaptureByRef, CaptureByValue, CaptureClause};
 use ast::{Crate, CrateConfig, Decl, DeclItem};
 use ast::{DeclLocal, DefaultBlock, UnDeref, BiDiv, EMPTY_CTXT, EnumDef, ExplicitSelf};
 use ast::{Expr, Expr_, ExprAddrOf, ExprMatch, ExprAgain};
 use ast::{ExprVec, ExprVstore, ExprVstoreSlice};
 use ast::{ExprVstoreMutSlice, ExprWhile, ExprForLoop, Field, FnDecl};
 use ast::{ExprVstoreUniq, Once, Many};
+use ast::{FnUnboxedClosureKind, FnMutUnboxedClosureKind};
+use ast::{FnOnceUnboxedClosureKind};
 use ast::{ForeignItem, ForeignItemStatic, ForeignItemFn, ForeignMod};
-use ast::{Ident, NormalFn, Inherited, Item, Item_, ItemStatic};
+use ast::{Ident, NormalFn, Inherited, ImplItem, Item, Item_, ItemStatic};
 use ast::{ItemEnum, ItemFn, ItemForeignMod, ItemImpl};
 use ast::{ItemMac, ItemMod, ItemStruct, ItemTrait, ItemTy, Lit, Lit_};
 use ast::{LitBool, LitChar, LitByte, LitBinary};
 use ast::{LitNil, LitStr, LitInt, Local, LocalLet};
 use ast::{MutImmutable, MutMutable, Mac_, MacInvocTT, Matcher, MatchNonterminal};
 use ast::{MatchSeq, MatchTok, Method, MutTy, BiMul, Mutability};
+use ast::{MethodImplItem};
 use ast::{NamedField, UnNeg, NoReturn, UnNot, P, Pat, PatEnum};
 use ast::{PatIdent, PatLit, PatRange, PatRegion, PatStruct};
 use ast::{PatTup, PatBox, PatWild, PatWildMulti, PatWildSingle};
-use ast::{BiRem, Required};
+use ast::{BiRem, RequiredMethod};
 use ast::{RetStyle, Return, BiShl, BiShr, Stmt, StmtDecl};
 use ast::{StmtExpr, StmtSemi, StmtMac, StructDef, StructField};
 use ast::{StructVariantKind, BiSub};
 use ast::StrStyle;
 use ast::{SelfExplicit, SelfRegion, SelfStatic, SelfValue};
-use ast::{TokenTree, TraitMethod, TraitRef, TTDelim, TTSeq, TTTok};
+use ast::{TokenTree, TraitItem, TraitRef, TTDelim, TTSeq, TTTok};
 use ast::{TTNonterminal, TupleVariantKind, Ty, Ty_, TyBot, TyBox};
 use ast::{TypeField, TyFixedLengthVec, TyClosure, TyProc, TyBareFn};
 use ast::{TyTypeof, TyInfer, TypeMethod};
 use ast::{TyNil, TyParam, TyParamBound, TyParen, TyPath, TyPtr, TyRptr};
 use ast::{TyTup, TyU32, TyUnboxedFn, TyUniq, TyVec, UnUniq};
-use ast::{UnboxedFnTy, UnboxedFnTyParamBound, UnnamedField, UnsafeBlock};
+use ast::{UnboxedClosureKind, UnboxedFnTy, UnboxedFnTyParamBound};
+use ast::{UnnamedField, UnsafeBlock};
 use ast::{UnsafeFn, ViewItem, ViewItem_, ViewItemExternCrate, ViewItemUse};
 use ast::{ViewPath, ViewPathGlob, ViewPathList, ViewPathSimple};
-use ast::Visibility;
+use ast::{Visibility, WhereClause, WherePredicate};
 use ast;
 use ast_util::{as_prec, ident_to_path, lit_is_str, operator_prec};
 use ast_util;
@@ -1086,6 +1091,34 @@ pub fn parse_proc_type(&mut self) -> Ty_ {
         })
     }
 
+    /// Parses an optional unboxed closure kind (`&:`, `&mut:`, or `:`).
+    pub fn parse_optional_unboxed_closure_kind(&mut self)
+                                               -> Option<UnboxedClosureKind> {
+        if self.token == token::BINOP(token::AND) &&
+                    self.look_ahead(1, |t| {
+                        token::is_keyword(keywords::Mut, t)
+                    }) &&
+                    self.look_ahead(2, |t| *t == token::COLON) {
+            self.bump();
+            self.bump();
+            self.bump();
+            return Some(FnMutUnboxedClosureKind)
+        }
+
+        if self.token == token::BINOP(token::AND) &&
+                    self.look_ahead(1, |t| *t == token::COLON) {
+            self.bump();
+            self.bump();
+            return Some(FnUnboxedClosureKind)
+        }
+
+        if self.eat(&token::COLON) {
+            return Some(FnOnceUnboxedClosureKind)
+        }
+
+        return None
+    }
+
     /// Parse a TyClosure type
     pub fn parse_ty_closure(&mut self) -> Ty_ {
         /*
@@ -1114,27 +1147,19 @@ pub fn parse_ty_closure(&mut self) -> Ty_ {
             Vec::new()
         };
 
-        let (is_unboxed, inputs) = if self.eat(&token::OROR) {
-            (false, Vec::new())
+        let (optional_unboxed_closure_kind, inputs) = if self.eat(&token::OROR) {
+            (None, Vec::new())
         } else {
             self.expect_or();
 
-            let is_unboxed = self.token == token::BINOP(token::AND) &&
-                self.look_ahead(1, |t| {
-                    token::is_keyword(keywords::Mut, t)
-                }) &&
-                self.look_ahead(2, |t| *t == token::COLON);
-            if is_unboxed {
-                self.bump();
-                self.bump();
-                self.bump();
-            }
+            let optional_unboxed_closure_kind =
+                self.parse_optional_unboxed_closure_kind();
 
             let inputs = self.parse_seq_to_before_or(
                 &token::COMMA,
                 |p| p.parse_arg_general(false));
             self.expect_or();
-            (is_unboxed, inputs)
+            (optional_unboxed_closure_kind, inputs)
         };
 
         let (region, bounds) = {
@@ -1154,18 +1179,22 @@ pub fn parse_ty_closure(&mut self) -> Ty_ {
             variadic: false
         });
 
-        if is_unboxed {
-            TyUnboxedFn(box(GC) UnboxedFnTy {
-                decl: decl,
-            })
-        } else {
-            TyClosure(box(GC) ClosureTy {
-                fn_style: fn_style,
-                onceness: onceness,
-                bounds: bounds,
-                decl: decl,
-                lifetimes: lifetime_defs,
-            }, region)
+        match optional_unboxed_closure_kind {
+            Some(unboxed_closure_kind) => {
+                TyUnboxedFn(box(GC) UnboxedFnTy {
+                    kind: unboxed_closure_kind,
+                    decl: decl,
+                })
+            }
+            None => {
+                TyClosure(box(GC) ClosureTy {
+                    fn_style: fn_style,
+                    onceness: onceness,
+                    bounds: bounds,
+                    decl: decl,
+                    lifetimes: lifetime_defs,
+                }, region)
+            }
         }
     }
 
@@ -1210,7 +1239,7 @@ pub fn parse_ty_fn_decl(&mut self, allow_variadic: bool)
     }
 
     /// Parse the methods in a trait declaration
-    pub fn parse_trait_methods(&mut self) -> Vec<TraitMethod> {
+    pub fn parse_trait_methods(&mut self) -> Vec<TraitItem> {
         self.parse_unspanned_seq(
             &token::LBRACE,
             &token::RBRACE,
@@ -1235,7 +1264,7 @@ pub fn parse_trait_methods(&mut self) -> Vec<TraitMethod> {
             let style = p.parse_fn_style();
             let ident = p.parse_ident();
 
-            let generics = p.parse_generics();
+            let mut generics = p.parse_generics();
 
             let (explicit_self, d) = p.parse_fn_decl_with_self(|p| {
                 // This is somewhat dubious; We don't want to allow argument
@@ -1243,12 +1272,14 @@ pub fn parse_trait_methods(&mut self) -> Vec<TraitMethod> {
                 p.parse_arg_general(false)
             });
 
+            p.parse_where_clause(&mut generics);
+
             let hi = p.last_span.hi;
             match p.token {
               token::SEMI => {
                 p.bump();
                 debug!("parse_trait_methods(): parsing required method");
-                Required(TypeMethod {
+                RequiredMethod(TypeMethod {
                     ident: ident,
                     attrs: attrs,
                     fn_style: style,
@@ -1266,7 +1297,7 @@ pub fn parse_trait_methods(&mut self) -> Vec<TraitMethod> {
                 let (inner_attrs, body) =
                     p.parse_inner_attrs_and_block();
                 let attrs = attrs.append(inner_attrs.as_slice());
-                Provided(box(GC) ast::Method {
+                ProvidedMethod(box(GC) ast::Method {
                     attrs: attrs,
                     id: ast::DUMMY_NODE_ID,
                     span: mk_sp(lo, hi),
@@ -1985,7 +2016,7 @@ pub fn parse_bottom_expr(&mut self) -> Gc<Expr> {
                                     ExprBlock(blk));
             },
             token::BINOP(token::OR) |  token::OROR => {
-                return self.parse_lambda_expr();
+                return self.parse_lambda_expr(CaptureByValue);
             },
             // FIXME #13626: Should be able to stick in
             // token::SELF_KEYWORD_NAME
@@ -2036,6 +2067,9 @@ pub fn parse_bottom_expr(&mut self) -> Gc<Expr> {
                 hi = self.last_span.hi;
             },
             _ => {
+                if self.eat_keyword(keywords::Ref) {
+                    return self.parse_lambda_expr(CaptureByRef);
+                }
                 if self.eat_keyword(keywords::Proc) {
                     let decl = self.parse_proc_decl();
                     let body = self.parse_expr();
@@ -2696,9 +2730,11 @@ pub fn parse_if_expr(&mut self) -> Gc<Expr> {
     }
 
     // `|args| expr`
-    pub fn parse_lambda_expr(&mut self) -> Gc<Expr> {
+    pub fn parse_lambda_expr(&mut self, capture_clause: CaptureClause)
+                             -> Gc<Expr> {
         let lo = self.span.lo;
-        let (decl, is_unboxed) = self.parse_fn_block_decl();
+        let (decl, optional_unboxed_closure_kind) =
+            self.parse_fn_block_decl();
         let body = self.parse_expr();
         let fakeblock = P(ast::Block {
             view_items: Vec::new(),
@@ -2709,10 +2745,20 @@ pub fn parse_lambda_expr(&mut self) -> Gc<Expr> {
             span: body.span,
         });
 
-        if is_unboxed {
-            self.mk_expr(lo, body.span.hi, ExprUnboxedFn(decl, fakeblock))
-        } else {
-            self.mk_expr(lo, body.span.hi, ExprFnBlock(decl, fakeblock))
+        match optional_unboxed_closure_kind {
+            Some(unboxed_closure_kind) => {
+                self.mk_expr(lo,
+                             body.span.hi,
+                             ExprUnboxedFn(capture_clause,
+                                           unboxed_closure_kind,
+                                           decl,
+                                           fakeblock))
+            }
+            None => {
+                self.mk_expr(lo,
+                             body.span.hi,
+                             ExprFnBlock(capture_clause, decl, fakeblock))
+            }
         }
     }
 
@@ -3544,28 +3590,22 @@ fn parse_block_tail_(&mut self, lo: BytePos, s: BlockCheckMode,
     }
 
     fn parse_unboxed_function_type(&mut self) -> UnboxedFnTy {
-        let inputs = if self.eat(&token::OROR) {
-            Vec::new()
-        } else {
-            self.expect_or();
+        let (optional_unboxed_closure_kind, inputs) =
+            if self.eat(&token::OROR) {
+                (None, Vec::new())
+            } else {
+                self.expect_or();
 
-            if self.token == token::BINOP(token::AND) &&
-                    self.look_ahead(1, |t| {
-                        token::is_keyword(keywords::Mut, t)
-                    }) &&
-                    self.look_ahead(2, |t| *t == token::COLON) {
-                self.bump();
-                self.bump();
-                self.bump();
-            }
+                let optional_unboxed_closure_kind =
+                    self.parse_optional_unboxed_closure_kind();
 
-            let inputs = self.parse_seq_to_before_or(&token::COMMA,
-                                                     |p| {
-                p.parse_arg_general(false)
-            });
-            self.expect_or();
-            inputs
-        };
+                let inputs = self.parse_seq_to_before_or(&token::COMMA,
+                                                         |p| {
+                    p.parse_arg_general(false)
+                });
+                self.expect_or();
+                (optional_unboxed_closure_kind, inputs)
+            };
 
         let (return_style, output) = self.parse_ret_ty();
         UnboxedFnTy {
@@ -3574,7 +3614,11 @@ fn parse_unboxed_function_type(&mut self) -> UnboxedFnTy {
                 output: output,
                 cf: return_style,
                 variadic: false,
-            })
+            }),
+            kind: match optional_unboxed_closure_kind {
+                Some(kind) => kind,
+                None => FnMutUnboxedClosureKind,
+            },
         }
     }
 
@@ -3700,7 +3744,10 @@ fn parse_ty_param(&mut self) -> TyParam {
         }
     }
 
-    /// Parse a set of optional generic type parameter declarations
+    /// Parse a set of optional generic type parameter declarations. Where
+    /// clauses are not parsed here, and must be added later via
+    /// `parse_where_clause()`.
+    ///
     /// matches generics = ( ) | ( < > ) | ( < typaramseq ( , )? > ) | ( < lifetimes ( , )? > )
     ///                  | ( < lifetimes , typaramseq ( , )? > )
     /// where   typaramseq = ( typaram ) | ( typaram , typaramseq )
@@ -3720,7 +3767,14 @@ pub fn parse_generics(&mut self) -> ast::Generics {
                 }
                 ty_param
             });
-            ast::Generics { lifetimes: lifetime_defs, ty_params: ty_params }
+            ast::Generics {
+                lifetimes: lifetime_defs,
+                ty_params: ty_params,
+                where_clause: WhereClause {
+                    id: ast::DUMMY_NODE_ID,
+                    predicates: Vec::new(),
+                }
+            }
         } else {
             ast_util::empty_generics()
         }
@@ -3746,6 +3800,52 @@ fn forbid_lifetime(&mut self) {
         }
     }
 
+    /// Parses an optional `where` clause and places it in `generics`.
+    fn parse_where_clause(&mut self, generics: &mut ast::Generics) {
+        if !self.eat_keyword(keywords::Where) {
+            return
+        }
+
+        let mut parsed_something = false;
+        loop {
+            let lo = self.span.lo;
+            let ident = match self.token {
+                token::IDENT(..) => self.parse_ident(),
+                _ => break,
+            };
+            self.expect(&token::COLON);
+
+            let (_, bounds) = self.parse_ty_param_bounds(false);
+            let hi = self.span.hi;
+            let span = mk_sp(lo, hi);
+
+            if bounds.len() == 0 {
+                self.span_err(span,
+                              "each predicate in a `where` clause must have \
+                               at least one bound in it");
+            }
+
+            generics.where_clause.predicates.push(ast::WherePredicate {
+                id: ast::DUMMY_NODE_ID,
+                span: span,
+                ident: ident,
+                bounds: bounds,
+            });
+            parsed_something = true;
+
+            if !self.eat(&token::COMMA) {
+                break
+            }
+        }
+
+        if !parsed_something {
+            let last_span = self.last_span;
+            self.span_err(last_span,
+                          "a `where` clause must have at least one predicate \
+                           in it");
+        }
+    }
+
     fn parse_fn_args(&mut self, named_args: bool, allow_variadic: bool)
                      -> (Vec<Arg> , bool) {
         let sp = self.span;
@@ -4017,29 +4117,22 @@ macro_rules! parse_remaining_arguments {
     }
 
     // parse the |arg, arg| header on a lambda
-    fn parse_fn_block_decl(&mut self) -> (P<FnDecl>, bool) {
-        let (is_unboxed, inputs_captures) = {
+    fn parse_fn_block_decl(&mut self)
+                           -> (P<FnDecl>, Option<UnboxedClosureKind>) {
+        let (optional_unboxed_closure_kind, inputs_captures) = {
             if self.eat(&token::OROR) {
-                (false, Vec::new())
+                (None, Vec::new())
             } else {
                 self.expect(&token::BINOP(token::OR));
-                let is_unboxed = self.token == token::BINOP(token::AND) &&
-                    self.look_ahead(1, |t| {
-                        token::is_keyword(keywords::Mut, t)
-                    }) &&
-                    self.look_ahead(2, |t| *t == token::COLON);
-                if is_unboxed {
-                    self.bump();
-                    self.bump();
-                    self.bump();
-                }
+                let optional_unboxed_closure_kind =
+                    self.parse_optional_unboxed_closure_kind();
                 let args = self.parse_seq_to_before_end(
                     &token::BINOP(token::OR),
                     seq_sep_trailing_disallowed(token::COMMA),
                     |p| p.parse_fn_block_arg()
                 );
                 self.bump();
-                (is_unboxed, args)
+                (optional_unboxed_closure_kind, args)
             }
         };
         let output = if self.eat(&token::RARROW) {
@@ -4057,7 +4150,7 @@ fn parse_fn_block_decl(&mut self) -> (P<FnDecl>, bool) {
             output: output,
             cf: Return,
             variadic: false
-        }), is_unboxed)
+        }), optional_unboxed_closure_kind)
     }
 
     /// Parses the `(arg, arg) -> return_type` header on a procedure.
@@ -4108,8 +4201,9 @@ fn mk_item(&mut self, lo: BytePos, hi: BytePos, ident: Ident,
 
     /// Parse an item-position function declaration.
     fn parse_item_fn(&mut self, fn_style: FnStyle, abi: abi::Abi) -> ItemInfo {
-        let (ident, generics) = self.parse_fn_header();
+        let (ident, mut generics) = self.parse_fn_header();
         let decl = self.parse_fn_decl(false);
+        self.parse_where_clause(&mut generics);
         let (inner_attrs, body) = self.parse_inner_attrs_and_block();
         (ident, ItemFn(decl, fn_style, abi, generics, body), Some(inner_attrs))
     }
@@ -4165,10 +4259,11 @@ pub fn parse_method(&mut self,
                 };
                 let fn_style = self.parse_fn_style();
                 let ident = self.parse_ident();
-                let generics = self.parse_generics();
+                let mut generics = self.parse_generics();
                 let (explicit_self, decl) = self.parse_fn_decl_with_self(|p| {
                         p.parse_arg()
                     });
+                self.parse_where_clause(&mut generics);
                 let (inner_attrs, body) = self.parse_inner_attrs_and_block();
                 let new_attrs = attrs.append(inner_attrs.as_slice());
                 (ast::MethDecl(ident,
@@ -4193,7 +4288,7 @@ pub fn parse_method(&mut self,
     /// Parse trait Foo { ... }
     fn parse_item_trait(&mut self) -> ItemInfo {
         let ident = self.parse_ident();
-        let tps = self.parse_generics();
+        let mut tps = self.parse_generics();
         let sized = self.parse_for_sized();
 
         // Parse traits, if necessary.
@@ -4205,16 +4300,30 @@ fn parse_item_trait(&mut self) -> ItemInfo {
             traits = Vec::new();
         }
 
+        self.parse_where_clause(&mut tps);
+
         let meths = self.parse_trait_methods();
         (ident, ItemTrait(tps, sized, traits, meths), None)
     }
 
+    fn parse_impl_items(&mut self) -> (Vec<ImplItem>, Vec<Attribute>) {
+        let mut impl_items = Vec::new();
+        self.expect(&token::LBRACE);
+        let (inner_attrs, next) = self.parse_inner_attrs_and_next();
+        let mut method_attrs = Some(next);
+        while !self.eat(&token::RBRACE) {
+            impl_items.push(MethodImplItem(self.parse_method(method_attrs)));
+            method_attrs = None;
+        }
+        (impl_items, inner_attrs)
+    }
+
     /// Parses two variants (with the region/type params always optional):
     ///    impl<T> Foo { ... }
     ///    impl<T> ToString for ~[T] { ... }
     fn parse_item_impl(&mut self) -> ItemInfo {
         // First, parse type parameters if necessary.
-        let generics = self.parse_generics();
+        let mut generics = self.parse_generics();
 
         // Special case: if the next identifier that follows is '(', don't
         // allow this to be parsed as a trait.
@@ -4250,18 +4359,14 @@ fn parse_item_impl(&mut self) -> ItemInfo {
             None
         };
 
-        let mut meths = Vec::new();
-        self.expect(&token::LBRACE);
-        let (inner_attrs, next) = self.parse_inner_attrs_and_next();
-        let mut method_attrs = Some(next);
-        while !self.eat(&token::RBRACE) {
-            meths.push(self.parse_method(method_attrs));
-            method_attrs = None;
-        }
+        self.parse_where_clause(&mut generics);
+        let (impl_items, attrs) = self.parse_impl_items();
 
         let ident = ast_util::impl_pretty_name(&opt_trait, &*ty);
 
-        (ident, ItemImpl(generics, opt_trait, ty, meths), Some(inner_attrs))
+        (ident,
+         ItemImpl(generics, opt_trait, ty, impl_items),
+         Some(attrs))
     }
 
     /// Parse a::B<String,int>
@@ -4284,7 +4389,7 @@ fn parse_trait_ref_list(&mut self, ket: &token::Token) -> Vec<TraitRef> {
     /// Parse struct Foo { ... }
     fn parse_item_struct(&mut self, is_virtual: bool) -> ItemInfo {
         let class_name = self.parse_ident();
-        let generics = self.parse_generics();
+        let mut generics = self.parse_generics();
 
         let super_struct = if self.eat(&token::COLON) {
             let ty = self.parse_ty(true);
@@ -4301,6 +4406,8 @@ fn parse_item_struct(&mut self, is_virtual: bool) -> ItemInfo {
             None
         };
 
+        self.parse_where_clause(&mut generics);
+
         let mut fields: Vec<StructField>;
         let is_tuple_like;
 
@@ -4641,8 +4748,9 @@ fn parse_item_foreign_fn(&mut self, vis: ast::Visibility,
         let lo = self.span.lo;
         self.expect_keyword(keywords::Fn);
 
-        let (ident, generics) = self.parse_fn_header();
+        let (ident, mut generics) = self.parse_fn_header();
         let decl = self.parse_fn_decl(true);
+        self.parse_where_clause(&mut generics);
         let hi = self.span.hi;
         self.expect(&token::SEMI);
         box(GC) ast::ForeignItem { ident: ident,
@@ -4792,7 +4900,8 @@ fn parse_item_foreign_mod(&mut self,
     /// Parse type Foo = Bar;
     fn parse_item_type(&mut self) -> ItemInfo {
         let ident = self.parse_ident();
-        let tps = self.parse_generics();
+        let mut tps = self.parse_generics();
+        self.parse_where_clause(&mut tps);
         self.expect(&token::EQ);
         let ty = self.parse_ty(true);
         self.expect(&token::SEMI);
@@ -4883,7 +4992,8 @@ fn parse_enum_def(&mut self, _generics: &ast::Generics) -> EnumDef {
     /// Parse an "enum" declaration
     fn parse_item_enum(&mut self) -> ItemInfo {
         let id = self.parse_ident();
-        let generics = self.parse_generics();
+        let mut generics = self.parse_generics();
+        self.parse_where_clause(&mut generics);
         self.expect(&token::LBRACE);
 
         let enum_definition = self.parse_enum_def(&generics);
@@ -5275,6 +5385,7 @@ fn parse_view_path(&mut self) -> Gc<ViewPath> {
         match self.token {
           token::EQ => {
             // x = foo::bar
+            // NOTE(stage0, #16461, pcwalton): Deprecate after snapshot.
             self.bump();
             let path_lo = self.span.lo;
             path = vec!(self.parse_ident());
@@ -5357,7 +5468,7 @@ fn parse_view_path(&mut self) -> Gc<ViewPath> {
           }
           _ => ()
         }
-        let last = *path.get(path.len() - 1u);
+        let mut rename_to = *path.get(path.len() - 1u);
         let path = ast::Path {
             span: mk_sp(lo, self.span.hi),
             global: false,
@@ -5369,9 +5480,12 @@ fn parse_view_path(&mut self) -> Gc<ViewPath> {
                 }
             }).collect()
         };
+        if self.eat_keyword(keywords::As) {
+            rename_to = self.parse_ident()
+        }
         return box(GC) spanned(lo,
                         self.last_span.hi,
-                        ViewPathSimple(last, path, ast::DUMMY_NODE_ID));
+                        ViewPathSimple(rename_to, path, ast::DUMMY_NODE_ID));
     }
 
     /// Parses a sequence of items. Stops when it finds program
index f1ef79801518d12b4f2eb7233fe0c8c105558eb5..4c959932f415d112fd5734ba39a17c4bd3fea268 100644 (file)
@@ -499,18 +499,19 @@ pub mod keywords {
         (41,                         Proc,       "proc");
         (42,                         Box,        "box");
         (43,                         Const,      "const");
+        (44,                         Where,      "where");
 
         'reserved:
-        (44,                         Alignof,    "alignof");
-        (45,                         Be,         "be");
-        (46,                         Offsetof,   "offsetof");
-        (47,                         Priv,       "priv");
-        (48,                         Pure,       "pure");
-        (49,                         Sizeof,     "sizeof");
-        (50,                         Typeof,     "typeof");
-        (51,                         Unsized,    "unsized");
-        (52,                         Yield,      "yield");
-        (53,                         Do,         "do");
+        (45,                         Alignof,    "alignof");
+        (46,                         Be,         "be");
+        (47,                         Offsetof,   "offsetof");
+        (48,                         Priv,       "priv");
+        (49,                         Pure,       "pure");
+        (50,                         Sizeof,     "sizeof");
+        (51,                         Typeof,     "typeof");
+        (52,                         Unsized,    "unsized");
+        (53,                         Yield,      "yield");
+        (54,                         Do,         "do");
     }
 }
 
index 9d4b7343c8a156fa63e039549773934a59199a8e..26d425563d09f5c77e12e29d27a2942102390a8f 100644 (file)
@@ -9,8 +9,10 @@
 // except according to those terms.
 
 use abi;
-use ast::{P, StaticRegionTyParamBound, OtherRegionTyParamBound};
-use ast::{TraitTyParamBound, UnboxedFnTyParamBound, Required, Provided};
+use ast::{FnMutUnboxedClosureKind, FnOnceUnboxedClosureKind};
+use ast::{FnUnboxedClosureKind, MethodImplItem, P, OtherRegionTyParamBound};
+use ast::{StaticRegionTyParamBound, TraitTyParamBound, UnboxedClosureKind};
+use ast::{UnboxedFnTyParamBound, RequiredMethod, ProvidedMethod};
 use ast;
 use ast_util;
 use owned_slice::OwnedSlice;
@@ -58,7 +60,8 @@ pub struct State<'a> {
     literals: Option<Vec<comments::Literal> >,
     cur_cmnt_and_lit: CurrentCommentAndLiteral,
     boxes: Vec<pp::Breaks>,
-    ann: &'a PpAnn
+    ann: &'a PpAnn,
+    encode_idents_with_hygiene: bool,
 }
 
 pub fn rust_printer(writer: Box<io::Writer>) -> State<'static> {
@@ -78,7 +81,8 @@ pub fn rust_printer_annotated<'a>(writer: Box<io::Writer>,
             cur_lit: 0
         },
         boxes: Vec::new(),
-        ann: ann
+        ann: ann,
+        encode_idents_with_hygiene: false,
     }
 }
 
@@ -148,7 +152,8 @@ pub fn new(cm: &'a CodeMap,
                 cur_lit: 0
             },
             boxes: Vec::new(),
-            ann: ann
+            ann: ann,
+            encode_idents_with_hygiene: false,
         }
     }
 }
@@ -169,70 +174,77 @@ pub fn to_string(f: |&mut State| -> IoResult<()>) -> String {
     }
 }
 
+// FIXME (Issue #16472): the thing_to_string_impls macro should go away
+// after we revise the syntax::ext::quote::ToToken impls to go directly
+// to token-trees instea of thing -> string -> token-trees.
+
+macro_rules! thing_to_string_impls {
+    ($to_string:ident) => {
+
 pub fn ty_to_string(ty: &ast::Ty) -> String {
-    to_string(|s| s.print_type(ty))
+    $to_string(|s| s.print_type(ty))
 }
 
 pub fn pat_to_string(pat: &ast::Pat) -> String {
-    to_string(|s| s.print_pat(pat))
+    $to_string(|s| s.print_pat(pat))
 }
 
 pub fn arm_to_string(arm: &ast::Arm) -> String {
-    to_string(|s| s.print_arm(arm))
+    $to_string(|s| s.print_arm(arm))
 }
 
 pub fn expr_to_string(e: &ast::Expr) -> String {
-    to_string(|s| s.print_expr(e))
+    $to_string(|s| s.print_expr(e))
 }
 
 pub fn lifetime_to_string(e: &ast::Lifetime) -> String {
-    to_string(|s| s.print_lifetime(e))
+    $to_string(|s| s.print_lifetime(e))
 }
 
 pub fn tt_to_string(tt: &ast::TokenTree) -> String {
-    to_string(|s| s.print_tt(tt))
+    $to_string(|s| s.print_tt(tt))
 }
 
 pub fn tts_to_string(tts: &[ast::TokenTree]) -> String {
-    to_string(|s| s.print_tts(tts))
+    $to_string(|s| s.print_tts(tts))
 }
 
 pub fn stmt_to_string(stmt: &ast::Stmt) -> String {
-    to_string(|s| s.print_stmt(stmt))
+    $to_string(|s| s.print_stmt(stmt))
 }
 
 pub fn item_to_string(i: &ast::Item) -> String {
-    to_string(|s| s.print_item(i))
+    $to_string(|s| s.print_item(i))
 }
 
 pub fn generics_to_string(generics: &ast::Generics) -> String {
-    to_string(|s| s.print_generics(generics))
+    $to_string(|s| s.print_generics(generics))
 }
 
 pub fn ty_method_to_string(p: &ast::TypeMethod) -> String {
-    to_string(|s| s.print_ty_method(p))
+    $to_string(|s| s.print_ty_method(p))
 }
 
 pub fn method_to_string(p: &ast::Method) -> String {
-    to_string(|s| s.print_method(p))
+    $to_string(|s| s.print_method(p))
 }
 
 pub fn fn_block_to_string(p: &ast::FnDecl) -> String {
-    to_string(|s| s.print_fn_block_args(p, false))
+    $to_string(|s| s.print_fn_block_args(p, None))
 }
 
 pub fn path_to_string(p: &ast::Path) -> String {
-    to_string(|s| s.print_path(p, false))
+    $to_string(|s| s.print_path(p, false))
 }
 
 pub fn ident_to_string(id: &ast::Ident) -> String {
-    to_string(|s| s.print_ident(*id))
+    $to_string(|s| s.print_ident(*id))
 }
 
 pub fn fun_to_string(decl: &ast::FnDecl, fn_style: ast::FnStyle, name: ast::Ident,
                   opt_explicit_self: Option<ast::ExplicitSelf_>,
                   generics: &ast::Generics) -> String {
-    to_string(|s| {
+    $to_string(|s| {
         try!(s.print_fn(decl, Some(fn_style), abi::Rust,
                         name, generics, opt_explicit_self, ast::Inherited));
         try!(s.end()); // Close the head box
@@ -241,7 +253,7 @@ pub fn fun_to_string(decl: &ast::FnDecl, fn_style: ast::FnStyle, name: ast::Iden
 }
 
 pub fn block_to_string(blk: &ast::Block) -> String {
-    to_string(|s| {
+    $to_string(|s| {
         // containing cbox, will be closed by print-block at }
         try!(s.cbox(indent_unit));
         // head-ibox, will be closed by print-block after {
@@ -251,31 +263,57 @@ pub fn block_to_string(blk: &ast::Block) -> String {
 }
 
 pub fn meta_item_to_string(mi: &ast::MetaItem) -> String {
-    to_string(|s| s.print_meta_item(mi))
+    $to_string(|s| s.print_meta_item(mi))
 }
 
 pub fn attribute_to_string(attr: &ast::Attribute) -> String {
-    to_string(|s| s.print_attribute(attr))
+    $to_string(|s| s.print_attribute(attr))
 }
 
 pub fn lit_to_string(l: &ast::Lit) -> String {
-    to_string(|s| s.print_literal(l))
+    $to_string(|s| s.print_literal(l))
 }
 
 pub fn explicit_self_to_string(explicit_self: ast::ExplicitSelf_) -> String {
-    to_string(|s| s.print_explicit_self(explicit_self, ast::MutImmutable).map(|_| {}))
+    $to_string(|s| s.print_explicit_self(explicit_self, ast::MutImmutable).map(|_| {}))
 }
 
 pub fn variant_to_string(var: &ast::Variant) -> String {
-    to_string(|s| s.print_variant(var))
+    $to_string(|s| s.print_variant(var))
 }
 
 pub fn arg_to_string(arg: &ast::Arg) -> String {
-    to_string(|s| s.print_arg(arg))
+    $to_string(|s| s.print_arg(arg))
 }
 
 pub fn mac_to_string(arg: &ast::Mac) -> String {
-    to_string(|s| s.print_mac(arg))
+    $to_string(|s| s.print_mac(arg))
+}
+
+} }
+
+thing_to_string_impls!(to_string)
+
+// FIXME (Issue #16472): the whole `with_hygiene` mod should go away
+// after we revise the syntax::ext::quote::ToToken impls to go directly
+// to token-trees instea of thing -> string -> token-trees.
+
+pub mod with_hygiene {
+    use abi;
+    use ast;
+    use std::io::IoResult;
+    use super::indent_unit;
+
+    // This function is the trick that all the rest of the routines
+    // hang on.
+    pub fn to_string_hyg(f: |&mut super::State| -> IoResult<()>) -> String {
+        super::to_string(|s| {
+            s.encode_idents_with_hygiene = true;
+            f(s)
+        })
+    }
+
+    thing_to_string_impls!(to_string_hyg)
 }
 
 pub fn visibility_qualified(vis: ast::Visibility, s: &str) -> String {
@@ -546,7 +584,11 @@ pub fn print_type(&mut self, ty: &ast::Ty) -> IoResult<()> {
             ast::TyBareFn(f) => {
                 let generics = ast::Generics {
                     lifetimes: f.lifetimes.clone(),
-                    ty_params: OwnedSlice::empty()
+                    ty_params: OwnedSlice::empty(),
+                    where_clause: ast::WhereClause {
+                        id: ast::DUMMY_NODE_ID,
+                        predicates: Vec::new(),
+                    },
                 };
                 try!(self.print_ty_fn(Some(f.abi),
                                       None,
@@ -558,12 +600,16 @@ pub fn print_type(&mut self, ty: &ast::Ty) -> IoResult<()> {
                                       &None,
                                       Some(&generics),
                                       None,
-                                      false));
+                                      None));
             }
             ast::TyClosure(f, ref region) => {
                 let generics = ast::Generics {
                     lifetimes: f.lifetimes.clone(),
-                    ty_params: OwnedSlice::empty()
+                    ty_params: OwnedSlice::empty(),
+                    where_clause: ast::WhereClause {
+                        id: ast::DUMMY_NODE_ID,
+                        predicates: Vec::new(),
+                    },
                 };
                 try!(self.print_ty_fn(None,
                                       Some('&'),
@@ -575,12 +621,16 @@ pub fn print_type(&mut self, ty: &ast::Ty) -> IoResult<()> {
                                       &f.bounds,
                                       Some(&generics),
                                       None,
-                                      false));
+                                      None));
             }
             ast::TyProc(ref f) => {
                 let generics = ast::Generics {
                     lifetimes: f.lifetimes.clone(),
-                    ty_params: OwnedSlice::empty()
+                    ty_params: OwnedSlice::empty(),
+                    where_clause: ast::WhereClause {
+                        id: ast::DUMMY_NODE_ID,
+                        predicates: Vec::new(),
+                    },
                 };
                 try!(self.print_ty_fn(None,
                                       Some('~'),
@@ -592,7 +642,7 @@ pub fn print_type(&mut self, ty: &ast::Ty) -> IoResult<()> {
                                       &f.bounds,
                                       Some(&generics),
                                       None,
-                                      false));
+                                      None));
             }
             ast::TyUnboxedFn(f) => {
                 try!(self.print_ty_fn(None,
@@ -605,7 +655,7 @@ pub fn print_type(&mut self, ty: &ast::Ty) -> IoResult<()> {
                                       &None,
                                       None,
                                       None,
-                                      true));
+                                      Some(f.kind)));
             }
             ast::TyPath(ref path, ref bounds, _) => {
                 try!(self.print_bounded_path(path, bounds));
@@ -727,6 +777,7 @@ pub fn print_item(&mut self, item: &ast::Item) -> IoResult<()> {
                 try!(space(&mut self.s));
                 try!(self.word_space("="));
                 try!(self.print_type(&**ty));
+                try!(self.print_where_clause(params));
                 try!(word(&mut self.s, ";"));
                 try!(self.end()); // end the outer ibox
             }
@@ -749,7 +800,10 @@ pub fn print_item(&mut self, item: &ast::Item) -> IoResult<()> {
                                        item.span));
             }
 
-            ast::ItemImpl(ref generics, ref opt_trait, ref ty, ref methods) => {
+            ast::ItemImpl(ref generics,
+                          ref opt_trait,
+                          ref ty,
+                          ref impl_items) => {
                 try!(self.head(visibility_qualified(item.vis,
                                                     "impl").as_slice()));
                 if generics.is_parameterized() {
@@ -767,12 +821,17 @@ pub fn print_item(&mut self, item: &ast::Item) -> IoResult<()> {
                 }
 
                 try!(self.print_type(&**ty));
+                try!(self.print_where_clause(generics));
 
                 try!(space(&mut self.s));
                 try!(self.bopen());
                 try!(self.print_inner_attributes(item.attrs.as_slice()));
-                for meth in methods.iter() {
-                    try!(self.print_method(&**meth));
+                for impl_item in impl_items.iter() {
+                    match *impl_item {
+                        ast::MethodImplItem(meth) => {
+                            try!(self.print_method(&*meth));
+                        }
+                    }
                 }
                 try!(self.bclose(item.span));
             }
@@ -800,6 +859,7 @@ pub fn print_item(&mut self, item: &ast::Item) -> IoResult<()> {
                         try!(self.print_path(&trait_.path, false));
                     }
                 }
+                try!(self.print_where_clause(generics));
                 try!(word(&mut self.s, " "));
                 try!(self.bopen());
                 for meth in methods.iter() {
@@ -835,6 +895,7 @@ pub fn print_enum_def(&mut self, enum_definition: &ast::EnumDef,
         try!(self.head(visibility_qualified(visibility, "enum").as_slice()));
         try!(self.print_ident(ident));
         try!(self.print_generics(generics));
+        try!(self.print_where_clause(generics));
         try!(space(&mut self.s));
         self.print_variants(enum_definition.variants.as_slice(), span)
     }
@@ -1018,15 +1079,21 @@ pub fn print_ty_method(&mut self, m: &ast::TypeMethod) -> IoResult<()> {
                               &None,
                               Some(&m.generics),
                               Some(m.explicit_self.node),
-                              false));
+                              None));
         word(&mut self.s, ";")
     }
 
     pub fn print_trait_method(&mut self,
-                              m: &ast::TraitMethod) -> IoResult<()> {
+                              m: &ast::TraitItem) -> IoResult<()> {
         match *m {
-            Required(ref ty_m) => self.print_ty_method(ty_m),
-            Provided(ref m) => self.print_method(&**m)
+            RequiredMethod(ref ty_m) => self.print_ty_method(ty_m),
+            ProvidedMethod(ref m) => self.print_method(&**m)
+        }
+    }
+
+    pub fn print_impl_item(&mut self, ii: &ast::ImplItem) -> IoResult<()> {
+        match *ii {
+            MethodImplItem(ref m) => self.print_method(&**m),
         }
     }
 
@@ -1437,13 +1504,15 @@ pub fn print_expr(&mut self, expr: &ast::Expr) -> IoResult<()> {
                 }
                 try!(self.bclose_(expr.span, indent_unit));
             }
-            ast::ExprFnBlock(ref decl, ref body) => {
+            ast::ExprFnBlock(capture_clause, ref decl, ref body) => {
+                try!(self.print_capture_clause(capture_clause));
+
                 // in do/for blocks we don't want to show an empty
                 // argument list, but at this point we don't know which
                 // we are inside.
                 //
                 // if !decl.inputs.is_empty() {
-                try!(self.print_fn_block_args(&**decl, false));
+                try!(self.print_fn_block_args(&**decl, None));
                 try!(space(&mut self.s));
                 // }
 
@@ -1467,13 +1536,15 @@ pub fn print_expr(&mut self, expr: &ast::Expr) -> IoResult<()> {
                 // empty box to satisfy the close.
                 try!(self.ibox(0));
             }
-            ast::ExprUnboxedFn(ref decl, ref body) => {
+            ast::ExprUnboxedFn(capture_clause, kind, ref decl, ref body) => {
+                try!(self.print_capture_clause(capture_clause));
+
                 // in do/for blocks we don't want to show an empty
                 // argument list, but at this point we don't know which
                 // we are inside.
                 //
                 // if !decl.inputs.is_empty() {
-                try!(self.print_fn_block_args(&**decl, true));
+                try!(self.print_fn_block_args(&**decl, Some(kind)));
                 try!(space(&mut self.s));
                 // }
 
@@ -1672,7 +1743,12 @@ pub fn print_decl(&mut self, decl: &ast::Decl) -> IoResult<()> {
     }
 
     pub fn print_ident(&mut self, ident: ast::Ident) -> IoResult<()> {
-        word(&mut self.s, token::get_ident(ident).get())
+        if self.encode_idents_with_hygiene {
+            let encoded = ident.encode_with_hygiene();
+            word(&mut self.s, encoded.as_slice())
+        } else {
+            word(&mut self.s, token::get_ident(ident).get())
+        }
     }
 
     pub fn print_name(&mut self, name: ast::Name) -> IoResult<()> {
@@ -1950,7 +2026,8 @@ pub fn print_fn(&mut self,
         try!(self.nbsp());
         try!(self.print_ident(name));
         try!(self.print_generics(generics));
-        self.print_fn_args_and_ret(decl, opt_explicit_self)
+        try!(self.print_fn_args_and_ret(decl, opt_explicit_self))
+        self.print_where_clause(generics)
     }
 
     pub fn print_fn_args(&mut self, decl: &ast::FnDecl,
@@ -2007,13 +2084,17 @@ pub fn print_fn_args_and_ret(&mut self, decl: &ast::FnDecl,
         }
     }
 
-    pub fn print_fn_block_args(&mut self,
-                               decl: &ast::FnDecl,
-                               is_unboxed: bool)
-                               -> IoResult<()> {
+    pub fn print_fn_block_args(
+            &mut self,
+            decl: &ast::FnDecl,
+            unboxed_closure_kind: Option<UnboxedClosureKind>)
+            -> IoResult<()> {
         try!(word(&mut self.s, "|"));
-        if is_unboxed {
-            try!(self.word_space("&mut:"));
+        match unboxed_closure_kind {
+            None => {}
+            Some(FnUnboxedClosureKind) => try!(self.word_space("&:")),
+            Some(FnMutUnboxedClosureKind) => try!(self.word_space("&mut:")),
+            Some(FnOnceUnboxedClosureKind) => try!(self.word_space(":")),
         }
         try!(self.print_fn_args(decl, None));
         try!(word(&mut self.s, "|"));
@@ -2030,6 +2111,14 @@ pub fn print_fn_block_args(&mut self,
         self.maybe_print_comment(decl.output.span.lo)
     }
 
+    pub fn print_capture_clause(&mut self, capture_clause: ast::CaptureClause)
+                                -> IoResult<()> {
+        match capture_clause {
+            ast::CaptureByValue => Ok(()),
+            ast::CaptureByRef => self.word_space("ref"),
+        }
+    }
+
     pub fn print_proc_args(&mut self, decl: &ast::FnDecl) -> IoResult<()> {
         try!(word(&mut self.s, "proc"));
         try!(word(&mut self.s, "("));
@@ -2095,7 +2184,7 @@ pub fn print_bounds(&mut self,
                                          &None,
                                          None,
                                          None,
-                                         true)
+                                         Some(unboxed_function_type.kind))
                     }
                     OtherRegionTyParamBound(_) => Ok(())
                 })
@@ -2129,54 +2218,83 @@ pub fn print_lifetime_def(&mut self,
         Ok(())
     }
 
-    pub fn print_generics(&mut self,
-                          generics: &ast::Generics) -> IoResult<()> {
-        let total = generics.lifetimes.len() + generics.ty_params.len();
-        if total > 0 {
-            try!(word(&mut self.s, "<"));
+    fn print_type_parameters(&mut self,
+                             lifetimes: &[ast::LifetimeDef],
+                             ty_params: &[ast::TyParam])
+                             -> IoResult<()> {
+        let total = lifetimes.len() + ty_params.len();
+        let mut ints = Vec::new();
+        for i in range(0u, total) {
+            ints.push(i);
+        }
 
-            let mut ints = Vec::new();
-            for i in range(0u, total) {
-                ints.push(i);
-            }
-
-            try!(self.commasep(
-                Inconsistent, ints.as_slice(),
-                |s, &idx| {
-                    if idx < generics.lifetimes.len() {
-                        let lifetime = generics.lifetimes.get(idx);
-                        s.print_lifetime_def(lifetime)
-                    } else {
-                        let idx = idx - generics.lifetimes.len();
-                        let param = generics.ty_params.get(idx);
-                        match param.unbound {
-                            Some(TraitTyParamBound(ref tref)) => {
-                                try!(s.print_trait_ref(tref));
-                                try!(s.word_space("?"));
-                            }
-                            _ => {}
-                        }
-                        try!(s.print_ident(param.ident));
-                        try!(s.print_bounds(&None,
-                                            &param.bounds,
-                                            false,
-                                            false));
-                        match param.default {
-                            Some(ref default) => {
-                                try!(space(&mut s.s));
-                                try!(s.word_space("="));
-                                s.print_type(&**default)
-                            }
-                            _ => Ok(())
-                        }
+        self.commasep(Inconsistent, ints.as_slice(), |s, &idx| {
+            if idx < lifetimes.len() {
+                let lifetime = &lifetimes[idx];
+                s.print_lifetime_def(lifetime)
+            } else {
+                let idx = idx - lifetimes.len();
+                let param = &ty_params[idx];
+                match param.unbound {
+                    Some(TraitTyParamBound(ref tref)) => {
+                        try!(s.print_trait_ref(tref));
+                        try!(s.word_space("?"));
                     }
-                }));
+                    _ => {}
+                }
+                try!(s.print_ident(param.ident));
+                try!(s.print_bounds(&None,
+                                    &param.bounds,
+                                    false,
+                                    false));
+                match param.default {
+                    Some(ref default) => {
+                        try!(space(&mut s.s));
+                        try!(s.word_space("="));
+                        s.print_type(&**default)
+                    }
+                    _ => Ok(())
+                }
+            }
+        })
+    }
+
+    pub fn print_generics(&mut self, generics: &ast::Generics)
+                          -> IoResult<()> {
+        if generics.lifetimes.len() + generics.ty_params.len() > 0 {
+            try!(word(&mut self.s, "<"));
+            try!(self.print_type_parameters(generics.lifetimes.as_slice(),
+                                            generics.ty_params.as_slice()));
             word(&mut self.s, ">")
         } else {
             Ok(())
         }
     }
 
+    pub fn print_where_clause(&mut self, generics: &ast::Generics)
+                              -> IoResult<()> {
+        if generics.where_clause.predicates.len() == 0 {
+            return Ok(())
+        }
+
+        try!(space(&mut self.s));
+        try!(self.word_space("where"));
+
+        for (i, predicate) in generics.where_clause
+                                      .predicates
+                                      .iter()
+                                      .enumerate() {
+            if i != 0 {
+                try!(self.word_space(","));
+            }
+
+            try!(self.print_ident(predicate.ident));
+            try!(self.print_bounds(&None, &predicate.bounds, false, false));
+        }
+
+        Ok(())
+    }
+
     pub fn print_meta_item(&mut self, item: &ast::MetaItem) -> IoResult<()> {
         try!(self.ibox(indent_unit));
         match item.node {
@@ -2203,13 +2321,17 @@ pub fn print_meta_item(&mut self, item: &ast::MetaItem) -> IoResult<()> {
     pub fn print_view_path(&mut self, vp: &ast::ViewPath) -> IoResult<()> {
         match vp.node {
             ast::ViewPathSimple(ident, ref path, _) => {
+                try!(self.print_path(path, false));
+
                 // FIXME(#6993) can't compare identifiers directly here
-                if path.segments.last().unwrap().identifier.name != ident.name {
-                    try!(self.print_ident(ident));
+                if path.segments.last().unwrap().identifier.name !=
+                        ident.name {
                     try!(space(&mut self.s));
-                    try!(self.word_space("="));
+                    try!(self.word_space("as"));
+                    try!(self.print_ident(ident));
                 }
-                self.print_path(path, false)
+
+                Ok(())
             }
 
             ast::ViewPathGlob(ref path, _) => {
@@ -2313,7 +2435,8 @@ pub fn print_ty_fn(&mut self,
                        opt_bounds: &Option<OwnedSlice<ast::TyParamBound>>,
                        generics: Option<&ast::Generics>,
                        opt_explicit_self: Option<ast::ExplicitSelf_>,
-                       is_unboxed: bool)
+                       opt_unboxed_closure_kind:
+                        Option<ast::UnboxedClosureKind>)
                        -> IoResult<()> {
         try!(self.ibox(indent_unit));
 
@@ -2330,7 +2453,7 @@ pub fn print_ty_fn(&mut self,
             try!(self.print_fn_style(fn_style));
             try!(self.print_opt_abi_and_extern_if_nondefault(opt_abi));
             try!(self.print_onceness(onceness));
-            if !is_unboxed {
+            if opt_unboxed_closure_kind.is_none() {
                 try!(word(&mut self.s, "fn"));
             }
         }
@@ -2346,20 +2469,30 @@ pub fn print_ty_fn(&mut self,
         match generics { Some(g) => try!(self.print_generics(g)), _ => () }
         try!(zerobreak(&mut self.s));
 
-        if is_unboxed || opt_sigil == Some('&') {
+        if opt_unboxed_closure_kind.is_some() || opt_sigil == Some('&') {
             try!(word(&mut self.s, "|"));
         } else {
             try!(self.popen());
         }
 
-        if is_unboxed {
-            try!(word(&mut self.s, "&mut"));
-            try!(self.word_space(":"));
+        match opt_unboxed_closure_kind {
+            Some(ast::FnUnboxedClosureKind) => {
+                try!(word(&mut self.s, "&"));
+                try!(self.word_space(":"));
+            }
+            Some(ast::FnMutUnboxedClosureKind) => {
+                try!(word(&mut self.s, "&mut"));
+                try!(self.word_space(":"));
+            }
+            Some(ast::FnOnceUnboxedClosureKind) => {
+                try!(self.word_space(":"));
+            }
+            None => {}
         }
 
         try!(self.print_fn_args(decl, opt_explicit_self));
 
-        if is_unboxed || opt_sigil == Some('&') {
+        if opt_unboxed_closure_kind.is_some() || opt_sigil == Some('&') {
             try!(word(&mut self.s, "|"));
         } else {
             if decl.variadic {
@@ -2389,6 +2522,11 @@ pub fn print_ty_fn(&mut self,
             }
         }
 
+        match generics {
+            Some(generics) => try!(self.print_where_clause(generics)),
+            None => {}
+        }
+
         self.end()
     }
 
index 647e81db1f1c03a28be271fd542a6c8b6c0eabff..ac1dbdc439ca0c4fe788c22efd4f8619f64e2d98 100644 (file)
@@ -27,6 +27,7 @@
 use abi::Abi;
 use ast::*;
 use ast;
+use ast_util;
 use codemap::Span;
 use parse;
 use owned_slice::OwnedSlice;
@@ -58,12 +59,7 @@ pub fn generics_of_fn(fk: &FnKind) -> Generics {
         FkMethod(_, generics, _) => {
             (*generics).clone()
         }
-        FkFnBlock(..) => {
-            Generics {
-                lifetimes: Vec::new(),
-                ty_params: OwnedSlice::empty(),
-            }
-        }
+        FkFnBlock(..) => ast_util::empty_generics(),
     }
 }
 
@@ -99,7 +95,7 @@ fn visit_fn(&mut self, fk: &FnKind, fd: &FnDecl, b: &Block, s: Span, _: NodeId,
         walk_fn(self, fk, fd, b, s, e)
     }
     fn visit_ty_method(&mut self, t: &TypeMethod, e: E) { walk_ty_method(self, t, e) }
-    fn visit_trait_method(&mut self, t: &TraitMethod, e: E) { walk_trait_method(self, t, e) }
+    fn visit_trait_item(&mut self, t: &TraitItem, e: E) { walk_trait_item(self, t, e) }
     fn visit_struct_def(&mut self, s: &StructDef, _: Ident, _: &Generics, _: NodeId, e: E) {
         walk_struct_def(self, s, e)
     }
@@ -148,7 +144,16 @@ pub fn walk_inlined_item<E: Clone, V: Visitor<E>>(visitor: &mut V,
     match *item {
         IIItem(i) => visitor.visit_item(&*i, env),
         IIForeign(i) => visitor.visit_foreign_item(&*i, env),
-        IIMethod(_, _, m) => walk_method_helper(visitor, &*m, env),
+        IITraitItem(_, iti) => {
+            match iti {
+                ProvidedInlinedTraitItem(m) => {
+                    walk_method_helper(visitor, &*m, env)
+                }
+                RequiredInlinedTraitItem(m) => {
+                    walk_method_helper(visitor, &*m, env)
+                }
+            }
+        }
     }
 }
 
@@ -269,7 +274,7 @@ pub fn walk_item<E: Clone, V: Visitor<E>>(visitor: &mut V, item: &Item, env: E)
         ItemImpl(ref type_parameters,
                  ref trait_reference,
                  typ,
-                 ref methods) => {
+                 ref impl_items) => {
             visitor.visit_generics(type_parameters, env.clone());
             match *trait_reference {
                 Some(ref trait_reference) => walk_trait_ref_helper(visitor,
@@ -277,8 +282,12 @@ pub fn walk_item<E: Clone, V: Visitor<E>>(visitor: &mut V, item: &Item, env: E)
                 None => ()
             }
             visitor.visit_ty(&*typ, env.clone());
-            for method in methods.iter() {
-                walk_method_helper(visitor, &**method, env.clone())
+            for impl_item in impl_items.iter() {
+                match *impl_item {
+                    MethodImplItem(method) => {
+                        walk_method_helper(visitor, &*method, env.clone())
+                    }
+                }
             }
         }
         ItemStruct(ref struct_definition, ref generics) => {
@@ -297,7 +306,7 @@ pub fn walk_item<E: Clone, V: Visitor<E>>(visitor: &mut V, item: &Item, env: E)
                                    env.clone())
             }
             for method in methods.iter() {
-                visitor.visit_trait_method(method, env.clone())
+                visitor.visit_trait_item(method, env.clone())
             }
         }
         ItemMac(ref macro) => visitor.visit_mac(macro, env.clone()),
@@ -546,7 +555,11 @@ pub fn walk_generics<E: Clone, V: Visitor<E>>(visitor: &mut V,
             None => {}
         }
     }
-    walk_lifetime_decls(visitor, &generics.lifetimes, env);
+    walk_lifetime_decls(visitor, &generics.lifetimes, env.clone());
+    for predicate in generics.where_clause.predicates.iter() {
+        visitor.visit_ident(predicate.span, predicate.ident, env.clone());
+        walk_ty_param_bounds(visitor, &predicate.bounds, env.clone());
+    }
 }
 
 pub fn walk_fn_decl<E: Clone, V: Visitor<E>>(visitor: &mut V,
@@ -626,14 +639,14 @@ pub fn walk_ty_method<E: Clone, V: Visitor<E>>(visitor: &mut V,
     }
 }
 
-pub fn walk_trait_method<E: Clone, V: Visitor<E>>(visitor: &mut V,
-                                                  trait_method: &TraitMethod,
+pub fn walk_trait_item<E: Clone, V: Visitor<E>>(visitor: &mut V,
+                                                  trait_method: &TraitItem,
                                                   env: E) {
     match *trait_method {
-        Required(ref method_type) => {
+        RequiredMethod(ref method_type) => {
             visitor.visit_ty_method(method_type, env)
         }
-        Provided(ref method) => walk_method_helper(visitor, &**method, env),
+        ProvidedMethod(ref method) => walk_method_helper(visitor, &**method, env),
     }
 }
 
@@ -787,7 +800,7 @@ pub fn walk_expr<E: Clone, V: Visitor<E>>(visitor: &mut V, expression: &Expr, en
                 visitor.visit_arm(arm, env.clone())
             }
         }
-        ExprFnBlock(ref function_declaration, ref body) => {
+        ExprFnBlock(_, ref function_declaration, ref body) => {
             visitor.visit_fn(&FkFnBlock,
                              &**function_declaration,
                              &**body,
@@ -795,7 +808,7 @@ pub fn walk_expr<E: Clone, V: Visitor<E>>(visitor: &mut V, expression: &Expr, en
                              expression.id,
                              env.clone())
         }
-        ExprUnboxedFn(ref function_declaration, ref body) => {
+        ExprUnboxedFn(_, _, ref function_declaration, ref body) => {
             visitor.visit_fn(&FkFnBlock,
                              &**function_declaration,
                              &**body,
index ec31181e8a7483f93ce1219b0fafde67ba39aeb4..a60e95c38272bf4f08c071587cc23a7a99a991d9 100644 (file)
 
 use core::cmp::{Equal, Less, Greater};
 use core::option::{Option, Some, None};
-use core::slice::ImmutableVector;
+use core::slice;
+use core::slice::ImmutableSlice;
 use tables::normalization::{canonical_table, compatibility_table, composition_table};
 
 fn bsearch_table<T>(c: char, r: &'static [(char, &'static [T])]) -> Option<&'static [T]> {
-    match r.bsearch(|&(val, _)| {
+    match r.binary_search(|&(val, _)| {
         if c == val { Equal }
         else if val < c { Less }
         else { Greater }
     }) {
-        Some(idx) => {
+        slice::Found(idx) => {
             let (_, result) = r[idx];
             Some(result)
         }
-        None => None
+        slice::NotFound(_) => None
     }
 }
 
@@ -82,16 +83,16 @@ pub fn compose(a: char, b: char) -> Option<char> {
         match bsearch_table(a, composition_table) {
             None => None,
             Some(candidates) => {
-                match candidates.bsearch(|&(val, _)| {
+                match candidates.binary_search(|&(val, _)| {
                     if b == val { Equal }
                     else if val < b { Less }
                     else { Greater }
                 }) {
-                    Some(idx) => {
+                    slice::Found(idx) => {
                         let (_, result) = candidates[idx];
                         Some(result)
                     }
-                    None => None
+                    slice::NotFound(_) => None
                 }
             }
         }
index 4332fc596c997c8541f78aa679fe1d41029d07a9..d6010cd8d7bfbbd467664ccb9b1c237e2d44cf1e 100644 (file)
 
 fn bsearch_range_table(c: char, r: &'static [(char,char)]) -> bool {
     use core::cmp::{Equal, Less, Greater};
-    use core::slice::ImmutableVector;
-    use core::option::None;
-    r.bsearch(|&(lo,hi)| {
+    use core::slice::ImmutableSlice;
+    r.binary_search(|&(lo,hi)| {
         if lo <= c && c <= hi { Equal }
         else if hi < c { Less }
         else { Greater }
-    }) != None
+    }).found().is_some()
 }
 
 pub mod general_category {
@@ -6228,19 +6227,19 @@ pub mod normalization {
 
 
     fn bsearch_range_value_table(c: char, r: &'static [(char, char, u8)]) -> u8 {
-        use core::option::{Some, None};
         use core::cmp::{Equal, Less, Greater};
-        use core::slice::ImmutableVector;
-        match r.bsearch(|&(lo, hi, _)| {
+        use core::slice::ImmutableSlice;
+        use core::slice;
+        match r.binary_search(|&(lo, hi, _)| {
             if lo <= c && c <= hi { Equal }
             else if hi < c { Less }
             else { Greater }
         }) {
-            Some(idx) => {
+            slice::Found(idx) => {
                 let (_, _, result) = r[idx];
                 result
             }
-            None => 0
+            slice::NotFound(_) => 0
         }
     }
 
@@ -6354,9 +6353,10 @@ pub fn canonical_combining_class(c: char) -> u8 {
 
 pub mod conversions {
     use core::cmp::{Equal, Less, Greater};
-    use core::slice::ImmutableVector;
+    use core::slice::ImmutableSlice;
     use core::tuple::Tuple2;
     use core::option::{Option, Some, None};
+    use core::slice;
 
     pub fn to_lower(c: char) -> char {
         match bsearch_case_table(c, LuLl_table) {
@@ -6373,11 +6373,14 @@ pub fn to_upper(c: char) -> char {
     }
 
     fn bsearch_case_table(c: char, table: &'static [(char, char)]) -> Option<uint> {
-        table.bsearch(|&(key, _)| {
+        match table.binary_search(|&(key, _)| {
             if c == key { Equal }
             else if key < c { Less }
             else { Greater }
-        })
+        }) {
+            slice::Found(i) => Some(i),
+            slice::NotFound(_) => None,
+        }
     }
 
     static LuLl_table: &'static [(char, char)] = &[
@@ -6915,20 +6918,21 @@ fn bsearch_case_table(c: char, table: &'static [(char, char)]) -> Option<uint> {
 
 pub mod charwidth {
     use core::option::{Option, Some, None};
-    use core::slice::ImmutableVector;
+    use core::slice::ImmutableSlice;
+    use core::slice;
 
     fn bsearch_range_value_table(c: char, is_cjk: bool, r: &'static [(char, char, u8, u8)]) -> u8 {
         use core::cmp::{Equal, Less, Greater};
-        match r.bsearch(|&(lo, hi, _, _)| {
+        match r.binary_search(|&(lo, hi, _, _)| {
             if lo <= c && c <= hi { Equal }
             else if hi < c { Less }
             else { Greater }
         }) {
-            Some(idx) => {
+            slice::Found(idx) => {
                 let (_, _, r_ncjk, r_cjk) = r[idx];
                 if is_cjk { r_cjk } else { r_ncjk }
             }
-            None => 1
+            slice::NotFound(_) => 1
         }
     }
 
@@ -7112,8 +7116,8 @@ pub fn width(c: char, is_cjk: bool) -> Option<uint> {
 }
 
 pub mod grapheme {
-    use core::option::{Some, None};
-    use core::slice::ImmutableVector;
+    use core::slice::ImmutableSlice;
+    use core::slice;
 
     #[allow(non_camel_case_types)]
     #[deriving(Clone)]
@@ -7132,16 +7136,16 @@ pub enum GraphemeCat {
 
     fn bsearch_range_value_table(c: char, r: &'static [(char, char, GraphemeCat)]) -> GraphemeCat {
         use core::cmp::{Equal, Less, Greater};
-        match r.bsearch(|&(lo, hi, _)| {
+        match r.binary_search(|&(lo, hi, _)| {
             if lo <= c && c <= hi { Equal }
             else if hi < c { Less }
             else { Greater }
         }) {
-            Some(idx) => {
+            slice::Found(idx) => {
                 let (_, _, cat) = r[idx];
                 cat
             }
-            None => GC_Any
+            slice::NotFound(_) => GC_Any
         }
     }
 
index 8c35424d394f4c357fb15d0d1726b72d4fb2daf8..9ced6cb62af00f0c310167f6720f498782f9db30 100644 (file)
@@ -396,7 +396,7 @@ fn maybe_push_value(map: &mut HashMap<String, Vec<String>>,
 }
 
 fn split_char_first(s: &str, c: char) -> (&str, &str) {
-    let mut iter = s.splitn(c, 1);
+    let mut iter = s.splitn(1, c);
 
     match (iter.next(), iter.next()) {
         (Some(a), Some(b)) => (a, b),
index 4936bff5768c96896ef2ddfe7bbd150d44f9416c..b62832066766653ed6f819469f7e353b77421bb2 100644 (file)
@@ -19,6 +19,7 @@
 use syntax::codemap::Span;
 use syntax::ext::base::*;
 use syntax::parse::token;
+use syntax::parse;
 use rustc::plugin::Registry;
 
 use std::gc::{Gc, GC};
@@ -31,6 +32,8 @@ macro_rules! unexported_macro (() => (3i))
 #[plugin_registrar]
 pub fn plugin_registrar(reg: &mut Registry) {
     reg.register_macro("make_a_1", expand_make_a_1);
+    reg.register_macro("forged_ident", expand_forged_ident);
+    reg.register_macro("identity", expand_identity);
     reg.register_syntax_extension(
         token::intern("into_foo"),
         ItemModifier(expand_into_foo));
@@ -44,6 +47,16 @@ fn expand_make_a_1(cx: &mut ExtCtxt, sp: Span, tts: &[TokenTree])
     MacExpr::new(quote_expr!(cx, 1i))
 }
 
+// See Issue #15750
+fn expand_identity(cx: &mut ExtCtxt, _span: Span, tts: &[TokenTree])
+                   -> Box<MacResult> {
+    // Parse an expression and emit it unchanged.
+    let mut parser = parse::new_parser_from_tts(cx.parse_sess(),
+        cx.cfg(), Vec::from_slice(tts));
+    let expr = parser.parse_expr();
+    MacExpr::new(quote_expr!(&mut *cx, $expr))
+}
+
 fn expand_into_foo(cx: &mut ExtCtxt, sp: Span, attr: Gc<MetaItem>, it: Gc<Item>)
                    -> Gc<Item> {
     box(GC) Item {
@@ -52,4 +65,29 @@ fn expand_into_foo(cx: &mut ExtCtxt, sp: Span, attr: Gc<MetaItem>, it: Gc<Item>)
     }
 }
 
+fn expand_forged_ident(cx: &mut ExtCtxt, sp: Span, tts: &[TokenTree]) -> Box<MacResult> {
+    use syntax::ext::quote::rt::*;
+
+    if !tts.is_empty() {
+        cx.span_fatal(sp, "forged_ident takes no arguments");
+    }
+
+    // Most of this is modelled after the expansion of the `quote_expr!`
+    // macro ...
+    let parse_sess = cx.parse_sess();
+    let cfg = cx.cfg();
+
+    // ... except this is where we inject a forged identifier,
+    // and deliberately do not call `cx.parse_tts_with_hygiene`
+    // (because we are testing that this will be *rejected*
+    //  by the default parser).
+
+    let expr = {
+        let tt = cx.parse_tts("\x00name_2,ctxt_0\x00".to_string());
+        let mut parser = new_parser_from_tts(parse_sess, cfg, tt);
+        parser.parse_expr()
+    };
+    MacExpr::new(expr)
+}
+
 pub fn foo() {}
index 7e0f7f3abfe227d3ff88188f997c5d51ba3ef797..266903169c7b07f373ced546cf85f392a7dd498f 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub use bar = foo;
+pub use foo as bar;
 
 mod foo {
     pub fn frob() {}
index 882442f5e00906203b5e24a135ecd75da98f809d..3bad76f0e703e62919f7ea9622bf32ffbe438fd8 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 pub use sub_foo::Foo;
-pub use Baz = self::Bar;
+pub use self::Bar as Baz;
 pub use sub_foo::Boz;
 pub use sub_foo::Bort;
 
index 0216e7c5854b8fcd531c3e7646531fea4583609f..b756eb2b582f70076b6dfb7f6189437e23a228d1 100644 (file)
@@ -39,10 +39,10 @@ pub enum reexported_d {}
 }
 
 pub mod bar {
-    pub use e = foo::reexported_a;
-    pub use f = foo::reexported_b;
-    pub use g = foo::reexported_c;
-    pub use h = foo::reexported_d;
+    pub use foo::reexported_a as e;
+    pub use foo::reexported_b as f;
+    pub use foo::reexported_c as g;
+    pub use foo::reexported_d as h;
 }
 
 pub static a: int = 0;
diff --git a/src/test/auxiliary/where_clauses_xc.rs b/src/test/auxiliary/where_clauses_xc.rs
new file mode 100644 (file)
index 0000000..002b31f
--- /dev/null
@@ -0,0 +1,30 @@
+// 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.
+
+pub trait Equal {
+    fn equal(&self, other: &Self) -> bool;
+    fn equals<T,U>(&self, this: &T, that: &T, x: &U, y: &U) -> bool
+            where T: Eq, U: Eq;
+}
+
+impl<T> Equal for T where T: Eq {
+    fn equal(&self, other: &T) -> bool {
+        self == other
+    }
+    fn equals<U,X>(&self, this: &U, other: &U, x: &X, y: &X) -> bool
+            where U: Eq, X: Eq {
+        this == other && x == y
+    }
+}
+
+pub fn equal<T>(x: &T, y: &T) -> bool where T: Eq {
+    x == y
+}
+
index 8908b5b87ed3c80f59dfc36046b473df0e254797..606f075d96db4d96c56588250bf24b9737175711 100644 (file)
@@ -39,7 +39,7 @@
 // OF THE POSSIBILITY OF SUCH DAMAGE.
 
 // FIXME(#13725) windows needs fixing.
-// ignore-win32
+// ignore-windows
 // ignore-stage1
 // ignore-cross-compile #12102
 
diff --git a/src/test/compile-fail-fulldeps/macro-crate-cannot-read-embedded-ident.rs b/src/test/compile-fail-fulldeps/macro-crate-cannot-read-embedded-ident.rs
new file mode 100644 (file)
index 0000000..268b6e6
--- /dev/null
@@ -0,0 +1,31 @@
+// 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.
+
+// aux-build:macro_crate_test.rs
+// ignore-stage1
+// ignore-android
+// error-pattern: unknown start of token: \x00
+
+// Issue #15750 and #15962 : this test is checking that the standard
+// parser rejects embedded idents.  pnkfelix did not want to attempt
+// to make a test file that itself used the embedded ident input form,
+// since he worrid that would be difficult to work with in many text
+// editors, so instead he made a macro that expands into the embedded
+// ident form.
+
+#![feature(phase)]
+
+#[phase(plugin)]
+extern crate macro_crate_test;
+
+fn main() {
+    let x = 0;
+    assert_eq!(3, forged_ident!());
+}
index bccba74e05c70e5dd20988758f68aaabc47bdc01..64ef1abe7de90f019321ff05f4574942d159db09 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 // FIXME(#13725) windows needs fixing.
-// ignore-win32
+// ignore-windows
 // ignore-stage1
 
 #![feature(phase)]
index 819c9e6b0fe2f9bf103e75c9e81621957175f13d..8d859c3f7ba2e866bdbcf5733a2f6b34f1280db2 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 // FIXME(#13725) windows needs fixing.
-// ignore-win32
+// ignore-windows
 // ignore-stage1
 
 #![feature(phase)]
index d96b3f6f224cfb35c10c0d6ef99052bdcd875e2e..304ad7423b1b25ce39206397b8c4a20cf56aaf8c 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 // FIXME(#13725) windows needs fixing.
-// ignore-win32
+// ignore-windows
 // ignore-stage1
 
 #![feature(phase)]
diff --git a/src/test/compile-fail/borrowck-closures-unique-imm.rs b/src/test/compile-fail/borrowck-closures-unique-imm.rs
new file mode 100644 (file)
index 0000000..dfe5de0
--- /dev/null
@@ -0,0 +1,25 @@
+// 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.
+
+struct Foo {
+    x: int,
+}
+
+pub fn main() {
+    let mut this = &mut Foo {
+        x: 1,
+    };
+    let r = || {
+        let p = &this.x;
+        &mut this.x; //~ ERROR cannot borrow
+    };
+    r()
+}
+
diff --git a/src/test/compile-fail/borrowck-for-loop-correct-cmt-for-pattern.rs b/src/test/compile-fail/borrowck-for-loop-correct-cmt-for-pattern.rs
new file mode 100644 (file)
index 0000000..93a4383
--- /dev/null
@@ -0,0 +1,33 @@
+// 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.
+
+// Issue #16205.
+
+struct Foo {
+    a: [Box<int>, ..3],
+}
+
+fn main() {
+    let mut y = 1i;
+    let x = Some(&mut y);
+    for &a in x.iter() {    //~ ERROR cannot move out
+    }
+
+    let f = Foo {
+        a: [box 3, box 4, box 5],
+    };
+    for &a in f.a.iter() {  //~ ERROR cannot move out
+    }
+
+    let x = Some(box 1i);
+    for &a in x.iter() {    //~ ERROR cannot move out
+    }
+}
+
index b5d274a5584ab13ba42228e3608f88661827b25c..23cd4d80724e0c5523b25cf3cf763b6af56c51ca 100644 (file)
@@ -12,7 +12,7 @@
 // move, when the struct implements Drop.
 
 // NoCopy
-use NP = std::kinds::marker::NoCopy;
+use std::kinds::marker::NoCopy as NP;
 
 
 struct S { a: int, np: NP }
diff --git a/src/test/compile-fail/borrowck-unboxed-closures.rs b/src/test/compile-fail/borrowck-unboxed-closures.rs
new file mode 100644 (file)
index 0000000..d822bb2
--- /dev/null
@@ -0,0 +1,29 @@
+// 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(overloaded_calls)]
+
+fn a<F:|&: int, int| -> int>(mut f: F) {
+    let g = &mut f;
+    f(1, 2);    //~ ERROR cannot borrow `f` as immutable
+    //~^ ERROR cannot borrow `f` as immutable
+}
+
+fn b<F:|&mut: int, int| -> int>(f: F) {
+    f(1, 2);    //~ ERROR cannot borrow immutable argument
+}
+
+fn c<F:|: int, int| -> int>(f: F) {
+    f(1, 2);
+    f(1, 2);    //~ ERROR use of moved value
+}
+
+fn main() {}
+
index aae5e0194a1d1d025a7add145aed42afeb5ecbd3..c522ecc4817f821c482ab9e0fe789b74ef99d593 100644 (file)
@@ -15,7 +15,7 @@
 use bar::*;
 
 mod bar {
-    use import = self::fpriv;
+    use self::fpriv as import;
     fn fpriv() {}
     extern {
         fn epriv();
index f7212779263117e0cfd6e6ba900a6a161d93ff76..ebd897a0611392efbf8117d092df35f2947137e8 100644 (file)
@@ -10,7 +10,7 @@
 
 // error-pattern:expected
 
-use baz = foo::{bar};
+use foo::{bar} as baz;
 
 mod foo {
     pub fn bar() {}
index 5016cab77233c8f1318c0294e582311f4342b3f9..fb400b6c2bb1e9465aacd8052909e046a2294996 100644 (file)
@@ -10,7 +10,7 @@
 
 // error-pattern:expected
 
-use baz = foo::*;
+use foo::* as baz;
 
 mod foo {
     pub fn bar() {}
index b646f8083b8d5590286cf99672a9fb1db7d5a060..bfc1ac2daef41d01c0c50e855fa7fb20a77f7dbf 100644 (file)
@@ -12,8 +12,8 @@
 
 // the `--test` harness creates modules with these textual names, but
 // they should be inaccessible from normal code.
-use x = __test; //~ ERROR unresolved import `__test`
-use y = __test_reexports; //~ ERROR unresolved import `__test_reexports`
+use __test as x; //~ ERROR unresolved import `__test`
+use __test_reexports as y; //~ ERROR unresolved import `__test_reexports`
 
 #[test]
 fn baz() {}
index 335012cedb84c1335e1e1136cfddbf41cdda44fb..e4fae73b18991293ee9c9a7a1ada252ca7e276c5 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use x = m::f; //~ ERROR unresolved import `m::f`. There is no `f` in `m`
+use m::f as x; //~ ERROR unresolved import `m::f`. There is no `f` in `m`
 
 mod m {}
 
index e34bfb10a719b9700da5595fd74d44bb5f82bbdb..41e6f24d79c79fcfdf3ead05be80f860fd232eeb 100644 (file)
@@ -16,7 +16,7 @@
 
 extern crate libc;
 
-pub use x = extern_foo;
+pub use extern_foo as x;
 extern {
     fn extern_foo();
 }
index db145be6ebd24b9a1f8b49503aaadb0677b39e1b..a63a3a61f68a0923d75b55e2d998e2c1f8b49e20 100644 (file)
@@ -148,8 +148,8 @@ fn also_undocumented2() {}
 }
 /// dox
 pub mod public_interface {
-    pub use foo = internal_impl::documented;
-    pub use bar = internal_impl::undocumented1;
+    pub use internal_impl::documented as foo;
+    pub use internal_impl::undocumented1 as bar;
     pub use internal_impl::{documented, undocumented2};
     pub use internal_impl::globbed::*;
 }
index f03e748e4176d5f495371816474818d307038ed4..d9bf722f73e4230f9a4e63df29f874006cc3b7db 100644 (file)
@@ -12,7 +12,7 @@
 #![deny(unused_imports)]
 #![allow(dead_code)]
 
-use cal = bar::c::cc;
+use bar::c::cc as cal;
 
 use std::mem::*;            // shouldn't get errors for not using
                             // everything imported
index a409ae60ccaa1e8077b68253907fb4a63f37423a..b5ffa3546c19d02cbbaefc8810762a19aa4a94d3 100644 (file)
@@ -43,7 +43,7 @@ mod n {
 }
 
 fn h() {
-    use not_okay = self::n::OKAY;
+    use self::n::OKAY as not_okay;
     let r = match (0,0) {
         (0, not_okay) => 0,
 //~^ ERROR static constant in pattern `not_okay` should have an uppercase name such as `NOT_OKAY`
index 52be07b463d8dd189ac1e35dfa09e6fd72623cbc..e52a4da13528799cbbe5a02df36253a17f4f681f 100644 (file)
@@ -176,7 +176,7 @@ pub mod mytest {
                          //~^ NOTE: module `i` is private
 
     pub mod foo {
-        pub use foo = self::i::A;
+        pub use self::i::A as foo;
 
         mod i {
             pub struct A;
diff --git a/src/test/compile-fail/regionck-unboxed-closure-lifetimes.rs b/src/test/compile-fail/regionck-unboxed-closure-lifetimes.rs
new file mode 100644 (file)
index 0000000..1c590db
--- /dev/null
@@ -0,0 +1,24 @@
+// 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(unboxed_closure_sugar, unboxed_closures, overloaded_calls)]
+
+use std::ops::FnMut;
+
+fn main() {
+    let mut f;
+    {
+        let c = 1;
+        let c_ref = &c;
+        f = |&mut: a: int, b: int| { a + b + *c_ref };
+        //~^ ERROR cannot infer an appropriate lifetime
+    }
+}
+
diff --git a/src/test/compile-fail/unboxed-closures-wrong-trait.rs b/src/test/compile-fail/unboxed-closures-wrong-trait.rs
new file mode 100644 (file)
index 0000000..50d90c6
--- /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(lang_items, overloaded_calls, unboxed_closures)]
+
+fn c<F:|: int, int| -> int>(f: F) -> int {
+    f(5, 6)
+}
+
+fn main() {
+    let z: int = 7;
+    assert_eq!(c(|&: x: int, y| x + y + z), 10);
+    //~^ ERROR failed to find an implementation
+}
+
index b5dcd5d165d4c0477cf0caab38b284569f636db7..7da7b364bda3658f16d07a4cece551e42530d460 100644 (file)
@@ -10,7 +10,7 @@
 
 use foo::bar; //~ ERROR unresolved import `foo::bar`. Maybe a missing `extern crate foo`?
 
-use x = bar::baz; //~ ERROR unresolved import `bar::baz`. There is no `baz` in `bar`
+use bar::baz as x; //~ ERROR unresolved import `bar::baz`. There is no `baz` in `bar`
 
 mod bar {
     struct bar;
diff --git a/src/test/compile-fail/where-clauses-no-bounds-or-predicates.rs b/src/test/compile-fail/where-clauses-no-bounds-or-predicates.rs
new file mode 100644 (file)
index 0000000..b96c7c2
--- /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.
+
+fn equal1<T>(_: &T, _: &T) -> bool where {
+//~^ ERROR a `where` clause must have at least one predicate in it
+    true
+}
+
+fn equal2<T>(_: &T, _: &T) -> bool where T: {
+//~^ ERROR each predicate in a `where` clause must have at least one bound
+    true
+}
+
+fn main() {
+}
+
diff --git a/src/test/compile-fail/where-clauses-not-parameter.rs b/src/test/compile-fail/where-clauses-not-parameter.rs
new file mode 100644 (file)
index 0000000..2817aa1
--- /dev/null
@@ -0,0 +1,17 @@
+// 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 equal<T>(_: &T, _: &T) -> bool where int : Eq {
+    //~^ ERROR undeclared type parameter
+}
+
+fn main() {
+}
+
diff --git a/src/test/compile-fail/where-clauses-unsatisfied.rs b/src/test/compile-fail/where-clauses-unsatisfied.rs
new file mode 100644 (file)
index 0000000..1d21313
--- /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.
+
+fn equal<T>(_: &T, _: &T) -> bool where T : Eq {
+}
+
+struct Struct;
+
+fn main() {
+    equal(&Struct, &Struct)
+    //~^ ERROR failed to find an implementation of trait
+}
+
index 1e157f10c12a5f4609286e81788f290ef23a698d..8621ce2a47ecb330d8b242be435cce6935cc212b 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-win32: FIXME #13256
+// ignore-windows: FIXME #13256
 // ignore-android: FIXME(#10381)
 
 // compile-flags:-g
index 2fc20bedc0747ef6b465233d6a7c3f15fc860334..c7e43ae2d98ac4049a3eeaeb9b270e3476e791e6 100644 (file)
@@ -14,7 +14,7 @@
 // about UTF-32 character encoding and will print a rust char as only
 // its numerical value.
 
-// ignore-win32: FIXME #13256
+// ignore-windows: FIXME #13256
 // ignore-android: FIXME(#10381)
 
 // compile-flags:-g
index f1579192b17b2484278ea1f7d3a3b1df22329dfc..392963b216caffe5b8531e560e8be36ece87c304 100644 (file)
@@ -14,7 +14,7 @@
 // about UTF-32 character encoding and will print a rust char as only
 // its numerical value.
 
-// ignore-win32: FIXME #13256
+// ignore-windows: FIXME #13256
 // ignore-android: FIXME(#10381)
 
 // compile-flags:-g
index da30363f271d07bf878657746d4329fe30c981c1..a81d42106f9e19f8738615b74b84d8e270ff2223 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-win32: FIXME #13256
+// ignore-windows: FIXME #13256
 // ignore-android: FIXME(#10381)
 
 // compile-flags:-g
index b5f9622e79a7bd977aaab5e63ee4c0e41bca8f8a..c36642b3069d0f6492b4d33471c74de9186932ff 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-win32: FIXME #13256
+// ignore-windows: FIXME #13256
 // ignore-android: FIXME(#10381)
 
 // compile-flags:-g
diff --git a/src/test/debuginfo/no-debug-attribute.rs b/src/test/debuginfo/no-debug-attribute.rs
new file mode 100644 (file)
index 0000000..e61ded4
--- /dev/null
@@ -0,0 +1,45 @@
+// 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.
+//
+// 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-android: FIXME(#10381)
+// ignore-lldb
+
+// compile-flags:-g
+
+// gdb-command:break 'no-debug-attribute.rs':32
+// gdb-command:break 'no-debug-attribute.rs':38
+// gdb-command:run
+
+// gdb-command:info locals
+// gdb-check:No locals.
+// gdb-command:continue
+
+// gdb-command:info locals
+// gdb-check:abc = 10
+// gdb-command:continue
+
+#![allow(unused_variable)]
+
+fn function_with_debuginfo() {
+    let abc = 10u;
+    return (); // #break
+}
+
+#[no_debug]
+fn function_without_debuginfo() {
+    let abc = -57i32;
+    return (); // #break
+}
+
+fn main() {
+    function_without_debuginfo();
+    function_with_debuginfo();
+}
+
index 5076673c3a512c897fae9608400927eb858253e7..dddd00dfbc5a86d20451c05721057e5de4d4c5ca 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-win32: FIXME #13256
+// ignore-windows: FIXME #13256
 // ignore-android: FIXME(#10381)
 
 // compile-flags:-g
index 29d739d7f183abce044f55edc83ef0ea726fb676..47b4f2cd2a2f4352a8d62cc5db074b542bf4c16f 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-win32: FIXME #13256
+// ignore-windows: FIXME #13256
 // ignore-android: FIXME(#10381)
 
 // compile-flags:-g
index 00398fd5c8234fbb2d059c3eee3361643b554454..ba8c4d249ce7f4d381354677f543c6ffd0fc79ed 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-win32: FIXME #13256
+// ignore-windows: FIXME #13256
 // ignore-android: FIXME(#10381)
 
 // compile-flags:-g
index 7372a6e7ca019bc6e27bc424e7850f4dac134c9a..00a4cb543097890d5c0fe34abe9f2212a9cdfb64 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-win32: FIXME #13256
+// ignore-windows: FIXME #13256
 // ignore-android: FIXME(#10381)
 
 // compile-flags:-g
diff --git a/src/test/run-make/cannot-read-embedded-idents/Makefile b/src/test/run-make/cannot-read-embedded-idents/Makefile
new file mode 100644 (file)
index 0000000..0d047be
--- /dev/null
@@ -0,0 +1,28 @@
+-include ../tools.mk
+
+# Issue #15750, #15962 : This test ensures that our special embedded
+# ident syntax hack is not treated as legitimate input by the lexer in
+# normal mode.
+#
+# It is modelled after the `unicode-input/` test, since we need to
+# create files with syntax that can trip up normal text editting tools
+# (namely text with embedded nul-bytes).
+
+# This test attempts to run rustc itself from the compiled binary; but
+# that means that you need to set the LD_LIBRARY_PATH for rustc itself
+# while running create_and_compile, and that won't work for stage1.
+
+# FIXME ignore windows
+ifndef IS_WINDOWS
+ifeq ($(RUST_BUILD_STAGE),1)
+DOTEST=
+else
+DOTEST=dotest
+endif
+endif
+
+all: $(DOTEST)
+
+dotest:
+       $(RUSTC) create_and_compile.rs
+       $(call RUN,create_and_compile)  "$(RUSTC)" "$(TMPDIR)"
diff --git a/src/test/run-make/cannot-read-embedded-idents/create_and_compile.rs b/src/test/run-make/cannot-read-embedded-idents/create_and_compile.rs
new file mode 100644 (file)
index 0000000..2d8fa35
--- /dev/null
@@ -0,0 +1,44 @@
+// 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.
+
+use std::os;
+use std::io::{File, Command};
+
+// creates broken.rs, which has the Ident \x00name_0,ctxt_0\x00
+// embedded within it, and then attempts to compile broken.rs with the
+// provided `rustc`
+
+fn main() {
+    let args = os::args();
+    let rustc = args[1].as_slice();
+    let tmpdir = Path::new(args[2].as_slice());
+
+    let main_file = tmpdir.join("broken.rs");
+    let _ = File::create(&main_file).unwrap()
+        .write_str("pub fn main() {
+                   let \x00name_0,ctxt_0\x00 = 3i;
+                   println!(\"{}\", \x00name_0,ctxt_0\x00);
+        }");
+
+    // rustc is passed to us with --out-dir and -L etc., so we
+    // can't exec it directly
+    let result = Command::new("sh")
+        .arg("-c")
+        .arg(format!("{} {}",
+                     rustc,
+                     main_file.as_str()
+                     .unwrap()).as_slice())
+        .output().unwrap();
+    let err = String::from_utf8_lossy(result.error.as_slice());
+
+    // positive test so that this test will be updated when the
+    // compiler changes.
+    assert!(err.as_slice().contains("unknown start of token"))
+}
diff --git a/src/test/run-pass-fulldeps/macro-crate-does-hygiene-work.rs b/src/test/run-pass-fulldeps/macro-crate-does-hygiene-work.rs
new file mode 100644 (file)
index 0000000..0afd76e
--- /dev/null
@@ -0,0 +1,28 @@
+// 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.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:macro_crate_test.rs
+// ignore-stage1
+
+// Issue #15750: a macro that internally parses its input and then
+// uses `quote_expr!` to rearrange it should be hygiene-preserving.
+
+#![feature(phase)]
+
+#[phase(plugin)]
+extern crate macro_crate_test;
+
+fn main() {
+    let x = 3i;
+    assert_eq!(3, identity!(x));
+    assert_eq!(6, identity!(x+x));
+    let x = 4i;
+    assert_eq!(4, identity!(x));
+}
index b03feb8fc224b050c2e822a23fcad972ad6bc618..10c3df9388a011f05c105ed4bf8f7f7e7cfd31ba 100644 (file)
@@ -19,8 +19,8 @@
 
 use std::hashmap::{HashMap, HashSet};
 
-use EBReader = rbml::reader;
-use EBWriter = rbml::writer;
+use rbml::reader as EBReader;
+use rbml::writer as EBWriter;
 use std::cmp::Eq;
 use std::cmp;
 use std::io;
index 0e4be12aa456d581f093b6e783cedfee35d36380..f487a1c6be5ced06433e50904c9ace67f23442a9 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 // no-pretty-expanded FIXME #15189
-// ignore-win32 FIXME #13259
+// ignore-windows FIXME #13259
 extern crate native;
 
 use std::os;
diff --git a/src/test/run-pass/capture-clauses-boxed-closures.rs b/src/test/run-pass/capture-clauses-boxed-closures.rs
new file mode 100644 (file)
index 0000000..c88b449
--- /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.
+
+fn each<T>(x: &[T], f: |&T|) {
+    for val in x.iter() {
+        f(val)
+    }
+}
+
+fn main() {
+    let mut sum = 0u;
+    let elems = [ 1u, 2, 3, 4, 5 ];
+    each(elems, ref |val| sum += *val);
+    assert_eq!(sum, 15);
+}
+
diff --git a/src/test/run-pass/capture-clauses-unboxed-closures.rs b/src/test/run-pass/capture-clauses-unboxed-closures.rs
new file mode 100644 (file)
index 0000000..99e6d6e
--- /dev/null
@@ -0,0 +1,29 @@
+// 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-test
+//
+// This is ignored because it depends on #16122.
+
+#![feature(overloaded_calls, unboxed_closures)]
+
+fn each<'a,T,F:|&mut: &'a T|>(x: &'a [T], mut f: F) {
+    for val in x.iter() {
+        f(val)
+    }
+}
+
+fn main() {
+    let mut sum = 0u;
+    let elems = [ 1u, 2, 3, 4, 5 ];
+    each(elems, ref |&mut: val: &uint| sum += *val);
+    assert_eq!(sum, 15);
+}
+
index 34f1e681608a367ad99d80e2d4c363bd4e4ded98..9cee83a8598c752503962207f83c4dbff24e254d 100644 (file)
@@ -25,6 +25,7 @@
 extern crate rustuv;
 
 use std::io::{Process, Command};
+use std::time::Duration;
 
 macro_rules! succeed( ($e:expr) => (
     match $e { Ok(..) => {}, Err(e) => fail!("failure: {}", e) }
@@ -115,7 +116,7 @@ pub fn test_destroy_actually_kills(force: bool) {
     // Don't let this test time out, this should be quick
     let (tx, rx1) = channel();
     let mut t = timer::Timer::new().unwrap();
-    let rx2 = t.oneshot(1000);
+    let rx2 = t.oneshot(Duration::milliseconds(1000));
     spawn(proc() {
         select! {
             () = rx2.recv() => unsafe { libc::exit(1) },
index 76dedaba40f0bbc9d6573daf374d9bf578dc7a38..f987446c6ad4348512130a63b0d38fbca1c9c953 100644 (file)
@@ -17,7 +17,8 @@ mod hello;
 #[cfg(target_os = "macos")]
 mod hello;
 
-#[cfg(target_os = "win32")]
+#[cfg(target_os = "windows")]
+/* NOTE: Remove after snapshot */#[cfg(stage0, target_os = "win32")]
 mod hello;
 
 #[cfg(target_os = "freebsd")]
index 7e71be4114836c30a441552d24dd19f13e717c35..318305b7ec38eda17b592b262f70767ab7391543 100644 (file)
@@ -10,8 +10,8 @@
 
 #![feature(macro_rules)]
 
-use s = std::num::strconv;
-use to_string = std::num::strconv::float_to_str_common;
+use std::num::strconv as s;
+use std::num::strconv::float_to_str_common as to_string;
 
 macro_rules! t(($a:expr, $b:expr) => { { let (r, _) = $a; assert_eq!(r, $b.to_string()) } })
 
index 34272b145a29ddcecdb55e1219802ef23aa50dfa..37f7d84aaf1e42a46742267fed395d0fc10b1d4e 100644 (file)
@@ -11,5 +11,5 @@
 pub fn main() {
     // Make sure that this view item is filtered out because otherwise it would
     // trigger a compilation error
-    #[cfg(not_present)] use foo = bar;
+    #[cfg(not_present)] use bar as foo;
 }
index 0e6b857d7cf52b292534843bac5da33bd90a927f..14843b30e1c41a3b5a0a7ad46fa9e927e472f42c 100644 (file)
@@ -11,7 +11,7 @@
 // Issue 4691: Ensure that functional-struct-updates operates
 // correctly and moves rather than copy when appropriate.
 
-use NP = std::kinds::marker::NoCopy;
+use std::kinds::marker::NoCopy as NP;
 
 struct ncint { np: NP, v: int }
 fn ncint(v: int) -> ncint { ncint { np: NP, v: v } }
index 26b575c4b07ffe3b1ce8efc177ed896d8a4f1a3b..2ed6b82cad2326a9e5ba6563b63d9c807e56be29 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-win32 TempDir may cause IoError on windows: #10462
+// ignore-windows TempDir may cause IoError on windows: #10462
 
 #![feature(macro_rules)]
 
index 5d404909bf229b54655a97cbb95ffa2e978c353d..cf825bbbcea76c8c4eb747604bbd7c16b82488af 100644 (file)
@@ -16,7 +16,7 @@ mod foo {
 
 mod bar {
     use foo::x;
-    use z = foo::x;
+    use foo::x as z;
     pub fn thing() { x(10); z(10); }
 }
 
index 58ccf3aaa1e3d9b651150f7a5d4fff09cd0e1350..119107404d74d60096f186b2627108ec766f5e6a 100644 (file)
@@ -11,7 +11,7 @@
 
 
 use foo::x;
-use z = foo::x;
+use foo::x as z;
 
 mod foo {
     pub fn x(y: int) { println!("{}", y); }
index edf5068184aea3d62b280c447397bc6fa11615f2..5d0a3c085b4f037a411341c66bf0e79afec48388 100644 (file)
@@ -42,7 +42,8 @@ pub fn main() {
     }
 }
 
-#[cfg(target_os = "win32")]
+#[cfg(target_os = "windows")]
+/* NOTE: Remove after snapshot */#[cfg(stage0, target_os = "win32")]
 mod m {
     #[main]
     #[cfg(target_arch = "x86")]
index 37e675b52ebd886d342c73f6a6f9b1e77960fad2..e21338746be2c91ff62e99b4d1b129a1cf2776bc 100644 (file)
@@ -13,6 +13,8 @@
 extern crate green;
 extern crate rustuv;
 
+use std::time::Duration;
+
 #[start]
 fn start(argc: int, argv: *const *const u8) -> int {
     green::start(argc, argv, rustuv::event_loop, main)
@@ -24,6 +26,6 @@ fn main() {
 
 fn customtask() {
     let mut timer = std::io::timer::Timer::new().unwrap();
-    let periodic = timer.periodic(10);
+    let periodic = timer.periodic(Duration::milliseconds(10));
     periodic.recv();
 }
index c24128f97e372a47954b24ce7b98182e3ad2a6df..6b6e770bc99a43bb802dccda18a2acca50bb1c2f 100644 (file)
@@ -12,6 +12,7 @@
 extern crate native;
 
 use std::io::timer;
+use std::time::Duration;
 
 #[start]
 fn start(argc: int, argv: *const *const u8) -> int {
@@ -19,5 +20,5 @@ fn start(argc: int, argv: *const *const u8) -> int {
 }
 
 fn main() {
-    timer::sleep(250);
+    timer::sleep(Duration::milliseconds(250));
 }
index 87108294ff36278f5d4bbe7eabe5db2556556c12..99af544e7865bd8f1087f1ca0c4fa74ce29815b0 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-win32: FIXME #13793
+// ignore-windows: FIXME #13793
 
 fn main() {
     match ("", 1u) {
index ee7595819bff081afc2335ca530bd9b5bcc5ec96..cc5db0af88bea3a162cb662617e9251a7e52e210 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-win32
+// ignore-windows
 
 #![feature(link_args)]
 
diff --git a/src/test/run-pass/issue-16441.rs b/src/test/run-pass/issue-16441.rs
new file mode 100644 (file)
index 0000000..62c36e1
--- /dev/null
@@ -0,0 +1,17 @@
+// 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.
+
+struct Empty;
+
+// This used to cause an ICE
+extern "C" fn ice(_a: Empty) {}
+
+fn main() {
+}
index fd852f7fd516da81ebe60a7ea9d861c306766fd2..c9413258e0fb8d82442e3b8b76955124eb931cd2 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 
-pub use local_alias = local;
+pub use local as local_alias;
 
 mod local { }
 
index 9f08f1db41057a6b5c9935172166d5a4b85d2abe..c16319a16f2821e4b1dad17ae4a88cb8908b3b13 100644 (file)
 
 use std::comm;
 use std::io::timer::Timer;
+use std::time::Duration;
 
 pub fn main() {
     let (tx, rx) = channel();
     spawn(proc (){
         let mut timer = Timer::new().unwrap();
-        timer.sleep(10);
+        timer.sleep(Duration::milliseconds(10));
         tx.send(());
     });
     loop {
index f541ca6794f62d05dadf5755aba52e651ad24677..f12c66ae7db326b70353a36c4775d2880f35a555 100644 (file)
@@ -10,7 +10,7 @@
 
 // aux-build:lang-item-public.rs
 // ignore-android
-// ignore-win32 #13361
+// ignore-windows #13361
 
 #![no_std]
 
index 58f66314e4430dd7fca25b6b6046b192787d9eb1..5e9e252cefa5158d75280b0fd554944218eead41 100644 (file)
@@ -10,7 +10,7 @@
 
 // aux-build:linkage-visibility.rs
 // ignore-android: FIXME(#10379)
-// ignore-win32: std::dynamic_lib does not work on win32 well
+// ignore-windows: std::dynamic_lib does not work on win32 well
 
 extern crate foo = "linkage-visibility";
 
index 852fe80fcc8fb612cecc83d24908a4723d1eee67..6d750ac1913541918d6d675f0519785e083a12c2 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-win32
+// ignore-windows
 // ignore-android
 // ignore-macos
 // aux-build:linkage1.rs
index 396b633b63313a2a41b1b30c987aeda19a3d7123..c1f7e569feb40d575ff2b4e55520531ade37b1ef 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-win32
+// ignore-windows
 // exec-env:RUST_LOG=debug
 
 use std::cell::Cell;
index ad7ba02970f0510b1cd4bd58a963640bb2a28880..ebbe7fa65cdf84dfc9d6a9e369b773dbfaf5d145 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 // ignore-android
-// ignore-win32
+// ignore-windows
 // exec-env:RUST_LOG=debug
 
 #![feature(phase)]
index 06f6be8265414f38289e3db717ff110e62e688c9..92f57f34c947d15b3ec641991ffb45f38515811c 100644 (file)
@@ -38,7 +38,7 @@ mod m {
 }
 
 fn g() {
-    use AHA = self::m::aha;
+    use self::m::aha as AHA;
     let r = match (0,0) {
         (0, AHA) => 0,
         (x, y)   => 1 + x + y,
index 69ff9fca6ceb935b0d0167b0c5d6ab2df825133c..9d6cab42b5c907e331a7ac2ef888408e17daef79 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-win32
+// ignore-windows
 // ignore-android
 
 // This test ensures that the 'detach' field on processes does the right thing.
index 5c484dec445b1dd30b99973ed60168ccbfaee7c5..3a4f877012278daf24eaecae3449483cfb4a3c93 100644 (file)
@@ -55,7 +55,8 @@ pub fn size() -> uint { 16u }
     }
 }
 
-#[cfg(target_os = "win32")]
+#[cfg(target_os = "windows")]
+/* NOTE: Remove after snapshot */#[cfg(stage0, target_os = "win32")]
 mod m {
     #[cfg(target_arch = "x86")]
     pub mod m {
index c28e128dd05274eb5b1642e5185279ba4cfd1fe8..ed7145412b0a09ed162d58aa611775bfa562dc73 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-win32
+// ignore-windows
 
 extern crate debug;
 
index c8918fda9e79ebc493e1c91e8dc9811fca746e3b..264662d7d8bb2b387d35fa67bf8b9b06a6eddd96 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-win32
+// ignore-windows
 // exec-env:RUST_LOG=debug
 
 // regression test for issue #10405, make sure we don't call println! too soon.
index 6f6fff15814d556f8865acac9353475f5bb09718..c1d93033ab6fea9ef85430d51f413c7e30c91402 100644 (file)
@@ -38,6 +38,7 @@ mod $name {
             use std::io::net::tcp::*;
             use std::io::test::*;
             use std::io;
+            use std::time::Duration;
 
             fn f() $b
 
@@ -72,7 +73,7 @@ fn f() $b
 
     let mut v = Vec::new();
     for _ in range(0u, 10000) {
-        match TcpStream::connect_timeout(addr, 100) {
+        match TcpStream::connect_timeout(addr, Duration::milliseconds(100)) {
             Ok(e) => v.push(e),
             Err(ref e) if e.kind == io::TimedOut => return,
             Err(e) => fail!("other error: {}", e),
@@ -87,11 +88,22 @@ fn f() $b
     let port = addr.port;
     let _l = TcpListener::bind(host.as_slice(), port).unwrap().listen();
 
-    assert!(TcpStream::connect_timeout(addr, 1000).is_ok());
+    assert!(TcpStream::connect_timeout(addr, Duration::milliseconds(1000)).is_ok());
 })
 
 iotest!(fn timeout_error() {
     let addr = next_test_ip4();
 
-    assert!(TcpStream::connect_timeout(addr, 1000).is_err());
+    assert!(TcpStream::connect_timeout(addr, Duration::milliseconds(1000)).is_err());
 })
+
+    iotest!(fn connect_timeout_zero() {
+        let addr = next_test_ip4();
+        assert!(TcpStream::connect_timeout(addr, Duration::milliseconds(0)).is_err());
+    })
+
+    iotest!(fn connect_timeout_negative() {
+        let addr = next_test_ip4();
+        assert!(TcpStream::connect_timeout(addr, Duration::milliseconds(-1)).is_err());
+    })
+
index f52a3455e4157684c16b98c5b29828db88b4f125..864d005f37344a710c85e78afc514fcea1d17de5 100644 (file)
@@ -23,6 +23,7 @@
 use std::io::net::tcp::{TcpListener, TcpStream};
 use std::io::{Acceptor, Listener};
 use std::task::TaskBuilder;
+use std::time::Duration;
 
 #[start]
 fn start(argc: int, argv: *const *const u8) -> int {
@@ -33,7 +34,7 @@ fn main() {
     // This test has a chance to time out, try to not let it time out
     spawn(proc() {
         use std::io::timer;
-        timer::sleep(30 * 1000);
+        timer::sleep(Duration::milliseconds(30 * 1000));
         println!("timed out!");
         unsafe { libc::exit(1) }
     });
index 4355bf4127fc4f9c727d679a9cad16269971a985..9ecf5c3940a72a394b141ff159b804a5441a7ef9 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-win32 TempDir may cause IoError on windows: #10463
+// ignore-windows TempDir may cause IoError on windows: #10463
 
 // These tests are here to exercise the functionality of the `tempfile` module.
 // One might expect these tests to be located in that module, but sadly they
index 05d5506f0a6b0df599d135befd9596f544789979..64b914a7438cd02bdcd58ecd591407b29837da46 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 // compile-flags:--test
-// ignore-win32 #10872
+// ignore-windows #10872
 // ignore-pretty: does not work well with `--test`
 
 // Building as a test runner means that a synthetic main will be run,
diff --git a/src/test/run-pass/unboxed-closures-all-traits.rs b/src/test/run-pass/unboxed-closures-all-traits.rs
new file mode 100644 (file)
index 0000000..c362a83
--- /dev/null
@@ -0,0 +1,31 @@
+// 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(lang_items, overloaded_calls, unboxed_closures)]
+
+fn a<F:|&: int, int| -> int>(f: F) -> int {
+    f(1, 2)
+}
+
+fn b<F:|&mut: int, int| -> int>(mut f: F) -> int {
+    f(3, 4)
+}
+
+fn c<F:|: int, int| -> int>(f: F) -> int {
+    f(5, 6)
+}
+
+fn main() {
+    let z: int = 7;
+    assert_eq!(a(|&: x: int, y| x + y + z), 10);
+    assert_eq!(b(|&mut: x: int, y| x + y + z), 14);
+    assert_eq!(c(|: x: int, y| x + y + z), 18);
+}
+
diff --git a/src/test/run-pass/unboxed-closures-drop.rs b/src/test/run-pass/unboxed-closures-drop.rs
new file mode 100644 (file)
index 0000000..f20dddc
--- /dev/null
@@ -0,0 +1,127 @@
+// 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.
+
+// A battery of tests to ensure destructors of unboxed closure environments
+// run at the right times.
+
+#![feature(overloaded_calls, unboxed_closures)]
+
+static mut DROP_COUNT: uint = 0;
+
+fn drop_count() -> uint {
+    unsafe {
+        DROP_COUNT
+    }
+}
+
+struct Droppable {
+    x: int,
+}
+
+impl Droppable {
+    fn new() -> Droppable {
+        Droppable {
+            x: 1
+        }
+    }
+}
+
+impl Drop for Droppable {
+    fn drop(&mut self) {
+        unsafe {
+            DROP_COUNT += 1
+        }
+    }
+}
+
+fn a<F:|&: int, int| -> int>(f: F) -> int {
+    f(1, 2)
+}
+
+fn b<F:|&mut: int, int| -> int>(mut f: F) -> int {
+    f(3, 4)
+}
+
+fn c<F:|: int, int| -> int>(f: F) -> int {
+    f(5, 6)
+}
+
+fn test_fn() {
+    {
+        a(|&: a: int, b| { a + b });
+    }
+    assert_eq!(drop_count(), 0);
+
+    {
+        let z = &Droppable::new();
+        a(|&: a: int, b| { z; a + b });
+        assert_eq!(drop_count(), 0);
+    }
+    assert_eq!(drop_count(), 1);
+
+    {
+        let z = &Droppable::new();
+        let zz = &Droppable::new();
+        a(|&: a: int, b| { z; zz; a + b });
+        assert_eq!(drop_count(), 1);
+    }
+    assert_eq!(drop_count(), 3);
+}
+
+fn test_fn_mut() {
+    {
+        b(|&mut: a: int, b| { a + b });
+    }
+    assert_eq!(drop_count(), 3);
+
+    {
+        let z = &Droppable::new();
+        b(|&mut: a: int, b| { z; a + b });
+        assert_eq!(drop_count(), 3);
+    }
+    assert_eq!(drop_count(), 4);
+
+    {
+        let z = &Droppable::new();
+        let zz = &Droppable::new();
+        b(|&mut: a: int, b| { z; zz; a + b });
+        assert_eq!(drop_count(), 4);
+    }
+    assert_eq!(drop_count(), 6);
+}
+
+fn test_fn_once() {
+    {
+        c(|: a: int, b| { a + b });
+    }
+    assert_eq!(drop_count(), 6);
+
+    {
+        let z = Droppable::new();
+        c(|: a: int, b| { z; a + b });
+        assert_eq!(drop_count(), 7);
+    }
+    assert_eq!(drop_count(), 7);
+
+    {
+        let z = Droppable::new();
+        let zz = Droppable::new();
+        c(|: a: int, b| { z; zz; a + b });
+        assert_eq!(drop_count(), 9);
+    }
+    assert_eq!(drop_count(), 9);
+}
+
+fn main() {
+    test_fn();
+    test_fn_mut();
+    test_fn_once();
+}
+
diff --git a/src/test/run-pass/unboxed-closures-single-word-env.rs b/src/test/run-pass/unboxed-closures-single-word-env.rs
new file mode 100644 (file)
index 0000000..754b1f7
--- /dev/null
@@ -0,0 +1,34 @@
+// 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.
+
+// Ensures that single-word environments work right in unboxed closures.
+// These take a different path in codegen.
+
+#![feature(overloaded_calls, unboxed_closures)]
+
+fn a<F:|&: int, int| -> int>(f: F) -> int {
+    f(1, 2)
+}
+
+fn b<F:|&mut: int, int| -> int>(mut f: F) -> int {
+    f(3, 4)
+}
+
+fn c<F:|: int, int| -> int>(f: F) -> int {
+    f(5, 6)
+}
+
+fn main() {
+    let z = 10;
+    assert_eq!(a(|&: x: int, y| x + y + z), 13);
+    assert_eq!(b(|&mut: x: int, y| x + y + z), 17);
+    assert_eq!(c(|: x: int, y| x + y + z), 21);
+}
+
index dfed391640516d0cf6e6b90e4d65d5c0d685b2f7..cdc0ffed7a1cb11f0b100959970d69ba3bf7b45e 100644 (file)
@@ -18,9 +18,9 @@
 
 
 use std::str;
-use x = zed::str;
+use zed::str as x;
 mod baz {
-    pub use x = std::str;
+    pub use std::str as x;
 }
 
 #[start]
diff --git a/src/test/run-pass/where-clauses-cross-crate.rs b/src/test/run-pass/where-clauses-cross-crate.rs
new file mode 100644 (file)
index 0000000..648f646
--- /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.
+
+// aux-build:where_clauses_xc.rs
+
+extern crate where_clauses_xc;
+
+use where_clauses_xc::{Equal, equal};
+
+fn main() {
+    println!("{}", equal(&1i, &2i));
+    println!("{}", equal(&1i, &1i));
+    println!("{}", "hello".equal(&"hello"));
+    println!("{}", "hello".equals::<int,&str>(&1i, &1i, &"foo", &"bar"));
+}
+
diff --git a/src/test/run-pass/where-clauses.rs b/src/test/run-pass/where-clauses.rs
new file mode 100644 (file)
index 0000000..807d956
--- /dev/null
@@ -0,0 +1,37 @@
+// 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.
+
+trait Equal {
+    fn equal(&self, other: &Self) -> bool;
+    fn equals<T,U>(&self, this: &T, that: &T, x: &U, y: &U) -> bool
+            where T: Eq, U: Eq;
+}
+
+impl<T> Equal for T where T: Eq {
+    fn equal(&self, other: &T) -> bool {
+        self == other
+    }
+    fn equals<U,X>(&self, this: &U, other: &U, x: &X, y: &X) -> bool
+            where U: Eq, X: Eq {
+        this == other && x == y
+    }
+}
+
+fn equal<T>(x: &T, y: &T) -> bool where T: Eq {
+    x == y
+}
+
+fn main() {
+    println!("{}", equal(&1i, &2i));
+    println!("{}", equal(&1i, &1i));
+    println!("{}", "hello".equal(&"hello"));
+    println!("{}", "hello".equals::<int,&str>(&1i, &1i, &"foo", &"bar"));
+}
+
index 634c9623e8468e1d7c354c82dc456087b3f6de68..6afa02fce55149a45552a0953c317d684b9fe5d4 100644 (file)
@@ -12,7 +12,7 @@
 
 extern crate xcrate_static_addresses;
 
-use other = xcrate_static_addresses;
+use xcrate_static_addresses as other;
 
 pub fn main() {
     other::verify_same(&other::global);