]> git.lizzy.rs Git - rust.git/commitdiff
auto merge of #14752 : jakub-/rust/issue-11940, r=alexcrichton
authorbors <bors@rust-lang.org>
Tue, 10 Jun 2014 20:17:10 +0000 (13:17 -0700)
committerbors <bors@rust-lang.org>
Tue, 10 Jun 2014 20:17:10 +0000 (13:17 -0700)
Fixes #8315
Fixes #11940

238 files changed:
mk/crates.mk
src/compiletest/compiletest.rs
src/compiletest/procsrv.rs
src/doc/rust.md
src/etc/licenseck.py
src/liballoc/lib.rs
src/libcollections/bitv.rs
src/libcollections/btree.rs
src/libcollections/deque.rs
src/libcollections/dlist.rs
src/libcollections/lib.rs
src/libcollections/priority_queue.rs
src/libcollections/ringbuf.rs
src/libcollections/slice.rs
src/libcollections/smallintmap.rs
src/libcollections/str.rs
src/libcollections/string.rs
src/libcollections/treemap.rs
src/libcollections/trie.rs
src/libcollections/vec.rs
src/libcore/collections.rs [new file with mode: 0644]
src/libcore/container.rs [deleted file]
src/libcore/fmt/float.rs
src/libcore/fmt/mod.rs
src/libcore/fmt/num.rs
src/libcore/lib.rs
src/libcore/ops.rs
src/libcore/prelude.rs
src/libcore/should_not_exist.rs
src/libcore/simd.rs
src/libcore/slice.rs
src/libcore/str.rs
src/libflate/lib.rs
src/libfourcc/lib.rs
src/libgetopts/lib.rs
src/libglob/lib.rs
src/libgreen/context.rs
src/libgreen/lib.rs
src/libhexfloat/lib.rs
src/liblog/lib.rs
src/liblog/macros.rs
src/libnative/io/c_win32.rs
src/libnative/io/file_win32.rs
src/libnative/io/mod.rs
src/libnative/io/net.rs
src/libnative/io/pipe_unix.rs
src/libnative/io/pipe_win32.rs
src/libnative/io/process.rs
src/libnum/bigint.rs
src/libnum/integer.rs [new file with mode: 0644]
src/libnum/lib.rs
src/librand/distributions/gamma.rs
src/librand/lib.rs
src/libregex/lib.rs
src/libregex/re.rs
src/libregex/test/mod.rs
src/libregex_macros/lib.rs
src/librustc/driver/driver.rs
src/librustc/driver/session.rs
src/librustc/front/feature_gate.rs
src/librustc/front/std_inject.rs
src/librustc/front/test.rs
src/librustc/lib.rs
src/librustc/metadata/common.rs
src/librustc/metadata/creader.rs
src/librustc/metadata/csearch.rs
src/librustc/metadata/cstore.rs
src/librustc/metadata/decoder.rs
src/librustc/metadata/encoder.rs
src/librustc/metadata/filesearch.rs
src/librustc/metadata/loader.rs
src/librustc/metadata/tyencode.rs
src/librustc/middle/borrowck/gather_loans/lifetime.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/dead.rs
src/librustc/middle/expr_use_visitor.rs
src/librustc/middle/lang_items.rs
src/librustc/middle/lint.rs
src/librustc/middle/liveness.rs
src/librustc/middle/privacy.rs
src/librustc/middle/resolve.rs
src/librustc/middle/trans/adt.rs
src/librustc/middle/trans/base.rs
src/librustc/middle/trans/expr.rs
src/librustc/middle/trans/foreign.rs
src/librustc/middle/typeck/astconv.rs
src/librustc/middle/typeck/check/mod.rs
src/librustc/middle/typeck/check/regionck.rs
src/librustc/middle/typeck/coherence.rs
src/librustc/middle/typeck/collect.rs
src/librustc/middle/typeck/infer/error_reporting.rs
src/librustc/middle/typeck/variance.rs
src/librustc/plugin/build.rs [new file with mode: 0644]
src/librustc/plugin/load.rs [new file with mode: 0644]
src/librustc/plugin/mod.rs [new file with mode: 0644]
src/librustc/plugin/registry.rs [new file with mode: 0644]
src/librustc/util/common.rs
src/librustdoc/clean/inline.rs
src/librustdoc/clean/mod.rs
src/librustdoc/core.rs
src/librustdoc/flock.rs
src/librustdoc/html/markdown.rs
src/librustdoc/lib.rs
src/librustdoc/plugins.rs
src/librustdoc/test.rs
src/librustrt/c_str.rs
src/librustrt/lib.rs
src/librustrt/mutex.rs
src/librustuv/idle.rs
src/librustuv/net.rs
src/librustuv/uvll.rs
src/libserialize/json.rs
src/libserialize/lib.rs
src/libstd/ascii.rs
src/libstd/c_vec.rs
src/libstd/collections/hashmap.rs
src/libstd/collections/lru_cache.rs
src/libstd/collections/mod.rs
src/libstd/comm/sync.rs
src/libstd/dynamic_lib.rs [new file with mode: 0644]
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/process.rs
src/libstd/io/stdio.rs
src/libstd/io/timer.rs
src/libstd/lib.rs
src/libstd/macros.rs
src/libstd/num/strconv.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/rand/reader.rs
src/libstd/rt/backtrace.rs
src/libstd/rt/thread.rs
src/libstd/task.rs
src/libstd/unstable/dynamic_lib.rs [deleted file]
src/libstd/unstable/mod.rs [deleted file]
src/libsync/lib.rs
src/libsync/raw.rs
src/libsyntax/ast.rs
src/libsyntax/ext/base.rs
src/libsyntax/ext/build.rs
src/libsyntax/ext/expand.rs
src/libsyntax/ext/registrar.rs [deleted file]
src/libsyntax/fold.rs
src/libsyntax/lib.rs
src/libsyntax/owned_slice.rs
src/libsyntax/parse/parser.rs
src/libsyntax/print/pprust.rs
src/libsyntax/util/small_vector.rs
src/libsyntax/visit.rs
src/libterm/lib.rs
src/libtest/lib.rs
src/libtime/lib.rs
src/test/auxiliary/issue-13560-3.rs
src/test/auxiliary/linkage-visibility.rs
src/test/auxiliary/logging_right_crate.rs
src/test/auxiliary/macro_crate_outlive_expansion_phase.rs [deleted file]
src/test/auxiliary/macro_crate_test.rs
src/test/auxiliary/plugin_crate_outlive_expansion_phase.rs [new file with mode: 0644]
src/test/auxiliary/syntax-extension-with-dll-deps-2.rs
src/test/auxiliary/weak-lang-items.rs
src/test/bench/shootout-chameneos-redux.rs
src/test/bench/shootout-fannkuch-redux.rs
src/test/bench/shootout-meteor.rs
src/test/bench/shootout-regex-dna.rs
src/test/bench/shootout-spectralnorm.rs
src/test/bench/shootout-threadring.rs
src/test/compile-fail-fulldeps/gated-phase.rs
src/test/compile-fail-fulldeps/macro-crate-unexported-macro.rs
src/test/compile-fail-fulldeps/macro-crate-unknown-crate.rs
src/test/compile-fail-fulldeps/phase-syntax-doesnt-resolve.rs
src/test/compile-fail-fulldeps/syntax-extension-fourcc-bad-len.rs
src/test/compile-fail-fulldeps/syntax-extension-fourcc-invalid-endian.rs
src/test/compile-fail-fulldeps/syntax-extension-fourcc-non-ascii-str.rs
src/test/compile-fail-fulldeps/syntax-extension-fourcc-non-literal.rs
src/test/compile-fail-fulldeps/syntax-extension-fourcc-unsupported-literal.rs
src/test/compile-fail-fulldeps/syntax-extension-hexfloat-bad-lits.rs
src/test/compile-fail-fulldeps/syntax-extension-hexfloat-bad-types.rs
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/gated-macro_registrar.rs [deleted file]
src/test/compile-fail/gated-plugin_registrar.rs [new file with mode: 0644]
src/test/compile-fail/issue-13446.rs [new file with mode: 0644]
src/test/compile-fail/lint-dead-code-1.rs
src/test/compile-fail/lint-dead-code-4.rs [new file with mode: 0644]
src/test/compile-fail/lint-managed-heap-memory.rs
src/test/compile-fail/lint-non-camel-case-types.rs
src/test/compile-fail/lint-non-snake-case-functions.rs
src/test/compile-fail/lint-non-uppercase-statics.rs
src/test/compile-fail/lint-owned-heap-memory.rs
src/test/compile-fail/lint-uppercase-variables.rs
src/test/compile-fail/map-types.rs
src/test/compile-fail/match-static-const-lc.rs
src/test/compile-fail/multiple-macro-registrars.rs [deleted file]
src/test/compile-fail/multiple-plugin-registrars.rs [new file with mode: 0644]
src/test/compile-fail/overloaded-calls-bad.rs [new file with mode: 0644]
src/test/compile-fail/overloaded-calls-nontuple.rs [new file with mode: 0644]
src/test/run-fail/rt-set-exit-status-fail.rs
src/test/run-fail/rt-set-exit-status-fail2.rs
src/test/run-fail/rt-set-exit-status.rs
src/test/run-make/extern-fn-reachable/main.rs
src/test/run-make/lto-syntax-extension/main.rs
src/test/run-pass-fulldeps/macro-crate-outlive-expansion-phase.rs
src/test/run-pass-fulldeps/macro-crate.rs
src/test/run-pass-fulldeps/phase-syntax-link-does-resolve.rs
src/test/run-pass-fulldeps/syntax-extension-fourcc.rs
src/test/run-pass-fulldeps/syntax-extension-hexfloat.rs
src/test/run-pass-fulldeps/syntax-extension-with-dll-deps.rs
src/test/run-pass/capturing-logging.rs
src/test/run-pass/class-impl-very-parameterized-trait.rs
src/test/run-pass/conditional-debug-macro-off.rs
src/test/run-pass/deprecated-phase-syntax.rs [new file with mode: 0644]
src/test/run-pass/fn-trait-sugar.rs [new file with mode: 0644]
src/test/run-pass/issue-14456.rs
src/test/run-pass/linkage-visibility.rs
src/test/run-pass/logging-enabled-debug.rs
src/test/run-pass/logging-enabled.rs
src/test/run-pass/logging-separate-lines.rs
src/test/run-pass/macro-crate-def-only.rs
src/test/run-pass/macro-export-inner-module.rs
src/test/run-pass/overloaded-calls-simple.rs [new file with mode: 0644]
src/test/run-pass/overloaded-calls-zero-args.rs [new file with mode: 0644]
src/test/run-pass/phase-use-ignored.rs
src/test/run-pass/send_str_hashmap.rs
src/test/run-pass/send_str_treemap.rs
src/test/run-pass/tcp-stress.rs

index 433490f6f5dbfd4985b52b7d53c2bb0ab794c477..cc6532945efad7fc2a7c65a43a9b7326f5e43eb7 100644 (file)
@@ -83,8 +83,8 @@ DEPS_uuid := std serialize
 DEPS_sync := std alloc
 DEPS_getopts := std
 DEPS_collections := core alloc
-DEPS_fourcc := syntax std
-DEPS_hexfloat := syntax std
+DEPS_fourcc := rustc syntax std
+DEPS_hexfloat := rustc syntax std
 DEPS_num := std
 DEPS_test := std getopts serialize term time regex native:rust_test_helpers
 DEPS_time := std serialize sync
@@ -92,7 +92,7 @@ DEPS_rand := core
 DEPS_url := std
 DEPS_log := std sync
 DEPS_regex := std
-DEPS_regex_macros = syntax std regex
+DEPS_regex_macros = rustc syntax std regex
 DEPS_fmt_macros = std
 
 TOOL_DEPS_compiletest := test green rustuv getopts
index 8fcad94ee1cfc7cff997f61b143426c9c50b7105..977b7dc32c5658b7d01e9bd4c4b79137bd647bff 100644 (file)
 
 extern crate test;
 extern crate getopts;
-#[phase(link, syntax)]
-extern crate log;
 extern crate green;
 extern crate rustuv;
 
+#[cfg(stage0)]
+#[phase(syntax, link)]
+extern crate log;
+
+#[cfg(not(stage0))]
+#[phase(plugin, link)]
+extern crate log;
+
 extern crate regex;
 
 use std::os;
@@ -286,6 +292,7 @@ pub fn test_opts(config: &Config) -> test::TestOpts {
         save_metrics: config.save_metrics.clone(),
         test_shard: config.test_shard.clone(),
         nocapture: false,
+        color: test::AutoColor,
     }
 }
 
index a48a9f1be754133af968a123c297bc9506cb0e2c..8fa34dd6d27c91ff254c139ac6df1c006766842b 100644 (file)
@@ -11,7 +11,7 @@
 use std::os;
 use std::str;
 use std::io::process::{ProcessExit, Command, Process, ProcessOutput};
-use std::unstable::dynamic_lib::DynamicLibrary;
+use std::dynamic_lib::DynamicLibrary;
 
 fn target_env(lib_path: &str, prog: &str) -> Vec<(String, String)> {
     let prog = if cfg!(windows) {prog.slice_to(prog.len() - 4)} else {prog};
index 619e24af36063b65a7c908dab0623d612f2d8702..35d356bb1b56cd8e4935a627d0a20b1f1134b072 100644 (file)
@@ -1819,9 +1819,8 @@ type int8_t = i8;
 
 ### Function-only attributes
 
-- `macro_registrar` - when using loadable syntax extensions, mark this
-  function as the registration point for the current crate's syntax
-  extensions.
+- `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`.
 - `start` - indicates that this function should be used as the entry point,
@@ -4098,7 +4097,7 @@ that demonstrates all four of them:
 
 ~~~~
 #![feature(phase)]
-#[phase(syntax, link)] extern crate log;
+#[phase(plugin, link)] extern crate log;
 
 fn main() {
     error!("This is an error log")
index e03b09cb53c219aef68ac1317b9731e2600f53c8..8b93f6e61bff1153edeef2604a498ad3cf17af2f 100644 (file)
@@ -42,6 +42,7 @@ exceptions = [
     "libstd/sync/spsc_queue.rs", # BSD
     "libstd/sync/mpmc_bounded_queue.rs", # BSD
     "libsync/mpsc_intrusive.rs", # BSD
+    "test/bench/shootout-fannkuch-redux.rs", # BSD
     "test/bench/shootout-meteor.rs", # BSD
     "test/bench/shootout-regex-dna.rs", # BSD
 ]
index ca7ed6f4ba05bda7329cc0139c0138d92de67330..7e2c9a75fad0d3eee0b23ecb3bb5de6dcc776302 100644 (file)
 #![no_std]
 #![feature(phase)]
 
+#[cfg(stage0)]
 #[phase(syntax, link)]
 extern crate core;
+
+#[cfg(not(stage0))]
+#[phase(plugin, link)]
+extern crate core;
+
 extern crate libc;
 
 
 #[cfg(test)] extern crate debug;
 #[cfg(test)] extern crate sync;
 #[cfg(test)] extern crate native;
-#[cfg(test)] #[phase(syntax, link)] extern crate std;
-#[cfg(test)] #[phase(syntax, link)] extern crate log;
+#[cfg(test, stage0)] #[phase(syntax, link)] extern crate std;
+#[cfg(test, stage0)] #[phase(syntax, link)] extern crate log;
+#[cfg(test, not(stage0))] #[phase(plugin, link)] extern crate std;
+#[cfg(test, not(stage0))] #[phase(plugin, link)] extern crate log;
 
 // Heaps provided for low-level allocation strategies
 
index 58f081b25e3e541f820ce60fa46738c7850624cc..e100baa1e3ac493bd329842ff40c592cb9d121e2 100644 (file)
 use core::prelude::*;
 
 use core::cmp;
+use core::default::Default;
 use core::fmt;
 use core::iter::{Enumerate, Repeat, Map, Zip};
 use core::ops;
 use core::slice;
 use core::uint;
+use std::hash;
 
+use {Collection, Mutable, Set, MutableSet};
 use vec::Vec;
 
 #[deriving(Clone)]
@@ -34,12 +37,12 @@ fn small_mask(nbits: uint) -> uint {
 }
 
 impl SmallBitv {
-    pub fn new(bits: uint) -> SmallBitv {
+    fn new(bits: uint) -> SmallBitv {
         SmallBitv {bits: bits}
     }
 
     #[inline]
-    pub fn bits_op(&mut self,
+    fn bits_op(&mut self,
                    right_bits: uint,
                    nbits: uint,
                    f: |uint, uint| -> uint)
@@ -52,32 +55,32 @@ pub fn bits_op(&mut self,
     }
 
     #[inline]
-    pub fn union(&mut self, s: &SmallBitv, nbits: uint) -> bool {
+    fn union(&mut self, s: &SmallBitv, nbits: uint) -> bool {
         self.bits_op(s.bits, nbits, |u1, u2| u1 | u2)
     }
 
     #[inline]
-    pub fn intersect(&mut self, s: &SmallBitv, nbits: uint) -> bool {
+    fn intersect(&mut self, s: &SmallBitv, nbits: uint) -> bool {
         self.bits_op(s.bits, nbits, |u1, u2| u1 & u2)
     }
 
     #[inline]
-    pub fn become(&mut self, s: &SmallBitv, nbits: uint) -> bool {
+    fn become(&mut self, s: &SmallBitv, nbits: uint) -> bool {
         self.bits_op(s.bits, nbits, |_u1, u2| u2)
     }
 
     #[inline]
-    pub fn difference(&mut self, s: &SmallBitv, nbits: uint) -> bool {
+    fn difference(&mut self, s: &SmallBitv, nbits: uint) -> bool {
         self.bits_op(s.bits, nbits, |u1, u2| u1 & !u2)
     }
 
     #[inline]
-    pub fn get(&self, i: uint) -> bool {
+    fn get(&self, i: uint) -> bool {
         (self.bits & (1 << i)) != 0
     }
 
     #[inline]
-    pub fn set(&mut self, i: uint, x: bool) {
+    fn set(&mut self, i: uint, x: bool) {
         if x {
             self.bits |= 1<<i;
         }
@@ -87,29 +90,29 @@ pub fn set(&mut self, i: uint, x: bool) {
     }
 
     #[inline]
-    pub fn equals(&self, b: &SmallBitv, nbits: uint) -> bool {
+    fn equals(&self, b: &SmallBitv, nbits: uint) -> bool {
         let mask = small_mask(nbits);
         mask & self.bits == mask & b.bits
     }
 
     #[inline]
-    pub fn clear(&mut self) { self.bits = 0; }
+    fn clear(&mut self) { self.bits = 0; }
 
     #[inline]
-    pub fn set_all(&mut self) { self.bits = !0; }
+    fn set_all(&mut self) { self.bits = !0; }
 
     #[inline]
-    pub fn all(&self, nbits: uint) -> bool {
+    fn all(&self, nbits: uint) -> bool {
         small_mask(nbits) & !self.bits == 0
     }
 
     #[inline]
-    pub fn none(&self, nbits: uint) -> bool {
+    fn none(&self, nbits: uint) -> bool {
         small_mask(nbits) & self.bits == 0
     }
 
     #[inline]
-    pub fn negate(&mut self) { self.bits = !self.bits; }
+    fn negate(&mut self) { self.bits = !self.bits; }
 }
 
 #[deriving(Clone)]
@@ -134,12 +137,12 @@ fn big_mask(nbits: uint, elem: uint) -> uint {
 }
 
 impl BigBitv {
-    pub fn new(storage: Vec<uint>) -> BigBitv {
+    fn new(storage: Vec<uint>) -> BigBitv {
         BigBitv {storage: storage}
     }
 
     #[inline]
-    pub fn process(&mut self,
+    fn process(&mut self,
                    b: &BigBitv,
                    nbits: uint,
                    op: |uint, uint| -> uint)
@@ -163,37 +166,37 @@ pub fn process(&mut self,
     }
 
     #[inline]
-    pub fn each_storage(&mut self, op: |v: &mut uint| -> bool) -> bool {
+    fn each_storage(&mut self, op: |v: &mut uint| -> bool) -> bool {
         self.storage.mut_iter().advance(|elt| op(elt))
     }
 
     #[inline]
-    pub fn negate(&mut self) {
+    fn negate(&mut self) {
         self.each_storage(|w| { *w = !*w; true });
     }
 
     #[inline]
-    pub fn union(&mut self, b: &BigBitv, nbits: uint) -> bool {
+    fn union(&mut self, b: &BigBitv, nbits: uint) -> bool {
         self.process(b, nbits, |w1, w2| w1 | w2)
     }
 
     #[inline]
-    pub fn intersect(&mut self, b: &BigBitv, nbits: uint) -> bool {
+    fn intersect(&mut self, b: &BigBitv, nbits: uint) -> bool {
         self.process(b, nbits, |w1, w2| w1 & w2)
     }
 
     #[inline]
-    pub fn become(&mut self, b: &BigBitv, nbits: uint) -> bool {
+    fn become(&mut self, b: &BigBitv, nbits: uint) -> bool {
         self.process(b, nbits, |_, w| w)
     }
 
     #[inline]
-    pub fn difference(&mut self, b: &BigBitv, nbits: uint) -> bool {
+    fn difference(&mut self, b: &BigBitv, nbits: uint) -> bool {
         self.process(b, nbits, |w1, w2| w1 & !w2)
     }
 
     #[inline]
-    pub fn get(&self, i: uint) -> bool {
+    fn get(&self, i: uint) -> bool {
         let w = i / uint::BITS;
         let b = i % uint::BITS;
         let x = 1 & self.storage.get(w) >> b;
@@ -201,7 +204,7 @@ pub fn get(&self, i: uint) -> bool {
     }
 
     #[inline]
-    pub fn set(&mut self, i: uint, x: bool) {
+    fn set(&mut self, i: uint, x: bool) {
         let w = i / uint::BITS;
         let b = i % uint::BITS;
         let flag = 1 << b;
@@ -210,7 +213,7 @@ pub fn set(&mut self, i: uint, x: bool) {
     }
 
     #[inline]
-    pub fn equals(&self, b: &BigBitv, nbits: uint) -> bool {
+    fn equals(&self, b: &BigBitv, nbits: uint) -> bool {
         for (i, elt) in b.storage.iter().enumerate() {
             let mask = big_mask(nbits, i);
             if mask & *self.storage.get(i) != mask & *elt {
@@ -596,6 +599,20 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
+impl<S: hash::Writer> hash::Hash<S> for Bitv {
+    fn hash(&self, state: &mut S) {
+        self.nbits.hash(state);
+        match self.rep {
+            Small(ref s) => (s.bits & small_mask(self.nbits)).hash(state),
+            Big(ref b) => {
+                for (i, ele) in b.storage.iter().enumerate() {
+                    (ele & big_mask(self.nbits, i)).hash(state);
+                }
+            }
+        }
+    }
+}
+
 #[inline]
 fn iterate_bits(base: uint, bits: uint, f: |uint| -> bool) -> bool {
     if bits == 0 {
@@ -682,6 +699,11 @@ pub struct BitvSet {
     bitv: BigBitv
 }
 
+impl Default for BitvSet {
+    #[inline]
+    fn default() -> BitvSet { BitvSet::new() }
+}
+
 impl BitvSet {
     /// Creates a new bit vector set with initially no contents
     pub fn new() -> BitvSet {
@@ -834,7 +856,15 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
-impl Container for BitvSet {
+impl<S: hash::Writer> hash::Hash<S> for BitvSet {
+    fn hash(&self, state: &mut S) {
+        for pos in self.iter() {
+            pos.hash(state);
+        }
+    }
+}
+
+impl Collection for BitvSet {
     #[inline]
     fn len(&self) -> uint { self.size }
 }
@@ -985,6 +1015,7 @@ mod tests {
     use std::rand::Rng;
     use test::Bencher;
 
+    use {Set, Mutable, MutableSet};
     use bitv::{Bitv, SmallBitv, BigBitv, BitvSet, from_bools, from_fn,
                from_bytes};
     use bitv;
index ebca0157da40be19d728e74ce87f758485ae8480..82abe69a63996fb3aad41a1f4deb81a8a6070a97 100644 (file)
@@ -24,6 +24,7 @@
 use core::fmt;
 use core::fmt::Show;
 
+use Collection;
 use vec::Vec;
 
 #[allow(missing_doc)]
index 5624c67f1084089da0583545b17c269e5f5acd1d..1faa9be99e3a54e919643e4be4f4409d223c5f5b 100644 (file)
 
 //! Container traits for collections
 
-use core::prelude::*;
-
-/// A double-ended sequence that allows querying, insertion and deletion at both ends.
-pub trait Deque<T> : Mutable {
-    /// Provide a reference to the front element, or None if the sequence is empty
-    fn front<'a>(&'a self) -> Option<&'a T>;
-
-    /// Provide a mutable reference to the front element, or None if the sequence is empty
-    fn front_mut<'a>(&'a mut self) -> Option<&'a mut T>;
-
-    /// Provide a reference to the back element, or None if the sequence is empty
-    fn back<'a>(&'a self) -> Option<&'a T>;
-
-    /// Provide a mutable reference to the back element, or None if the sequence is empty
-    fn back_mut<'a>(&'a mut self) -> Option<&'a mut T>;
-
-    /// Insert an element first in the sequence
-    fn push_front(&mut self, elt: T);
-
-    /// Insert an element last in the sequence
-    fn push_back(&mut self, elt: T);
-
-    /// Remove the last element and return it, or None if the sequence is empty
-    fn pop_back(&mut self) -> Option<T>;
-
-    /// Remove the first element and return it, or None if the sequence is empty
-    fn pop_front(&mut self) -> Option<T>;
-}
-
 #[cfg(test)]
 pub mod bench {
     use std::prelude::*;
     use std::rand;
     use std::rand::Rng;
     use test::Bencher;
+    use MutableMap;
 
     pub fn insert_rand_n<M:MutableMap<uint,uint>>(n: uint,
                                                   map: &mut M,
@@ -121,3 +93,4 @@ pub fn find_seq_n<M:MutableMap<uint,uint>>(n: uint,
         })
      }
 }
+
index 9d0e8e83698d8bac04832f23bcb5a63a7580d447..ac8c5c5557ed9cff4921f08afa9e252fddd51fc6 100644 (file)
@@ -13,7 +13,7 @@
 //! The DList allows pushing and popping elements at either end.
 //!
 //! DList implements the trait Deque. It should be imported with `use
-//! collections::deque::Deque`.
+//! collections::Deque`.
 
 // DList is constructed like a singly-linked list over the field `next`.
 // including the last link being None; each Node owns its `next` field.
 use core::prelude::*;
 
 use alloc::owned::Box;
+use core::default::Default;
 use core::fmt;
 use core::iter;
 use core::mem;
 use core::ptr;
 
-use deque::Deque;
+use {Collection, Mutable, Deque};
 
 /// A doubly-linked list.
 pub struct DList<T> {
@@ -125,7 +126,7 @@ fn link_with_prev<T>(mut next: Box<Node<T>>, prev: Rawlink<Node<T>>)
     Some(next)
 }
 
-impl<T> Container for DList<T> {
+impl<T> Collection for DList<T> {
     /// O(1)
     #[inline]
     fn is_empty(&self) -> bool {
@@ -262,6 +263,11 @@ fn pop_back(&mut self) -> Option<T> {
     }
 }
 
+impl<T> Default for DList<T> {
+    #[inline]
+    fn default() -> DList<T> { DList::new() }
+}
+
 impl<T> DList<T> {
     /// Create an empty DList
     #[inline]
@@ -629,7 +635,7 @@ mod tests {
     use test::Bencher;
     use test;
 
-    use deque::Deque;
+    use Deque;
     use super::{DList, Node, ListInsertion};
     use vec::Vec;
 
index c46ea84a765cea9adace56d880d220a5f8c6fdb7..a114755a0ed91a3ac011fd8b6cc8020e8ef3b89c 100644 (file)
 #![feature(macro_rules, managed_boxes, default_type_params, phase, globs)]
 #![no_std]
 
-#[phase(syntax, link)] extern crate core;
 extern crate alloc;
 
+#[cfg(stage0)]
+#[phase(syntax, link)]
+extern crate core;
+
+#[cfg(not(stage0))]
+#[phase(plugin, link)]
+extern crate core;
+
 #[cfg(test)] extern crate native;
 #[cfg(test)] extern crate test;
 #[cfg(test)] extern crate debug;
-#[cfg(test)] #[phase(syntax, link)] extern crate std;
-#[cfg(test)] #[phase(syntax, link)] extern crate log;
 
+#[cfg(test, stage0)] #[phase(syntax, link)] extern crate std;
+#[cfg(test, stage0)] #[phase(syntax, link)] extern crate log;
+#[cfg(test, not(stage0))] #[phase(plugin, link)] extern crate std;
+#[cfg(test, not(stage0))] #[phase(plugin, link)] extern crate log;
+
+use core::prelude::*;
+
+pub use core::collections::Collection;
 pub use bitv::{Bitv, BitvSet};
 pub use btree::BTree;
-pub use deque::Deque;
 pub use dlist::DList;
 pub use enum_set::EnumSet;
 pub use priority_queue::PriorityQueue;
@@ -47,7 +59,6 @@
 
 pub mod bitv;
 pub mod btree;
-pub mod deque;
 pub mod dlist;
 pub mod enum_set;
 pub mod priority_queue;
 // Internal unicode fiddly bits for the str module
 mod unicode;
 
-// FIXME(#14008) should this actually exist, or should a method be added?
-fn expect<T>(a: core::option::Option<T>, b: &str) -> T {
-    match a {
-        core::option::Some(a) => a,
-        core::option::None => fail!("{}", b),
+mod deque;
+
+/// A trait to represent mutable containers
+pub trait Mutable: Collection {
+    /// Clear the container, removing all values.
+    fn clear(&mut self);
+}
+
+/// A map is a key-value store where values may be looked up by their keys. This
+/// trait provides basic operations to operate on these stores.
+pub trait Map<K, V>: Collection {
+    /// Return a reference to the value corresponding to the key
+    fn find<'a>(&'a self, key: &K) -> Option<&'a V>;
+
+    /// Return true if the map contains a value for the specified key
+    #[inline]
+    fn contains_key(&self, key: &K) -> bool {
+        self.find(key).is_some()
+    }
+}
+
+/// This trait provides basic operations to modify the contents of a map.
+pub trait MutableMap<K, V>: Map<K, V> + Mutable {
+    /// Insert a key-value pair into the map. An existing value for a
+    /// key is replaced by the new value. Return true if the key did
+    /// not already exist in the map.
+    #[inline]
+    fn insert(&mut self, key: K, value: V) -> bool {
+        self.swap(key, value).is_none()
     }
+
+    /// Remove a key-value pair from the map. Return true if the key
+    /// was present in the map, otherwise false.
+    #[inline]
+    fn remove(&mut self, key: &K) -> bool {
+        self.pop(key).is_some()
+    }
+
+    /// Insert a key-value pair from the map. If the key already had a value
+    /// present in the map, that value is returned. Otherwise None is returned.
+    fn swap(&mut self, k: K, v: V) -> Option<V>;
+
+    /// Removes a key from the map, returning the value at the key if the key
+    /// was previously in the map.
+    fn pop(&mut self, k: &K) -> Option<V>;
+
+    /// Return a mutable reference to the value corresponding to the key
+    fn find_mut<'a>(&'a mut self, key: &K) -> Option<&'a mut V>;
+}
+
+/// A set is a group of objects which are each distinct from one another. This
+/// trait represents actions which can be performed on sets to iterate over
+/// them.
+pub trait Set<T>: Collection {
+    /// Return true if the set contains a value
+    fn contains(&self, value: &T) -> bool;
+
+    /// Return true if the set has no elements in common with `other`.
+    /// This is equivalent to checking for an empty intersection.
+    fn is_disjoint(&self, other: &Self) -> bool;
+
+    /// Return true if the set is a subset of another
+    fn is_subset(&self, other: &Self) -> bool;
+
+    /// Return true if the set is a superset of another
+    fn is_superset(&self, other: &Self) -> bool {
+        other.is_subset(self)
+    }
+
+    // FIXME #8154: Add difference, sym. difference, intersection and union iterators
+}
+
+/// This trait represents actions which can be performed on sets to mutate
+/// them.
+pub trait MutableSet<T>: Set<T> + Mutable {
+    /// Add a value to the set. Return true if the value was not already
+    /// present in the set.
+    fn insert(&mut self, value: T) -> bool;
+
+    /// Remove a value from the set. Return true if the value was
+    /// present in the set.
+    fn remove(&mut self, value: &T) -> bool;
+}
+
+/// A double-ended sequence that allows querying, insertion and deletion at both
+/// ends.
+pub trait Deque<T> : Mutable {
+    /// Provide a reference to the front element, or None if the sequence is
+    /// empty
+    fn front<'a>(&'a self) -> Option<&'a T>;
+
+    /// Provide a mutable reference to the front element, or None if the
+    /// sequence is empty
+    fn front_mut<'a>(&'a mut self) -> Option<&'a mut T>;
+
+    /// Provide a reference to the back element, or None if the sequence is
+    /// empty
+    fn back<'a>(&'a self) -> Option<&'a T>;
+
+    /// Provide a mutable reference to the back element, or None if the sequence
+    /// is empty
+    fn back_mut<'a>(&'a mut self) -> Option<&'a mut T>;
+
+    /// Insert an element first in the sequence
+    fn push_front(&mut self, elt: T);
+
+    /// Insert an element last in the sequence
+    fn push_back(&mut self, elt: T);
+
+    /// Remove the last element and return it, or None if the sequence is empty
+    fn pop_back(&mut self) -> Option<T>;
+
+    /// Remove the first element and return it, or None if the sequence is empty
+    fn pop_front(&mut self) -> Option<T>;
 }
 
 // FIXME(#14344) this shouldn't be necessary
index 34d6bbbb66567d93ba9f69258ac3d4196b4aa5e5..f25864933f2eba691de2dddcb257aeeb11430c48 100644 (file)
 
 use core::prelude::*;
 
+use core::default::Default;
 use core::mem::{zeroed, replace, swap};
 use core::ptr;
 
+use {Collection, Mutable};
 use slice;
 use vec::Vec;
 
@@ -26,7 +28,7 @@ pub struct PriorityQueue<T> {
     data: Vec<T>,
 }
 
-impl<T: Ord> Container for PriorityQueue<T> {
+impl<T: Ord> Collection for PriorityQueue<T> {
     /// Returns the length of the queue
     fn len(&self) -> uint { self.data.len() }
 }
@@ -36,6 +38,11 @@ impl<T: Ord> Mutable for PriorityQueue<T> {
     fn clear(&mut self) { self.data.truncate(0) }
 }
 
+impl<T: Ord> Default for PriorityQueue<T> {
+    #[inline]
+    fn default() -> PriorityQueue<T> { PriorityQueue::new() }
+}
+
 impl<T: Ord> PriorityQueue<T> {
     /// An iterator visiting all values in underlying vector, in
     /// arbitrary order.
index ce4195789fab6a24060acb2aef6cae6910c45da1..ae1925126cae7055f8ef8b2cc0bb8fd395705ed8 100644 (file)
 //! A double-ended queue implemented as a circular buffer
 //!
 //! RingBuf implements the trait Deque. It should be imported with `use
-//! collections::deque::Deque`.
+//! collections::Deque`.
 
 use core::prelude::*;
 
 use core::cmp;
+use core::default::Default;
 use core::fmt;
 use core::iter::RandomAccessIterator;
 
-use deque::Deque;
+use {Deque, Collection, Mutable};
 use vec::Vec;
 
 static INITIAL_CAPACITY: uint = 8u; // 2^3
@@ -33,7 +34,7 @@ pub struct RingBuf<T> {
     elts: Vec<Option<T>>
 }
 
-impl<T> Container for RingBuf<T> {
+impl<T> Collection for RingBuf<T> {
     /// Return the number of elements in the RingBuf
     fn len(&self) -> uint { self.nelts }
 }
@@ -112,6 +113,11 @@ fn push_back(&mut self, t: T) {
     }
 }
 
+impl<T> Default for RingBuf<T> {
+    #[inline]
+    fn default() -> RingBuf<T> { RingBuf::new() }
+}
+
 impl<T> RingBuf<T> {
     /// Create an empty RingBuf
     pub fn new() -> RingBuf<T> {
@@ -415,7 +421,7 @@ mod tests {
     use test::Bencher;
     use test;
 
-    use deque::Deque;
+    use {Deque, Mutable};
     use super::RingBuf;
     use vec::Vec;
 
index 4798218e3ff25dbc9653882f2d64c51c38799b18..1bc563686933e5efa23a23d4407ad8b8c878f55c 100644 (file)
 use core::mem;
 use core::ptr;
 use core::iter::{range_step, MultiplicativeIterator};
+
+use Collection;
 use vec::Vec;
 
 pub use core::slice::{ref_slice, mut_ref_slice, Splits, Windows};
@@ -296,9 +298,9 @@ fn to_owned(&self) -> ~[T] {
 
         let len = self.len();
         let data_size = len.checked_mul(&mem::size_of::<T>());
-        let data_size = ::expect(data_size, "overflow in to_owned()");
+        let data_size = data_size.expect("overflow in to_owned()");
         let size = mem::size_of::<RawVec<()>>().checked_add(&data_size);
-        let size = ::expect(size, "overflow in to_owned()");
+        let size = size.expect("overflow in to_owned()");
 
         unsafe {
             // this should pass the real required alignment
@@ -865,6 +867,7 @@ mod tests {
     use std::rt;
     use slice::*;
 
+    use Mutable;
     use vec::Vec;
 
     fn square(n: uint) -> uint { n * n }
index 45584dd4b28ba4eccda480616bd855e23cbc1bcb..6b4982de0821699816e94a85214d2e87681d54cf 100644 (file)
 
 use core::prelude::*;
 
+use core::default::Default;
 use core::fmt;
 use core::iter::{Enumerate, FilterMap};
 use core::mem::replace;
 
+use {Collection, Mutable, Map, MutableMap};
 use {vec, slice};
 use vec::Vec;
 
@@ -29,7 +31,7 @@ pub struct SmallIntMap<T> {
     v: Vec<Option<T>>,
 }
 
-impl<V> Container for SmallIntMap<V> {
+impl<V> Collection for SmallIntMap<V> {
     /// Return the number of elements in the map
     fn len(&self) -> uint {
         self.v.iter().filter(|elt| elt.is_some()).count()
@@ -113,6 +115,11 @@ fn pop(&mut self, key: &uint) -> Option<V> {
     }
 }
 
+impl<V> Default for SmallIntMap<V> {
+    #[inline]
+    fn default() -> SmallIntMap<V> { SmallIntMap::new() }
+}
+
 impl<V> SmallIntMap<V> {
     /// Create an empty SmallIntMap
     pub fn new() -> SmallIntMap<V> { SmallIntMap{v: vec!()} }
@@ -123,7 +130,7 @@ pub fn with_capacity(capacity: uint) -> SmallIntMap<V> {
     }
 
     pub fn get<'a>(&'a self, key: &uint) -> &'a V {
-        ::expect(self.find(key), "key not present")
+        self.find(key).expect("key not present")
     }
 
     /// An iterator visiting all key-value pairs in ascending order by the keys.
@@ -264,6 +271,7 @@ pub struct MutEntries<'a, T> {
 mod test_map {
     use std::prelude::*;
 
+    use {Map, MutableMap, Mutable};
     use super::SmallIntMap;
 
     #[test]
index 5fd133b450f7610717d4b7eee023daae0808bb52..49d8775dd9cb649a97570ac2416828c7779b7e7d 100644 (file)
@@ -76,6 +76,7 @@ fn main() {
 use core::iter::AdditiveIterator;
 use core::mem;
 
+use Collection;
 use hash;
 use string::String;
 use vec::Vec;
@@ -610,7 +611,7 @@ fn into_string(self) -> String {
     }
 }
 
-impl<'a> Container for MaybeOwned<'a> {
+impl<'a> Collection for MaybeOwned<'a> {
     #[inline]
     fn len(&self) -> uint { self.as_slice().len() }
 }
@@ -2036,7 +2037,7 @@ fn t<S: Default + Str>() {
 
     #[test]
     fn test_str_container() {
-        fn sum_len<S: Container>(v: &[S]) -> uint {
+        fn sum_len<S: Collection>(v: &[S]) -> uint {
             v.iter().map(|x| x.len()).sum()
         }
 
index bd39c74aa840b97c4cb74907c8be13e404c06cf5..76f53c9b257493216ef5ee9e715ac845fd0560de 100644 (file)
@@ -18,6 +18,7 @@
 use core::ptr;
 use core::raw::Slice;
 
+use {Collection, Mutable};
 use hash;
 use str;
 use str::{CharRange, StrAllocating};
@@ -279,7 +280,7 @@ pub unsafe fn as_mut_vec<'a>(&'a mut self) -> &'a mut Vec<u8> {
     }
 }
 
-impl Container for String {
+impl Collection for String {
     #[inline]
     fn len(&self) -> uint {
         self.vec.len()
@@ -356,6 +357,7 @@ mod tests {
     use std::prelude::*;
     use test::Bencher;
 
+    use Mutable;
     use str::{Str, StrSlice};
     use super::String;
 
index def1c353bc1324e3ea41100f96e9f96b0e7f7b0b..1f4ee52008cdc56833056a95fe6288dadb0f8e3c 100644 (file)
@@ -15,6 +15,7 @@
 use core::prelude::*;
 
 use alloc::owned::Box;
+use core::default::Default;
 use core::fmt;
 use core::fmt::Show;
 use core::iter::Peekable;
@@ -22,6 +23,7 @@
 use core::mem::{replace, swap};
 use core::ptr;
 
+use {Collection, Mutable, Set, MutableSet, MutableMap, Map};
 use vec::Vec;
 
 // This is implemented as an AA tree, which is a simplified variation of
@@ -86,7 +88,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
-impl<K: Ord, V> Container for TreeMap<K, V> {
+impl<K: Ord, V> Collection for TreeMap<K, V> {
     fn len(&self) -> uint { self.length }
 }
 
@@ -134,6 +136,11 @@ fn pop(&mut self, key: &K) -> Option<V> {
     }
 }
 
+impl<K: Ord, V> Default for TreeMap<K,V> {
+    #[inline]
+    fn default() -> TreeMap<K, V> { TreeMap::new() }
+}
+
 impl<K: Ord, V> TreeMap<K, V> {
     /// Create an empty TreeMap
     pub fn new() -> TreeMap<K, V> { TreeMap{root: None, length: 0} }
@@ -579,7 +586,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
-impl<T: Ord> Container for TreeSet<T> {
+impl<T: Ord> Collection for TreeSet<T> {
     #[inline]
     fn len(&self) -> uint { self.map.len() }
 }
@@ -632,6 +639,11 @@ fn insert(&mut self, value: T) -> bool { self.map.insert(value, ()) }
     fn remove(&mut self, value: &T) -> bool { self.map.remove(value) }
 }
 
+impl<T: Ord> Default for TreeSet<T> {
+    #[inline]
+    fn default() -> TreeSet<T> { TreeSet::new() }
+}
+
 impl<T: Ord> TreeSet<T> {
     /// Create an empty TreeSet
     #[inline]
@@ -1006,6 +1018,7 @@ mod test_treemap {
     use std::rand::Rng;
     use std::rand;
 
+    use {Map, MutableMap, Mutable};
     use super::{TreeMap, TreeNode};
 
     #[test]
@@ -1437,7 +1450,6 @@ fn test_from_iter() {
 
 #[cfg(test)]
 mod bench {
-    use std::prelude::*;
     use test::Bencher;
 
     use super::TreeMap;
@@ -1500,6 +1512,7 @@ pub fn find_seq_10_000(b: &mut Bencher) {
 mod test_set {
     use std::prelude::*;
 
+    use {Set, MutableSet, Mutable, MutableMap};
     use super::{TreeMap, TreeSet};
 
     #[test]
index c15a6e9e5bf48fae118e367c551d05a9e44796ea..3f4fdd66b802accf5b46a9ed5036783a66d5a100 100644 (file)
 use core::prelude::*;
 
 use alloc::owned::Box;
+use core::default::Default;
 use core::mem::zeroed;
 use core::mem;
 use core::uint;
 
+use {Collection, Mutable, Map, MutableMap, Set, MutableSet};
 use slice::{Items, MutItems};
 use slice;
 
@@ -38,7 +40,7 @@ pub struct TrieMap<T> {
     length: uint
 }
 
-impl<T> Container for TrieMap<T> {
+impl<T> Collection for TrieMap<T> {
     /// Return the number of elements in the map
     #[inline]
     fn len(&self) -> uint { self.length }
@@ -104,6 +106,11 @@ fn pop(&mut self, key: &uint) -> Option<T> {
     }
 }
 
+impl<T> Default for TrieMap<T> {
+    #[inline]
+    fn default() -> TrieMap<T> { TrieMap::new() }
+}
+
 impl<T> TrieMap<T> {
     /// Create an empty TrieMap
     #[inline]
@@ -285,7 +292,7 @@ pub struct TrieSet {
     map: TrieMap<()>
 }
 
-impl Container for TrieSet {
+impl Collection for TrieSet {
     /// Return the number of elements in the set
     #[inline]
     fn len(&self) -> uint { self.map.len() }
@@ -331,6 +338,11 @@ fn remove(&mut self, value: &uint) -> bool {
     }
 }
 
+impl Default for TrieSet {
+    #[inline]
+    fn default() -> TrieSet { TrieSet::new() }
+}
+
 impl TrieSet {
     /// Create an empty TrieSet
     #[inline]
@@ -645,6 +657,7 @@ mod test_map {
     use std::iter::range_step;
     use std::uint;
 
+    use {MutableMap, Map};
     use super::{TrieMap, TrieNode, Internal, External, Nothing};
 
     fn check_integrity<T>(trie: &TrieNode<T>) {
@@ -923,6 +936,7 @@ mod bench_map {
     use std::rand::{weak_rng, Rng};
     use test::Bencher;
 
+    use MutableMap;
     use super::TrieMap;
 
     #[bench]
@@ -1031,6 +1045,7 @@ mod test_set {
     use std::prelude::*;
     use std::uint;
 
+    use {MutableSet, Set};
     use super::TrieSet;
 
     #[test]
index 6ca21262f51cc8754bdcc6fb7120577377edf9fc..dbef73efc479462b1539acf7ed8d47eb305648c8 100644 (file)
@@ -24,6 +24,7 @@
 use core::ptr;
 use core::uint;
 
+use {Collection, Mutable};
 use slice::{MutableOrdVector, OwnedVector, MutableVectorAllocating};
 use slice::{Items, MutItems};
 
@@ -91,8 +92,8 @@ pub fn with_capacity(capacity: uint) -> Vec<T> {
         } else if capacity == 0 {
             Vec::new()
         } else {
-            let size = ::expect(capacity.checked_mul(&mem::size_of::<T>()),
-                                "capacity overflow");
+            let size = capacity.checked_mul(&mem::size_of::<T>())
+                               .expect("capacity overflow");
             let ptr = unsafe { allocate(size, mem::min_align_of::<T>()) };
             Vec { len: 0, cap: capacity, ptr: ptr as *mut T }
         }
@@ -393,7 +394,7 @@ fn cmp(&self, other: &Vec<T>) -> Ordering {
     }
 }
 
-impl<T> Container for Vec<T> {
+impl<T> Collection for Vec<T> {
     #[inline]
     fn len(&self) -> uint {
         self.len
@@ -499,8 +500,8 @@ pub fn reserve_exact(&mut self, capacity: uint) {
         if mem::size_of::<T>() == 0 { return }
 
         if capacity > self.cap {
-            let size = ::expect(capacity.checked_mul(&mem::size_of::<T>()),
-                                "capacity overflow");
+            let size = capacity.checked_mul(&mem::size_of::<T>())
+                               .expect("capacity overflow");
             unsafe {
                 self.ptr = alloc_or_realloc(self.ptr, size,
                                             self.cap * mem::size_of::<T>());
@@ -579,7 +580,7 @@ pub fn pop(&mut self) -> Option<T> {
     pub fn push(&mut self, value: T) {
         if mem::size_of::<T>() == 0 {
             // zero-size types consume no memory, so we can't rely on the address space running out
-            self.len = ::expect(self.len.checked_add(&1), "length overflow");
+            self.len = self.len.checked_add(&1).expect("length overflow");
             unsafe { mem::forget(value); }
             return
         }
@@ -1526,13 +1527,13 @@ impl<T> FromVec<T> for ~[T] {
     fn from_vec(mut v: Vec<T>) -> ~[T] {
         let len = v.len();
         let data_size = len.checked_mul(&mem::size_of::<T>());
-        let data_size = ::expect(data_size, "overflow in from_vec()");
+        let data_size = data_size.expect("overflow in from_vec()");
         let size = mem::size_of::<RawVec<()>>().checked_add(&data_size);
-        let size = ::expect(size, "overflow in from_vec()");
+        let size = size.expect("overflow in from_vec()");
 
         // In a post-DST world, we can attempt to reuse the Vec allocation by calling
         // shrink_to_fit() on it. That may involve a reallocation+memcpy, but that's no
-        // diffrent than what we're doing manually here.
+        // different than what we're doing manually here.
 
         let vp = v.as_mut_ptr();
 
diff --git a/src/libcore/collections.rs b/src/libcore/collections.rs
new file mode 100644 (file)
index 0000000..0bb9289
--- /dev/null
@@ -0,0 +1,24 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <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.
+
+//! Traits for generic collections
+
+/// A trait to represent the abstract idea of a container. The only concrete
+/// knowledge known is the number of elements contained within.
+pub trait Collection {
+    /// Return the number of elements in the container
+    fn len(&self) -> uint;
+
+    /// Return true if the container contains no elements
+    #[inline]
+    fn is_empty(&self) -> bool {
+        self.len() == 0
+    }
+}
diff --git a/src/libcore/container.rs b/src/libcore/container.rs
deleted file mode 100644 (file)
index e8ee379..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <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.
-
-//! Traits for generic containers (including `Map` and `Set`)
-
-use option::Option;
-
-/// A trait to represent the abstract idea of a container. The only concrete
-/// knowledge known is the number of elements contained within.
-pub trait Container {
-    /// Return the number of elements in the container
-    fn len(&self) -> uint;
-
-    /// Return true if the container contains no elements
-    #[inline]
-    fn is_empty(&self) -> bool {
-        self.len() == 0
-    }
-}
-
-/// A trait to represent mutable containers
-pub trait Mutable: Container {
-    /// Clear the container, removing all values.
-    fn clear(&mut self);
-}
-
-/// A map is a key-value store where values may be looked up by their keys. This
-/// trait provides basic operations to operate on these stores.
-pub trait Map<K, V>: Container {
-    /// Return a reference to the value corresponding to the key
-    fn find<'a>(&'a self, key: &K) -> Option<&'a V>;
-
-    /// Return true if the map contains a value for the specified key
-    #[inline]
-    fn contains_key(&self, key: &K) -> bool {
-        self.find(key).is_some()
-    }
-}
-
-/// This trait provides basic operations to modify the contents of a map.
-pub trait MutableMap<K, V>: Map<K, V> + Mutable {
-    /// Insert a key-value pair into the map. An existing value for a
-    /// key is replaced by the new value. Return true if the key did
-    /// not already exist in the map.
-    #[inline]
-    fn insert(&mut self, key: K, value: V) -> bool {
-        self.swap(key, value).is_none()
-    }
-
-    /// Remove a key-value pair from the map. Return true if the key
-    /// was present in the map, otherwise false.
-    #[inline]
-    fn remove(&mut self, key: &K) -> bool {
-        self.pop(key).is_some()
-    }
-
-    /// Insert a key-value pair from the map. If the key already had a value
-    /// present in the map, that value is returned. Otherwise None is returned.
-    fn swap(&mut self, k: K, v: V) -> Option<V>;
-
-    /// Removes a key from the map, returning the value at the key if the key
-    /// was previously in the map.
-    fn pop(&mut self, k: &K) -> Option<V>;
-
-    /// Return a mutable reference to the value corresponding to the key
-    fn find_mut<'a>(&'a mut self, key: &K) -> Option<&'a mut V>;
-}
-
-/// A set is a group of objects which are each distinct from one another. This
-/// trait represents actions which can be performed on sets to iterate over
-/// them.
-pub trait Set<T>: Container {
-    /// Return true if the set contains a value
-    fn contains(&self, value: &T) -> bool;
-
-    /// Return true if the set has no elements in common with `other`.
-    /// This is equivalent to checking for an empty intersection.
-    fn is_disjoint(&self, other: &Self) -> bool;
-
-    /// Return true if the set is a subset of another
-    fn is_subset(&self, other: &Self) -> bool;
-
-    /// Return true if the set is a superset of another
-    fn is_superset(&self, other: &Self) -> bool {
-        other.is_subset(self)
-    }
-
-    // FIXME #8154: Add difference, sym. difference, intersection and union iterators
-}
-
-/// This trait represents actions which can be performed on sets to mutate
-/// them.
-pub trait MutableSet<T>: Set<T> + Mutable {
-    /// Add a value to the set. Return true if the value was not already
-    /// present in the set.
-    fn insert(&mut self, value: T) -> bool;
-
-    /// Remove a value from the set. Return true if the value was
-    /// present in the set.
-    fn remove(&mut self, value: &T) -> bool;
-}
index e5fb148aded341b64fa5db72d5faa8ecfa1dd69e..f326195be1607f270e6283c4a0830b6c9816b563 100644 (file)
@@ -11,7 +11,7 @@
 #![allow(missing_doc)]
 
 use char;
-use container::Container;
+use collections::Collection;
 use fmt;
 use iter::{Iterator, range, DoubleEndedIterator};
 use num::{Float, FPNaN, FPInfinite, ToPrimitive, Primitive};
index 2cce68d5f60f2c33198b153fbbfeff78f425eeef..37ef325d937e23d789d968c34fc2f06fdf7872fb 100644 (file)
@@ -15,7 +15,7 @@
 use any;
 use cell::Cell;
 use char::Char;
-use container::Container;
+use collections::Collection;
 use iter::{Iterator, range};
 use kinds::Copy;
 use mem;
index 890733dc229afccb033c5759aaed1e8fc290a518..f36acf344e4cfe71adb2bc5c7c59f0a5563345f2 100644 (file)
@@ -14,7 +14,7 @@
 
 #![allow(unsigned_negate)]
 
-use container::Container;
+use collections::Collection;
 use fmt;
 use iter::{Iterator, DoubleEndedIterator};
 use num::{Int, cast, zero};
index 2ccf431fc22e138fe1161601eeb8e6cbc7187bdd..5661c6683739b58ffb7b80c7d0a8218265dc7a1e 100644 (file)
 #[cfg(not(test))] pub mod cmp;
 pub mod clone;
 pub mod default;
-pub mod container;
+pub mod collections;
 
 /* Core types and methods on primitives */
 
index 08e033f961f45d3583aa59d5f299641b4f6e48fd..af1df973a3e655c2fc61da948e7a48ccc3b5410c 100644 (file)
@@ -726,6 +726,27 @@ pub trait DerefMut<Result>: Deref<Result> {
     fn deref_mut<'a>(&'a mut self) -> &'a mut Result;
 }
 
+/// A version of the call operator that takes an immutable receiver.
+#[lang="fn"]
+pub trait Fn<Args,Result> {
+    /// This is called when the call operator is used.
+    fn call(&self, args: Args) -> Result;
+}
+
+/// A version of the call operator that takes a mutable receiver.
+#[lang="fn_mut"]
+pub trait FnMut<Args,Result> {
+    /// This is called when the call operator is used.
+    fn call_mut(&mut self, args: Args) -> Result;
+}
+
+/// A version of the call operator that takes a by-value receiver.
+#[lang="fn_once"]
+pub trait FnOnce<Args,Result> {
+    /// This is called when the call operator is used.
+    fn call_once(self, args: Args) -> Result;
+}
+
 #[cfg(test)]
 mod bench {
     extern crate test;
index a6a8319ca02a5b2c965b2d480df7f7bb048516bd..df9c0e67b0d6d3ab1176df298b39aacffd3db9d4 100644 (file)
@@ -47,7 +47,7 @@
 pub use clone::Clone;
 pub use cmp::{PartialEq, PartialOrd, Eq, Ord};
 pub use cmp::{Ordering, Less, Equal, Greater, Equiv};
-pub use container::{Container, Mutable, Map, MutableMap, Set, MutableSet};
+pub use collections::Collection;
 pub use iter::{FromIterator, Extendable};
 pub use iter::{Iterator, DoubleEndedIterator, RandomAccessIterator, CloneableIterator};
 pub use iter::{OrdIterator, MutableDoubleEndedIterator, ExactSize};
index 2c6f2978aa735727b4beb6a4d271ba4a3ce832b2..ed6b73df38d4d42ebb25feaac70186b6a316d2ca 100644 (file)
@@ -25,7 +25,7 @@
 // Currently, no progress has been made on this list.
 
 use clone::Clone;
-use container::Container;
+use collections::Collection;
 use finally::try_finally;
 use intrinsics;
 use iter::{range, Iterator};
index 99b802f9918f10e8c8528f9093e8cc9e64bbe65e..54e7d077bb141cb63fc1ef92cbdecee60fe209b6 100644 (file)
@@ -31,7 +31,7 @@
 //!
 //! ## Stability Note
 //!
-//! These are all experimental. The inferface may change entirely, without
+//! These are all experimental. The interface may change entirely, without
 //! warning.
 
 #![allow(non_camel_case_types)]
index 4dea1fd75a4bf16b5923bfa6295c3ea57da661ee..585373ec70ca560cea9de2e4b4d2b953a8ca29b4 100644 (file)
@@ -16,7 +16,7 @@
 
 use mem::transmute;
 use clone::Clone;
-use container::Container;
+use collections::Collection;
 use cmp::{PartialEq, Ord, Ordering, Less, Equal, Greater};
 use cmp;
 use default::Default;
@@ -253,7 +253,7 @@ pub mod traits {
 
     use cmp::{PartialEq, PartialOrd, Eq, Ord, Ordering, Equiv};
     use iter::order;
-    use container::Container;
+    use collections::Collection;
 
     impl<'a,T:PartialEq> PartialEq for &'a [T] {
         fn eq(&self, other: & &'a [T]) -> bool {
@@ -347,7 +347,7 @@ impl<T> Vector<T> for ~[T] {
     fn as_slice<'a>(&'a self) -> &'a [T] { let v: &'a [T] = *self; v }
 }
 
-impl<'a, T> Container for &'a [T] {
+impl<'a, T> Collection for &'a [T] {
     /// Returns the length of a vector
     #[inline]
     fn len(&self) -> uint {
@@ -355,7 +355,7 @@ fn len(&self) -> uint {
     }
 }
 
-impl<T> Container for ~[T] {
+impl<T> Collection for ~[T] {
     /// Returns the length of a vector
     #[inline]
     fn len(&self) -> uint {
@@ -1205,7 +1205,7 @@ pub unsafe fn pop_ptr<T>(slice: &mut Slice<T>) -> Option<*T> {
 
 /// Operations on `[u8]`.
 pub mod bytes {
-    use container::Container;
+    use collections::Collection;
     use ptr;
     use slice::MutableVector;
 
index 936b698d4b10a771f5f6ed22190025e4862d9d25..c01997f1c42c75e48491d658d00baab15ea84c80 100644 (file)
@@ -19,7 +19,7 @@
 use clone::Clone;
 use cmp;
 use cmp::{PartialEq, Eq};
-use container::Container;
+use collections::Collection;
 use default::Default;
 use iter::{Filter, Map, Iterator};
 use iter::{DoubleEndedIterator, ExactSize};
@@ -478,7 +478,7 @@ fn maximal_suffix(arr: &[u8], reversed: bool) -> (uint, uint) {
 }
 
 /// The internal state of an iterator that searches for matches of a substring
-/// within a larger string using a dynamically chosed search algorithm
+/// within a larger string using a dynamically chosen search algorithm
 #[deriving(Clone)]
 enum Searcher {
     Naive(NaiveSearcher),
@@ -866,7 +866,7 @@ macro_rules! utf8_acc_cont_byte(
 /// Unsafe operations
 pub mod raw {
     use mem;
-    use container::Container;
+    use collections::Collection;
     use ptr::RawPtr;
     use raw::Slice;
     use slice::{ImmutableVector};
@@ -930,8 +930,8 @@ pub unsafe fn slice_unchecked<'a>(s: &'a str, begin: uint, end: uint) -> &'a str
 #[cfg(not(test))]
 #[allow(missing_doc)]
 pub mod traits {
-    use container::Container;
     use cmp::{Ord, Ordering, Less, Equal, Greater, PartialEq, PartialOrd, Equiv, Eq};
+    use collections::Collection;
     use iter::Iterator;
     use option::{Some, None};
     use str::{Str, StrSlice, eq_slice};
@@ -987,7 +987,7 @@ impl<'a> Str for &'a str {
     fn as_slice<'a>(&'a self) -> &'a str { *self }
 }
 
-impl<'a> Container for &'a str {
+impl<'a> Collection for &'a str {
     #[inline]
     fn len(&self) -> uint {
         self.repr().len
@@ -1120,7 +1120,7 @@ pub trait StrSlice<'a> {
     ///
     /// That is, each returned value `(start, end)` satisfies
     /// `self.slice(start, end) == sep`. For matches of `sep` within
-    /// `self` that overlap, only the indicies corresponding to the
+    /// `self` that overlap, only the indices corresponding to the
     /// first match are returned.
     ///
     /// # Example
index 8bfd2d867c130ad749497202ef0d56b40b62d1c4..8d8fe8ffe8cfe404c10aa577d9cd0f4207bc3cc3 100644 (file)
@@ -28,7 +28,8 @@
 #![feature(phase)]
 #![deny(deprecated_owned_vector)]
 
-#[cfg(test)] #[phase(syntax, link)] extern crate log;
+#[cfg(test, stage0)] #[phase(syntax, link)] extern crate log;
+#[cfg(test, not(stage0))] #[phase(plugin, link)] extern crate log;
 
 extern crate libc;
 
index 194de7b2f4aee5a944950a6ae0a3daa411f5a56f..694fe7d0f48b08fa3e3fb9097f443c67e2379b50 100644 (file)
@@ -22,7 +22,7 @@
 To load the extension and use it:
 
 ```rust,ignore
-#[phase(syntax)]
+#[phase(plugin)]
 extern crate fourcc;
 
 fn main() {
@@ -48,29 +48,25 @@ fn main() {
        html_root_url = "http://doc.rust-lang.org/")]
 
 #![deny(deprecated_owned_vector)]
-#![feature(macro_registrar, managed_boxes)]
+#![feature(plugin_registrar, managed_boxes)]
 
 extern crate syntax;
+extern crate rustc;
 
 use syntax::ast;
-use syntax::ast::Name;
 use syntax::attr::contains;
 use syntax::codemap::{Span, mk_sp};
 use syntax::ext::base;
-use syntax::ext::base::{SyntaxExtension, BasicMacroExpander, NormalTT, ExtCtxt, MacExpr};
+use syntax::ext::base::{ExtCtxt, MacExpr};
 use syntax::ext::build::AstBuilder;
 use syntax::parse;
 use syntax::parse::token;
 use syntax::parse::token::InternedString;
+use rustc::plugin::Registry;
 
-#[macro_registrar]
-pub fn macro_registrar(register: |Name, SyntaxExtension|) {
-    register(token::intern("fourcc"),
-        NormalTT(box BasicMacroExpander {
-            expander: expand_syntax_ext,
-            span: None,
-        },
-        None));
+#[plugin_registrar]
+pub fn plugin_registrar(reg: &mut Registry) {
+    reg.register_macro("fourcc", expand_syntax_ext);
 }
 
 pub fn expand_syntax_ext(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
index 10584223486c00a8dd9a495104727817d5383dc3..dec62265516fdb5da21e4285641a8b105300b9e8 100644 (file)
@@ -91,7 +91,8 @@
 #![deny(deprecated_owned_vector)]
 
 #[cfg(test)] extern crate debug;
-#[cfg(test)] #[phase(syntax, link)] extern crate log;
+#[cfg(test, stage0)] #[phase(syntax, link)] extern crate log;
+#[cfg(test, not(stage0))] #[phase(plugin, link)] extern crate log;
 
 use std::cmp::PartialEq;
 use std::result::{Err, Ok};
index f3e1da77ce5c773e05801b8e7cf436350343d8a5..6d39a332ad9bd5a3549c7475a9dafa4d0aeb64b8 100644 (file)
@@ -44,7 +44,6 @@
  * pattern - see the `glob` function for more details.
  */
 pub struct Paths {
-    root: Path,
     dir_patterns: Vec<Pattern>,
     require_dir: bool,
     options: MatchOptions,
@@ -108,7 +107,6 @@ fn check_windows_verbatim(_: &Path) -> bool { false }
             // FIXME: How do we want to handle verbatim paths? I'm inclined to return nothing,
             // since we can't very well find all UNC shares with a 1-letter server name.
             return Paths {
-                root: root,
                 dir_patterns: Vec::new(),
                 require_dir: false,
                 options: options,
@@ -134,7 +132,6 @@ fn check_windows_verbatim(_: &Path) -> bool { false }
     }
 
     Paths {
-        root: root,
         dir_patterns: dir_patterns,
         require_dir: require_dir,
         options: options,
index 5b1a4a8b80ec0e2394b665390584a9ab9c56740c..e377c203e30737cffaa306dd168701bca0bcd89a 100644 (file)
@@ -143,6 +143,7 @@ pub fn swap(out_context: &mut Context, in_context: &Context) {
 // stacks are disabled.
 
 #[cfg(target_arch = "x86")]
+#[repr(C)]
 struct Registers {
     eax: u32, ebx: u32, ecx: u32, edx: u32,
     ebp: u32, esi: u32, edi: u32, esp: u32,
index 333ac80907f6a9012a2ea6e5040674e0fddc4983..9748dfbae33f0dc8f744797f43e695cea15f4068 100644 (file)
 //!
 //! ```
 //! #![feature(phase)]
-//! #[phase(syntax)] extern crate green;
+//! #[phase(plugin)] extern crate green;
 //!
 //! green_start!(main)
 //!
 #![allow(visible_private_types)]
 #![deny(deprecated_owned_vector)]
 
-#[cfg(test)] #[phase(syntax, link)] extern crate log;
+#[cfg(test)] #[phase(plugin, link)] extern crate log;
 #[cfg(test)] extern crate rustuv;
 extern crate libc;
 extern crate alloc;
 ///
 /// ```
 /// #![feature(phase)]
-/// #[phase(syntax)] extern crate green;
+/// #[phase(plugin)] extern crate green;
 ///
 /// green_start!(main)
 ///
index ee14f1aaea9a2a97fd0b2d28eb8dbc56cf2bd291..54bc2802b09ac364cb92ab2b6f42d3dcc44abf62 100644 (file)
@@ -21,7 +21,7 @@
 To load the extension and use it:
 
 ```rust,ignore
-#[phase(syntax)]
+#[phase(plugin)]
 extern crate hexfloat;
 
 fn main() {
@@ -45,27 +45,23 @@ fn main() {
        html_root_url = "http://doc.rust-lang.org/")]
 
 #![deny(deprecated_owned_vector)]
-#![feature(macro_registrar, managed_boxes)]
+#![feature(plugin_registrar, managed_boxes)]
 
 extern crate syntax;
+extern crate rustc;
 
 use syntax::ast;
-use syntax::ast::Name;
 use syntax::codemap::{Span, mk_sp};
 use syntax::ext::base;
-use syntax::ext::base::{SyntaxExtension, BasicMacroExpander, NormalTT, ExtCtxt, MacExpr};
+use syntax::ext::base::{ExtCtxt, MacExpr};
 use syntax::ext::build::AstBuilder;
 use syntax::parse;
 use syntax::parse::token;
+use rustc::plugin::Registry;
 
-#[macro_registrar]
-pub fn macro_registrar(register: |Name, SyntaxExtension|) {
-    register(token::intern("hexfloat"),
-        NormalTT(box BasicMacroExpander {
-            expander: expand_syntax_ext,
-            span: None,
-        },
-        None));
+#[plugin_registrar]
+pub fn plugin_registrar(reg: &mut Registry) {
+    reg.register_macro("hexfloat", expand_syntax_ext);
 }
 
 //Check if the literal is valid (as LLVM expects),
index daacf8b3c47610ff6294905ce7cbce2256eb83f1..254f9aaf55e4399a9ff06816d6e512494caed3cd 100644 (file)
@@ -16,7 +16,7 @@
 
 ```
 #![feature(phase)]
-#[phase(syntax, link)] extern crate log;
+#[phase(plugin, link)] extern crate log;
 
 fn main() {
     debug!("this is a debug {}", "message");
index 3bb49c237f14686651e21ca731aa0156bd81fc42..dba34c42a7e15997a7f9afa039a30be880b2f217 100644 (file)
@@ -22,7 +22,7 @@
 ///
 /// ```
 /// #![feature(phase)]
-/// #[phase(syntax, link)] extern crate log;
+/// #[phase(plugin, link)] extern crate log;
 ///
 /// # fn main() {
 /// log!(log::DEBUG, "this is a debug message");
@@ -51,7 +51,7 @@ macro_rules! log(
 ///
 /// ```
 /// #![feature(phase)]
-/// #[phase(syntax, link)] extern crate log;
+/// #[phase(plugin, link)] extern crate log;
 ///
 /// # fn main() {
 /// # let error = 3;
@@ -69,7 +69,7 @@ macro_rules! error(
 ///
 /// ```
 /// #![feature(phase)]
-/// #[phase(syntax, link)] extern crate log;
+/// #[phase(plugin, link)] extern crate log;
 ///
 /// # fn main() {
 /// # let code = 3;
@@ -87,7 +87,7 @@ macro_rules! warn(
 ///
 /// ```
 /// #![feature(phase)]
-/// #[phase(syntax, link)] extern crate log;
+/// #[phase(plugin, link)] extern crate log;
 ///
 /// # fn main() {
 /// # let ret = 3;
@@ -107,7 +107,7 @@ macro_rules! info(
 ///
 /// ```
 /// #![feature(phase)]
-/// #[phase(syntax, link)] extern crate log;
+/// #[phase(plugin, link)] extern crate log;
 ///
 /// # fn main() {
 /// debug!("x = {x}, y = {y}", x=10, y=20);
@@ -124,7 +124,7 @@ macro_rules! debug(
 ///
 /// ```
 /// #![feature(phase)]
-/// #[phase(syntax, link)] extern crate log;
+/// #[phase(plugin, link)] extern crate log;
 ///
 /// # fn main() {
 /// # struct Point { x: int, y: int }
index 93b3ec7ccefbf204f1b1d8ea9c31dc7013440271..e855b8bd4f2647f6efa983d526eb21d3f106e1c2 100644 (file)
@@ -20,6 +20,7 @@
 static FD_SETSIZE: uint = 64;
 pub static MSG_DONTWAIT: libc::c_int = 0;
 
+#[repr(C)]
 pub struct WSADATA {
     pub wVersion: libc::WORD,
     pub wHighVersion: libc::WORD,
@@ -32,6 +33,7 @@ pub struct WSADATA {
 
 pub type LPWSADATA = *mut WSADATA;
 
+#[repr(C)]
 pub struct fd_set {
     fd_count: libc::c_uint,
     fd_array: [libc::SOCKET, ..FD_SETSIZE],
@@ -69,7 +71,6 @@ pub fn CancelIoEx(hFile: libc::HANDLE,
 pub mod compat {
     use std::intrinsics::{atomic_store_relaxed, transmute};
     use libc::types::os::arch::extra::{LPCWSTR, HMODULE, LPCSTR, LPVOID};
-    use std::os::win32::as_utf16_p;
 
     extern "system" {
         fn GetModuleHandleW(lpModuleName: LPCWSTR) -> HMODULE;
@@ -80,12 +81,11 @@ pub mod compat {
     // This way, calling a function in this compatibility layer (after it's loaded) shouldn't
     // be any slower than a regular DLL call.
     unsafe fn store_func<T: Copy>(ptr: *mut T, module: &str, symbol: &str, fallback: T) {
-        as_utf16_p(module, |module| {
-            symbol.with_c_str(|symbol| {
-                let handle = GetModuleHandleW(module);
-                let func: Option<T> = transmute(GetProcAddress(handle, symbol));
-                atomic_store_relaxed(ptr, func.unwrap_or(fallback))
-            })
+        let module = module.to_utf16().append_one(0);
+        symbol.with_c_str(|symbol| {
+            let handle = GetModuleHandleW(module.as_ptr());
+            let func: Option<T> = transmute(GetProcAddress(handle, symbol));
+            atomic_store_relaxed(ptr, func.unwrap_or(fallback))
         })
     }
 
index 2a5b78e55067cb75e5ef369981b210157f6f2309..5ace8e347c67ef7d5c4e521f91ec125d5314d908 100644 (file)
 use libc;
 use std::c_str::CString;
 use std::mem;
-use std::os::win32::{as_utf16_p, fill_utf16_buf_and_decode};
+use std::os::win32::fill_utf16_buf_and_decode;
 use std::ptr;
 use std::rt::rtio;
-use std::rt::rtio::IoResult;
+use std::rt::rtio::{IoResult, IoError};
 use std::str;
 use std::vec;
 
@@ -253,6 +253,17 @@ fn drop(&mut self) {
     }
 }
 
+pub fn to_utf16(s: &CString) -> IoResult<Vec<u16>> {
+    match s.as_str() {
+        Some(s) => Ok(s.to_utf16().append_one(0)),
+        None => Err(IoError {
+            code: libc::ERROR_INVALID_NAME as uint,
+            extra: 0,
+            detail: Some("valid unicode input required".to_str()),
+        })
+    }
+}
+
 pub fn open(path: &CString, fm: rtio::FileMode, fa: rtio::FileAccess)
         -> IoResult<FileDesc> {
     // Flags passed to open_osfhandle
@@ -299,15 +310,16 @@ pub fn open(path: &CString, fm: rtio::FileMode, fa: rtio::FileAccess)
     // Compat with unix, this allows opening directories (see libuv)
     dwFlagsAndAttributes |= libc::FILE_FLAG_BACKUP_SEMANTICS;
 
-    let handle = as_utf16_p(path.as_str().unwrap(), |buf| unsafe {
-        libc::CreateFileW(buf,
+    let path = try!(to_utf16(path));
+    let handle = unsafe {
+        libc::CreateFileW(path.as_ptr(),
                           dwDesiredAccess,
                           dwShareMode,
                           ptr::mut_null(),
                           dwCreationDisposition,
                           dwFlagsAndAttributes,
                           ptr::mut_null())
-    });
+    };
     if handle == libc::INVALID_HANDLE_VALUE as libc::HANDLE {
         Err(super::last_error())
     } else {
@@ -324,11 +336,10 @@ pub fn open(path: &CString, fm: rtio::FileMode, fa: rtio::FileAccess)
 }
 
 pub fn mkdir(p: &CString, _mode: uint) -> IoResult<()> {
+    let p = try!(to_utf16(p));
     super::mkerr_winbool(unsafe {
         // FIXME: turn mode into something useful? #2623
-        as_utf16_p(p.as_str().unwrap(), |buf| {
-            libc::CreateDirectoryW(buf, ptr::mut_null())
-        })
+        libc::CreateDirectoryW(p.as_ptr(), ptr::mut_null())
     })
 }
 
@@ -351,9 +362,11 @@ fn prune(root: &CString, dirs: Vec<Path>) -> Vec<CString> {
     let star = Path::new(unsafe {
         CString::new(p.with_ref(|p| p), false)
     }).join("*");
-    as_utf16_p(star.as_str().unwrap(), |path_ptr| unsafe {
+    let path = try!(to_utf16(&star.to_c_str()));
+
+    unsafe {
         let wfd_ptr = malloc_raw(rust_list_dir_wfd_size() as uint);
-        let find_handle = libc::FindFirstFileW(path_ptr, wfd_ptr as libc::HANDLE);
+        let find_handle = libc::FindFirstFileW(path.as_ptr(), wfd_ptr as libc::HANDLE);
         if find_handle as libc::c_int != libc::INVALID_HANDLE_VALUE {
             let mut paths = vec!();
             let mut more_files = 1 as libc::c_int;
@@ -377,37 +390,35 @@ fn prune(root: &CString, dirs: Vec<Path>) -> Vec<CString> {
         } else {
             Err(super::last_error())
         }
-    })
+    }
 }
 
 pub fn unlink(p: &CString) -> IoResult<()> {
+    let p = try!(to_utf16(p));
     super::mkerr_winbool(unsafe {
-        as_utf16_p(p.as_str().unwrap(), |buf| {
-            libc::DeleteFileW(buf)
-        })
+        libc::DeleteFileW(p.as_ptr())
     })
 }
 
 pub fn rename(old: &CString, new: &CString) -> IoResult<()> {
+    let old = try!(to_utf16(old));
+    let new = try!(to_utf16(new));
     super::mkerr_winbool(unsafe {
-        as_utf16_p(old.as_str().unwrap(), |old| {
-            as_utf16_p(new.as_str().unwrap(), |new| {
-                libc::MoveFileExW(old, new, libc::MOVEFILE_REPLACE_EXISTING)
-            })
-        })
+        libc::MoveFileExW(old.as_ptr(), new.as_ptr(),
+                          libc::MOVEFILE_REPLACE_EXISTING)
     })
 }
 
 pub fn chmod(p: &CString, mode: uint) -> IoResult<()> {
-    super::mkerr_libc(as_utf16_p(p.as_str().unwrap(), |p| unsafe {
-        libc::wchmod(p, mode as libc::c_int)
-    }))
+    let p = try!(to_utf16(p));
+    super::mkerr_libc(unsafe {
+        libc::wchmod(p.as_ptr(), mode as libc::c_int)
+    })
 }
 
 pub fn rmdir(p: &CString) -> IoResult<()> {
-    super::mkerr_libc(as_utf16_p(p.as_str().unwrap(), |p| unsafe {
-        libc::wrmdir(p)
-    }))
+    let p = try!(to_utf16(p));
+    super::mkerr_libc(unsafe { libc::wrmdir(p.as_ptr()) })
 }
 
 pub fn chown(_p: &CString, _uid: int, _gid: int) -> IoResult<()> {
@@ -418,16 +429,15 @@ pub fn chown(_p: &CString, _uid: int, _gid: int) -> IoResult<()> {
 pub fn readlink(p: &CString) -> IoResult<CString> {
     // FIXME: I have a feeling that this reads intermediate symlinks as well.
     use io::c::compat::kernel32::GetFinalPathNameByHandleW;
+    let p = try!(to_utf16(p));
     let handle = unsafe {
-        as_utf16_p(p.as_str().unwrap(), |p| {
-            libc::CreateFileW(p,
-                              libc::GENERIC_READ,
-                              libc::FILE_SHARE_READ,
-                              ptr::mut_null(),
-                              libc::OPEN_EXISTING,
-                              libc::FILE_ATTRIBUTE_NORMAL,
-                              ptr::mut_null())
-        })
+        libc::CreateFileW(p.as_ptr(),
+                          libc::GENERIC_READ,
+                          libc::FILE_SHARE_READ,
+                          ptr::mut_null(),
+                          libc::OPEN_EXISTING,
+                          libc::FILE_ATTRIBUTE_NORMAL,
+                          ptr::mut_null())
     };
     if handle as int == libc::INVALID_HANDLE_VALUE as int {
         return Err(super::last_error())
@@ -453,19 +463,19 @@ pub fn readlink(p: &CString) -> IoResult<CString> {
 
 pub fn symlink(src: &CString, dst: &CString) -> IoResult<()> {
     use io::c::compat::kernel32::CreateSymbolicLinkW;
-    super::mkerr_winbool(as_utf16_p(src.as_str().unwrap(), |src| {
-        as_utf16_p(dst.as_str().unwrap(), |dst| {
-            unsafe { CreateSymbolicLinkW(dst, src, 0) }
-        }) as libc::BOOL
-    }))
+    let src = try!(to_utf16(src));
+    let dst = try!(to_utf16(dst));
+    super::mkerr_winbool(unsafe {
+        CreateSymbolicLinkW(dst.as_ptr(), src.as_ptr(), 0) as libc::BOOL
+    })
 }
 
 pub fn link(src: &CString, dst: &CString) -> IoResult<()> {
-    super::mkerr_winbool(as_utf16_p(src.as_str().unwrap(), |src| {
-        as_utf16_p(dst.as_str().unwrap(), |dst| {
-            unsafe { libc::CreateHardLinkW(dst, src, ptr::mut_null()) }
-        })
-    }))
+    let src = try!(to_utf16(src));
+    let dst = try!(to_utf16(dst));
+    super::mkerr_winbool(unsafe {
+        libc::CreateHardLinkW(dst.as_ptr(), src.as_ptr(), ptr::mut_null())
+    })
 }
 
 fn mkstat(stat: &libc::stat) -> rtio::FileStat {
@@ -491,12 +501,11 @@ fn mkstat(stat: &libc::stat) -> rtio::FileStat {
 
 pub fn stat(p: &CString) -> IoResult<rtio::FileStat> {
     let mut stat: libc::stat = unsafe { mem::zeroed() };
-    as_utf16_p(p.as_str().unwrap(), |up| {
-        match unsafe { libc::wstat(up, &mut stat) } {
-            0 => Ok(mkstat(&stat)),
-            _ => Err(super::last_error()),
-        }
-    })
+    let p = try!(to_utf16(p));
+    match unsafe { libc::wstat(p.as_ptr(), &mut stat) } {
+        0 => Ok(mkstat(&stat)),
+        _ => Err(super::last_error()),
+    }
 }
 
 pub fn lstat(_p: &CString) -> IoResult<rtio::FileStat> {
@@ -509,7 +518,8 @@ pub fn utime(p: &CString, atime: u64, mtime: u64) -> IoResult<()> {
         actime: (atime / 1000) as libc::time64_t,
         modtime: (mtime / 1000) as libc::time64_t,
     };
-    super::mkerr_libc(as_utf16_p(p.as_str().unwrap(), |p| unsafe {
-        libc::wutime(p, &buf)
-    }))
+    let p = try!(to_utf16(p));
+    super::mkerr_libc(unsafe {
+        libc::wutime(p.as_ptr(), &buf)
+    })
 }
index 3b0dbe2d0dce978e63be79d4c53ef6cdfd302e2a..4158db7bb8ea1d902ef8fe40e67a1596f4d7d60c 100644 (file)
@@ -77,7 +77,7 @@ fn unimpl() -> IoError {
     IoError {
         code: ERROR as uint,
         extra: 0,
-        detail: None,
+        detail: Some("not yet supported by the `native` runtime, maybe try `green`.".to_string()),
     }
 }
 
@@ -152,13 +152,13 @@ fn keep_going(data: &[u8], f: |*u8, uint| -> i64) -> i64 {
 /// Implementation of rt::rtio's IoFactory trait to generate handles to the
 /// native I/O functionality.
 pub struct IoFactory {
-    cannot_construct_outside_of_this_module: ()
+    _cannot_construct_outside_of_this_module: ()
 }
 
 impl IoFactory {
     pub fn new() -> IoFactory {
         net::init();
-        IoFactory { cannot_construct_outside_of_this_module: () }
+        IoFactory { _cannot_construct_outside_of_this_module: () }
     }
 }
 
index 24956e514ec83e09cb85ce4234040e270ad2d03d..e7effbd6bdbfb064ba935408f9cd0fc9a932b86d 100644 (file)
@@ -254,7 +254,10 @@ pub struct TcpStream {
 
 struct Inner {
     fd: sock_t,
-    lock: mutex::NativeMutex,
+
+    // Unused on Linux, where this lock is not necessary.
+    #[allow(dead_code)]
+    lock: mutex::NativeMutex
 }
 
 pub struct Guard<'a> {
index 7a1134fbe5956109bed023e09ad0e6997ce1b0d8..1458b475ae9598729e4cc700ae52f7ea515f8800 100644 (file)
@@ -58,7 +58,10 @@ fn addr_to_sockaddr_un(addr: &CString) -> IoResult<(libc::sockaddr_storage, uint
 
 struct Inner {
     fd: fd_t,
-    lock: mutex::NativeMutex,
+
+    // Unused on Linux, where this lock is not necessary.
+    #[allow(dead_code)]
+    lock: mutex::NativeMutex
 }
 
 impl Inner {
index a5694436b97200016f91a4d4463493a7029b6531..45b12aa7007ff307320d33bd8be67816c0c13ce4 100644 (file)
@@ -88,7 +88,6 @@
 use libc;
 use std::c_str::CString;
 use std::mem;
-use std::os::win32::as_utf16_p;
 use std::os;
 use std::ptr;
 use std::rt::rtio;
@@ -98,6 +97,7 @@
 
 use super::c;
 use super::util;
+use super::file::to_utf16;
 
 struct Event(libc::HANDLE);
 
@@ -261,67 +261,66 @@ fn try_connect(p: *u16) -> Option<libc::HANDLE> {
     }
 
     pub fn connect(addr: &CString, timeout: Option<u64>) -> IoResult<UnixStream> {
-        as_utf16_p(addr.as_str().unwrap(), |p| {
-            let start = ::io::timer::now();
-            loop {
-                match UnixStream::try_connect(p) {
-                    Some(handle) => {
-                        let inner = Inner::new(handle);
-                        let mut mode = libc::PIPE_TYPE_BYTE |
-                                       libc::PIPE_READMODE_BYTE |
-                                       libc::PIPE_WAIT;
-                        let ret = unsafe {
-                            libc::SetNamedPipeHandleState(inner.handle,
-                                                          &mut mode,
-                                                          ptr::mut_null(),
-                                                          ptr::mut_null())
-                        };
-                        return if ret == 0 {
-                            Err(super::last_error())
-                        } else {
-                            Ok(UnixStream {
-                                inner: Arc::new(inner),
-                                read: None,
-                                write: None,
-                                read_deadline: 0,
-                                write_deadline: 0,
-                            })
-                        }
+        let addr = try!(to_utf16(addr));
+        let start = ::io::timer::now();
+        loop {
+            match UnixStream::try_connect(addr.as_ptr()) {
+                Some(handle) => {
+                    let inner = Inner::new(handle);
+                    let mut mode = libc::PIPE_TYPE_BYTE |
+                                   libc::PIPE_READMODE_BYTE |
+                                   libc::PIPE_WAIT;
+                    let ret = unsafe {
+                        libc::SetNamedPipeHandleState(inner.handle,
+                                                      &mut mode,
+                                                      ptr::mut_null(),
+                                                      ptr::mut_null())
+                    };
+                    return if ret == 0 {
+                        Err(super::last_error())
+                    } else {
+                        Ok(UnixStream {
+                            inner: Arc::new(inner),
+                            read: None,
+                            write: None,
+                            read_deadline: 0,
+                            write_deadline: 0,
+                        })
                     }
-                    None => {}
                 }
+                None => {}
+            }
 
-                // On windows, if you fail to connect, you may need to call the
-                // `WaitNamedPipe` function, and this is indicated with an error
-                // code of ERROR_PIPE_BUSY.
-                let code = unsafe { libc::GetLastError() };
-                if code as int != libc::ERROR_PIPE_BUSY as int {
-                    return Err(super::last_error())
-                }
+            // On windows, if you fail to connect, you may need to call the
+            // `WaitNamedPipe` function, and this is indicated with an error
+            // code of ERROR_PIPE_BUSY.
+            let code = unsafe { libc::GetLastError() };
+            if code as int != libc::ERROR_PIPE_BUSY as int {
+                return Err(super::last_error())
+            }
 
-                match timeout {
-                    Some(timeout) => {
-                        let now = ::io::timer::now();
-                        let timed_out = (now - start) >= timeout || unsafe {
-                            let ms = (timeout - (now - start)) as libc::DWORD;
-                            libc::WaitNamedPipeW(p, ms) == 0
-                        };
-                        if timed_out {
-                            return Err(util::timeout("connect timed out"))
-                        }
+            match timeout {
+                Some(timeout) => {
+                    let now = ::io::timer::now();
+                    let timed_out = (now - start) >= timeout || unsafe {
+                        let ms = (timeout - (now - start)) as libc::DWORD;
+                        libc::WaitNamedPipeW(addr.as_ptr(), ms) == 0
+                    };
+                    if timed_out {
+                        return Err(util::timeout("connect timed out"))
                     }
+                }
 
-                    // An example I found on microsoft's website used 20
-                    // seconds, libuv uses 30 seconds, hence we make the
-                    // obvious choice of waiting for 25 seconds.
-                    None => {
-                        if unsafe { libc::WaitNamedPipeW(p, 25000) } == 0 {
-                            return Err(super::last_error())
-                        }
+                // An example I found on microsoft's website used 20
+                // seconds, libuv uses 30 seconds, hence we make the
+                // obvious choice of waiting for 25 seconds.
+                None => {
+                    if unsafe { libc::WaitNamedPipeW(addr.as_ptr(), 25000) } == 0 {
+                        return Err(super::last_error())
                     }
                 }
             }
-        })
+        }
     }
 
     fn handle(&self) -> libc::HANDLE { self.inner.handle }
@@ -564,14 +563,13 @@ pub fn bind(addr: &CString) -> IoResult<UnixListener> {
         // Although we technically don't need the pipe until much later, we
         // create the initial handle up front to test the validity of the name
         // and such.
-        as_utf16_p(addr.as_str().unwrap(), |p| {
-            let ret = unsafe { pipe(p, true) };
-            if ret == libc::INVALID_HANDLE_VALUE as libc::HANDLE {
-                Err(super::last_error())
-            } else {
-                Ok(UnixListener { handle: ret, name: addr.clone() })
-            }
-        })
+        let addr_v = try!(to_utf16(addr));
+        let ret = unsafe { pipe(addr_v.as_ptr(), true) };
+        if ret == libc::INVALID_HANDLE_VALUE as libc::HANDLE {
+            Err(super::last_error())
+        } else {
+            Ok(UnixListener { handle: ret, name: addr.clone() })
+        }
     }
 
     pub fn native_listen(self) -> IoResult<UnixAcceptor> {
@@ -639,6 +637,8 @@ pub fn native_accept(&mut self) -> IoResult<UnixStream> {
         // using the original server pipe.
         let handle = self.listener.handle;
 
+        let name = try!(to_utf16(&self.listener.name));
+
         // Once we've got a "server handle", we need to wait for a client to
         // connect. The ConnectNamedPipe function will block this thread until
         // someone on the other end connects. This function can "fail" if a
@@ -678,9 +678,7 @@ pub fn native_accept(&mut self) -> IoResult<UnixStream> {
         // Now that we've got a connected client to our handle, we need to
         // create a second server pipe. If this fails, we disconnect the
         // connected client and return an error (see comments above).
-        let new_handle = as_utf16_p(self.listener.name.as_str().unwrap(), |p| {
-            unsafe { pipe(p, false) }
-        });
+        let new_handle = unsafe { pipe(name.as_ptr(), false) };
         if new_handle == libc::INVALID_HANDLE_VALUE as libc::HANDLE {
             let ret = Err(super::last_error());
             // If our disconnection fails, then there's not really a whole lot
index 2c2b7cec1dec4806a3d32835de56b458b825d85f..97b227ae1d8d3b6ee14f1b4b3b56fab34b0bd7ce 100644 (file)
@@ -296,16 +296,15 @@ fn spawn_process_os(cfg: ProcessConfig,
                     lpSecurityDescriptor: ptr::mut_null(),
                     bInheritHandle: 1,
                 };
-                *slot = os::win32::as_utf16_p("NUL", |filename| {
-                    libc::CreateFileW(filename,
-                                      access,
-                                      libc::FILE_SHARE_READ |
-                                          libc::FILE_SHARE_WRITE,
-                                      &mut sa,
-                                      libc::OPEN_EXISTING,
-                                      0,
-                                      ptr::mut_null())
-                });
+                let filename = "NUL".to_utf16().append_one(0);
+                *slot = libc::CreateFileW(filename.as_ptr(),
+                                          access,
+                                          libc::FILE_SHARE_READ |
+                                              libc::FILE_SHARE_WRITE,
+                                          &mut sa,
+                                          libc::OPEN_EXISTING,
+                                          0,
+                                          ptr::mut_null());
                 if *slot == INVALID_HANDLE_VALUE as libc::HANDLE {
                     return Err(super::last_error())
                 }
@@ -338,18 +337,17 @@ fn spawn_process_os(cfg: ProcessConfig,
 
         with_envp(cfg.env, |envp| {
             with_dirp(cfg.cwd, |dirp| {
-                os::win32::as_mut_utf16_p(cmd_str.as_slice(), |cmdp| {
-                    let created = CreateProcessW(ptr::null(),
-                                                 cmdp,
-                                                 ptr::mut_null(),
-                                                 ptr::mut_null(),
-                                                 TRUE,
-                                                 flags, envp, dirp,
-                                                 &mut si, &mut pi);
-                    if created == FALSE {
-                        create_err = Some(super::last_error());
-                    }
-                })
+                let mut cmd_str = cmd_str.to_utf16().append_one(0);
+                let created = CreateProcessW(ptr::null(),
+                                             cmd_str.as_mut_ptr(),
+                                             ptr::mut_null(),
+                                             ptr::mut_null(),
+                                             TRUE,
+                                             flags, envp, dirp,
+                                             &mut si, &mut pi);
+                if created == FALSE {
+                    create_err = Some(super::last_error());
+                }
             })
         });
 
@@ -740,7 +738,8 @@ fn with_dirp<T>(d: Option<&CString>, cb: |*u16| -> T) -> T {
       Some(dir) => {
           let dir_str = dir.as_str()
                            .expect("expected workingdirectory to be utf-8 encoded");
-          os::win32::as_utf16_p(dir_str, cb)
+          let dir_str = dir_str.to_utf16().append_one(0);
+          cb(dir_str.as_ptr())
       },
       None => cb(ptr::null())
     }
index 67501c9795d18fda7fdc10eb46075db760a507a0..0933301970d1969a3901a1c9f6b196107653e7b4 100644 (file)
 */
 
 use Integer;
+use rand::Rng;
 
-use std::cmp;
+use std::{cmp, fmt};
 use std::default::Default;
-use std::fmt;
 use std::from_str::FromStr;
 use std::num::CheckedDiv;
 use std::num::{Bitwise, ToPrimitive, FromPrimitive};
 use std::num::{Zero, One, ToStrRadix, FromStrRadix};
-use rand::Rng;
 use std::string::String;
-use std::uint;
-use std::{i64, u64};
+use std::{uint, i64, u64};
 
 /**
 A `BigDigit` is a `BigUint`'s composing element.
@@ -94,7 +92,7 @@ impl Eq for BigUint {}
 impl PartialOrd for BigUint {
     #[inline]
     fn lt(&self, other: &BigUint) -> bool {
-        match self.cmp(other) { Less => true, _ => false}
+        self.cmp(other) == Less
     }
 }
 
@@ -115,7 +113,7 @@ fn cmp(&self, other: &BigUint) -> Ordering {
 
 impl Default for BigUint {
     #[inline]
-    fn default() -> BigUint { BigUint::new(Vec::new()) }
+    fn default() -> BigUint { Zero::zero() }
 }
 
 impl fmt::Show for BigUint {
@@ -605,7 +603,7 @@ fn to_biguint(&self) -> Option<BigUint> {
 
 impl ToStrRadix for BigUint {
     fn to_str_radix(&self, radix: uint) -> String {
-        assert!(1 < radix && radix <= 16);
+        assert!(1 < radix && radix <= 16, "The radix must be within (1, 16]");
         let (base, max_len) = get_radix_base(radix);
         if base == BigDigit::base {
             return fill_concat(self.data.as_slice(), radix, max_len)
@@ -645,8 +643,7 @@ fn fill_concat(v: &[BigDigit], radix: uint, l: uint) -> String {
 impl FromStrRadix for BigUint {
     /// Creates and initializes a `BigUint`.
     #[inline]
-    fn from_str_radix(s: &str, radix: uint)
-        -> Option<BigUint> {
+    fn from_str_radix(s: &str, radix: uint) -> Option<BigUint> {
         BigUint::parse_bytes(s.as_bytes(), radix)
     }
 }
@@ -656,14 +653,11 @@ impl BigUint {
     ///
     /// The digits are be in base 2^32.
     #[inline]
-    pub fn new(v: Vec<BigDigit>) -> BigUint {
+    pub fn new(mut digits: Vec<BigDigit>) -> BigUint {
         // omit trailing zeros
-        let new_len = v.iter().rposition(|n| *n != 0).map_or(0, |p| p + 1);
-
-        if new_len == v.len() { return BigUint { data: v }; }
-        let mut v = v;
-        v.truncate(new_len);
-        return BigUint { data: v };
+        let new_len = digits.iter().rposition(|n| *n != 0).map_or(0, |p| p + 1);
+        digits.truncate(new_len);
+        BigUint { data: digits }
     }
 
     /// Creates and initializes a `BigUint`.
@@ -671,7 +665,7 @@ pub fn new(v: Vec<BigDigit>) -> BigUint {
     /// The digits are be in base 2^32.
     #[inline]
     pub fn from_slice(slice: &[BigDigit]) -> BigUint {
-        return BigUint::new(Vec::from_slice(slice));
+        BigUint::new(Vec::from_slice(slice))
     }
 
     /// Creates and initializes a `BigUint`.
@@ -768,7 +762,6 @@ pub fn bits(&self) -> uint {
 // `DoubleBigDigit` size dependent
 #[inline]
 fn get_radix_base(radix: uint) -> (DoubleBigDigit, uint) {
-    assert!(1 < radix && radix <= 16);
     match radix {
         2  => (4294967296, 32),
         3  => (3486784401, 20),
@@ -785,7 +778,7 @@ fn get_radix_base(radix: uint) -> (DoubleBigDigit, uint) {
         14 => (1475789056, 8),
         15 => (2562890625, 8),
         16 => (4294967296, 8),
-        _  => fail!()
+        _  => fail!("The radix must be within (1, 16]")
     }
 }
 
@@ -815,7 +808,7 @@ pub struct BigInt {
 impl PartialEq for BigInt {
     #[inline]
     fn eq(&self, other: &BigInt) -> bool {
-        match self.cmp(other) { Equal => true, _ => false }
+        self.cmp(other) == Equal
     }
 }
 
@@ -824,7 +817,7 @@ impl Eq for BigInt {}
 impl PartialOrd for BigInt {
     #[inline]
     fn lt(&self, other: &BigInt) -> bool {
-        match self.cmp(other) { Less => true, _ => false}
+        self.cmp(other) == Less
     }
 }
 
@@ -844,7 +837,7 @@ fn cmp(&self, other: &BigInt) -> Ordering {
 
 impl Default for BigInt {
     #[inline]
-    fn default() -> BigInt { BigInt::new(Zero, Vec::new()) }
+    fn default() -> BigInt { Zero::zero() }
 }
 
 impl fmt::Show for BigInt {
@@ -929,8 +922,7 @@ fn add(&self, other: &BigInt) -> BigInt {
         match (self.sign, other.sign) {
             (Zero, _)      => other.clone(),
             (_,    Zero)   => self.clone(),
-            (Plus, Plus)   => BigInt::from_biguint(Plus,
-                                                   self.data + other.data),
+            (Plus, Plus)   => BigInt::from_biguint(Plus, self.data + other.data),
             (Plus, Minus)  => self - (-*other),
             (Minus, Plus)  => other - (-*self),
             (Minus, Minus) => -((-self) + (-*other))
@@ -975,7 +967,7 @@ impl Div<BigInt, BigInt> for BigInt {
     #[inline]
     fn div(&self, other: &BigInt) -> BigInt {
         let (q, _) = self.div_rem(other);
-        return q;
+        q
     }
 }
 
@@ -983,7 +975,7 @@ impl Rem<BigInt, BigInt> for BigInt {
     #[inline]
     fn rem(&self, other: &BigInt) -> BigInt {
         let (_, r) = self.div_rem(other);
-        return r;
+        r
     }
 }
 
@@ -1045,13 +1037,13 @@ fn div_rem(&self, other: &BigInt) -> (BigInt, BigInt) {
     #[inline]
     fn div_floor(&self, other: &BigInt) -> BigInt {
         let (d, _) = self.div_mod_floor(other);
-        return d;
+        d
     }
 
     #[inline]
     fn mod_floor(&self, other: &BigInt) -> BigInt {
         let (_, m) = self.div_mod_floor(other);
-        return m;
+        m
     }
 
     fn div_mod_floor(&self, other: &BigInt) -> (BigInt, BigInt) {
@@ -1265,7 +1257,7 @@ fn gen_biguint(&mut self, bit_size: uint) -> BigUint {
             let final_digit: BigDigit = self.gen();
             data.push(final_digit >> (BigDigit::bits - rem));
         }
-        return BigUint::new(data);
+        BigUint::new(data)
     }
 
     fn gen_bigint(&mut self, bit_size: uint) -> BigInt {
@@ -1287,7 +1279,7 @@ fn gen_bigint(&mut self, bit_size: uint) -> BigInt {
         } else {
             Minus
         };
-        return BigInt::from_biguint(sign, biguint);
+        BigInt::from_biguint(sign, biguint)
     }
 
     fn gen_biguint_below(&mut self, bound: &BigUint) -> BigUint {
@@ -1322,8 +1314,8 @@ impl BigInt {
     ///
     /// The digits are be in base 2^32.
     #[inline]
-    pub fn new(sign: Sign, v: Vec<BigDigit>) -> BigInt {
-        BigInt::from_biguint(sign, BigUint::new(v))
+    pub fn new(sign: Sign, digits: Vec<BigDigit>) -> BigInt {
+        BigInt::from_biguint(sign, BigUint::new(digits))
     }
 
     /// Creates and initializes a `BigInt`.
@@ -1334,7 +1326,7 @@ pub fn from_biguint(sign: Sign, data: BigUint) -> BigInt {
         if sign == Zero || data.is_zero() {
             return BigInt { sign: Zero, data: Zero::zero() };
         }
-        return BigInt { sign: sign, data: data };
+        BigInt { sign: sign, data: data }
     }
 
     /// Creates and initializes a `BigInt`.
@@ -1344,8 +1336,7 @@ pub fn from_slice(sign: Sign, slice: &[BigDigit]) -> BigInt {
     }
 
     /// Creates and initializes a `BigInt`.
-    pub fn parse_bytes(buf: &[u8], radix: uint)
-        -> Option<BigInt> {
+    pub fn parse_bytes(buf: &[u8], radix: uint) -> Option<BigInt> {
         if buf.is_empty() { return None; }
         let mut sign  = Plus;
         let mut start = 0;
diff --git a/src/libnum/integer.rs b/src/libnum/integer.rs
new file mode 100644 (file)
index 0000000..d958d40
--- /dev/null
@@ -0,0 +1,411 @@
+// 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.
+
+//! Integer trait and functions
+
+pub trait Integer: Num + PartialOrd
+                 + Div<Self, Self>
+                 + Rem<Self, Self> {
+    /// Simultaneous truncated integer division and modulus
+    #[inline]
+    fn div_rem(&self, other: &Self) -> (Self, Self) {
+        (*self / *other, *self % *other)
+    }
+
+    /// Floored integer division
+    ///
+    /// # Examples
+    ///
+    /// ~~~
+    /// # use num::Integer;
+    /// assert!(( 8i).div_floor(& 3) ==  2);
+    /// assert!(( 8i).div_floor(&-3) == -3);
+    /// assert!((-8i).div_floor(& 3) == -3);
+    /// assert!((-8i).div_floor(&-3) ==  2);
+    ///
+    /// assert!(( 1i).div_floor(& 2) ==  0);
+    /// assert!(( 1i).div_floor(&-2) == -1);
+    /// assert!((-1i).div_floor(& 2) == -1);
+    /// assert!((-1i).div_floor(&-2) ==  0);
+    /// ~~~
+    fn div_floor(&self, other: &Self) -> Self;
+
+    /// Floored integer modulo, satisfying:
+    ///
+    /// ~~~
+    /// # use num::Integer;
+    /// # let n = 1i; let d = 1i;
+    /// assert!(n.div_floor(&d) * d + n.mod_floor(&d) == n)
+    /// ~~~
+    ///
+    /// # Examples
+    ///
+    /// ~~~
+    /// # use num::Integer;
+    /// assert!(( 8i).mod_floor(& 3) ==  2);
+    /// assert!(( 8i).mod_floor(&-3) == -1);
+    /// assert!((-8i).mod_floor(& 3) ==  1);
+    /// assert!((-8i).mod_floor(&-3) == -2);
+    ///
+    /// assert!(( 1i).mod_floor(& 2) ==  1);
+    /// assert!(( 1i).mod_floor(&-2) == -1);
+    /// assert!((-1i).mod_floor(& 2) ==  1);
+    /// assert!((-1i).mod_floor(&-2) == -1);
+    /// ~~~
+    fn mod_floor(&self, other: &Self) -> Self;
+
+    /// Simultaneous floored integer division and modulus
+    fn div_mod_floor(&self, other: &Self) -> (Self, Self) {
+        (self.div_floor(other), self.mod_floor(other))
+    }
+
+    /// Greatest Common Divisor (GCD)
+    fn gcd(&self, other: &Self) -> Self;
+
+    /// Lowest Common Multiple (LCM)
+    fn lcm(&self, other: &Self) -> Self;
+
+    /// Returns `true` if `other` divides evenly into `self`
+    fn divides(&self, other: &Self) -> bool;
+
+    /// Returns `true` if the number is even
+    fn is_even(&self) -> bool;
+
+    /// Returns `true` if the number is odd
+    fn is_odd(&self) -> bool;
+}
+
+/// Simultaneous integer division and modulus
+#[inline] pub fn div_rem<T: Integer>(x: T, y: T) -> (T, T) { x.div_rem(&y) }
+/// Floored integer division
+#[inline] pub fn div_floor<T: Integer>(x: T, y: T) -> T { x.div_floor(&y) }
+/// Floored integer modulus
+#[inline] pub fn mod_floor<T: Integer>(x: T, y: T) -> T { x.mod_floor(&y) }
+/// Simultaneous floored integer division and modulus
+#[inline] pub fn div_mod_floor<T: Integer>(x: T, y: T) -> (T, T) { x.div_mod_floor(&y) }
+
+/// Calculates the Greatest Common Divisor (GCD) of the number and `other`. The
+/// result is always positive.
+#[inline(always)] pub fn gcd<T: Integer>(x: T, y: T) -> T { x.gcd(&y) }
+/// Calculates the Lowest Common Multiple (LCM) of the number and `other`.
+#[inline(always)] pub fn lcm<T: Integer>(x: T, y: T) -> T { x.lcm(&y) }
+
+macro_rules! impl_integer_for_int {
+    ($T:ty, $test_mod:ident) => (
+        impl Integer for $T {
+            /// Floored integer division
+            #[inline]
+            fn div_floor(&self, other: &$T) -> $T {
+                // Algorithm from [Daan Leijen. _Division and Modulus for Computer Scientists_,
+                // December 2001](http://research.microsoft.com/pubs/151917/divmodnote-letter.pdf)
+                match self.div_rem(other) {
+                    (d, r) if (r > 0 && *other < 0)
+                           || (r < 0 && *other > 0) => d - 1,
+                    (d, _)                          => d,
+                }
+            }
+
+            /// Floored integer modulo
+            #[inline]
+            fn mod_floor(&self, other: &$T) -> $T {
+                // Algorithm from [Daan Leijen. _Division and Modulus for Computer Scientists_,
+                // December 2001](http://research.microsoft.com/pubs/151917/divmodnote-letter.pdf)
+                match *self % *other {
+                    r if (r > 0 && *other < 0)
+                      || (r < 0 && *other > 0) => r + *other,
+                    r                          => r,
+                }
+            }
+
+            /// Calculates `div_floor` and `mod_floor` simultaneously
+            #[inline]
+            fn div_mod_floor(&self, other: &$T) -> ($T,$T) {
+                // Algorithm from [Daan Leijen. _Division and Modulus for Computer Scientists_,
+                // December 2001](http://research.microsoft.com/pubs/151917/divmodnote-letter.pdf)
+                match self.div_rem(other) {
+                    (d, r) if (r > 0 && *other < 0)
+                           || (r < 0 && *other > 0) => (d - 1, r + *other),
+                    (d, r)                          => (d, r),
+                }
+            }
+
+            /// Calculates the Greatest Common Divisor (GCD) of the number and
+            /// `other`. The result is always positive.
+            #[inline]
+            fn gcd(&self, other: &$T) -> $T {
+                // Use Euclid's algorithm
+                let mut m = *self;
+                let mut n = *other;
+                while m != 0 {
+                    let temp = m;
+                    m = n % temp;
+                    n = temp;
+                }
+                n.abs()
+            }
+
+            /// Calculates the Lowest Common Multiple (LCM) of the number and
+            /// `other`.
+            #[inline]
+            fn lcm(&self, other: &$T) -> $T {
+                // should not have to recalculate abs
+                ((*self * *other) / self.gcd(other)).abs()
+            }
+
+            /// Returns `true` if the number can be divided by `other` without
+            /// leaving a remainder
+            #[inline]
+            fn divides(&self, other: &$T) -> bool { *self % *other == 0 }
+
+            /// Returns `true` if the number is divisible by `2`
+            #[inline]
+            fn is_even(&self) -> bool { self & 1 == 0 }
+
+            /// Returns `true` if the number is not divisible by `2`
+            #[inline]
+            fn is_odd(&self) -> bool { !self.is_even() }
+        }
+
+        #[cfg(test)]
+        mod $test_mod {
+            use Integer;
+
+            /// Checks that the division rule holds for:
+            ///
+            /// - `n`: numerator (dividend)
+            /// - `d`: denominator (divisor)
+            /// - `qr`: quotient and remainder
+            #[cfg(test)]
+            fn test_division_rule((n,d): ($T,$T), (q,r): ($T,$T)) {
+                assert_eq!(d * q + r, n);
+            }
+
+            #[test]
+            fn test_div_rem() {
+                fn test_nd_dr(nd: ($T,$T), qr: ($T,$T)) {
+                    let (n,d) = nd;
+                    let separate_div_rem = (n / d, n % d);
+                    let combined_div_rem = n.div_rem(&d);
+
+                    assert_eq!(separate_div_rem, qr);
+                    assert_eq!(combined_div_rem, qr);
+
+                    test_division_rule(nd, separate_div_rem);
+                    test_division_rule(nd, combined_div_rem);
+                }
+
+                test_nd_dr(( 8,  3), ( 2,  2));
+                test_nd_dr(( 8, -3), (-2,  2));
+                test_nd_dr((-8,  3), (-2, -2));
+                test_nd_dr((-8, -3), ( 2, -2));
+
+                test_nd_dr(( 1,  2), ( 0,  1));
+                test_nd_dr(( 1, -2), ( 0,  1));
+                test_nd_dr((-1,  2), ( 0, -1));
+                test_nd_dr((-1, -2), ( 0, -1));
+            }
+
+            #[test]
+            fn test_div_mod_floor() {
+                fn test_nd_dm(nd: ($T,$T), dm: ($T,$T)) {
+                    let (n,d) = nd;
+                    let separate_div_mod_floor = (n.div_floor(&d), n.mod_floor(&d));
+                    let combined_div_mod_floor = n.div_mod_floor(&d);
+
+                    assert_eq!(separate_div_mod_floor, dm);
+                    assert_eq!(combined_div_mod_floor, dm);
+
+                    test_division_rule(nd, separate_div_mod_floor);
+                    test_division_rule(nd, combined_div_mod_floor);
+                }
+
+                test_nd_dm(( 8,  3), ( 2,  2));
+                test_nd_dm(( 8, -3), (-3, -1));
+                test_nd_dm((-8,  3), (-3,  1));
+                test_nd_dm((-8, -3), ( 2, -2));
+
+                test_nd_dm(( 1,  2), ( 0,  1));
+                test_nd_dm(( 1, -2), (-1, -1));
+                test_nd_dm((-1,  2), (-1,  1));
+                test_nd_dm((-1, -2), ( 0, -1));
+            }
+
+            #[test]
+            fn test_gcd() {
+                assert_eq!((10 as $T).gcd(&2), 2 as $T);
+                assert_eq!((10 as $T).gcd(&3), 1 as $T);
+                assert_eq!((0 as $T).gcd(&3), 3 as $T);
+                assert_eq!((3 as $T).gcd(&3), 3 as $T);
+                assert_eq!((56 as $T).gcd(&42), 14 as $T);
+                assert_eq!((3 as $T).gcd(&-3), 3 as $T);
+                assert_eq!((-6 as $T).gcd(&3), 3 as $T);
+                assert_eq!((-4 as $T).gcd(&-2), 2 as $T);
+            }
+
+            #[test]
+            fn test_lcm() {
+                assert_eq!((1 as $T).lcm(&0), 0 as $T);
+                assert_eq!((0 as $T).lcm(&1), 0 as $T);
+                assert_eq!((1 as $T).lcm(&1), 1 as $T);
+                assert_eq!((-1 as $T).lcm(&1), 1 as $T);
+                assert_eq!((1 as $T).lcm(&-1), 1 as $T);
+                assert_eq!((-1 as $T).lcm(&-1), 1 as $T);
+                assert_eq!((8 as $T).lcm(&9), 72 as $T);
+                assert_eq!((11 as $T).lcm(&5), 55 as $T);
+            }
+
+            #[test]
+            fn test_even() {
+                assert_eq!((-4 as $T).is_even(), true);
+                assert_eq!((-3 as $T).is_even(), false);
+                assert_eq!((-2 as $T).is_even(), true);
+                assert_eq!((-1 as $T).is_even(), false);
+                assert_eq!((0 as $T).is_even(), true);
+                assert_eq!((1 as $T).is_even(), false);
+                assert_eq!((2 as $T).is_even(), true);
+                assert_eq!((3 as $T).is_even(), false);
+                assert_eq!((4 as $T).is_even(), true);
+            }
+
+            #[test]
+            fn test_odd() {
+                assert_eq!((-4 as $T).is_odd(), false);
+                assert_eq!((-3 as $T).is_odd(), true);
+                assert_eq!((-2 as $T).is_odd(), false);
+                assert_eq!((-1 as $T).is_odd(), true);
+                assert_eq!((0 as $T).is_odd(), false);
+                assert_eq!((1 as $T).is_odd(), true);
+                assert_eq!((2 as $T).is_odd(), false);
+                assert_eq!((3 as $T).is_odd(), true);
+                assert_eq!((4 as $T).is_odd(), false);
+            }
+        }
+    )
+}
+
+impl_integer_for_int!(i8,   test_integer_i8)
+impl_integer_for_int!(i16,  test_integer_i16)
+impl_integer_for_int!(i32,  test_integer_i32)
+impl_integer_for_int!(i64,  test_integer_i64)
+impl_integer_for_int!(int,  test_integer_int)
+
+macro_rules! impl_integer_for_uint {
+    ($T:ty, $test_mod:ident) => (
+        impl Integer for $T {
+            /// Unsigned integer division. Returns the same result as `div` (`/`).
+            #[inline]
+            fn div_floor(&self, other: &$T) -> $T { *self / *other }
+
+            /// Unsigned integer modulo operation. Returns the same result as `rem` (`%`).
+            #[inline]
+            fn mod_floor(&self, other: &$T) -> $T { *self % *other }
+
+            /// Calculates the Greatest Common Divisor (GCD) of the number and `other`
+            #[inline]
+            fn gcd(&self, other: &$T) -> $T {
+                // Use Euclid's algorithm
+                let mut m = *self;
+                let mut n = *other;
+                while m != 0 {
+                    let temp = m;
+                    m = n % temp;
+                    n = temp;
+                }
+                n
+            }
+
+            /// Calculates the Lowest Common Multiple (LCM) of the number and `other`
+            #[inline]
+            fn lcm(&self, other: &$T) -> $T {
+                (*self * *other) / self.gcd(other)
+            }
+
+            /// Returns `true` if the number can be divided by `other` without leaving a remainder
+            #[inline]
+            fn divides(&self, other: &$T) -> bool { *self % *other == 0 }
+
+            /// Returns `true` if the number is divisible by `2`
+            #[inline]
+            fn is_even(&self) -> bool { self & 1 == 0 }
+
+            /// Returns `true` if the number is not divisible by `2`
+            #[inline]
+            fn is_odd(&self) -> bool { !self.is_even() }
+        }
+
+        #[cfg(test)]
+        mod $test_mod {
+            use Integer;
+
+            #[test]
+            fn test_div_mod_floor() {
+                assert_eq!((10 as $T).div_floor(&(3 as $T)), 3 as $T);
+                assert_eq!((10 as $T).mod_floor(&(3 as $T)), 1 as $T);
+                assert_eq!((10 as $T).div_mod_floor(&(3 as $T)), (3 as $T, 1 as $T));
+                assert_eq!((5 as $T).div_floor(&(5 as $T)), 1 as $T);
+                assert_eq!((5 as $T).mod_floor(&(5 as $T)), 0 as $T);
+                assert_eq!((5 as $T).div_mod_floor(&(5 as $T)), (1 as $T, 0 as $T));
+                assert_eq!((3 as $T).div_floor(&(7 as $T)), 0 as $T);
+                assert_eq!((3 as $T).mod_floor(&(7 as $T)), 3 as $T);
+                assert_eq!((3 as $T).div_mod_floor(&(7 as $T)), (0 as $T, 3 as $T));
+            }
+
+            #[test]
+            fn test_gcd() {
+                assert_eq!((10 as $T).gcd(&2), 2 as $T);
+                assert_eq!((10 as $T).gcd(&3), 1 as $T);
+                assert_eq!((0 as $T).gcd(&3), 3 as $T);
+                assert_eq!((3 as $T).gcd(&3), 3 as $T);
+                assert_eq!((56 as $T).gcd(&42), 14 as $T);
+            }
+
+            #[test]
+            fn test_lcm() {
+                assert_eq!((1 as $T).lcm(&0), 0 as $T);
+                assert_eq!((0 as $T).lcm(&1), 0 as $T);
+                assert_eq!((1 as $T).lcm(&1), 1 as $T);
+                assert_eq!((8 as $T).lcm(&9), 72 as $T);
+                assert_eq!((11 as $T).lcm(&5), 55 as $T);
+                assert_eq!((99 as $T).lcm(&17), 1683 as $T);
+            }
+
+            #[test]
+            fn test_divides() {
+                assert!((6 as $T).divides(&(6 as $T)));
+                assert!((6 as $T).divides(&(3 as $T)));
+                assert!((6 as $T).divides(&(1 as $T)));
+            }
+
+            #[test]
+            fn test_even() {
+                assert_eq!((0 as $T).is_even(), true);
+                assert_eq!((1 as $T).is_even(), false);
+                assert_eq!((2 as $T).is_even(), true);
+                assert_eq!((3 as $T).is_even(), false);
+                assert_eq!((4 as $T).is_even(), true);
+            }
+
+            #[test]
+            fn test_odd() {
+                assert_eq!((0 as $T).is_odd(), false);
+                assert_eq!((1 as $T).is_odd(), true);
+                assert_eq!((2 as $T).is_odd(), false);
+                assert_eq!((3 as $T).is_odd(), true);
+                assert_eq!((4 as $T).is_odd(), false);
+            }
+        }
+    )
+}
+
+impl_integer_for_uint!(u8,   test_integer_u8)
+impl_integer_for_uint!(u16,  test_integer_u16)
+impl_integer_for_uint!(u32,  test_integer_u32)
+impl_integer_for_uint!(u64,  test_integer_u64)
+impl_integer_for_uint!(uint, test_integer_uint)
index fae21e80f307256101498420fc2459bc9109e80a..709882c87cedb970b3be3f693517592507fefd77 100644 (file)
 
 extern crate rand;
 
+pub use bigint::{BigInt, BigUint};
+pub use rational::{Rational, BigRational};
+pub use complex::Complex;
+pub use integer::Integer;
+
 pub mod bigint;
-pub mod rational;
 pub mod complex;
-
-pub trait Integer: Num + PartialOrd
-                 + Div<Self, Self>
-                 + Rem<Self, Self> {
-    /// Simultaneous truncated integer division and modulus
-    #[inline]
-    fn div_rem(&self, other: &Self) -> (Self, Self) {
-        (*self / *other, *self % *other)
-    }
-
-    /// Floored integer division
-    ///
-    /// # Examples
-    ///
-    /// ~~~
-    /// # use num::Integer;
-    /// assert!(( 8i).div_floor(& 3) ==  2);
-    /// assert!(( 8i).div_floor(&-3) == -3);
-    /// assert!((-8i).div_floor(& 3) == -3);
-    /// assert!((-8i).div_floor(&-3) ==  2);
-    ///
-    /// assert!(( 1i).div_floor(& 2) ==  0);
-    /// assert!(( 1i).div_floor(&-2) == -1);
-    /// assert!((-1i).div_floor(& 2) == -1);
-    /// assert!((-1i).div_floor(&-2) ==  0);
-    /// ~~~
-    fn div_floor(&self, other: &Self) -> Self;
-
-    /// Floored integer modulo, satisfying:
-    ///
-    /// ~~~
-    /// # use num::Integer;
-    /// # let n = 1i; let d = 1i;
-    /// assert!(n.div_floor(&d) * d + n.mod_floor(&d) == n)
-    /// ~~~
-    ///
-    /// # Examples
-    ///
-    /// ~~~
-    /// # use num::Integer;
-    /// assert!(( 8i).mod_floor(& 3) ==  2);
-    /// assert!(( 8i).mod_floor(&-3) == -1);
-    /// assert!((-8i).mod_floor(& 3) ==  1);
-    /// assert!((-8i).mod_floor(&-3) == -2);
-    ///
-    /// assert!(( 1i).mod_floor(& 2) ==  1);
-    /// assert!(( 1i).mod_floor(&-2) == -1);
-    /// assert!((-1i).mod_floor(& 2) ==  1);
-    /// assert!((-1i).mod_floor(&-2) == -1);
-    /// ~~~
-    fn mod_floor(&self, other: &Self) -> Self;
-
-    /// Simultaneous floored integer division and modulus
-    fn div_mod_floor(&self, other: &Self) -> (Self, Self) {
-        (self.div_floor(other), self.mod_floor(other))
-    }
-
-    /// Greatest Common Divisor (GCD)
-    fn gcd(&self, other: &Self) -> Self;
-
-    /// Lowest Common Multiple (LCM)
-    fn lcm(&self, other: &Self) -> Self;
-
-    /// Returns `true` if `other` divides evenly into `self`
-    fn divides(&self, other: &Self) -> bool;
-
-    /// Returns `true` if the number is even
-    fn is_even(&self) -> bool;
-
-    /// Returns `true` if the number is odd
-    fn is_odd(&self) -> bool;
-}
-
-/// Simultaneous integer division and modulus
-#[inline] pub fn div_rem<T: Integer>(x: T, y: T) -> (T, T) { x.div_rem(&y) }
-/// Floored integer division
-#[inline] pub fn div_floor<T: Integer>(x: T, y: T) -> T { x.div_floor(&y) }
-/// Floored integer modulus
-#[inline] pub fn mod_floor<T: Integer>(x: T, y: T) -> T { x.mod_floor(&y) }
-/// Simultaneous floored integer division and modulus
-#[inline] pub fn div_mod_floor<T: Integer>(x: T, y: T) -> (T, T) { x.div_mod_floor(&y) }
-
-/// Calculates the Greatest Common Divisor (GCD) of the number and `other`. The
-/// result is always positive.
-#[inline(always)] pub fn gcd<T: Integer>(x: T, y: T) -> T { x.gcd(&y) }
-/// Calculates the Lowest Common Multiple (LCM) of the number and `other`.
-#[inline(always)] pub fn lcm<T: Integer>(x: T, y: T) -> T { x.lcm(&y) }
-
-macro_rules! impl_integer_for_int {
-    ($T:ty, $test_mod:ident) => (
-        impl Integer for $T {
-            /// Floored integer division
-            #[inline]
-            fn div_floor(&self, other: &$T) -> $T {
-                // Algorithm from [Daan Leijen. _Division and Modulus for Computer Scientists_,
-                // December 2001](http://research.microsoft.com/pubs/151917/divmodnote-letter.pdf)
-                match self.div_rem(other) {
-                    (d, r) if (r > 0 && *other < 0)
-                           || (r < 0 && *other > 0) => d - 1,
-                    (d, _)                          => d,
-                }
-            }
-
-            /// Floored integer modulo
-            #[inline]
-            fn mod_floor(&self, other: &$T) -> $T {
-                // Algorithm from [Daan Leijen. _Division and Modulus for Computer Scientists_,
-                // December 2001](http://research.microsoft.com/pubs/151917/divmodnote-letter.pdf)
-                match *self % *other {
-                    r if (r > 0 && *other < 0)
-                      || (r < 0 && *other > 0) => r + *other,
-                    r                          => r,
-                }
-            }
-
-            /// Calculates `div_floor` and `mod_floor` simultaneously
-            #[inline]
-            fn div_mod_floor(&self, other: &$T) -> ($T,$T) {
-                // Algorithm from [Daan Leijen. _Division and Modulus for Computer Scientists_,
-                // December 2001](http://research.microsoft.com/pubs/151917/divmodnote-letter.pdf)
-                match self.div_rem(other) {
-                    (d, r) if (r > 0 && *other < 0)
-                           || (r < 0 && *other > 0) => (d - 1, r + *other),
-                    (d, r)                          => (d, r),
-                }
-            }
-
-            /// Calculates the Greatest Common Divisor (GCD) of the number and
-            /// `other`. The result is always positive.
-            #[inline]
-            fn gcd(&self, other: &$T) -> $T {
-                // Use Euclid's algorithm
-                let mut m = *self;
-                let mut n = *other;
-                while m != 0 {
-                    let temp = m;
-                    m = n % temp;
-                    n = temp;
-                }
-                n.abs()
-            }
-
-            /// Calculates the Lowest Common Multiple (LCM) of the number and
-            /// `other`.
-            #[inline]
-            fn lcm(&self, other: &$T) -> $T {
-                // should not have to recalculate abs
-                ((*self * *other) / self.gcd(other)).abs()
-            }
-
-            /// Returns `true` if the number can be divided by `other` without
-            /// leaving a remainder
-            #[inline]
-            fn divides(&self, other: &$T) -> bool { *self % *other == 0 }
-
-            /// Returns `true` if the number is divisible by `2`
-            #[inline]
-            fn is_even(&self) -> bool { self & 1 == 0 }
-
-            /// Returns `true` if the number is not divisible by `2`
-            #[inline]
-            fn is_odd(&self) -> bool { !self.is_even() }
-        }
-
-        #[cfg(test)]
-        mod $test_mod {
-            use Integer;
-
-            /// Checks that the division rule holds for:
-            ///
-            /// - `n`: numerator (dividend)
-            /// - `d`: denominator (divisor)
-            /// - `qr`: quotient and remainder
-            #[cfg(test)]
-            fn test_division_rule((n,d): ($T,$T), (q,r): ($T,$T)) {
-                assert_eq!(d * q + r, n);
-            }
-
-            #[test]
-            fn test_div_rem() {
-                fn test_nd_dr(nd: ($T,$T), qr: ($T,$T)) {
-                    let (n,d) = nd;
-                    let separate_div_rem = (n / d, n % d);
-                    let combined_div_rem = n.div_rem(&d);
-
-                    assert_eq!(separate_div_rem, qr);
-                    assert_eq!(combined_div_rem, qr);
-
-                    test_division_rule(nd, separate_div_rem);
-                    test_division_rule(nd, combined_div_rem);
-                }
-
-                test_nd_dr(( 8,  3), ( 2,  2));
-                test_nd_dr(( 8, -3), (-2,  2));
-                test_nd_dr((-8,  3), (-2, -2));
-                test_nd_dr((-8, -3), ( 2, -2));
-
-                test_nd_dr(( 1,  2), ( 0,  1));
-                test_nd_dr(( 1, -2), ( 0,  1));
-                test_nd_dr((-1,  2), ( 0, -1));
-                test_nd_dr((-1, -2), ( 0, -1));
-            }
-
-            #[test]
-            fn test_div_mod_floor() {
-                fn test_nd_dm(nd: ($T,$T), dm: ($T,$T)) {
-                    let (n,d) = nd;
-                    let separate_div_mod_floor = (n.div_floor(&d), n.mod_floor(&d));
-                    let combined_div_mod_floor = n.div_mod_floor(&d);
-
-                    assert_eq!(separate_div_mod_floor, dm);
-                    assert_eq!(combined_div_mod_floor, dm);
-
-                    test_division_rule(nd, separate_div_mod_floor);
-                    test_division_rule(nd, combined_div_mod_floor);
-                }
-
-                test_nd_dm(( 8,  3), ( 2,  2));
-                test_nd_dm(( 8, -3), (-3, -1));
-                test_nd_dm((-8,  3), (-3,  1));
-                test_nd_dm((-8, -3), ( 2, -2));
-
-                test_nd_dm(( 1,  2), ( 0,  1));
-                test_nd_dm(( 1, -2), (-1, -1));
-                test_nd_dm((-1,  2), (-1,  1));
-                test_nd_dm((-1, -2), ( 0, -1));
-            }
-
-            #[test]
-            fn test_gcd() {
-                assert_eq!((10 as $T).gcd(&2), 2 as $T);
-                assert_eq!((10 as $T).gcd(&3), 1 as $T);
-                assert_eq!((0 as $T).gcd(&3), 3 as $T);
-                assert_eq!((3 as $T).gcd(&3), 3 as $T);
-                assert_eq!((56 as $T).gcd(&42), 14 as $T);
-                assert_eq!((3 as $T).gcd(&-3), 3 as $T);
-                assert_eq!((-6 as $T).gcd(&3), 3 as $T);
-                assert_eq!((-4 as $T).gcd(&-2), 2 as $T);
-            }
-
-            #[test]
-            fn test_lcm() {
-                assert_eq!((1 as $T).lcm(&0), 0 as $T);
-                assert_eq!((0 as $T).lcm(&1), 0 as $T);
-                assert_eq!((1 as $T).lcm(&1), 1 as $T);
-                assert_eq!((-1 as $T).lcm(&1), 1 as $T);
-                assert_eq!((1 as $T).lcm(&-1), 1 as $T);
-                assert_eq!((-1 as $T).lcm(&-1), 1 as $T);
-                assert_eq!((8 as $T).lcm(&9), 72 as $T);
-                assert_eq!((11 as $T).lcm(&5), 55 as $T);
-            }
-
-            #[test]
-            fn test_even() {
-                assert_eq!((-4 as $T).is_even(), true);
-                assert_eq!((-3 as $T).is_even(), false);
-                assert_eq!((-2 as $T).is_even(), true);
-                assert_eq!((-1 as $T).is_even(), false);
-                assert_eq!((0 as $T).is_even(), true);
-                assert_eq!((1 as $T).is_even(), false);
-                assert_eq!((2 as $T).is_even(), true);
-                assert_eq!((3 as $T).is_even(), false);
-                assert_eq!((4 as $T).is_even(), true);
-            }
-
-            #[test]
-            fn test_odd() {
-                assert_eq!((-4 as $T).is_odd(), false);
-                assert_eq!((-3 as $T).is_odd(), true);
-                assert_eq!((-2 as $T).is_odd(), false);
-                assert_eq!((-1 as $T).is_odd(), true);
-                assert_eq!((0 as $T).is_odd(), false);
-                assert_eq!((1 as $T).is_odd(), true);
-                assert_eq!((2 as $T).is_odd(), false);
-                assert_eq!((3 as $T).is_odd(), true);
-                assert_eq!((4 as $T).is_odd(), false);
-            }
-        }
-    )
-}
-
-impl_integer_for_int!(i8,   test_integer_i8)
-impl_integer_for_int!(i16,  test_integer_i16)
-impl_integer_for_int!(i32,  test_integer_i32)
-impl_integer_for_int!(i64,  test_integer_i64)
-impl_integer_for_int!(int,  test_integer_int)
-
-macro_rules! impl_integer_for_uint {
-    ($T:ty, $test_mod:ident) => (
-        impl Integer for $T {
-            /// Unsigned integer division. Returns the same result as `div` (`/`).
-            #[inline]
-            fn div_floor(&self, other: &$T) -> $T { *self / *other }
-
-            /// Unsigned integer modulo operation. Returns the same result as `rem` (`%`).
-            #[inline]
-            fn mod_floor(&self, other: &$T) -> $T { *self % *other }
-
-            /// Calculates the Greatest Common Divisor (GCD) of the number and `other`
-            #[inline]
-            fn gcd(&self, other: &$T) -> $T {
-                // Use Euclid's algorithm
-                let mut m = *self;
-                let mut n = *other;
-                while m != 0 {
-                    let temp = m;
-                    m = n % temp;
-                    n = temp;
-                }
-                n
-            }
-
-            /// Calculates the Lowest Common Multiple (LCM) of the number and `other`
-            #[inline]
-            fn lcm(&self, other: &$T) -> $T {
-                (*self * *other) / self.gcd(other)
-            }
-
-            /// Returns `true` if the number can be divided by `other` without leaving a remainder
-            #[inline]
-            fn divides(&self, other: &$T) -> bool { *self % *other == 0 }
-
-            /// Returns `true` if the number is divisible by `2`
-            #[inline]
-            fn is_even(&self) -> bool { self & 1 == 0 }
-
-            /// Returns `true` if the number is not divisible by `2`
-            #[inline]
-            fn is_odd(&self) -> bool { !self.is_even() }
-        }
-
-        #[cfg(test)]
-        mod $test_mod {
-            use Integer;
-
-            #[test]
-            fn test_div_mod_floor() {
-                assert_eq!((10 as $T).div_floor(&(3 as $T)), 3 as $T);
-                assert_eq!((10 as $T).mod_floor(&(3 as $T)), 1 as $T);
-                assert_eq!((10 as $T).div_mod_floor(&(3 as $T)), (3 as $T, 1 as $T));
-                assert_eq!((5 as $T).div_floor(&(5 as $T)), 1 as $T);
-                assert_eq!((5 as $T).mod_floor(&(5 as $T)), 0 as $T);
-                assert_eq!((5 as $T).div_mod_floor(&(5 as $T)), (1 as $T, 0 as $T));
-                assert_eq!((3 as $T).div_floor(&(7 as $T)), 0 as $T);
-                assert_eq!((3 as $T).mod_floor(&(7 as $T)), 3 as $T);
-                assert_eq!((3 as $T).div_mod_floor(&(7 as $T)), (0 as $T, 3 as $T));
-            }
-
-            #[test]
-            fn test_gcd() {
-                assert_eq!((10 as $T).gcd(&2), 2 as $T);
-                assert_eq!((10 as $T).gcd(&3), 1 as $T);
-                assert_eq!((0 as $T).gcd(&3), 3 as $T);
-                assert_eq!((3 as $T).gcd(&3), 3 as $T);
-                assert_eq!((56 as $T).gcd(&42), 14 as $T);
-            }
-
-            #[test]
-            fn test_lcm() {
-                assert_eq!((1 as $T).lcm(&0), 0 as $T);
-                assert_eq!((0 as $T).lcm(&1), 0 as $T);
-                assert_eq!((1 as $T).lcm(&1), 1 as $T);
-                assert_eq!((8 as $T).lcm(&9), 72 as $T);
-                assert_eq!((11 as $T).lcm(&5), 55 as $T);
-                assert_eq!((99 as $T).lcm(&17), 1683 as $T);
-            }
-
-            #[test]
-            fn test_divides() {
-                assert!((6 as $T).divides(&(6 as $T)));
-                assert!((6 as $T).divides(&(3 as $T)));
-                assert!((6 as $T).divides(&(1 as $T)));
-            }
-
-            #[test]
-            fn test_even() {
-                assert_eq!((0 as $T).is_even(), true);
-                assert_eq!((1 as $T).is_even(), false);
-                assert_eq!((2 as $T).is_even(), true);
-                assert_eq!((3 as $T).is_even(), false);
-                assert_eq!((4 as $T).is_even(), true);
-            }
-
-            #[test]
-            fn test_odd() {
-                assert_eq!((0 as $T).is_odd(), false);
-                assert_eq!((1 as $T).is_odd(), true);
-                assert_eq!((2 as $T).is_odd(), false);
-                assert_eq!((3 as $T).is_odd(), true);
-                assert_eq!((4 as $T).is_odd(), false);
-            }
-        }
-    )
-}
-
-impl_integer_for_uint!(u8,   test_integer_u8)
-impl_integer_for_uint!(u16,  test_integer_u16)
-impl_integer_for_uint!(u32,  test_integer_u32)
-impl_integer_for_uint!(u64,  test_integer_u64)
-impl_integer_for_uint!(uint, test_integer_uint)
+pub mod integer;
+pub mod rational;
index cfabf2b08e2e81ce574b8f44f5c0eefbdb3de328..b1a951498309fca3c1efed3dc8c1f6aa4c7a2f03 100644 (file)
@@ -81,7 +81,6 @@ struct GammaSmallShape {
 /// See `Gamma` for sampling from a Gamma distribution with general
 /// shape parameters.
 struct GammaLargeShape {
-    shape: f64,
     scale: f64,
     c: f64,
     d: f64
@@ -118,7 +117,6 @@ impl GammaLargeShape {
     fn new_raw(shape: f64, scale: f64) -> GammaLargeShape {
         let d = shape - 1. / 3.;
         GammaLargeShape {
-            shape: shape,
             scale: scale,
             c: 1. / (9. * d).sqrt(),
             d: d
index 7a12dcf9f7f319ffcf32b049c5b94c352dea6a37..1f7216fc1a37d9e05b6270cf121703edc3e1af3f 100644 (file)
 #![no_std]
 #![experimental]
 
+#[cfg(stage0)]
 #[phase(syntax, link)]
 extern crate core;
 
+#[cfg(not(stage0))]
+#[phase(plugin, link)]
+extern crate core;
+
+#[cfg(test, stage0)]
+#[phase(syntax, link)] extern crate std;
+
+#[cfg(test, stage0)]
+#[phase(syntax, link)] extern crate log;
+
+#[cfg(test, not(stage0))]
+#[phase(plugin, link)] extern crate std;
+
+#[cfg(test, not(stage0))]
+#[phase(plugin, link)] extern crate log;
+
 #[cfg(test)] extern crate native;
 #[cfg(test)] extern crate debug;
-#[cfg(test)] #[phase(syntax, link)] extern crate std;
-#[cfg(test)] #[phase(syntax, link)] extern crate log;
 
 use core::prelude::*;
 
index 44c206162ab25f24cadc0d35fecc4b8a7edc301b..61e62a0d1053e960bd905310144fb9fbfe8bbe7c 100644 (file)
@@ -65,7 +65,7 @@
 //!
 //! ```rust
 //! #![feature(phase)]
-//! #[phase(syntax)]
+//! #[phase(plugin)]
 //! extern crate regex_macros;
 //! extern crate regex;
 //!
@@ -95,7 +95,7 @@
 //!
 //! ```rust
 //! # #![feature(phase)]
-//! # extern crate regex; #[phase(syntax)] extern crate regex_macros;
+//! # extern crate regex; #[phase(plugin)] extern crate regex_macros;
 //! # fn main() {
 //! let re = regex!(r"(\d{4})-(\d{2})-(\d{2})");
 //! let text = "2012-03-14, 2013-01-01 and 2014-07-05";
 //!
 //! ```rust
 //! # #![feature(phase)]
-//! # extern crate regex; #[phase(syntax)] extern crate regex_macros;
+//! # extern crate regex; #[phase(plugin)] extern crate regex_macros;
 //! # fn main() {
 //! let re = regex!(r"(?P<y>\d{4})-(?P<m>\d{2})-(?P<d>\d{2})");
 //! let before = "2012-03-14, 2013-01-01 and 2014-07-05";
 //!
 //! ```rust
 //! # #![feature(phase)]
-//! # extern crate regex; #[phase(syntax)] extern crate regex_macros;
+//! # extern crate regex; #[phase(plugin)] extern crate regex_macros;
 //! # fn main() {
 //! let re = regex!(r"(?i)Δ+");
 //! assert_eq!(re.find("ΔδΔ"), Some((0, 6)));
 //!
 //! ```rust
 //! # #![feature(phase)]
-//! # extern crate regex; #[phase(syntax)] extern crate regex_macros;
+//! # extern crate regex; #[phase(plugin)] extern crate regex_macros;
 //! # fn main() {
 //! let re = regex!(r"[\pN\p{Greek}\p{Cherokee}]+");
 //! assert_eq!(re.find("abcΔᎠβⅠᏴγδⅡxyz"), Some((3, 23)));
 //!
 //! ```rust
 //! # #![feature(phase)]
-//! # extern crate regex; #[phase(syntax)] extern crate regex_macros;
+//! # extern crate regex; #[phase(plugin)] extern crate regex_macros;
 //! # fn main() {
 //! let re = regex!(r"(?i)a+(?-i)b+");
 //! let cap = re.captures("AaAaAbbBBBb").unwrap();
index fbe0359ff6fa2001f7fedc0efd1ff582372cce4e..054cbb0fcd63dfa2c518f793bdeb3fd80f4599aa 100644 (file)
@@ -87,7 +87,7 @@ pub fn is_match(regex: &str, text: &str) -> Result<bool, parse::Error> {
 /// ```rust
 /// #![feature(phase)]
 /// extern crate regex;
-/// #[phase(syntax)] extern crate regex_macros;
+/// #[phase(plugin)] extern crate regex_macros;
 ///
 /// fn main() {
 ///     let re = regex!(r"\d+");
@@ -172,7 +172,7 @@ pub fn new(re: &str) -> Result<Regex, parse::Error> {
     ///
     /// ```rust
     /// # #![feature(phase)]
-    /// # extern crate regex; #[phase(syntax)] extern crate regex_macros;
+    /// # extern crate regex; #[phase(plugin)] extern crate regex_macros;
     /// # fn main() {
     /// let text = "I categorically deny having triskaidekaphobia.";
     /// let matched = regex!(r"\b\w{13}\b").is_match(text);
@@ -197,7 +197,7 @@ pub fn is_match(&self, text: &str) -> bool {
     ///
     /// ```rust
     /// # #![feature(phase)]
-    /// # extern crate regex; #[phase(syntax)] extern crate regex_macros;
+    /// # extern crate regex; #[phase(plugin)] extern crate regex_macros;
     /// # fn main() {
     /// let text = "I categorically deny having triskaidekaphobia.";
     /// let pos = regex!(r"\b\w{13}\b").find(text);
@@ -224,7 +224,7 @@ pub fn find(&self, text: &str) -> Option<(uint, uint)> {
     ///
     /// ```rust
     /// # #![feature(phase)]
-    /// # extern crate regex; #[phase(syntax)] extern crate regex_macros;
+    /// # extern crate regex; #[phase(plugin)] extern crate regex_macros;
     /// # fn main() {
     /// let text = "Retroactively relinquishing remunerations is reprehensible.";
     /// for pos in regex!(r"\b\w{13}\b").find_iter(text) {
@@ -263,7 +263,7 @@ pub fn find_iter<'r, 't>(&'r self, text: &'t str) -> FindMatches<'r, 't> {
     ///
     /// ```rust
     /// # #![feature(phase)]
-    /// # extern crate regex; #[phase(syntax)] extern crate regex_macros;
+    /// # extern crate regex; #[phase(plugin)] extern crate regex_macros;
     /// # fn main() {
     /// let re = regex!(r"'([^']+)'\s+\((\d{4})\)");
     /// let text = "Not my favorite movie: 'Citizen Kane' (1941).";
@@ -281,7 +281,7 @@ pub fn find_iter<'r, 't>(&'r self, text: &'t str) -> FindMatches<'r, 't> {
     ///
     /// ```rust
     /// # #![feature(phase)]
-    /// # extern crate regex; #[phase(syntax)] extern crate regex_macros;
+    /// # extern crate regex; #[phase(plugin)] extern crate regex_macros;
     /// # fn main() {
     /// let re = regex!(r"'(?P<title>[^']+)'\s+\((?P<year>\d{4})\)");
     /// let text = "Not my favorite movie: 'Citizen Kane' (1941).";
@@ -314,7 +314,7 @@ pub fn captures<'t>(&self, text: &'t str) -> Option<Captures<'t>> {
     ///
     /// ```rust
     /// # #![feature(phase)]
-    /// # extern crate regex; #[phase(syntax)] extern crate regex_macros;
+    /// # extern crate regex; #[phase(plugin)] extern crate regex_macros;
     /// # fn main() {
     /// let re = regex!(r"'(?P<title>[^']+)'\s+\((?P<year>\d{4})\)");
     /// let text = "'Citizen Kane' (1941), 'The Wizard of Oz' (1939), 'M' (1931).";
@@ -350,7 +350,7 @@ pub fn captures_iter<'r, 't>(&'r self, text: &'t str)
     ///
     /// ```rust
     /// # #![feature(phase)]
-    /// # extern crate regex; #[phase(syntax)] extern crate regex_macros;
+    /// # extern crate regex; #[phase(plugin)] extern crate regex_macros;
     /// # fn main() {
     /// let re = regex!(r"[ \t]+");
     /// let fields: Vec<&str> = re.split("a b \t  c\td    e").collect();
@@ -380,7 +380,7 @@ pub fn split<'r, 't>(&'r self, text: &'t str) -> RegexSplits<'r, 't> {
     ///
     /// ```rust
     /// # #![feature(phase)]
-    /// # extern crate regex; #[phase(syntax)] extern crate regex_macros;
+    /// # extern crate regex; #[phase(plugin)] extern crate regex_macros;
     /// # fn main() {
     /// let re = regex!(r"\W+");
     /// let fields: Vec<&str> = re.splitn("Hey! How are you?", 3).collect();
@@ -410,7 +410,7 @@ pub fn splitn<'r, 't>(&'r self, text: &'t str, limit: uint)
     ///
     /// ```rust
     /// # #![feature(phase)]
-    /// # extern crate regex; #[phase(syntax)] extern crate regex_macros;
+    /// # extern crate regex; #[phase(plugin)] extern crate regex_macros;
     /// # fn main() {
     /// let re = regex!("[^01]+");
     /// assert_eq!(re.replace("1078910", "").as_slice(), "1010");
@@ -424,7 +424,7 @@ pub fn splitn<'r, 't>(&'r self, text: &'t str, limit: uint)
     ///
     /// ```rust
     /// # #![feature(phase)]
-    /// # extern crate regex; #[phase(syntax)] extern crate regex_macros;
+    /// # extern crate regex; #[phase(plugin)] extern crate regex_macros;
     /// # use regex::Captures; fn main() {
     /// let re = regex!(r"([^,\s]+),\s+(\S+)");
     /// let result = re.replace("Springsteen, Bruce", |caps: &Captures| {
@@ -441,7 +441,7 @@ pub fn splitn<'r, 't>(&'r self, text: &'t str, limit: uint)
     ///
     /// ```rust
     /// # #![feature(phase)]
-    /// # extern crate regex; #[phase(syntax)] extern crate regex_macros;
+    /// # extern crate regex; #[phase(plugin)] extern crate regex_macros;
     /// # fn main() {
     /// let re = regex!(r"(?P<last>[^,\s]+),\s+(?P<first>\S+)");
     /// let result = re.replace("Springsteen, Bruce", "$first $last");
@@ -458,7 +458,7 @@ pub fn splitn<'r, 't>(&'r self, text: &'t str, limit: uint)
     ///
     /// ```rust
     /// # #![feature(phase)]
-    /// # extern crate regex; #[phase(syntax)] extern crate regex_macros;
+    /// # extern crate regex; #[phase(plugin)] extern crate regex_macros;
     /// # fn main() {
     /// use regex::NoExpand;
     ///
@@ -775,7 +775,7 @@ pub fn expand(&self, text: &str) -> String {
     }
 }
 
-impl<'t> Container for Captures<'t> {
+impl<'t> Collection for Captures<'t> {
     /// Returns the number of captured groups.
     #[inline]
     fn len(&self) -> uint {
index c563c84fc34ed351971353ffadb6336f77efcc31..96c600b0fda3a4a50f0a5dc04345b1b604d322c1 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 #[cfg(not(stage1))]
-#[phase(syntax)]
+#[phase(plugin)]
 extern crate regex_macros;
 
 #[cfg(not(stage1))]
index fb7e4211d494c74e1d751cd7594fda9e11b22f91..bbee09d0f38b37512ca502e9e2bdf95d0d0e47e4 100644 (file)
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
        html_root_url = "http://doc.rust-lang.org/")]
 
-#![feature(macro_registrar, managed_boxes, quote)]
+#![feature(plugin_registrar, managed_boxes, quote)]
 
 extern crate regex;
 extern crate syntax;
+extern crate rustc;
 
 use std::rc::Rc;
 
 use syntax::ast;
 use syntax::codemap;
 use syntax::ext::build::AstBuilder;
-use syntax::ext::base::{
-    SyntaxExtension, ExtCtxt, MacResult, MacExpr, DummyResult,
-    NormalTT, BasicMacroExpander,
-};
+use syntax::ext::base::{ExtCtxt, MacResult, MacExpr, DummyResult};
 use syntax::parse;
 use syntax::parse::token;
 use syntax::print::pprust;
 
+use rustc::plugin::Registry;
+
 use regex::Regex;
 use regex::native::{
     OneChar, CharClass, Any, Save, Jump, Split,
 };
 
 /// For the `regex!` syntax extension. Do not use.
-#[macro_registrar]
+#[plugin_registrar]
 #[doc(hidden)]
-pub fn macro_registrar(register: |ast::Name, SyntaxExtension|) {
-    let expander = box BasicMacroExpander { expander: native, span: None };
-    register(token::intern("regex"), NormalTT(expander, None))
+pub fn plugin_registrar(reg: &mut Registry) {
+    reg.register_macro("regex", native);
 }
 
 /// Generates specialized code for the Pike VM for a particular regular
index 89c0a381cf9f295afa4e38ab1b797eba50de5978..45e9c7b562d0f1631b36f976bc0cd115bcfb12d1 100644 (file)
 use lib::llvm::{ContextRef, ModuleRef};
 use metadata::common::LinkMeta;
 use metadata::creader;
-use metadata::creader::Loader;
 use middle::cfg;
 use middle::cfg::graphviz::LabelledCFG;
 use middle::{trans, freevars, kind, ty, typeck, lint, reachable};
 use middle::dependency_format;
 use middle;
+use plugin::load::Plugins;
+use plugin::registry::Registry;
+use plugin;
 use util::common::time;
 use util::ppaux;
 use util::nodemap::{NodeSet};
@@ -39,7 +41,6 @@
 use syntax::attr;
 use syntax::attr::{AttrMetaMethods};
 use syntax::crateid::CrateId;
-use syntax::ext::base::CrateLoader;
 use syntax::parse;
 use syntax::parse::token;
 use syntax::print::{pp, pprust};
@@ -75,11 +76,10 @@ pub fn compile_input(sess: Session,
                                                  output,
                                                  krate.attrs.as_slice(),
                                                  &sess);
-            let loader = &mut Loader::new(&sess);
             let id = link::find_crate_id(krate.attrs.as_slice(),
                                          outputs.out_filestem.as_slice());
             let (expanded_crate, ast_map) =
-                phase_2_configure_and_expand(&sess, loader, krate, &id);
+                phase_2_configure_and_expand(&sess, krate, &id);
             (outputs, expanded_crate, ast_map)
         };
         write_out_deps(&sess, input, &outputs, &expanded_crate);
@@ -172,7 +172,6 @@ pub fn phase_1_parse_input(sess: &Session, cfg: ast::CrateConfig, input: &Input)
 /// harness if one is to be provided and injection of a dependency on the
 /// standard library and prelude.
 pub fn phase_2_configure_and_expand(sess: &Session,
-                                    loader: &mut CrateLoader,
                                     mut krate: ast::Crate,
                                     crate_id: &CrateId)
                                     -> (ast::Crate, syntax::ast_map::Map) {
@@ -197,25 +196,42 @@ pub fn phase_2_configure_and_expand(sess: &Session,
     krate = time(time_passes, "configuration 1", krate, |krate|
                  front::config::strip_unconfigured_items(krate));
 
-    krate = time(time_passes, "expansion", krate, |krate| {
-        // Windows dlls do not have rpaths, so they don't know how to find their
-        // dependencies. It's up to us to tell the system where to find all the
-        // dependent dlls. Note that this uses cfg!(windows) as opposed to
-        // targ_cfg because syntax extensions are always loaded for the host
-        // compiler, not for the target.
-        if cfg!(windows) {
-            sess.host_filesearch().add_dylib_search_paths();
+    let Plugins { macros, registrars }
+        = time(time_passes, "plugin loading", (), |_|
+               plugin::load::load_plugins(sess, &krate));
+
+    let mut registry = Registry::new(&krate);
+
+    time(time_passes, "plugin registration", (), |_| {
+        for &registrar in registrars.iter() {
+            registrar(&mut registry);
         }
-        let cfg = syntax::ext::expand::ExpansionConfig {
-            loader: loader,
-            deriving_hash_type_parameter: sess.features.default_type_params.get(),
-            crate_id: crate_id.clone(),
-        };
-        syntax::ext::expand::expand_crate(&sess.parse_sess,
-                                          cfg,
-                                          krate)
     });
 
+    let Registry { syntax_exts, .. } = registry;
+
+    krate = time(time_passes, "expansion", (krate, macros, syntax_exts),
+        |(krate, macros, syntax_exts)| {
+            // Windows dlls do not have rpaths, so they don't know how to find their
+            // dependencies. It's up to us to tell the system where to find all the
+            // dependent dlls. Note that this uses cfg!(windows) as opposed to
+            // targ_cfg because syntax extensions are always loaded for the host
+            // compiler, not for the target.
+            if cfg!(windows) {
+                sess.host_filesearch().add_dylib_search_paths();
+            }
+            let cfg = syntax::ext::expand::ExpansionConfig {
+                deriving_hash_type_parameter: sess.features.default_type_params.get(),
+                crate_id: crate_id.clone(),
+            };
+            syntax::ext::expand::expand_crate(&sess.parse_sess,
+                                              cfg,
+                                              macros,
+                                              syntax_exts,
+                                              krate)
+        }
+    );
+
     // strip again, in case expansion added anything with a #[cfg].
     krate = time(time_passes, "configuration 2", krate, |krate|
                  front::config::strip_unconfigured_items(krate));
@@ -281,9 +297,9 @@ pub fn phase_3_run_analysis_passes(sess: Session,
     time(time_passes, "looking for entry point", (),
          |_| middle::entry::find_entry_point(&sess, krate, &ast_map));
 
-    sess.macro_registrar_fn.set(
-        time(time_passes, "looking for macro registrar", (), |_|
-            syntax::ext::registrar::find_macro_registrar(
+    sess.plugin_registrar_fn.set(
+        time(time_passes, "looking for plugin registrar", (), |_|
+            plugin::build::find_plugin_registrar(
                 sess.diagnostic(), krate)));
 
     let freevars = time(time_passes, "freevar finding", (), |_|
@@ -596,9 +612,7 @@ pub fn pretty_print_input(sess: Session,
 
     let (krate, ast_map, is_expanded) = match ppm {
         PpmExpanded | PpmExpandedIdentified | PpmTyped | PpmFlowGraph(_) => {
-            let loader = &mut Loader::new(&sess);
             let (krate, ast_map) = phase_2_configure_and_expand(&sess,
-                                                                loader,
                                                                 krate,
                                                                 &id);
             (krate, Some(ast_map), true)
index 109622b66277a3c86077059b28cc3092cf3dfc03..773b9e6e0aac4022055e64b6cfea8afa95b38009 100644 (file)
@@ -36,7 +36,7 @@ pub struct Session {
     // For a library crate, this is always none
     pub entry_fn: RefCell<Option<(NodeId, codemap::Span)>>,
     pub entry_type: Cell<Option<config::EntryFnType>>,
-    pub macro_registrar_fn: Cell<Option<ast::NodeId>>,
+    pub plugin_registrar_fn: Cell<Option<ast::NodeId>>,
     pub default_sysroot: Option<Path>,
     // The name of the root source file of the crate, in the local file system. The path is always
     // expected to be absolute. `None` means that there is no source file.
@@ -232,7 +232,7 @@ pub fn build_session_(sopts: config::Options,
         // For a library crate, this is always none
         entry_fn: RefCell::new(None),
         entry_type: Cell::new(None),
-        macro_registrar_fn: Cell::new(None),
+        plugin_registrar_fn: Cell::new(None),
         default_sysroot: default_sysroot,
         local_crate_source_file: local_crate_source_file,
         working_dir: os::getcwd(),
index 25f0dc808c849f62ca1da0391bef7f2e78a04c29..cd472321237624db94cc4ad4b6e4c6776dbb5145 100644 (file)
@@ -46,7 +46,7 @@
     ("thread_local", Active),
     ("link_args", Active),
     ("phase", Active),
-    ("macro_registrar", Active),
+    ("plugin_registrar", Active),
     ("log_syntax", Active),
     ("trace_macros", Active),
     ("concat_idents", Active),
@@ -56,6 +56,8 @@
     ("quote", Active),
     ("linkage", Active),
     ("struct_inherit", Active),
+    ("overloaded_calls", Active),
+    ("unboxed_closure_sugar", Active),
 
     ("quad_precision_float", Active),
 
@@ -86,6 +88,7 @@ pub struct Features {
     pub default_type_params: Cell<bool>,
     pub quad_precision_float: Cell<bool>,
     pub issue_5723_bootstrap: Cell<bool>,
+    pub overloaded_calls: Cell<bool>,
 }
 
 impl Features {
@@ -94,6 +97,7 @@ pub fn new() -> Features {
             default_type_params: Cell::new(false),
             quad_precision_float: Cell::new(false),
             issue_5723_bootstrap: Cell::new(false),
+            overloaded_calls: Cell::new(false),
         }
     }
 }
@@ -192,10 +196,9 @@ fn visit_item(&mut self, i: &ast::Item, _:()) {
             }
 
             ast::ItemFn(..) => {
-                if attr::contains_name(i.attrs.as_slice(), "macro_registrar") {
-                    self.gate_feature("macro_registrar", i.span,
-                                      "cross-crate macro exports are \
-                                       experimental and possibly buggy");
+                if attr::contains_name(i.attrs.as_slice(), "plugin_registrar") {
+                    self.gate_feature("plugin_registrar", i.span,
+                                      "compiler plugins are experimental and possibly buggy");
                 }
             }
 
@@ -289,6 +292,11 @@ fn visit_ty(&mut self, t: &ast::Ty, _: ()) {
 
             },
             ast::TyBox(_) => { self.gate_box(t.span); }
+            ast::TyUnboxedFn(_) => {
+                self.gate_feature("unboxed_closure_sugar",
+                                  t.span,
+                                  "unboxed closure trait sugar is experimental");
+            }
             _ => {}
         }
 
@@ -376,4 +384,5 @@ pub fn check_crate(sess: &Session, krate: &ast::Crate) {
     sess.features.default_type_params.set(cx.has_feature("default_type_params"));
     sess.features.quad_precision_float.set(cx.has_feature("quad_precision_float"));
     sess.features.issue_5723_bootstrap.set(cx.has_feature("issue_5723_bootstrap"));
+    sess.features.overloaded_calls.set(cx.has_feature("overloaded_calls"));
 }
index fe636f7b686a018f839e37229238214752c671c0..0bb1481a4022572c6c0509e3201943af22e3568d 100644 (file)
@@ -81,7 +81,7 @@ fn fold_crate(&mut self, mut krate: ast::Crate) -> ast::Crate {
                 attr::mk_attr_outer(attr::mk_attr_id(), attr::mk_list_item(
                         InternedString::new("phase"),
                         vec!(
-                            attr::mk_word_item(InternedString::new("syntax")),
+                            attr::mk_word_item(InternedString::new("plugin")),
                             attr::mk_word_item(InternedString::new("link")
                         ))))),
             vis: ast::Inherited,
@@ -130,9 +130,7 @@ fn inject_crates_ref(sess: &Session, krate: ast::Crate) -> ast::Crate {
     fold.fold_crate(krate)
 }
 
-struct PreludeInjector<'a> {
-    sess: &'a Session,
-}
+struct PreludeInjector<'a>;
 
 
 impl<'a> fold::Folder for PreludeInjector<'a> {
@@ -223,9 +221,7 @@ fn fold_mod(&mut self, module: &ast::Mod) -> ast::Mod {
     }
 }
 
-fn inject_prelude(sess: &Session, krate: ast::Crate) -> ast::Crate {
-    let mut fold = PreludeInjector {
-        sess: sess,
-    };
+fn inject_prelude(_: &Session, krate: ast::Crate) -> ast::Crate {
+    let mut fold = PreludeInjector;
     fold.fold_crate(krate)
 }
index b21f3c2a019322ea5d74265b9bc720ae0e1ec052..174bcc86d263a4f0f9c82fe18a0dcdc452e7a941 100644 (file)
@@ -16,7 +16,6 @@
 use driver::session::Session;
 use front::config;
 use front::std_inject::with_version;
-use metadata::creader::Loader;
 
 use std::cell::RefCell;
 use std::slice;
@@ -150,12 +149,10 @@ fn nomain(item: @ast::Item) -> @ast::Item {
 
 fn generate_test_harness(sess: &Session, krate: ast::Crate)
                          -> ast::Crate {
-    let loader = &mut Loader::new(sess);
     let mut cx: TestCtxt = TestCtxt {
         sess: sess,
         ext_cx: ExtCtxt::new(&sess.parse_sess, sess.opts.cfg.clone(),
                              ExpansionConfig {
-                                 loader: loader,
                                  deriving_hash_type_parameter: false,
                                  crate_id: from_str("test").unwrap(),
                              }),
index 1b17cfb1bae01dd8b038ea644fb8a82812330e1c..4ac4e3a5a9ffbd547f2dffcf4a3c60aba6781916 100644 (file)
 extern crate syntax;
 extern crate time;
 
+#[cfg(stage0)]
 #[phase(syntax, link)]
 extern crate log;
 
+#[cfg(not(stage0))]
+#[phase(plugin, link)]
+extern crate log;
+
 pub mod middle {
     pub mod def;
     pub mod trans;
@@ -109,6 +114,8 @@ pub mod back {
 
 pub mod driver;
 
+pub mod plugin;
+
 pub mod util {
     pub mod common;
     pub mod ppaux;
index 6287683c1a1416313d15822ed2085d2b40ec3fc3..2ff656853c3bdbffb9617dbc56ef6bb320642452 100644 (file)
@@ -198,7 +198,7 @@ pub fn from_uint(value : uint) -> Option<astencode_tag> {
 pub static tag_native_libraries_name: uint = 0x89;
 pub static tag_native_libraries_kind: uint = 0x8a;
 
-pub static tag_macro_registrar_fn: uint = 0x8b;
+pub static tag_plugin_registrar_fn: uint = 0x8b;
 pub static tag_exported_macros: uint = 0x8c;
 pub static tag_macro_def: uint = 0x8d;
 
index 38d2b7a67a0e17e5afd36228de48822e630d7a32..4df21fbc974be7f20f78d5d57eab24c1ff7d19e6 100644 (file)
@@ -21,6 +21,7 @@
 use metadata::decoder;
 use metadata::loader;
 use metadata::loader::CratePaths;
+use plugin::load::PluginMetadata;
 
 use std::rc::Rc;
 use std::collections::HashMap;
@@ -30,7 +31,6 @@
 use syntax::attr::AttrMetaMethods;
 use syntax::codemap::{Span};
 use syntax::diagnostic::SpanHandler;
-use syntax::ext::base::{CrateLoader, MacroCrate};
 use syntax::parse::token::InternedString;
 use syntax::parse::token;
 use syntax::crateid::CrateId;
@@ -379,23 +379,21 @@ fn resolve_crate_deps(e: &mut Env,
     }).collect()
 }
 
-pub struct Loader<'a> {
+pub struct PluginMetadataReader<'a> {
     env: Env<'a>,
 }
 
-impl<'a> Loader<'a> {
-    pub fn new(sess: &'a Session) -> Loader<'a> {
-        Loader {
+impl<'a> PluginMetadataReader<'a> {
+    pub fn new(sess: &'a Session) -> PluginMetadataReader<'a> {
+        PluginMetadataReader {
             env: Env {
                 sess: sess,
                 next_crate_num: sess.cstore.next_crate_num(),
             }
         }
     }
-}
 
-impl<'a> CrateLoader for Loader<'a> {
-    fn load_crate(&mut self, krate: &ast::ViewItem) -> MacroCrate {
+    pub fn read_plugin_metadata(&mut self, krate: &ast::ViewItem) -> PluginMetadata {
         let info = extract_crate_info(&self.env, krate).unwrap();
         let target_triple = self.env.sess.targ_cfg.target_strs.target_triple.as_slice();
         let is_cross = target_triple != driver::host_triple();
@@ -425,8 +423,8 @@ fn load_crate(&mut self, krate: &ast::ViewItem) -> MacroCrate {
                 load_ctxt.os = config::cfg_os_to_meta_os(self.env.sess.targ_cfg.os);
                 load_ctxt.filesearch = self.env.sess.target_filesearch();
                 let lib = load_ctxt.load_library_crate();
-                if decoder::get_macro_registrar_fn(lib.metadata.as_slice()).is_some() {
-                    let message = format!("crate `{}` contains a macro_registrar fn but \
+                if decoder::get_plugin_registrar_fn(lib.metadata.as_slice()).is_some() {
+                    let message = format!("crate `{}` contains a plugin_registrar fn but \
                                   only a version for triple `{}` could be found (need {})",
                                   info.ident, target_triple, driver::host_triple());
                     self.env.sess.span_err(krate.span, message.as_slice());
@@ -441,10 +439,10 @@ fn load_crate(&mut self, krate: &ast::ViewItem) -> MacroCrate {
             None => { load_ctxt.report_load_errs(); unreachable!() },
         };
         let macros = decoder::get_exported_macros(library.metadata.as_slice());
-        let registrar = decoder::get_macro_registrar_fn(library.metadata.as_slice()).map(|id| {
+        let registrar = decoder::get_plugin_registrar_fn(library.metadata.as_slice()).map(|id| {
             decoder::get_symbol(library.metadata.as_slice(), id).to_string()
         });
-        let mc = MacroCrate {
+        let pc = PluginMetadata {
             lib: library.dylib.clone(),
             macros: macros.move_iter().map(|x| x.to_string()).collect(),
             registrar_symbol: registrar,
@@ -454,6 +452,6 @@ fn load_crate(&mut self, krate: &ast::ViewItem) -> MacroCrate {
             register_crate(&mut self.env, &None, info.ident.as_slice(),
                            &info.crate_id, krate.span, library);
         }
-        mc
+        pc
     }
 }
index c7ad74dce571c5fcae73c6900728d68fa3fe0fd0..0a88abd67d9dfffab5e5c96512b81598c23f745c 100644 (file)
@@ -321,3 +321,8 @@ pub fn get_reachable_extern_fns(cstore: &cstore::CStore, cnum: ast::CrateNum)
     let cdata = cstore.get_crate_data(cnum);
     decoder::get_reachable_extern_fns(&*cdata)
 }
+
+pub fn is_typedef(cstore: &cstore::CStore, did: ast::DefId) -> bool {
+    let cdata = cstore.get_crate_data(did.krate);
+    decoder::is_typedef(&*cdata, did.node)
+}
index aa8d695465a117628ae29c0566200128a29c0a68..846f879104f64f7ba559e62815d7b025d65b024e 100644 (file)
@@ -139,9 +139,6 @@ pub fn get_used_crate_source(&self, cnum: ast::CrateNum)
             .map(|source| source.clone())
     }
 
-    pub fn dump_phase_syntax_crates(&self) {
-    }
-
     pub fn reset(&self) {
         self.metas.borrow_mut().clear();
         self.extern_mod_crate_map.borrow_mut().clear();
index c67b5bf1a60076363268a27db47f53d0e7a2df31..56d6766e1b719f6be681c7f2d0bdb7d820194c2f 100644 (file)
@@ -1255,8 +1255,8 @@ pub fn get_native_libraries(cdata: Cmd)
     return result;
 }
 
-pub fn get_macro_registrar_fn(data: &[u8]) -> Option<ast::NodeId> {
-    reader::maybe_get_doc(ebml::Doc::new(data), tag_macro_registrar_fn)
+pub fn get_plugin_registrar_fn(data: &[u8]) -> Option<ast::NodeId> {
+    reader::maybe_get_doc(ebml::Doc::new(data), tag_plugin_registrar_fn)
         .map(|doc| FromPrimitive::from_u32(reader::doc_as_u32(doc)).unwrap())
 }
 
@@ -1339,3 +1339,11 @@ pub fn get_reachable_extern_fns(cdata: Cmd) -> Vec<ast::DefId> {
     });
     return ret;
 }
+
+pub fn is_typedef(cdata: Cmd, id: ast::NodeId) -> bool {
+    let item_doc = lookup_item(id, cdata.data());
+    match item_family(item_doc) {
+        Type => true,
+        _ => false,
+    }
+}
index 37cb75e4697b30cff2dc253d672077d074ff6302..1846c9c881bc570fd3611dc83bf8c33629d3fd93 100644 (file)
@@ -1582,9 +1582,9 @@ fn encode_native_libraries(ecx: &EncodeContext, ebml_w: &mut Encoder) {
     ebml_w.end_tag();
 }
 
-fn encode_macro_registrar_fn(ecx: &EncodeContext, ebml_w: &mut Encoder) {
-    match ecx.tcx.sess.macro_registrar_fn.get() {
-        Some(id) => { ebml_w.wr_tagged_u32(tag_macro_registrar_fn, id); }
+fn encode_plugin_registrar_fn(ecx: &EncodeContext, ebml_w: &mut Encoder) {
+    match ecx.tcx.sess.plugin_registrar_fn.get() {
+        Some(id) => { ebml_w.wr_tagged_u32(tag_plugin_registrar_fn, id); }
         None => {}
     }
 }
@@ -1791,7 +1791,7 @@ struct Stats {
         dep_bytes: u64,
         lang_item_bytes: u64,
         native_lib_bytes: u64,
-        macro_registrar_fn_bytes: u64,
+        plugin_registrar_fn_bytes: u64,
         macro_defs_bytes: u64,
         impl_bytes: u64,
         misc_bytes: u64,
@@ -1805,7 +1805,7 @@ struct Stats {
         dep_bytes: 0,
         lang_item_bytes: 0,
         native_lib_bytes: 0,
-        macro_registrar_fn_bytes: 0,
+        plugin_registrar_fn_bytes: 0,
         macro_defs_bytes: 0,
         impl_bytes: 0,
         misc_bytes: 0,
@@ -1870,10 +1870,10 @@ struct Stats {
     encode_native_libraries(&ecx, &mut ebml_w);
     stats.native_lib_bytes = ebml_w.writer.tell().unwrap() - i;
 
-    // Encode the macro registrar function
+    // Encode the plugin registrar function
     i = ebml_w.writer.tell().unwrap();
-    encode_macro_registrar_fn(&ecx, &mut ebml_w);
-    stats.macro_registrar_fn_bytes = ebml_w.writer.tell().unwrap() - i;
+    encode_plugin_registrar_fn(&ecx, &mut ebml_w);
+    stats.plugin_registrar_fn_bytes = ebml_w.writer.tell().unwrap() - i;
 
     // Encode macro definitions
     i = ebml_w.writer.tell().unwrap();
@@ -1912,18 +1912,18 @@ struct Stats {
         }
 
         println!("metadata stats:");
-        println!("      attribute bytes: {}", stats.attr_bytes);
-        println!("            dep bytes: {}", stats.dep_bytes);
-        println!("      lang item bytes: {}", stats.lang_item_bytes);
-        println!("         native bytes: {}", stats.native_lib_bytes);
-        println!("macro registrar bytes: {}", stats.macro_registrar_fn_bytes);
-        println!("      macro def bytes: {}", stats.macro_defs_bytes);
-        println!("           impl bytes: {}", stats.impl_bytes);
-        println!("           misc bytes: {}", stats.misc_bytes);
-        println!("           item bytes: {}", stats.item_bytes);
-        println!("          index bytes: {}", stats.index_bytes);
-        println!("           zero bytes: {}", stats.zero_bytes);
-        println!("          total bytes: {}", stats.total_bytes);
+        println!("       attribute bytes: {}", stats.attr_bytes);
+        println!("             dep bytes: {}", stats.dep_bytes);
+        println!("       lang item bytes: {}", stats.lang_item_bytes);
+        println!("          native bytes: {}", stats.native_lib_bytes);
+        println!("plugin registrar bytes: {}", stats.plugin_registrar_fn_bytes);
+        println!("       macro def bytes: {}", stats.macro_defs_bytes);
+        println!("            impl bytes: {}", stats.impl_bytes);
+        println!("            misc bytes: {}", stats.misc_bytes);
+        println!("            item bytes: {}", stats.item_bytes);
+        println!("           index bytes: {}", stats.index_bytes);
+        println!("            zero bytes: {}", stats.zero_bytes);
+        println!("           total bytes: {}", stats.total_bytes);
     }
 }
 
index 9033b83d47420cacf22e2d3c6088f5cc8efb9cd9..ec46e7f8592d3391ffbc4e69e101bf47df625e61 100644 (file)
@@ -13,7 +13,7 @@
 use std::cell::RefCell;
 use std::os;
 use std::io::fs;
-use std::unstable::dynamic_lib::DynamicLibrary;
+use std::dynamic_lib::DynamicLibrary;
 use std::collections::HashSet;
 
 use myfs = util::fs;
index acd96b94f315e3e4def4ba6fbf8cd7f25dc40f5e..cfda97ad26fd77860573621c224ec92743bd548d 100644 (file)
@@ -86,7 +86,7 @@ pub struct Library {
 }
 
 pub struct ArchiveMetadata {
-    archive: ArchiveRO,
+    _archive: ArchiveRO,
     // See comments in ArchiveMetadata::new for why this is static
     data: &'static [u8],
 }
@@ -487,7 +487,7 @@ fn new(ar: ArchiveRO) -> Option<ArchiveMetadata> {
             unsafe { mem::transmute(data) }
         };
         Some(ArchiveMetadata {
-            archive: ar,
+            _archive: ar,
             data: data,
         })
     }
index f48dbecc53025e362f0b5e2858ea979fa9284c1f..363fcf79eb52129384083a38d87d9310f15f0cff 100644 (file)
@@ -42,8 +42,6 @@ pub struct ctxt<'a> {
 // Extra parameters are for converting to/from def_ids in the string rep.
 // Whatever format you choose should not contain pipe characters.
 pub struct ty_abbrev {
-    pos: uint,
-    len: uint,
     s: String
 }
 
@@ -68,8 +66,6 @@ fn estimate_sz(u: u64) -> u64 {
     if abbrev_len < len {
         // I.e. it's actually an abbreviation.
         cx.abbrevs.borrow_mut().insert(t, ty_abbrev {
-            pos: pos as uint,
-            len: len as uint,
             s: format!("\\#{:x}:{:x}\\#", pos, len)
         });
     }
index 3337a56edf008d8f52f7e29d1f6d03bb3a034c43..dc8567af9edad9fb9727a8639815791ca6d86479 100644 (file)
@@ -29,7 +29,7 @@ pub fn guarantee_lifetime(bccx: &BorrowckCtxt,
                           cause: euv::LoanCause,
                           cmt: mc::cmt,
                           loan_region: ty::Region,
-                          loan_kind: ty::BorrowKind)
+                          _: ty::BorrowKind)
                           -> Result<(),()> {
     debug!("guarantee_lifetime(cmt={}, loan_region={})",
            cmt.repr(bccx.tcx), loan_region.repr(bccx.tcx));
@@ -38,7 +38,6 @@ pub fn guarantee_lifetime(bccx: &BorrowckCtxt,
                                          span: span,
                                          cause: cause,
                                          loan_region: loan_region,
-                                         loan_kind: loan_kind,
                                          cmt_original: cmt.clone()};
     ctxt.check(&cmt, None)
 }
@@ -55,7 +54,6 @@ struct GuaranteeLifetimeContext<'a> {
     span: Span,
     cause: euv::LoanCause,
     loan_region: ty::Region,
-    loan_kind: ty::BorrowKind,
     cmt_original: mc::cmt
 }
 
index 003687e7b63f9e342c86074d2fd4e3c9fa346a2d..ec362f924418c0ba77b8ea153a0ece57efbafdbb 100644 (file)
@@ -310,7 +310,6 @@ fn guarantee_valid(&mut self,
                 Loan {
                     index: self.all_loans.len(),
                     loan_path: loan_path,
-                    cmt: cmt,
                     kind: req_kind,
                     gen_scope: gen_scope,
                     kill_scope: kill_scope,
@@ -481,8 +480,7 @@ pub fn report_potential_errors(&self) {
 /// This visitor walks static initializer's expressions and makes
 /// sure the loans being taken are sound.
 struct StaticInitializerCtxt<'a> {
-    bccx: &'a BorrowckCtxt<'a>,
-    item_ub: ast::NodeId,
+    bccx: &'a BorrowckCtxt<'a>
 }
 
 impl<'a> visit::Visitor<()> for StaticInitializerCtxt<'a> {
@@ -509,8 +507,7 @@ pub fn gather_loans_in_static_initializer(bccx: &mut BorrowckCtxt, expr: &ast::E
     debug!("gather_loans_in_static_initializer(expr={})", expr.repr(bccx.tcx));
 
     let mut sicx = StaticInitializerCtxt {
-        bccx: bccx,
-        item_ub: expr.id,
+        bccx: bccx
     };
 
     sicx.visit_expr(expr, ());
index 552381e4216538bd7d6bb7078a3f0bc2a9fceffd..7c1f5937472970f86af8903950c8a46b1fa13063 100644 (file)
@@ -36,7 +36,6 @@ pub fn compute_restrictions(bccx: &BorrowckCtxt,
         bccx: bccx,
         span: span,
         cause: cause,
-        cmt_original: cmt.clone(),
         loan_region: loan_region,
     };
 
@@ -49,7 +48,6 @@ pub fn compute_restrictions(bccx: &BorrowckCtxt,
 struct RestrictionsContext<'a> {
     bccx: &'a BorrowckCtxt<'a>,
     span: Span,
-    cmt_original: mc::cmt,
     loan_region: ty::Region,
     cause: euv::LoanCause,
 }
index 5706d249c46dabd98f12e670462b468dff96c1f1..7aaba22dd843584150e5e50bbdd2ea8379bb7a1e 100644 (file)
@@ -180,7 +180,6 @@ pub enum PartialTotal {
 pub struct Loan {
     index: uint,
     loan_path: Rc<LoanPath>,
-    cmt: mc::cmt,
     kind: ty::BorrowKind,
     restrictions: Vec<Restriction>,
     gen_scope: ast::NodeId,
index fb19fbd70c69e117c0159c6454bbc6bcc956b179..46899ae19ca095f84bed03c2c85fe211cca8f2de 100644 (file)
@@ -124,6 +124,32 @@ fn lookup_and_handle_method(&mut self, id: ast::NodeId,
         }
     }
 
+    fn handle_field_access(&mut self, lhs: &ast::Expr, name: &ast::Ident) {
+        match ty::get(ty::expr_ty_adjusted(self.tcx, lhs)).sty {
+            ty::ty_struct(id, _) => {
+                let fields = ty::lookup_struct_fields(self.tcx, id);
+                let field_id = fields.iter()
+                    .find(|field| field.name == name.name).unwrap().id;
+                self.live_symbols.insert(field_id.node);
+            },
+            _ => ()
+        }
+    }
+
+    fn handle_field_pattern_match(&mut self, lhs: &ast::Pat, pats: &[ast::FieldPat]) {
+        match self.tcx.def_map.borrow().get(&lhs.id) {
+            &def::DefStruct(id) | &def::DefVariant(_, id, _) => {
+                let fields = ty::lookup_struct_fields(self.tcx, id);
+                for pat in pats.iter() {
+                    let field_id = fields.iter()
+                        .find(|field| field.name == pat.ident.name).unwrap().id;
+                    self.live_symbols.insert(field_id.node);
+                }
+            }
+            _ => ()
+        }
+    }
+
     fn mark_live_symbols(&mut self) {
         let mut scanned = HashSet::new();
         while self.worklist.len() > 0 {
@@ -147,10 +173,22 @@ fn visit_node(&mut self, node: &ast_map::Node) {
         match *node {
             ast_map::NodeItem(item) => {
                 match item.node {
+                    ast::ItemStruct(struct_def, _) => {
+                        let has_extern_repr = item.attrs.iter().fold(attr::ReprAny, |acc, attr| {
+                            attr::find_repr_attr(self.tcx.sess.diagnostic(), attr, acc)
+                        }) == attr::ReprExtern;
+                        let live_fields = struct_def.fields.iter().filter(|f| {
+                            has_extern_repr || match f.node.kind {
+                                ast::NamedField(_, ast::Public) => true,
+                                _ => false
+                            }
+                        });
+                        self.live_symbols.extend(live_fields.map(|f| f.node.id));
+                        visit::walk_item(self, item, ());
+                    }
                     ast::ItemFn(..)
                     | ast::ItemTy(..)
                     | ast::ItemEnum(..)
-                    | ast::ItemStruct(..)
                     | ast::ItemStatic(..) => {
                         visit::walk_item(self, item, ());
                     }
@@ -178,18 +216,32 @@ fn visit_expr(&mut self, expr: &ast::Expr, _: ()) {
             ast::ExprMethodCall(..) => {
                 self.lookup_and_handle_method(expr.id, expr.span);
             }
+            ast::ExprField(ref lhs, ref ident, _) => {
+                self.handle_field_access(*lhs, ident);
+            }
             _ => ()
         }
 
         visit::walk_expr(self, expr, ())
     }
 
+    fn visit_pat(&mut self, pat: &ast::Pat, _: ()) {
+        match pat.node {
+            ast::PatStruct(_, ref fields, _) => {
+                self.handle_field_pattern_match(pat, fields.as_slice());
+            }
+            _ => ()
+        }
+
+        visit::walk_pat(self, pat, ())
+    }
+
     fn visit_path(&mut self, path: &ast::Path, id: ast::NodeId, _: ()) {
         self.lookup_and_handle_definition(&id);
         visit::walk_path(self, path, ());
     }
 
-    fn visit_item(&mut self, _item: &ast::Item, _: ()) {
+    fn visit_item(&mut self, _: &ast::Item, _: ()) {
         // Do not recurse into items. These items will be added to the
         // worklist and recursed into manually if necessary.
     }
@@ -317,6 +369,23 @@ struct DeadVisitor<'a> {
 }
 
 impl<'a> DeadVisitor<'a> {
+    fn should_warn_about_field(&mut self, node: &ast::StructField_) -> bool {
+        let (is_named, has_leading_underscore) = match node.ident() {
+            Some(ref ident) => (true, token::get_ident(*ident).get()[0] == ('_' as u8)),
+            _ => (false, false)
+        };
+        let field_type = ty::node_id_to_type(self.tcx, node.id);
+        let is_marker_field = match ty::ty_to_def_id(field_type) {
+            Some(def_id) => self.tcx.lang_items.items().any(|(_, item)| *item == Some(def_id)),
+            _ => false
+        };
+        is_named
+            && !self.symbol_is_live(node.id, None)
+            && !has_leading_underscore
+            && !is_marker_field
+            && !has_allow_dead_code_or_lang_attr(node.attrs.as_slice())
+    }
+
     // id := node id of an item's definition.
     // ctor_id := `Some` if the item is a struct_ctor (tuple struct),
     //            `None` otherwise.
@@ -399,6 +468,14 @@ fn visit_fn(&mut self, fk: &visit::FnKind,
         visit::walk_block(self, block, ());
     }
 
+    fn visit_struct_field(&mut self, field: &ast::StructField, _: ()) {
+        if self.should_warn_about_field(&field.node) {
+            self.warn_dead_code(field.node.id, field.span, field.node.ident().unwrap());
+        }
+
+        visit::walk_struct_field(self, field, ());
+    }
+
     // Overwrite so that we don't warn the trait method itself.
     fn visit_trait_method(&mut self, trait_method: &ast::TraitMethod, _: ()) {
         match *trait_method {
index c44ea0ae78b10a9765fbc466a8a1b70672f041ce..540dfdab19e990b6362f1926bf4e6e07954ae41f 100644 (file)
@@ -19,6 +19,7 @@
 use middle::freevars;
 use middle::pat_util;
 use middle::ty;
+use middle::typeck::MethodCall;
 use middle::typeck;
 use syntax::ast;
 use syntax::codemap::{Span};
@@ -427,10 +428,20 @@ fn walk_callee(&mut self, call: &ast::Expr, callee: &ast::Expr) {
                 }
             }
             _ => {
-                self.tcx().sess.span_bug(
-                    callee.span,
-                    format!("unxpected callee type {}",
-                            callee_ty.repr(self.tcx())).as_slice());
+                match self.tcx()
+                          .method_map
+                          .borrow()
+                          .find(&MethodCall::expr(call.id)) {
+                    Some(_) => {
+                        // FIXME(#14774, pcwalton): Implement this.
+                    }
+                    None => {
+                        self.tcx().sess.span_bug(
+                            callee.span,
+                            format!("unxpected callee type {}",
+                                    callee_ty.repr(self.tcx())).as_slice());
+                    }
+                }
             }
         }
     }
index 748c29cd92c42d56ffc1d2dfbcba3a1d9d46f040..20e4188a8f6c5cf01386610e71d9b435b0b4a968 100644 (file)
@@ -240,6 +240,10 @@ pub fn collect_language_items(krate: &ast::Crate,
     DerefTraitLangItem,              "deref",                   deref_trait;
     DerefMutTraitLangItem,           "deref_mut",               deref_mut_trait;
 
+    FnTraitLangItem,                 "fn",                      fn_trait;
+    FnMutTraitLangItem,              "fn_mut",                  fn_mut_trait;
+    FnOnceTraitLangItem,             "fn_once",                 fn_once_trait;
+
     EqTraitLangItem,                 "eq",                      eq_trait;
     OrdTraitLangItem,                "ord",                     ord_trait;
 
index 9500f4d7ceebace551f0e5e87b3900ed2d8f48e0..a3ee8003a455f12b5b4e123fedfec91456a63167 100644 (file)
@@ -1253,12 +1253,21 @@ fn is_camel_case(ident: ast::Ident) -> bool {
         !ident.char_at(0).is_lowercase() && !ident.contains_char('_')
     }
 
+    fn to_camel_case(s: &str) -> String {
+        s.split('_').flat_map(|word| word.chars().enumerate().map(|(i, c)|
+            if i == 0 { c.to_uppercase() }
+            else { c }
+        )).collect()
+    }
+
     fn check_case(cx: &Context, sort: &str, ident: ast::Ident, span: Span) {
+        let s = token::get_ident(ident);
+
         if !is_camel_case(ident) {
             cx.span_lint(
                 NonCamelCaseTypes, span,
-                format!("{} `{}` should have a camel case identifier",
-                    sort, token::get_ident(ident)).as_slice());
+                format!("{} `{}` should have a camel case name such as `{}`",
+                    sort, s, to_camel_case(s.get())).as_slice());
         }
     }
 
@@ -1296,10 +1305,29 @@ fn is_snake_case(ident: ast::Ident) -> bool {
         })
     }
 
+    fn to_snake_case(str: &str) -> String {
+        let mut words = vec![];
+        for s in str.split('_') {
+            let mut buf = String::new();
+            if s.is_empty() { continue; }
+            for ch in s.chars() {
+                if !buf.is_empty() && ch.is_uppercase() {
+                    words.push(buf);
+                    buf = String::new();
+                }
+                buf.push_char(ch.to_lowercase());
+            }
+            words.push(buf);
+        }
+        words.connect("_")
+    }
+
+    let s = token::get_ident(ident);
+
     if !is_snake_case(ident) {
         cx.span_lint(NonSnakeCaseFunctions, span,
-                    format!("{} `{}` should have a snake case identifier",
-                            sort, token::get_ident(ident)).as_slice());
+                    format!("{} `{}` should have a snake case name such as `{}`",
+                            sort, s, to_snake_case(s.get())).as_slice());
     }
 }
 
@@ -1313,7 +1341,10 @@ fn check_item_non_uppercase_statics(cx: &Context, it: &ast::Item) {
             // upper/lowercase)
             if s.get().chars().any(|c| c.is_lowercase()) {
                 cx.span_lint(NonUppercaseStatics, it.span,
-                             "static constant should have an uppercase identifier");
+                            format!("static constant `{}` should have an uppercase name \
+                                such as `{}`", s.get(),
+                                s.get().chars().map(|c| c.to_uppercase())
+                                    .collect::<String>().as_slice()).as_slice());
             }
         }
         _ => {}
@@ -1329,7 +1360,10 @@ fn check_pat_non_uppercase_statics(cx: &Context, p: &ast::Pat) {
             let s = token::get_ident(ident);
             if s.get().chars().any(|c| c.is_lowercase()) {
                 cx.span_lint(NonUppercasePatternStatics, path.span,
-                             "static constant in pattern should be all caps");
+                            format!("static constant in pattern `{}` should have an uppercase \
+                                name such as `{}`", s.get(),
+                                s.get().chars().map(|c| c.to_uppercase())
+                                    .collect::<String>().as_slice()).as_slice());
             }
         }
         _ => {}
index 8b1de130053ee15f944f3640a9a87769df2784b8..a7fd81e9c9a83e84f2368831d9107fddf06392a2 100644 (file)
 use middle::def::*;
 use middle::freevars;
 use middle::lint::{UnusedVariable, DeadAssignment};
+use middle::mem_categorization::Typer;
 use middle::pat_util;
 use middle::ty;
 use util::nodemap::NodeMap;
@@ -225,21 +226,12 @@ fn invalid_node() -> LiveNode { LiveNode(uint::MAX) }
 
 struct CaptureInfo {
     ln: LiveNode,
-    is_move: bool,
     var_nid: NodeId
 }
 
-enum LocalKind {
-    FromMatch(BindingMode),
-    FromLetWithInitializer,
-    FromLetNoInitializer
-}
-
 struct LocalInfo {
     id: NodeId,
-    ident: Ident,
-    is_mutbl: bool,
-    kind: LocalKind,
+    ident: Ident
 }
 
 enum VarKind {
@@ -405,23 +397,13 @@ fn visit_fn(ir: &mut IrMaps,
 }
 
 fn visit_local(ir: &mut IrMaps, local: &Local) {
-    pat_util::pat_bindings(&ir.tcx.def_map, local.pat, |bm, p_id, sp, path| {
+    pat_util::pat_bindings(&ir.tcx.def_map, local.pat, |_, p_id, sp, path| {
         debug!("adding local variable {}", p_id);
         let name = ast_util::path_to_ident(path);
         ir.add_live_node_for_node(p_id, VarDefNode(sp));
-        let kind = match local.init {
-          Some(_) => FromLetWithInitializer,
-          None => FromLetNoInitializer
-        };
-        let mutbl = match bm {
-            BindByValue(MutMutable) => true,
-            _ => false
-        };
         ir.add_variable(Local(LocalInfo {
           id: p_id,
-          ident: name,
-          is_mutbl: mutbl,
-          kind: kind
+          ident: name
         }));
     });
     visit::walk_local(ir, local, ());
@@ -433,16 +415,10 @@ fn visit_arm(ir: &mut IrMaps, arm: &Arm) {
             debug!("adding local variable {} from match with bm {:?}",
                    p_id, bm);
             let name = ast_util::path_to_ident(path);
-            let mutbl = match bm {
-                BindByValue(MutMutable) => true,
-                _ => false
-            };
             ir.add_live_node_for_node(p_id, VarDefNode(sp));
             ir.add_variable(Local(LocalInfo {
                 id: p_id,
-                ident: name,
-                is_mutbl: mutbl,
-                kind: FromMatch(bm)
+                ident: name
             }));
         })
     }
@@ -480,27 +456,12 @@ fn visit_expr(ir: &mut IrMaps, expr: &Expr) {
         // in better error messages than just pointing at the closure
         // construction site.
         let mut call_caps = Vec::new();
-        let fv_mode = freevars::get_capture_mode(ir.tcx, expr.id);
         freevars::with_freevars(ir.tcx, expr.id, |freevars| {
             for fv in freevars.iter() {
                 match moved_variable_node_id_from_def(fv.def) {
                     Some(rv) => {
                         let fv_ln = ir.add_live_node(FreeVarNode(fv.span));
-                        let fv_id = fv.def.def_id().node;
-                        let fv_ty = ty::node_id_to_type(ir.tcx, fv_id);
-                        let is_move = match fv_mode {
-                            // var must be dead afterwards
-                            freevars::CaptureByValue => {
-                                ty::type_moves_by_default(ir.tcx, fv_ty)
-                            }
-
-                            // var can still be used
-                            freevars::CaptureByRef => {
-                                false
-                            }
-                        };
                         call_caps.push(CaptureInfo {ln: fv_ln,
-                                                    is_move: is_move,
                                                     var_nid: rv});
                     }
                     None => {}
@@ -1146,9 +1107,15 @@ fn propagate_through_expr(&mut self, expr: &Expr, succ: LiveNode)
           ExprCall(f, ref args) => {
             // calling a fn with bot return type means that the fn
             // will fail, and hence the successors can be ignored
-            let t_ret = ty::ty_fn_ret(ty::expr_ty(self.ir.tcx, f));
-            let succ = if ty::type_is_bot(t_ret) {self.s.exit_ln}
-                       else {succ};
+            let is_bot = !self.ir.tcx.is_method_call(expr.id) && {
+                let t_ret = ty::ty_fn_ret(ty::expr_ty(self.ir.tcx, f));
+                ty::type_is_bot(t_ret)
+            };
+            let succ = if is_bot {
+                self.s.exit_ln
+            } else {
+                succ
+            };
             let succ = self.propagate_through_exprs(args.as_slice(), succ);
             self.propagate_through_expr(f, succ)
           }
index fcd6d4246592ba54bba18f4cadcaa4047252a363..50cbf6bbaf0c58abd0933c6baaabf411f9f51414 100644 (file)
@@ -353,7 +353,6 @@ fn visit_mod(&mut self, m: &ast::Mod, _sp: Span, id: ast::NodeId, _: ()) {
 struct PrivacyVisitor<'a> {
     tcx: &'a ty::ctxt,
     curitem: ast::NodeId,
-    in_fn: bool,
     in_foreign: bool,
     parents: NodeMap<ast::NodeId>,
     external_exports: resolve::ExternalExports,
@@ -1445,7 +1444,6 @@ pub fn check_crate(tcx: &ty::ctxt,
     // Use the parent map to check the privacy of everything
     let mut visitor = PrivacyVisitor {
         curitem: ast::DUMMY_NODE_ID,
-        in_fn: false,
         in_foreign: false,
         tcx: tcx,
         parents: visitor.parents,
index 9bfa0e10aedeff3ba653d0e483356b144c51c8eb..b0a322a9eb7ed51c4ac7b1388b61dda36b1677c1 100644 (file)
@@ -806,7 +806,6 @@ fn namespace_error_to_str(ns: NamespaceError) -> &'static str {
 /// The main resolver class.
 struct Resolver<'a> {
     session: &'a Session,
-    lang_items: &'a LanguageItems,
 
     graph_root: NameBindings,
 
@@ -843,9 +842,6 @@ struct Resolver<'a> {
     // The idents for the primitive types.
     primitive_type_table: PrimitiveTypeTable,
 
-    // The four namespaces.
-    namespaces: Vec<Namespace> ,
-
     def_map: DefMap,
     export_map2: ExportMap2,
     trait_map: TraitMap,
@@ -902,7 +898,7 @@ fn visit_view_item(&mut self, vi: &ViewItem, _: ()) {
 }
 
 impl<'a> Resolver<'a> {
-    fn new(session: &'a Session, lang_items: &'a LanguageItems, crate_span: Span) -> Resolver<'a> {
+    fn new(session: &'a Session, crate_span: Span) -> Resolver<'a> {
         let graph_root = NameBindings::new();
 
         graph_root.define_module(NoParentLink,
@@ -916,7 +912,6 @@ fn new(session: &'a Session, lang_items: &'a LanguageItems, crate_span: Span) ->
 
         Resolver {
             session: session,
-            lang_items: lang_items,
 
             // The outermost module has def ID 0; this is not reflected in the
             // AST.
@@ -941,8 +936,6 @@ fn new(session: &'a Session, lang_items: &'a LanguageItems, crate_span: Span) ->
 
             primitive_type_table: PrimitiveTypeTable::new(),
 
-            namespaces: vec!(TypeNS, ValueNS),
-
             def_map: RefCell::new(NodeMap::new()),
             export_map2: RefCell::new(NodeMap::new()),
             trait_map: NodeMap::new(),
@@ -3856,14 +3849,20 @@ fn resolve_type_parameters(&mut self,
     }
 
     fn resolve_type_parameter_bound(&mut self,
-                                        id: NodeId,
-                                        type_parameter_bound: &TyParamBound) {
+                                    id: NodeId,
+                                    type_parameter_bound: &TyParamBound) {
         match *type_parameter_bound {
             TraitTyParamBound(ref tref) => {
                 self.resolve_trait_reference(id, tref, TraitBoundingTypeParameter)
             }
-            StaticRegionTyParamBound => {}
-            OtherRegionTyParamBound(_) => {}
+            UnboxedFnTyParamBound(ref unboxed_function) => {
+                for argument in unboxed_function.decl.inputs.iter() {
+                    self.resolve_type(argument.ty);
+                }
+
+                self.resolve_type(unboxed_function.decl.output);
+            }
+            StaticRegionTyParamBound | OtherRegionTyParamBound(_) => {}
         }
     }
 
@@ -5576,10 +5575,10 @@ pub struct CrateMap {
 
 /// Entry point to crate resolution.
 pub fn resolve_crate(session: &Session,
-                     lang_items: &LanguageItems,
+                     _: &LanguageItems,
                      krate: &Crate)
                   -> CrateMap {
-    let mut resolver = Resolver::new(session, lang_items, krate.span);
+    let mut resolver = Resolver::new(session, krate.span);
     resolver.resolve(krate);
     let Resolver { def_map, export_map2, trait_map, last_private,
                    external_exports, .. } = resolver;
index 5f51f80299f4be21e070459de497ffc6269b5da0..9fe403159f2b7ec3ac23bb86e262b68d194b0102 100644 (file)
@@ -45,7 +45,6 @@
 
 #![allow(unsigned_negate)]
 
-use std::container::Map;
 use libc::c_ulonglong;
 use std::num::{Bitwise};
 use std::rc::Rc;
index 09f5d2a350769b79bf82024591c588ae200b7989..1cc490bf8f8ac66079d5a969c88e5193b60d8513 100644 (file)
@@ -106,7 +106,9 @@ pub fn init_insn_ctxt() {
     task_local_insn_key.replace(Some(RefCell::new(Vec::new())));
 }
 
-pub struct _InsnCtxt { _x: () }
+pub struct _InsnCtxt {
+    _cannot_construct_outside_of_this_module: ()
+}
 
 #[unsafe_destructor]
 impl Drop for _InsnCtxt {
@@ -124,7 +126,7 @@ pub fn push_ctxt(s: &'static str) -> _InsnCtxt {
         Some(ctx) => ctx.borrow_mut().push(s),
         None => {}
     }
-    _InsnCtxt { _x: () }
+    _InsnCtxt { _cannot_construct_outside_of_this_module: () }
 }
 
 pub struct StatRecorder<'a> {
index 9f90de61cfeb6478bca49d3b66add136ac4dbc80..b21877e4fa030f56c6348e14d6714da110889c7f 100644 (file)
@@ -39,6 +39,7 @@
 use metadata::csearch;
 use middle::def;
 use middle::lang_items::MallocFnLangItem;
+use middle::mem_categorization::Typer;
 use middle::trans::_match;
 use middle::trans::adt;
 use middle::trans::asm;
@@ -65,6 +66,7 @@
 use middle::ty::{AutoPtr, AutoBorrowVec, AutoBorrowVecRef};
 use middle::ty;
 use middle::typeck::MethodCall;
+use middle::typeck;
 use util::common::indenter;
 use util::ppaux::Repr;
 use util::nodemap::NodeMap;
@@ -713,7 +715,20 @@ fn trans_rvalue_dps_unadjusted<'a>(bcx: &'a Block<'a>,
             closure::trans_expr_fn(bcx, store, decl, body, expr.id, dest)
         }
         ast::ExprCall(f, ref args) => {
-            callee::trans_call(bcx, expr, f, callee::ArgExprs(args.as_slice()), dest)
+            if bcx.tcx().is_method_call(expr.id) {
+                let callee_datum = unpack_datum!(bcx, trans(bcx, f));
+                trans_overloaded_call(bcx,
+                                      expr,
+                                      callee_datum,
+                                      args.as_slice(),
+                                      Some(dest))
+            } else {
+                callee::trans_call(bcx,
+                                   expr,
+                                   f,
+                                   callee::ArgExprs(args.as_slice()),
+                                   dest)
+            }
         }
         ast::ExprMethodCall(_, _, ref args) => {
             callee::trans_method_call(bcx,
@@ -1461,6 +1476,76 @@ fn trans_overloaded_op<'a, 'b>(
                              dest)
 }
 
+fn trans_overloaded_call<'a>(
+                         mut bcx: &'a Block<'a>,
+                         expr: &ast::Expr,
+                         callee: Datum<Expr>,
+                         args: &[@ast::Expr],
+                         dest: Option<Dest>)
+                         -> &'a Block<'a> {
+    // Evaluate and tuple the arguments.
+    let tuple_type = ty::mk_tup(bcx.tcx(),
+                                args.iter()
+                                    .map(|e| expr_ty(bcx, *e))
+                                    .collect());
+    let repr = adt::represent_type(bcx.ccx(), tuple_type);
+    let numbered_fields: Vec<(uint, @ast::Expr)> =
+        args.iter().enumerate().map(|(i, arg)| (i, *arg)).collect();
+    let argument_scope = bcx.fcx.push_custom_cleanup_scope();
+    let tuple_datum =
+        unpack_datum!(bcx,
+                      lvalue_scratch_datum(bcx,
+                                           tuple_type,
+                                           "tupled_arguments",
+                                           false,
+                                           cleanup::CustomScope(
+                                               argument_scope),
+                                           (),
+                                           |(), bcx, addr| {
+            trans_adt(bcx,
+                      &*repr,
+                      0,
+                      numbered_fields.as_slice(),
+                      None,
+                      SaveIn(addr))
+        }));
+
+    let method_call = typeck::MethodCall::expr(expr.id);
+    let method_type = bcx.tcx()
+                         .method_map
+                         .borrow()
+                         .get(&method_call)
+                         .ty;
+    let callee_rvalue = unpack_datum!(bcx,
+                                      callee.to_rvalue_datum(bcx, "callee"));
+    let tuple_datum = tuple_datum.to_expr_datum();
+    let tuple_rvalue = unpack_datum!(bcx,
+                                     tuple_datum.to_rvalue_datum(bcx,
+                                                                 "tuple"));
+    let argument_values = [
+        callee_rvalue.add_clean(bcx.fcx,
+                                cleanup::CustomScope(argument_scope)),
+        tuple_rvalue.add_clean(bcx.fcx, cleanup::CustomScope(argument_scope))
+    ];
+    unpack_result!(bcx,
+                   callee::trans_call_inner(bcx,
+                                            Some(expr_info(expr)),
+                                            monomorphize_type(bcx,
+                                                              method_type),
+                                            |bcx, arg_cleanup_scope| {
+                                                meth::trans_method_callee(
+                                                    bcx,
+                                                    method_call,
+                                                    None,
+                                                    arg_cleanup_scope)
+                                            },
+                                            callee::ArgVals(argument_values),
+                                            dest));
+
+    bcx.fcx.pop_custom_cleanup_scope(argument_scope);
+    bcx
+}
+
 fn int_cast(bcx: &Block,
             lldsttype: Type,
             llsrctype: Type,
index 6f217d83a624a2497f29fd016d6940877c63d5a5..565fa88bf438e77cb0fdd2b0176b04d4a961eb48 100644 (file)
@@ -64,9 +64,6 @@ struct LlvmSignature {
     // function, because the foreign function may opt to return via an
     // out pointer.
     llret_ty: Type,
-
-    // True if *Rust* would use an outpointer for this function.
-    sret: bool,
 }
 
 
@@ -847,8 +844,7 @@ fn foreign_signature(ccx: &CrateContext, fn_sig: &ty::FnSig, arg_tys: &[ty::t])
     let llret_ty = type_of::type_of(ccx, fn_sig.output);
     LlvmSignature {
         llarg_tys: llarg_tys,
-        llret_ty: llret_ty,
-        sret: type_of::return_uses_outptr(ccx, fn_sig.output),
+        llret_ty: llret_ty
     }
 }
 
index bdb23aea06708acd655c29132a739bb99b6b31ae..1e6f5fe870be321b74df6f78cf03f976afef45a0 100644 (file)
 
 use middle::const_eval;
 use middle::def;
-use middle::subst;
+use middle::lang_items::FnMutTraitLangItem;
 use middle::subst::{Subst, Substs};
-use middle::ty::{ty_param_substs_and_ty};
+use middle::subst;
+use middle::ty::ty_param_substs_and_ty;
 use middle::ty;
-use middle::typeck::rscope;
-use middle::typeck::rscope::{RegionScope};
 use middle::typeck::lookup_def_tcx;
+use middle::typeck::rscope::RegionScope;
+use middle::typeck::rscope;
 use util::ppaux::Repr;
 
 use std::rc::Rc;
@@ -469,6 +470,38 @@ fn ast_ty_to_mt<AC:AstConv, RS:RegionScope>(this: &AC,
     ty::mt {ty: ast_ty_to_ty(this, rscope, ty), mutbl: ast::MutImmutable}
 }
 
+pub fn trait_ref_for_unboxed_function<AC:AstConv,
+                                      RS:RegionScope>(
+                                      this: &AC,
+                                      rscope: &RS,
+                                      unboxed_function: &ast::UnboxedFnTy)
+                                      -> ty::TraitRef {
+    let fn_mut_trait_did = this.tcx()
+                               .lang_items
+                               .require(FnMutTraitLangItem)
+                               .unwrap();
+    let input_types =
+        unboxed_function.decl
+                        .inputs
+                        .iter()
+                        .map(|input| {
+                            ast_ty_to_ty(this, rscope, input.ty)
+                        }).collect::<Vec<_>>();
+    let input_tuple = ty::mk_tup(this.tcx(), input_types);
+    let output_type = ast_ty_to_ty(this,
+                                   rscope,
+                                   unboxed_function.decl.output);
+    let substs = subst::Substs {
+        self_ty: None,
+        tps: vec!(input_tuple, output_type),
+        regions: subst::NonerasedRegions(Vec::new()),
+    };
+    ty::TraitRef {
+        def_id: fn_mut_trait_did,
+        substs: substs,
+    }
+}
+
 // Handle `~`, `Box`, and `&` being able to mean strs and vecs.
 // If a_seq_ty is a str or a vec, make it a str/vec.
 // Also handle first-class trait types.
@@ -491,6 +524,32 @@ fn mk_pointer<AC:AstConv,
             }
             return constr(ty::mk_vec(tcx, mt, None));
         }
+        ast::TyUnboxedFn(ref unboxed_function) => {
+            let trait_store = match ptr_ty {
+                Uniq => ty::UniqTraitStore,
+                RPtr(r) => {
+                    ty::RegionTraitStore(r, a_seq_ty.mutbl)
+                }
+                _ => {
+                    tcx.sess.span_err(
+                        a_seq_ty.ty.span,
+                        "~trait or &trait are the only supported \
+                         forms of casting-to-trait");
+                    return ty::mk_err();
+                }
+            };
+            let ty::TraitRef {
+                def_id,
+                substs
+            } = trait_ref_for_unboxed_function(this,
+                                               rscope,
+                                               *unboxed_function);
+            return ty::mk_trait(this.tcx(),
+                                def_id,
+                                substs,
+                                trait_store,
+                                ty::empty_builtin_bounds());
+        }
         ast::TyPath(ref path, ref bounds, id) => {
             // Note that the "bounds must be empty if path is not a trait"
             // restriction is enforced in the below case for ty_path, which
@@ -528,7 +587,10 @@ fn mk_pointer<AC:AstConv,
                             return ty::mk_err();
                         }
                     };
-                    let bounds = conv_builtin_bounds(this.tcx(), bounds, trait_store);
+                    let bounds = conv_builtin_bounds(this.tcx(),
+                                                     path.span,
+                                                     bounds,
+                                                     trait_store);
                     return ty::mk_trait(tcx,
                                         result.def_id,
                                         result.substs.clone(),
@@ -621,7 +683,10 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:RegionScope>(
 
                 // Use corresponding trait store to figure out default bounds
                 // if none were specified.
-                let bounds = conv_builtin_bounds(this.tcx(), &f.bounds, store);
+                let bounds = conv_builtin_bounds(this.tcx(),
+                                                 ast_ty.span,
+                                                 &f.bounds,
+                                                 store);
 
                 let fn_decl = ty_of_closure(this,
                                             ast_ty.id,
@@ -636,7 +701,10 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:RegionScope>(
             ast::TyProc(ref f) => {
                 // Use corresponding trait store to figure out default bounds
                 // if none were specified.
-                let bounds = conv_builtin_bounds(this.tcx(), &f.bounds, ty::UniqTraitStore);
+                let bounds = conv_builtin_bounds(this.tcx(),
+                                                 ast_ty.span,
+                                                 &f.bounds,
+                                                 ty::UniqTraitStore);
 
                 let fn_decl = ty_of_closure(this,
                                             ast_ty.id,
@@ -648,6 +716,11 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:RegionScope>(
                                             None);
                 ty::mk_closure(tcx, fn_decl)
             }
+            ast::TyUnboxedFn(_) => {
+                tcx.sess.span_err(ast_ty.span,
+                                  "cannot use unboxed functions here");
+                ty::mk_err()
+            }
             ast::TyPath(ref path, ref bounds, id) => {
                 let a_def = match tcx.def_map.borrow().find(&id) {
                     None => {
@@ -891,7 +964,9 @@ pub fn ty_of_closure<AC:AstConv>(
     }
 }
 
-fn conv_builtin_bounds(tcx: &ty::ctxt, ast_bounds: &Option<OwnedSlice<ast::TyParamBound>>,
+fn conv_builtin_bounds(tcx: &ty::ctxt,
+                       span: Span,
+                       ast_bounds: &Option<OwnedSlice<ast::TyParamBound>>,
                        store: ty::TraitStore)
                        -> ty::BuiltinBounds {
     //! Converts a list of bounds from the AST into a `BuiltinBounds`
@@ -928,6 +1003,11 @@ fn conv_builtin_bounds(tcx: &ty::ctxt, ast_bounds: &Option<OwnedSlice<ast::TyPar
                     ast::StaticRegionTyParamBound => {
                         builtin_bounds.add(ty::BoundStatic);
                     }
+                    ast::UnboxedFnTyParamBound(_) => {
+                        tcx.sess.span_err(span,
+                                          "unboxed functions are not allowed \
+                                           here");
+                    }
                     ast::OtherRegionTyParamBound(span) => {
                         if !tcx.sess.features.issue_5723_bootstrap.get() {
                             tcx.sess.span_err(
index d25fc9cc5bcdb298abd9cd49517d9d4d487739ae..1463cf9602dcae137a104a643e90ea67757697b4 100644 (file)
@@ -1353,6 +1353,61 @@ pub fn autoderef<T>(fcx: &FnCtxt, sp: Span, base_ty: ty::t,
     (ty::mk_err(), 0, None)
 }
 
+/// Attempts to resolve a call expression as an overloaded call.
+fn try_overloaded_call(fcx: &FnCtxt,
+                       call_expression: &ast::Expr,
+                       callee: @ast::Expr,
+                       callee_type: ty::t,
+                       args: &[@ast::Expr])
+                       -> bool {
+    // Try `FnOnce`, then `FnMut`, then `Fn`.
+    for &(maybe_function_trait, method_name) in [
+        (fcx.tcx().lang_items.fn_once_trait(), token::intern("call_once")),
+        (fcx.tcx().lang_items.fn_mut_trait(), token::intern("call_mut")),
+        (fcx.tcx().lang_items.fn_trait(), token::intern("call"))
+    ].iter() {
+        let function_trait = match maybe_function_trait {
+            None => continue,
+            Some(function_trait) => function_trait,
+        };
+        let method_callee = match method::lookup_in_trait(
+                fcx,
+                call_expression.span,
+                Some(&*callee),
+                method_name,
+                function_trait,
+                callee_type,
+                [],
+                DontAutoderefReceiver,
+                IgnoreStaticMethods) {
+            None => continue,
+            Some(method_callee) => method_callee,
+        };
+        let method_call = MethodCall::expr(call_expression.id);
+        let output_type = check_method_argument_types(fcx,
+                                                      call_expression.span,
+                                                      method_callee.ty,
+                                                      call_expression,
+                                                      args,
+                                                      DontDerefArgs,
+                                                      TupleArguments);
+        fcx.inh.method_map.borrow_mut().insert(method_call, method_callee);
+        write_call(fcx, call_expression, output_type);
+
+        if !fcx.tcx().sess.features.overloaded_calls.get() {
+            fcx.tcx().sess.span_err(call_expression.span,
+                                    "overloaded calls are experimental");
+            fcx.tcx().sess.span_note(call_expression.span,
+                                     "add `#[feature(overloaded_calls)]` to \
+                                      the crate attributes to enable");
+        }
+
+        return true
+    }
+
+    false
+}
+
 fn try_overloaded_deref(fcx: &FnCtxt,
                         span: Span,
                         method_call: Option<MethodCall>,
@@ -1395,6 +1450,261 @@ fn try_overloaded_deref(fcx: &FnCtxt,
     }
 }
 
+fn check_method_argument_types(fcx: &FnCtxt,
+                               sp: Span,
+                               method_fn_ty: ty::t,
+                               callee_expr: &ast::Expr,
+                               args: &[@ast::Expr],
+                               deref_args: DerefArgs,
+                               tuple_arguments: TupleArgumentsFlag)
+                               -> ty::t {
+    // HACK(eddyb) ignore provided self (it has special typeck rules).
+    let args = if tuple_arguments == DontTupleArguments {
+        args.slice_from(1)
+    } else {
+        args
+    };
+    if ty::type_is_error(method_fn_ty) {
+        let err_inputs = err_args(args.len());
+        check_argument_types(fcx,
+                             sp,
+                             err_inputs.as_slice(),
+                             callee_expr,
+                             args,
+                             deref_args,
+                             false,
+                             tuple_arguments);
+        method_fn_ty
+    } else {
+        match ty::get(method_fn_ty).sty {
+            ty::ty_bare_fn(ref fty) => {
+                // HACK(eddyb) ignore self in the definition (see above).
+                check_argument_types(fcx,
+                                     sp,
+                                     fty.sig.inputs.slice_from(1),
+                                     callee_expr,
+                                     args,
+                                     deref_args,
+                                     fty.sig.variadic,
+                                     tuple_arguments);
+                fty.sig.output
+            }
+            _ => {
+                fcx.tcx().sess.span_bug(callee_expr.span,
+                                        "method without bare fn type");
+            }
+        }
+    }
+}
+
+fn check_argument_types(fcx: &FnCtxt,
+                        sp: Span,
+                        fn_inputs: &[ty::t],
+                        callee_expr: &ast::Expr,
+                        args: &[@ast::Expr],
+                        deref_args: DerefArgs,
+                        variadic: bool,
+                        tuple_arguments: TupleArgumentsFlag) {
+    /*!
+     *
+     * Generic function that factors out common logic from
+     * function calls, method calls and overloaded operators.
+     */
+
+    let tcx = fcx.ccx.tcx;
+
+    // Grab the argument types, supplying fresh type variables
+    // if the wrong number of arguments were supplied
+    let supplied_arg_count = if tuple_arguments == DontTupleArguments {
+        args.len()
+    } else {
+        1
+    };
+
+    let expected_arg_count = fn_inputs.len();
+    let formal_tys = if tuple_arguments == TupleArguments {
+        let tuple_type = structurally_resolved_type(fcx, sp, fn_inputs[0]);
+        match ty::get(tuple_type).sty {
+            ty::ty_tup(ref arg_types) => {
+                if arg_types.len() != args.len() {
+                    let msg = format!(
+                        "this function takes \
+                         {nexpected, plural, =1{# parameter} \
+                         other{# parameters}} \
+                         but {nsupplied, plural, =1{# parameter was} \
+                         other{# parameters were}} supplied",
+                         nexpected = arg_types.len(),
+                         nsupplied = args.len());
+                    tcx.sess.span_err(sp, msg.as_slice());
+                    err_args(args.len())
+                } else {
+                    (*arg_types).clone()
+                }
+            }
+            ty::ty_nil => {
+                if args.len() != 0 {
+                    let msg = format!(
+                        "this function takes 0 parameters \
+                         but {nsupplied, plural, =1{# parameter was} \
+                         other{# parameters were}} supplied",
+                         nsupplied = args.len());
+                    tcx.sess.span_err(sp, msg.as_slice());
+                }
+                Vec::new()
+            }
+            _ => {
+                tcx.sess
+                   .span_err(sp,
+                             "cannot use call notation; the first type \
+                              parameter for the function trait is neither a \
+                              tuple nor unit");
+                err_args(supplied_arg_count)
+            }
+        }
+    } else if expected_arg_count == supplied_arg_count {
+        fn_inputs.iter().map(|a| *a).collect()
+    } else if variadic {
+        if supplied_arg_count >= expected_arg_count {
+            fn_inputs.iter().map(|a| *a).collect()
+        } else {
+            let msg = format!(
+                "this function takes at least {nexpected, plural, =1{# parameter} \
+                                                               other{# parameters}} \
+                 but {nsupplied, plural, =1{# parameter was} \
+                                      other{# parameters were}} supplied",
+                 nexpected = expected_arg_count,
+                 nsupplied = supplied_arg_count);
+
+            tcx.sess.span_err(sp, msg.as_slice());
+
+            err_args(supplied_arg_count)
+        }
+    } else {
+        let msg = format!(
+            "this function takes {nexpected, plural, =1{# parameter} \
+                                                  other{# parameters}} \
+             but {nsupplied, plural, =1{# parameter was} \
+                                  other{# parameters were}} supplied",
+             nexpected = expected_arg_count,
+             nsupplied = supplied_arg_count);
+
+        tcx.sess.span_err(sp, msg.as_slice());
+
+        err_args(supplied_arg_count)
+    };
+
+    debug!("check_argument_types: formal_tys={:?}",
+           formal_tys.iter().map(|t| fcx.infcx().ty_to_str(*t)).collect::<Vec<String>>());
+
+    // Check the arguments.
+    // We do this in a pretty awful way: first we typecheck any arguments
+    // that are not anonymous functions, then we typecheck the anonymous
+    // functions. This is so that we have more information about the types
+    // of arguments when we typecheck the functions. This isn't really the
+    // right way to do this.
+    let xs = [false, true];
+    for check_blocks in xs.iter() {
+        let check_blocks = *check_blocks;
+        debug!("check_blocks={}", check_blocks);
+
+        // More awful hacks: before we check the blocks, try to do
+        // an "opportunistic" vtable resolution of any trait
+        // bounds on the call.
+        if check_blocks {
+            vtable::early_resolve_expr(callee_expr, fcx, true);
+        }
+
+        // For variadic functions, we don't have a declared type for all of
+        // the arguments hence we only do our usual type checking with
+        // the arguments who's types we do know.
+        let t = if variadic {
+            expected_arg_count
+        } else if tuple_arguments == TupleArguments {
+            args.len()
+        } else {
+            supplied_arg_count
+        };
+        for (i, arg) in args.iter().take(t).enumerate() {
+            let is_block = match arg.node {
+                ast::ExprFnBlock(..) |
+                ast::ExprProc(..) => true,
+                _ => false
+            };
+
+            if is_block == check_blocks {
+                debug!("checking the argument");
+                let mut formal_ty = *formal_tys.get(i);
+
+                match deref_args {
+                    DoDerefArgs => {
+                        match ty::get(formal_ty).sty {
+                            ty::ty_rptr(_, mt) => formal_ty = mt.ty,
+                            ty::ty_err => (),
+                            _ => {
+                                // So we hit this case when one implements the
+                                // operator traits but leaves an argument as
+                                // just T instead of &T. We'll catch it in the
+                                // mismatch impl/trait method phase no need to
+                                // ICE here.
+                                // See: #11450
+                                formal_ty = ty::mk_err();
+                            }
+                        }
+                    }
+                    DontDerefArgs => {}
+                }
+
+                check_expr_coercable_to_type(fcx, *arg, formal_ty);
+
+            }
+        }
+    }
+
+    // We also need to make sure we at least write the ty of the other
+    // arguments which we skipped above.
+    if variadic {
+        for arg in args.iter().skip(expected_arg_count) {
+            check_expr(fcx, *arg);
+
+            // There are a few types which get autopromoted when passed via varargs
+            // in C but we just error out instead and require explicit casts.
+            let arg_ty = structurally_resolved_type(fcx, arg.span, fcx.expr_ty(*arg));
+            match ty::get(arg_ty).sty {
+                ty::ty_float(ast::TyF32) => {
+                    fcx.type_error_message(arg.span,
+                                           |t| {
+                        format!("can't pass an {} to variadic \
+                                 function, cast to c_double", t)
+                    }, arg_ty, None);
+                }
+                ty::ty_int(ast::TyI8) | ty::ty_int(ast::TyI16) | ty::ty_bool => {
+                    fcx.type_error_message(arg.span, |t| {
+                        format!("can't pass {} to variadic \
+                                 function, cast to c_int",
+                                       t)
+                    }, arg_ty, None);
+                }
+                ty::ty_uint(ast::TyU8) | ty::ty_uint(ast::TyU16) => {
+                    fcx.type_error_message(arg.span, |t| {
+                        format!("can't pass {} to variadic \
+                                 function, cast to c_uint",
+                                       t)
+                    }, arg_ty, None);
+                }
+                _ => {}
+            }
+        }
+    }
+}
+
+fn err_args(len: uint) -> Vec<ty::t> {
+    Vec::from_fn(len, |_| ty::mk_err())
+}
+
+fn write_call(fcx: &FnCtxt, call_expr: &ast::Expr, output: ty::t) {
+    fcx.write_ty(call_expr.id, output);
+}
+
 // AST fragment checking
 pub fn check_lit(fcx: &FnCtxt, lit: &ast::Lit) -> ty::t {
     let tcx = fcx.ccx.tcx;
@@ -1521,6 +1831,28 @@ pub enum DerefArgs {
     DoDerefArgs
 }
 
+/// Controls whether the arguments are tupled. This is used for the call
+/// operator.
+///
+/// Tupling means that all call-side arguments are packed into a tuple and
+/// passed as a single parameter. For example, if tupling is enabled, this
+/// function:
+///
+///     fn f(x: (int, int))
+///
+/// Can be called as:
+///
+///     f(1, 2);
+///
+/// Instead of:
+///
+///     f((1, 2));
+#[deriving(Clone, Eq, PartialEq)]
+enum TupleArgumentsFlag {
+    DontTupleArguments,
+    TupleArguments,
+}
+
 // Given the provenance of a static method, returns the generics of the static
 // method's container.
 fn generics_of_static_method_container(type_context: &ty::ctxt,
@@ -1704,207 +2036,11 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
                            unifier: ||) {
     debug!(">> typechecking");
 
-    fn check_method_argument_types(
-        fcx: &FnCtxt,
-        sp: Span,
-        method_fn_ty: ty::t,
-        callee_expr: &ast::Expr,
-        args: &[@ast::Expr],
-        deref_args: DerefArgs) -> ty::t {
-        // HACK(eddyb) ignore provided self (it has special typeck rules).
-        let args = args.slice_from(1);
-        if ty::type_is_error(method_fn_ty) {
-            let err_inputs = err_args(args.len());
-            check_argument_types(fcx, sp, err_inputs.as_slice(), callee_expr,
-                                 args, deref_args, false);
-            method_fn_ty
-        } else {
-            match ty::get(method_fn_ty).sty {
-                ty::ty_bare_fn(ref fty) => {
-                    // HACK(eddyb) ignore self in the definition (see above).
-                    check_argument_types(fcx, sp, fty.sig.inputs.slice_from(1),
-                                         callee_expr, args, deref_args,
-                                         fty.sig.variadic);
-                    fty.sig.output
-                }
-                _ => {
-                    fcx.tcx().sess.span_bug(callee_expr.span,
-                                            "method without bare fn type");
-                }
-            }
-        }
-    }
-
-    fn check_argument_types(fcx: &FnCtxt,
-                            sp: Span,
-                            fn_inputs: &[ty::t],
-                            callee_expr: &ast::Expr,
-                            args: &[@ast::Expr],
-                            deref_args: DerefArgs,
-                            variadic: bool) {
-        /*!
-         *
-         * Generic function that factors out common logic from
-         * function calls, method calls and overloaded operators.
-         */
-
-        let tcx = fcx.ccx.tcx;
-
-        // Grab the argument types, supplying fresh type variables
-        // if the wrong number of arguments were supplied
-        let supplied_arg_count = args.len();
-        let expected_arg_count = fn_inputs.len();
-        let formal_tys = if expected_arg_count == supplied_arg_count {
-            fn_inputs.iter().map(|a| *a).collect()
-        } else if variadic {
-            if supplied_arg_count >= expected_arg_count {
-                fn_inputs.iter().map(|a| *a).collect()
-            } else {
-                let msg = format!(
-                    "this function takes at least {nexpected, plural, =1{# parameter} \
-                                                                   other{# parameters}} \
-                     but {nsupplied, plural, =1{# parameter was} \
-                                          other{# parameters were}} supplied",
-                     nexpected = expected_arg_count,
-                     nsupplied = supplied_arg_count);
-
-                tcx.sess.span_err(sp, msg.as_slice());
-
-                err_args(supplied_arg_count)
-            }
-        } else {
-            let msg = format!(
-                "this function takes {nexpected, plural, =1{# parameter} \
-                                                      other{# parameters}} \
-                 but {nsupplied, plural, =1{# parameter was} \
-                                      other{# parameters were}} supplied",
-                 nexpected = expected_arg_count,
-                 nsupplied = supplied_arg_count);
-
-            tcx.sess.span_err(sp, msg.as_slice());
-
-            err_args(supplied_arg_count)
-        };
-
-        debug!("check_argument_types: formal_tys={:?}",
-               formal_tys.iter().map(|t| fcx.infcx().ty_to_str(*t)).collect::<Vec<String>>());
-
-        // Check the arguments.
-        // We do this in a pretty awful way: first we typecheck any arguments
-        // that are not anonymous functions, then we typecheck the anonymous
-        // functions. This is so that we have more information about the types
-        // of arguments when we typecheck the functions. This isn't really the
-        // right way to do this.
-        let xs = [false, true];
-        for check_blocks in xs.iter() {
-            let check_blocks = *check_blocks;
-            debug!("check_blocks={}", check_blocks);
-
-            // More awful hacks: before we check the blocks, try to do
-            // an "opportunistic" vtable resolution of any trait
-            // bounds on the call.
-            if check_blocks {
-                vtable::early_resolve_expr(callee_expr, fcx, true);
-            }
-
-            // For variadic functions, we don't have a declared type for all of
-            // the arguments hence we only do our usual type checking with
-            // the arguments who's types we do know.
-            let t = if variadic {
-                expected_arg_count
-            } else {
-                supplied_arg_count
-            };
-            for (i, arg) in args.iter().take(t).enumerate() {
-                let is_block = match arg.node {
-                    ast::ExprFnBlock(..) |
-                    ast::ExprProc(..) => true,
-                    _ => false
-                };
-
-                if is_block == check_blocks {
-                    debug!("checking the argument");
-                    let mut formal_ty = *formal_tys.get(i);
-
-                    match deref_args {
-                        DoDerefArgs => {
-                            match ty::get(formal_ty).sty {
-                                ty::ty_rptr(_, mt) => formal_ty = mt.ty,
-                                ty::ty_err => (),
-                                _ => {
-                                    // So we hit this case when one implements the
-                                    // operator traits but leaves an argument as
-                                    // just T instead of &T. We'll catch it in the
-                                    // mismatch impl/trait method phase no need to
-                                    // ICE here.
-                                    // See: #11450
-                                    formal_ty = ty::mk_err();
-                                }
-                            }
-                        }
-                        DontDerefArgs => {}
-                    }
-
-                    check_expr_coercable_to_type(fcx, *arg, formal_ty);
-
-                }
-            }
-        }
-
-        // We also need to make sure we at least write the ty of the other
-        // arguments which we skipped above.
-        if variadic {
-            for arg in args.iter().skip(expected_arg_count) {
-                check_expr(fcx, *arg);
-
-                // There are a few types which get autopromoted when passed via varargs
-                // in C but we just error out instead and require explicit casts.
-                let arg_ty = structurally_resolved_type(fcx, arg.span, fcx.expr_ty(*arg));
-                match ty::get(arg_ty).sty {
-                    ty::ty_float(ast::TyF32) => {
-                        fcx.type_error_message(arg.span,
-                                               |t| {
-                            format!("can't pass an {} to variadic \
-                                     function, cast to c_double", t)
-                        }, arg_ty, None);
-                    }
-                    ty::ty_int(ast::TyI8) | ty::ty_int(ast::TyI16) | ty::ty_bool => {
-                        fcx.type_error_message(arg.span, |t| {
-                            format!("can't pass {} to variadic \
-                                     function, cast to c_int",
-                                           t)
-                        }, arg_ty, None);
-                    }
-                    ty::ty_uint(ast::TyU8) | ty::ty_uint(ast::TyU16) => {
-                        fcx.type_error_message(arg.span, |t| {
-                            format!("can't pass {} to variadic \
-                                     function, cast to c_uint",
-                                           t)
-                        }, arg_ty, None);
-                    }
-                    _ => {}
-                }
-            }
-        }
-    }
-
-    fn err_args(len: uint) -> Vec<ty::t> {
-        Vec::from_fn(len, |_| ty::mk_err())
-    }
-
-    fn write_call(fcx: &FnCtxt, call_expr: &ast::Expr, output: ty::t) {
-        fcx.write_ty(call_expr.id, output);
-    }
-
     // A generic function for doing all of the checking for call expressions
     fn check_call(fcx: &FnCtxt,
                   call_expr: &ast::Expr,
                   f: &ast::Expr,
                   args: &[@ast::Expr]) {
-        // Index expressions need to be handled separately, to inform them
-        // that they appear in call position.
-        check_expr(fcx, f);
-
         // Store the type of `f` as the type of the callee
         let fn_ty = fcx.expr_ty(f);
 
@@ -1939,8 +2075,14 @@ fn check_call(fcx: &FnCtxt,
         });
 
         // Call the generic checker.
-        check_argument_types(fcx, call_expr.span, fn_sig.inputs.as_slice(), f,
-                             args, DontDerefArgs, fn_sig.variadic);
+        check_argument_types(fcx,
+                             call_expr.span,
+                             fn_sig.inputs.as_slice(),
+                             f,
+                             args,
+                             DontDerefArgs,
+                             fn_sig.variadic,
+                             DontTupleArguments);
 
         write_call(fcx, call_expr, fn_sig.output);
     }
@@ -2008,9 +2150,13 @@ fn check_method_call(fcx: &FnCtxt,
         };
 
         // Call the generic checker.
-        let ret_ty = check_method_argument_types(fcx, method_name.span,
-                                                 fn_ty, expr, args,
-                                                 DontDerefArgs);
+        let ret_ty = check_method_argument_types(fcx,
+                                                 method_name.span,
+                                                 fn_ty,
+                                                 expr,
+                                                 args,
+                                                 DontDerefArgs,
+                                                 DontTupleArguments);
 
         write_call(fcx, expr, ret_ty);
     }
@@ -2078,18 +2224,26 @@ fn lookup_op_method(fcx: &FnCtxt,
                 // HACK(eddyb) Fully qualified path to work around a resolve bug.
                 let method_call = ::middle::typeck::MethodCall::expr(op_ex.id);
                 fcx.inh.method_map.borrow_mut().insert(method_call, method);
-                check_method_argument_types(fcx, op_ex.span,
-                                            method_ty, op_ex,
-                                            args, DoDerefArgs)
+                check_method_argument_types(fcx,
+                                            op_ex.span,
+                                            method_ty,
+                                            op_ex,
+                                            args,
+                                            DoDerefArgs,
+                                            DontTupleArguments)
             }
             None => {
                 unbound_method();
                 // Check the args anyway
                 // so we get all the error messages
                 let expected_ty = ty::mk_err();
-                check_method_argument_types(fcx, op_ex.span,
-                                            expected_ty, op_ex,
-                                            args, DoDerefArgs);
+                check_method_argument_types(fcx,
+                                            op_ex.span,
+                                            expected_ty,
+                                            op_ex,
+                                            args,
+                                            DoDerefArgs,
+                                            DontTupleArguments);
                 ty::mk_err()
             }
         }
@@ -3045,19 +3199,25 @@ fn check_struct_enum_variant(fcx: &FnCtxt,
         fcx.write_ty(id, fcx.node_ty(b.id));
       }
       ast::ExprCall(f, ref args) => {
-          check_call(fcx, expr, f, args.as_slice());
+          // Index expressions need to be handled separately, to inform them
+          // that they appear in call position.
+          check_expr(fcx, f);
           let f_ty = fcx.expr_ty(f);
-          let (args_bot, args_err) = args.iter().fold((false, false),
-             |(rest_bot, rest_err), a| {
-                 // is this not working?
-                 let a_ty = fcx.expr_ty(*a);
-                 (rest_bot || ty::type_is_bot(a_ty),
-                  rest_err || ty::type_is_error(a_ty))});
-          if ty::type_is_error(f_ty) || args_err {
-              fcx.write_error(id);
-          }
-          else if ty::type_is_bot(f_ty) || args_bot {
-              fcx.write_bot(id);
+
+          if !try_overloaded_call(fcx, expr, f, f_ty, args.as_slice()) {
+              check_call(fcx, expr, f, args.as_slice());
+              let (args_bot, args_err) = args.iter().fold((false, false),
+                 |(rest_bot, rest_err), a| {
+                     // is this not working?
+                     let a_ty = fcx.expr_ty(*a);
+                     (rest_bot || ty::type_is_bot(a_ty),
+                      rest_err || ty::type_is_error(a_ty))});
+              if ty::type_is_error(f_ty) || args_err {
+                  fcx.write_error(id);
+              }
+              else if ty::type_is_bot(f_ty) || args_bot {
+                  fcx.write_bot(id);
+              }
           }
       }
       ast::ExprMethodCall(ident, ref tps, ref args) => {
index e488a946d4a14deae9248086f154691fd8d7c040..d3ddbcf5b38a412dd01627182cc8cd630be72f1b 100644 (file)
@@ -442,13 +442,15 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
 
     match expr.node {
         ast::ExprCall(callee, ref args) => {
-            constrain_callee(rcx, callee.id, expr, callee);
-            constrain_call(rcx,
-                           Some(callee.id),
-                           expr,
-                           None,
-                           args.as_slice(),
-                           false);
+            if !has_method_map {
+                constrain_callee(rcx, callee.id, expr, callee);
+                constrain_call(rcx,
+                               Some(callee.id),
+                               expr,
+                               None,
+                               args.as_slice(),
+                               false);
+            }
 
             visit::walk_expr(rcx, expr, ());
         }
index 99a6aad715ccbf548c9f1895e3a6b58f77a5651b..2c0593184786e961ec20fad955d4df55666a92db 100644 (file)
@@ -52,9 +52,7 @@
 use std::rc::Rc;
 
 struct UniversalQuantificationResult {
-    monotype: t,
-    type_variables: Vec<ty::t> ,
-    type_param_defs: Rc<Vec<ty::TypeParameterDef> >
+    monotype: t
 }
 
 fn get_base_type(inference_context: &InferCtxt,
@@ -515,9 +513,7 @@ fn universally_quantify_polytype(&self, polytype: ty_param_bounds_and_ty)
         let monotype = polytype.ty.subst(self.crate_context.tcx, &substitutions);
 
         UniversalQuantificationResult {
-            monotype: monotype,
-            type_variables: substitutions.tps,
-            type_param_defs: polytype.generics.type_param_defs.clone()
+            monotype: monotype
         }
     }
 
index c6bc6ce72974052cc40b7143650ad0e8efa98547..edb7f589e952305bee2428335c1efbb3e510f5d3 100644 (file)
 use util::ppaux;
 use util::ppaux::Repr;
 
-use std::rc::Rc;
 use std::collections::{HashMap, HashSet};
-
+use std::rc::Rc;
 use syntax::abi;
-use syntax::ast::{StaticRegionTyParamBound, OtherRegionTyParamBound,
-                  TraitTyParamBound};
+use syntax::ast::{StaticRegionTyParamBound, OtherRegionTyParamBound};
+use syntax::ast::{TraitTyParamBound, UnboxedFnTyParamBound};
 use syntax::ast;
 use syntax::ast_map;
 use syntax::ast_util::{local_def, split_trait_methods};
 use syntax::codemap::Span;
 use syntax::codemap;
+use syntax::owned_slice::OwnedSlice;
 use syntax::parse::token::special_idents;
 use syntax::parse::token;
 use syntax::print::pprust::{path_to_str};
 use syntax::visit;
-use syntax::owned_slice::OwnedSlice;
 
 struct CollectItemTypesVisitor<'a> {
     ccx: &'a CrateCtxt<'a>
@@ -1114,6 +1113,20 @@ fn compute_bounds(
                     param_bounds.builtin_bounds.add(ty::BoundStatic);
                 }
 
+                UnboxedFnTyParamBound(ref unboxed_function) => {
+                    let rscope = ExplicitRscope;
+                    let mut trait_ref =
+                        astconv::trait_ref_for_unboxed_function(
+                            ccx,
+                            &rscope,
+                            unboxed_function);
+                    let self_ty = ty::mk_param(ccx.tcx,
+                                               param_ty.idx,
+                                               param_ty.def_id);
+                    trait_ref.substs.self_ty = 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(
index 6464b191b76911b431cdabbb970ef4af4d9ae57f..8f53c0a7530516a778af8878bd86564d9c69272b 100644 (file)
@@ -909,6 +909,9 @@ fn rebuild_ty_param_bounds(&self,
             match tpb {
                 &ast::StaticRegionTyParamBound => ast::StaticRegionTyParamBound,
                 &ast::OtherRegionTyParamBound(s) => ast::OtherRegionTyParamBound(s),
+                &ast::UnboxedFnTyParamBound(unboxed_function_type) => {
+                    ast::UnboxedFnTyParamBound(unboxed_function_type)
+                }
                 &ast::TraitTyParamBound(ref tr) => {
                     let last_seg = tr.path.segments.last().unwrap();
                     let mut insert = Vec::new();
index 04244ff31a8c31923db9bc647e9efd1414dbd46d..92ebf42c7af98088a4ba5e2164ebcda817e88de9 100644 (file)
@@ -271,7 +271,6 @@ enum ParamKind { TypeParam, RegionParam, SelfParam }
 struct InferredInfo<'a> {
     item_id: ast::NodeId,
     kind: ParamKind,
-    index: uint,
     param_id: ast::NodeId,
     term: VarianceTermPtr<'a>,
 }
@@ -310,7 +309,6 @@ fn add_inferred(&mut self,
         let term = self.arena.alloc(|| InferredTerm(inf_index));
         self.inferred_infos.push(InferredInfo { item_id: item_id,
                                                 kind: kind,
-                                                index: index,
                                                 param_id: param_id,
                                                 term: term });
         let newly_added = self.inferred_map.insert(param_id, inf_index);
diff --git a/src/librustc/plugin/build.rs b/src/librustc/plugin/build.rs
new file mode 100644 (file)
index 0000000..ad35c4e
--- /dev/null
@@ -0,0 +1,61 @@
+// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <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.
+
+//! Used by `rustc` when compiling a plugin crate.
+
+use syntax::ast;
+use syntax::attr;
+use syntax::codemap::Span;
+use syntax::diagnostic;
+use syntax::visit;
+use syntax::visit::Visitor;
+
+struct RegistrarFinder {
+    registrars: Vec<(ast::NodeId, Span)> ,
+}
+
+impl Visitor<()> for RegistrarFinder {
+    fn visit_item(&mut self, item: &ast::Item, _: ()) {
+        match item.node {
+            ast::ItemFn(..) => {
+                if attr::contains_name(item.attrs.as_slice(),
+                                       "plugin_registrar") {
+                    self.registrars.push((item.id, item.span));
+                }
+            }
+            _ => {}
+        }
+
+        visit::walk_item(self, item, ());
+    }
+}
+
+/// Find the function marked with `#[plugin_registrar]`, if any.
+pub fn find_plugin_registrar(diagnostic: &diagnostic::SpanHandler,
+                             krate: &ast::Crate) -> Option<ast::NodeId> {
+    let mut finder = RegistrarFinder { registrars: Vec::new() };
+    visit::walk_crate(&mut finder, krate, ());
+
+    match finder.registrars.len() {
+        0 => None,
+        1 => {
+            let (node_id, _) = finder.registrars.pop().unwrap();
+            Some(node_id)
+        },
+        _ => {
+            diagnostic.handler().err("multiple plugin registration functions found");
+            for &(_, span) in finder.registrars.iter() {
+                diagnostic.span_note(span, "one is here");
+            }
+            diagnostic.handler().abort_if_errors();
+            unreachable!();
+        }
+    }
+}
diff --git a/src/librustc/plugin/load.rs b/src/librustc/plugin/load.rs
new file mode 100644 (file)
index 0000000..97ffcf2
--- /dev/null
@@ -0,0 +1,145 @@
+// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <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.
+
+//! Used by `rustc` when loading a plugin.
+
+use driver::session::Session;
+use metadata::creader::PluginMetadataReader;
+use plugin::registry::Registry;
+
+use std::mem;
+use std::os;
+use std::dynamic_lib::DynamicLibrary;
+use syntax::ast;
+use syntax::attr;
+use syntax::visit;
+use syntax::visit::Visitor;
+use syntax::ext::expand::ExportedMacros;
+use syntax::attr::AttrMetaMethods;
+
+/// Plugin-related crate metadata.
+pub struct PluginMetadata {
+    /// Source code of macros exported by the crate.
+    pub macros: Vec<String>,
+    /// Path to the shared library file.
+    pub lib: Option<Path>,
+    /// Symbol name of the plugin registrar function.
+    pub registrar_symbol: Option<String>,
+}
+
+/// Pointer to a registrar function.
+pub type PluginRegistrarFun =
+    fn(&mut Registry);
+
+/// Information about loaded plugins.
+pub struct Plugins {
+    /// Source code of exported macros.
+    pub macros: Vec<ExportedMacros>,
+    /// Registrars, as function pointers.
+    pub registrars: Vec<PluginRegistrarFun>,
+}
+
+struct PluginLoader<'a> {
+    sess: &'a Session,
+    reader: PluginMetadataReader<'a>,
+    plugins: Plugins,
+}
+
+impl<'a> PluginLoader<'a> {
+    fn new(sess: &'a Session) -> PluginLoader<'a> {
+        PluginLoader {
+            sess: sess,
+            reader: PluginMetadataReader::new(sess),
+            plugins: Plugins {
+                macros: vec!(),
+                registrars: vec!(),
+            },
+        }
+    }
+}
+
+/// Read plugin metadata and dynamically load registrar functions.
+pub fn load_plugins(sess: &Session, krate: &ast::Crate) -> Plugins {
+    let mut loader = PluginLoader::new(sess);
+    visit::walk_crate(&mut loader, krate, ());
+    loader.plugins
+}
+
+impl<'a> Visitor<()> for PluginLoader<'a> {
+    fn visit_view_item(&mut self, vi: &ast::ViewItem, _: ()) {
+        match vi.node {
+            ast::ViewItemExternCrate(name, _, _) => {
+                let mut plugin_phase = false;
+
+                for attr in vi.attrs.iter().filter(|a| a.check_name("phase")) {
+                    let phases = attr.meta_item_list().unwrap_or(&[]);
+                    if attr::contains_name(phases, "plugin") {
+                        plugin_phase = true;
+                    }
+                    if attr::contains_name(phases, "syntax") {
+                        plugin_phase = true;
+                        self.sess.span_warn(attr.span,
+                            "phase(syntax) is a deprecated synonym for phase(plugin)");
+                    }
+                }
+
+                if !plugin_phase { return; }
+
+                let PluginMetadata { macros, lib, registrar_symbol } =
+                    self.reader.read_plugin_metadata(vi);
+
+                self.plugins.macros.push(ExportedMacros {
+                    crate_name: name,
+                    macros: macros,
+                });
+
+                match (lib, registrar_symbol) {
+                    (Some(lib), Some(symbol))
+                        => self.dylink_registrar(vi, lib, symbol),
+                    _ => (),
+                }
+            }
+            _ => (),
+        }
+    }
+}
+
+impl<'a> PluginLoader<'a> {
+    // Dynamically link a registrar function into the compiler process.
+    fn dylink_registrar(&mut self, vi: &ast::ViewItem, path: Path, symbol: String) {
+        // Make sure the path contains a / or the linker will search for it.
+        let path = os::make_absolute(&path);
+
+        let lib = match DynamicLibrary::open(Some(&path)) {
+            Ok(lib) => lib,
+            // this is fatal: there are almost certainly macros we need
+            // inside this crate, so continue would spew "macro undefined"
+            // errors
+            Err(err) => self.sess.span_fatal(vi.span, err.as_slice())
+        };
+
+        unsafe {
+            let registrar: PluginRegistrarFun =
+                match lib.symbol(symbol.as_slice()) {
+                    Ok(registrar) => registrar,
+                    // again fatal if we can't register macros
+                    Err(err) => self.sess.span_fatal(vi.span, err.as_slice())
+                };
+
+            self.plugins.registrars.push(registrar);
+
+            // Intentionally leak the dynamic library. We can't ever unload it
+            // since the library can make things that will live arbitrarily long
+            // (e.g. an @-box cycle or a task).
+            mem::forget(lib);
+
+        }
+    }
+}
diff --git a/src/librustc/plugin/mod.rs b/src/librustc/plugin/mod.rs
new file mode 100644 (file)
index 0000000..fa70ffc
--- /dev/null
@@ -0,0 +1,64 @@
+// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <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.
+
+/*!
+ * Infrastructure for compiler plugins.
+ *
+ * Plugins are Rust libraries which extend the behavior of `rustc`
+ * in various ways.
+ *
+ * Plugin authors will use the `Registry` type re-exported by
+ * this module, along with its methods.  The rest of the module
+ * is for use by `rustc` itself.
+ *
+ * To define a plugin, build a dylib crate with a
+ * `#[plugin_registrar]` function:
+ *
+ * ```rust,ignore
+ * #![crate_id = "myplugin"]
+ * #![crate_type = "dylib"]
+ * #![feature(plugin_registrar)]
+ *
+ * extern crate rustc;
+ *
+ * use rustc::plugin::Registry;
+ *
+ * #[plugin_registrar]
+ * pub fn plugin_registrar(reg: &mut Registry) {
+ *     reg.register_macro("mymacro", expand_mymacro);
+ * }
+ *
+ * fn expand_mymacro(...) {  // details elided
+ * ```
+ *
+ * WARNING: We currently don't check that the registrar function
+ * has the appropriate type!
+ *
+ * To use a plugin while compiling another crate:
+ *
+ * ```rust
+ * #![feature(phase)]
+ *
+ * #[phase(plugin)]
+ * extern crate myplugin;
+ * ```
+ *
+ * If you also need the plugin crate available at runtime, use
+ * `phase(plugin, link)`.
+ *
+ * See `src/test/auxiliary/macro_crate_test.rs` and `src/libfourcc`
+ * for examples of syntax extension plugins.
+ */
+
+pub use self::registry::Registry;
+
+pub mod registry;
+pub mod load;
+pub mod build;
diff --git a/src/librustc/plugin/registry.rs b/src/librustc/plugin/registry.rs
new file mode 100644 (file)
index 0000000..f6e3782
--- /dev/null
@@ -0,0 +1,70 @@
+// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <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.
+
+//! Used by plugin crates to tell `rustc` about the plugins they provide.
+
+use syntax::ext::base::{SyntaxExtension, NamedSyntaxExtension, NormalTT};
+use syntax::ext::base::{IdentTT, ItemDecorator, ItemModifier, BasicMacroExpander};
+use syntax::ext::base::{MacroExpanderFn};
+use syntax::codemap::Span;
+use syntax::parse::token;
+use syntax::ast;
+
+/// Structure used to register plugins.
+///
+/// A plugin registrar function takes an `&mut Registry` and should call
+/// methods to register its plugins.
+///
+/// This struct has public fields and other methods for use by `rustc`
+/// itself. They are not documented here, and plugin authors should
+/// not use them.
+pub struct Registry {
+    #[doc(hidden)]
+    pub krate_span: Span,
+
+    #[doc(hidden)]
+    pub syntax_exts: Vec<NamedSyntaxExtension>,
+}
+
+impl Registry {
+    #[doc(hidden)]
+    pub fn new(krate: &ast::Crate) -> Registry {
+        Registry {
+            krate_span: krate.span,
+            syntax_exts: vec!(),
+        }
+    }
+
+    /// Register a syntax extension of any kind.
+    ///
+    /// This is the most general hook into `libsyntax`'s expansion behavior.
+    pub fn register_syntax_extension(&mut self, name: ast::Name, extension: SyntaxExtension) {
+        self.syntax_exts.push((name, match extension {
+            NormalTT(ext, _) => NormalTT(ext, Some(self.krate_span)),
+            IdentTT(ext, _) => IdentTT(ext, Some(self.krate_span)),
+            ItemDecorator(ext) => ItemDecorator(ext),
+            ItemModifier(ext) => ItemModifier(ext),
+        }));
+    }
+
+    /// Register a macro of the usual kind.
+    ///
+    /// This is a convenience wrapper for `register_syntax_extension`.
+    /// It builds for you a `NormalTT` with a `BasicMacroExpander`,
+    /// and also takes care of interning the macro's name.
+    pub fn register_macro(&mut self, name: &str, expander: MacroExpanderFn) {
+        self.register_syntax_extension(
+            token::intern(name),
+            NormalTT(box BasicMacroExpander {
+                expander: expander,
+                span: None,
+            }, None));
+    }
+}
index 5ddae0c1bfef6358a43eb3d1d547e15e52a308a7..08052c03de482e13091348b8e57bd07ebb27fe65 100644 (file)
@@ -42,23 +42,17 @@ pub fn indent<R>(op: || -> R) -> R {
     r
 }
 
-pub struct _indenter {
-    _i: (),
+pub struct Indenter {
+    _cannot_construct_outside_of_this_module: ()
 }
 
-impl Drop for _indenter {
+impl Drop for Indenter {
     fn drop(&mut self) { debug!("<<"); }
 }
 
-pub fn _indenter(_i: ()) -> _indenter {
-    _indenter {
-        _i: ()
-    }
-}
-
-pub fn indenter() -> _indenter {
+pub fn indenter() -> Indenter {
     debug!(">>");
-    _indenter(())
+    Indenter { _cannot_construct_outside_of_this_module: () }
 }
 
 struct LoopQueryVisitor<'a> {
index 2a4774ffd84d4f5574edc73f1b7ef0c79fe00f4c..d243c61ddaff8ba3d91bdab8fb135e9888352d12 100644 (file)
@@ -203,7 +203,7 @@ fn build_struct(tcx: &ty::ctxt, did: ast::DefId) -> clean::Struct {
 fn build_type(tcx: &ty::ctxt, did: ast::DefId) -> clean::ItemEnum {
     let t = ty::lookup_item_type(tcx, did);
     match ty::get(t.ty).sty {
-        ty::ty_enum(edid, _) => {
+        ty::ty_enum(edid, _) if !csearch::is_typedef(&tcx.sess.cstore, did) => {
             return clean::EnumItem(clean::Enum {
                 generics: t.generics.clean(),
                 variants_stripped: false,
index 650cd749af69e1e8d949f0bc2139887f3d3036f1..54128fda6c6a5fc95b2e7182eba07119b5a8f5dc 100644 (file)
@@ -477,6 +477,10 @@ fn clean(&self) -> TyParamBound {
         match *self {
             ast::StaticRegionTyParamBound => RegionBound,
             ast::OtherRegionTyParamBound(_) => RegionBound,
+            ast::UnboxedFnTyParamBound(_) => {
+                // FIXME(pcwalton): Wrong.
+                RegionBound
+            }
             ast::TraitTyParamBound(ref t) => TraitBound(t.clean()),
         }
     }
index 1786e5b3fd24998471b5b1fb8f71e0b47a64e8d6..f848c5224b7c8318552fb1f404e3d0000709ac6a 100644 (file)
@@ -10,7 +10,6 @@
 
 use rustc;
 use rustc::{driver, middle};
-use rustc::metadata::creader::Loader;
 use rustc::middle::privacy;
 use rustc::middle::lint;
 
@@ -100,8 +99,8 @@ fn get_ast_and_resolve(cpath: &Path, libs: HashSet<Path>, cfgs: Vec<String>)
     }
 
     let krate = phase_1_parse_input(&sess, cfg, &input);
-    let (krate, ast_map) = phase_2_configure_and_expand(&sess, &mut Loader::new(&sess),
-                                                        krate, &from_str("rustdoc").unwrap());
+    let (krate, ast_map) = phase_2_configure_and_expand(&sess, krate,
+                                                        &from_str("rustdoc").unwrap());
     let driver::driver::CrateAnalysis {
         exported_items, public_items, ty_cx, ..
     } = phase_3_run_analysis_passes(sess, &krate, ast_map);
index fea6748660bde2c0e2df962032226a7503a7b6e2..8ad10a686e677677778e4ce92efb73b5f6424094 100644 (file)
@@ -135,7 +135,6 @@ fn drop(&mut self) {
 mod imp {
     use libc;
     use std::mem;
-    use std::os::win32::as_utf16_p;
     use std::os;
     use std::ptr;
 
@@ -162,8 +161,9 @@ pub struct Lock {
 
     impl Lock {
         pub fn new(p: &Path) -> Lock {
-            let handle = as_utf16_p(p.as_str().unwrap(), |p| unsafe {
-                libc::CreateFileW(p,
+            let p_16 = p.as_str().unwrap().to_utf16().append_one(0);
+            let handle = unsafe {
+                libc::CreateFileW(p_16.as_ptr(),
                                   libc::FILE_GENERIC_READ |
                                     libc::FILE_GENERIC_WRITE,
                                   libc::FILE_SHARE_READ |
@@ -173,7 +173,7 @@ pub fn new(p: &Path) -> Lock {
                                   libc::CREATE_ALWAYS,
                                   libc::FILE_ATTRIBUTE_NORMAL,
                                   ptr::mut_null())
-            });
+            };
             if handle as uint == libc::INVALID_HANDLE_VALUE as uint {
                 fail!("create file error: {}", os::last_os_error());
             }
index 260d26c543736c754904730f634f791a7ce56e09..061c05058ae367d84871dcd504e06528741cc3ad 100644 (file)
@@ -24,6 +24,7 @@
 //! // ... something using html
 //! ```
 
+#![allow(dead_code)]
 #![allow(non_camel_case_types)]
 
 use libc;
index e623d54675c25c820cddfe898067f9ebca0fe2fb..05875f59fbe1852bb4da502a1cdba1f47aceeb71 100644 (file)
@@ -19,8 +19,6 @@
 extern crate debug;
 extern crate getopts;
 extern crate libc;
-#[phase(syntax, link)]
-extern crate log;
 extern crate rustc;
 extern crate serialize;
 extern crate sync;
 extern crate testing = "test";
 extern crate time;
 
+#[cfg(stage0)]
+#[phase(syntax, link)]
+extern crate log;
+
+#[cfg(not(stage0))]
+#[phase(plugin, link)]
+extern crate log;
+
 use std::io;
 use std::io::{File, MemWriter};
 use std::str;
index 7a796e97f412f2ee98bf4158a7c05a8a167779a5..fee1d63a274d51ab7530e157bb98d8c0de1e2db1 100644 (file)
@@ -10,7 +10,7 @@
 
 use clean;
 
-use dl = std::unstable::dynamic_lib;
+use dl = std::dynamic_lib;
 use serialize::json;
 use std::string::String;
 
index 745e29508d218a3554996d5078513db04f45a51d..0d77764127465bcee61ad89cb2aefe8c9579efb5 100644 (file)
@@ -15,7 +15,7 @@
 use std::os;
 use std::str;
 use std::string::String;
-use std::unstable::dynamic_lib::DynamicLibrary;
+use std::dynamic_lib::DynamicLibrary;
 
 use std::collections::{HashSet, HashMap};
 use testing;
@@ -23,7 +23,6 @@
 use rustc::driver::config;
 use rustc::driver::driver;
 use rustc::driver::session;
-use rustc::metadata::creader::Loader;
 use syntax::ast;
 use syntax::codemap::{CodeMap, dummy_spanned};
 use syntax::diagnostic;
@@ -68,7 +67,7 @@ pub fn run(input: &str,
         @dummy_spanned(ast::MetaWord(cfg_))
     }));
     let krate = driver::phase_1_parse_input(&sess, cfg, &input);
-    let (krate, _) = driver::phase_2_configure_and_expand(&sess, &mut Loader::new(&sess), krate,
+    let (krate, _) = driver::phase_2_configure_and_expand(&sess, krate,
                                                           &from_str("rustdoc-test").unwrap());
 
     let ctx = @core::DocContext {
index 4234c085148cb575acbe2856a8ba099b220c44e2..b4d9ac7efbebcce50deb04af89445f41f9756a37 100644 (file)
@@ -229,7 +229,7 @@ fn drop(&mut self) {
     }
 }
 
-impl Container for CString {
+impl Collection for CString {
     /// Return the number of bytes in the CString (not including the NUL terminator).
     ///
     /// # Failure
index 3158687c6ab937e04be0b278f4a2252e17eba01f..bb57f5c038c0323c4f111c814f37d427f4dd2f3c 100644 (file)
 #![no_std]
 #![experimental]
 
+#[cfg(stage0)]
 #[phase(syntax, link)]
 extern crate core;
+
+#[cfg(not(stage0))]
+#[phase(plugin, link)]
+extern crate core;
+
 extern crate alloc;
 extern crate libc;
 extern crate collections;
@@ -28,7 +34,9 @@
 #[cfg(test)] extern crate realrustrt = "rustrt";
 #[cfg(test)] extern crate test;
 #[cfg(test)] extern crate native;
-#[cfg(test)] #[phase(syntax, link)] extern crate std;
+
+#[cfg(test, stage0)] #[phase(syntax, link)] extern crate std;
+#[cfg(test, not(stage0))] #[phase(plugin, link)] extern crate std;
 
 pub use self::util::{Stdio, Stdout, Stderr};
 pub use self::unwind::{begin_unwind, begin_unwind_fmt};
index fccbe4a15e948144cf8f67488107da5313951692..eec19e9d5db86bf9cb5ad55587516b9a2b668d40 100644 (file)
@@ -298,10 +298,12 @@ mod os {
         static _PTHREAD_MUTEX_SIG_init: libc::c_long = 0x32AAABA7;
         static _PTHREAD_COND_SIG_init: libc::c_long = 0x3CB0B1BB;
 
+        #[repr(C)]
         pub struct pthread_mutex_t {
             __sig: libc::c_long,
             __opaque: [u8, ..__PTHREAD_MUTEX_SIZE__],
         }
+        #[repr(C)]
         pub struct pthread_cond_t {
             __sig: libc::c_long,
             __opaque: [u8, ..__PTHREAD_COND_SIZE__],
@@ -339,10 +341,12 @@ mod os {
         #[cfg(target_arch = "mips")]
         static __SIZEOF_PTHREAD_COND_T: uint = 48 - 8;
 
+        #[repr(C)]
         pub struct pthread_mutex_t {
             __align: libc::c_longlong,
             size: [u8, ..__SIZEOF_PTHREAD_MUTEX_T],
         }
+        #[repr(C)]
         pub struct pthread_cond_t {
             __align: libc::c_longlong,
             size: [u8, ..__SIZEOF_PTHREAD_COND_T],
@@ -361,7 +365,9 @@ pub struct pthread_cond_t {
     mod os {
         use libc;
 
+        #[repr(C)]
         pub struct pthread_mutex_t { value: libc::c_int }
+        #[repr(C)]
         pub struct pthread_cond_t { value: libc::c_int }
 
         pub static PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t {
index f5cde39bc8343405cde618df3f69e4a8824fbe0b..fe8935db2ec128278b9c7367ccce085e9513169c 100644 (file)
@@ -18,7 +18,6 @@
 pub struct IdleWatcher {
     handle: *uvll::uv_idle_t,
     idle_flag: bool,
-    closed: bool,
     callback: Box<Callback:Send>,
 }
 
@@ -31,7 +30,6 @@ pub fn new(loop_: &mut Loop, cb: Box<Callback:Send>) -> Box<IdleWatcher> {
         let me = box IdleWatcher {
             handle: handle,
             idle_flag: false,
-            closed: false,
             callback: cb,
         };
         return me.install();
index e7bdc25a1fd91d6bb07ea5021998f1ba52351ccd..47b321b068b36ae6046cd91107d38e428f3e51d0 100644 (file)
@@ -165,7 +165,6 @@ pub struct TcpWatcher {
 pub struct TcpListener {
     home: HomeHandle,
     handle: *uvll::uv_pipe_t,
-    closing_task: Option<BlockedTask>,
     outgoing: Sender<Result<Box<rtio::RtioTcpStream:Send>, IoError>>,
     incoming: Receiver<Result<Box<rtio::RtioTcpStream:Send>, IoError>>,
 }
@@ -358,7 +357,6 @@ pub fn bind(io: &mut UvIoFactory, address: rtio::SocketAddr)
         let l = box TcpListener {
             home: io.make_handle(),
             handle: handle,
-            closing_task: None,
             outgoing: tx,
             incoming: rx,
         };
index f6c6d6c9068e0cbbfc46a43811f50d22dd183382..a6193dd9379c1636734f8428338848c8534e0b7a 100644 (file)
@@ -136,6 +136,7 @@ pub struct uv_process_options_t {
 
 // These fields are private because they must be interfaced with through the
 // functions below.
+#[repr(C)]
 pub struct uv_stdio_container_t {
     flags: libc::c_int,
     stream: *uv_stream_t,
index 046d25f98e43a9f1a2003ddfc4308524ca5ef584..9907faae52bc4bd0c1b193e5211e4b639d3865b7 100644 (file)
@@ -992,7 +992,7 @@ enum ParserState {
     ParseObject(bool),
     // Parse ',' or ']' after an element in an object.
     ParseObjectComma,
-    // Initialial state.
+    // Initial state.
     ParseStart,
     // Expecting the stream to end.
     ParseBeforeFinish,
@@ -1152,7 +1152,7 @@ pub struct Parser<T> {
     // We maintain a stack representing where we are in the logical structure
     // of the JSON stream.
     stack: Stack,
-    // A state machine is kept to make it possible to interupt and resume parsing.
+    // A state machine is kept to make it possible to interrupt and resume parsing.
     state: ParserState,
 }
 
@@ -1449,7 +1449,7 @@ fn parse_str(&mut self) -> Result<String, ParserError> {
     // information to return a JsonEvent.
     // Manages an internal state so that parsing can be interrupted and resumed.
     // Also keeps track of the position in the logical structure of the json
-    // stream int the form of a stack that can be queried by the user usng the
+    // stream int the form of a stack that can be queried by the user using the
     // stack() method.
     fn parse(&mut self) -> JsonEvent {
         loop {
index 08348c963338265c0812094ac2054a8d6e3ca0be..33d20ed7bcd0fe35313719066df22d713da674e1 100644 (file)
 // test harness access
 #[cfg(test)]
 extern crate test;
+
+#[cfg(stage0)]
 #[phase(syntax, link)]
 extern crate log;
 
+#[cfg(not(stage0))]
+#[phase(plugin, link)]
+extern crate log;
+
 pub use self::serialize::{Decoder, Encoder, Decodable, Encodable,
                           DecoderHelpers, EncoderHelpers};
 
index e9bb23a75c88f4bd7169ebb46c48cf8414acfbf9..b9edc9a811e43486af96ba81ebc99df56c73a4de 100644 (file)
@@ -10,7 +10,7 @@
 
 //! Operations on ASCII strings and characters
 
-use container::Container;
+use collections::Collection;
 use fmt;
 use iter::Iterator;
 use mem;
index 817b54fb692f20b8e5838d53671de59ae7c2b38d..e8a158ad230aa40fac8601942b609f1480fde8ee 100644 (file)
@@ -33,7 +33,7 @@
 //! handled correctly, i.e. that allocated memory is eventually freed
 //! if necessary.
 
-use container::Container;
+use collections::Collection;
 use kinds::Send;
 use mem;
 use ops::Drop;
@@ -149,7 +149,7 @@ pub unsafe fn unwrap(mut self) -> *mut T {
     }
 }
 
-impl<T> Container for CVec<T> {
+impl<T> Collection for CVec<T> {
     fn len(&self) -> uint { self.len }
 }
 
index 571c579470441e92ee8a0ebb0e783be2467aa5ad..34851265409ec495b8afbdb907ef75669056a226 100644 (file)
@@ -12,7 +12,7 @@
 
 use clone::Clone;
 use cmp::{max, Eq, Equiv, PartialEq};
-use container::{Container, Mutable, Set, MutableSet, Map, MutableMap};
+use collections::{Collection, Mutable, Set, MutableSet, Map, MutableMap};
 use default::Default;
 use fmt::Show;
 use fmt;
@@ -393,7 +393,7 @@ pub fn mut_iter<'a>(&'a mut self) -> MutEntries<'a, K, V> {
         }
 
         pub fn move_iter(self) -> MoveEntries<K, V> {
-            MoveEntries { table: self, idx: 0, elems_seen: 0 }
+            MoveEntries { table: self, idx: 0 }
         }
     }
 
@@ -428,8 +428,7 @@ pub struct MutEntries<'a, K, V> {
     /// Iterator over the entries in a table, consuming the table.
     pub struct MoveEntries<K, V> {
         table: RawTable<K, V>,
-        idx: uint,
-        elems_seen: uint,
+        idx: uint
     }
 
     impl<'a, K, V> Iterator<(&'a K, &'a V)> for Entries<'a, K, V> {
@@ -930,7 +929,7 @@ pub fn pop_equiv<Q:Hash<S> + Equiv<K>>(&mut self, k: &Q) -> Option<V> {
     }
 }
 
-impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> Container for HashMap<K, V, H> {
+impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> Collection for HashMap<K, V, H> {
     /// Return the number of elements in the map
     fn len(&self) -> uint { self.table.size() }
 }
@@ -1504,7 +1503,7 @@ fn eq(&self, other: &HashSet<T, H>) -> bool {
 
 impl<T: Eq + Hash<S>, S, H: Hasher<S>> Eq for HashSet<T, H> {}
 
-impl<T: Eq + Hash<S>, S, H: Hasher<S>> Container for HashSet<T, H> {
+impl<T: Eq + Hash<S>, S, H: Hasher<S>> Collection for HashSet<T, H> {
     fn len(&self) -> uint { self.map.len() }
 }
 
@@ -2159,8 +2158,8 @@ mod test_set {
     use prelude::*;
 
     use super::HashSet;
-    use container::Container;
     use slice::ImmutableEqVector;
+    use collections::Collection;
 
     #[test]
     fn test_disjoint() {
index a12b00f34dc4a01fd48fd8d852d4bcf37ab2acce..72d96804d6d7e4dd99a571ff7248c2ca37bb8017 100644 (file)
@@ -38,8 +38,7 @@
 //! ```
 
 use cmp::{PartialEq, Eq};
-use collections::HashMap;
-use container::{Container, Mutable, MutableMap};
+use collections::{HashMap, Collection, Mutable, MutableMap};
 use fmt;
 use hash::Hash;
 use iter::{range, Iterator};
@@ -227,7 +226,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
-impl<K: Hash + Eq, V> Container for LruCache<K, V> {
+impl<K: Hash + Eq, V> Collection for LruCache<K, V> {
     /// Return the number of key-value pairs in the cache.
     fn len(&self) -> uint {
         self.map.len()
index 16a6a35d9d5f751970397317196a692ea911e03b..9e5288f9541b8c1869ac400f8936e36998dbe2b2 100644 (file)
  * Collection types.
  */
 
-pub use core_collections::{Bitv, BitvSet, BTree, Deque, DList, EnumSet};
+pub use core_collections::{Collection, Mutable, Map, MutableMap};
+pub use core_collections::{Set, MutableSet, Deque};
+pub use core_collections::{Bitv, BitvSet, BTree, DList, EnumSet};
 pub use core_collections::{PriorityQueue, RingBuf, SmallIntMap};
 pub use core_collections::{TreeMap, TreeSet, TrieMap, TrieSet};
-pub use core_collections::{bitv, btree, deque, dlist, enum_set};
+pub use core_collections::{bitv, btree, dlist, enum_set};
 pub use core_collections::{priority_queue, ringbuf, smallintmap, treemap, trie};
 
 pub use self::hashmap::{HashMap, HashSet};
index 7fe505573b799bb12257a682a043fe6fde04df5d..84ef6d0aa8fcf51ecadb6afdeedd6691a43ed80c 100644 (file)
@@ -33,7 +33,7 @@
 /// of a synchronous channel. There are a few branches for the unbuffered case,
 /// but they're mostly just relevant to blocking senders.
 
-use container::Container;
+use collections::Collection;
 use iter::Iterator;
 use kinds::Send;
 use mem;
diff --git a/src/libstd/dynamic_lib.rs b/src/libstd/dynamic_lib.rs
new file mode 100644 (file)
index 0000000..fa6efc8
--- /dev/null
@@ -0,0 +1,332 @@
+// 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.
+
+/*!
+
+Dynamic library facilities.
+
+A simple wrapper over the platform's dynamic library facilities
+
+*/
+
+#![experimental]
+#![allow(missing_doc)]
+
+use clone::Clone;
+use c_str::ToCStr;
+use iter::Iterator;
+use mem;
+use ops::*;
+use option::*;
+use os;
+use path::{Path,GenericPath};
+use result::*;
+use slice::{Vector,ImmutableVector};
+use str;
+use string::String;
+use vec::Vec;
+
+pub struct DynamicLibrary { handle: *u8}
+
+impl Drop for DynamicLibrary {
+    fn drop(&mut self) {
+        match dl::check_for_errors_in(|| {
+            unsafe {
+                dl::close(self.handle)
+            }
+        }) {
+            Ok(()) => {},
+            Err(str) => fail!("{}", str)
+        }
+    }
+}
+
+impl DynamicLibrary {
+    // FIXME (#12938): Until DST lands, we cannot decompose &str into
+    // & and str, so we cannot usefully take ToCStr arguments by
+    // reference (without forcing an additional & around &str). So we
+    // are instead temporarily adding an instance for &Path, so that
+    // we can take ToCStr as owned. When DST lands, the &Path instance
+    // should be removed, and arguments bound by ToCStr should be
+    // passed by reference. (Here: in the `open` method.)
+
+    /// Lazily open a dynamic library. When passed None it gives a
+    /// handle to the calling process
+    pub fn open<T: ToCStr>(filename: Option<T>)
+                        -> Result<DynamicLibrary, String> {
+        unsafe {
+            let mut filename = filename;
+            let maybe_library = dl::check_for_errors_in(|| {
+                match filename.take() {
+                    Some(name) => dl::open_external(name),
+                    None => dl::open_internal()
+                }
+            });
+
+            // The dynamic library must not be constructed if there is
+            // an error opening the library so the destructor does not
+            // run.
+            match maybe_library {
+                Err(err) => Err(err),
+                Ok(handle) => Ok(DynamicLibrary { handle: handle })
+            }
+        }
+    }
+
+    /// Prepends a path to this process's search path for dynamic libraries
+    pub fn prepend_search_path(path: &Path) {
+        let mut search_path = DynamicLibrary::search_path();
+        search_path.insert(0, path.clone());
+        let newval = DynamicLibrary::create_path(search_path.as_slice());
+        os::setenv(DynamicLibrary::envvar(),
+                   str::from_utf8(newval.as_slice()).unwrap());
+    }
+
+    /// From a slice of paths, create a new vector which is suitable to be an
+    /// environment variable for this platforms dylib search path.
+    pub fn create_path(path: &[Path]) -> Vec<u8> {
+        let mut newvar = Vec::new();
+        for (i, path) in path.iter().enumerate() {
+            if i > 0 { newvar.push(DynamicLibrary::separator()); }
+            newvar.push_all(path.as_vec());
+        }
+        return newvar;
+    }
+
+    /// Returns the environment variable for this process's dynamic library
+    /// search path
+    pub fn envvar() -> &'static str {
+        if cfg!(windows) {
+            "PATH"
+        } else if cfg!(target_os = "macos") {
+            "DYLD_LIBRARY_PATH"
+        } else {
+            "LD_LIBRARY_PATH"
+        }
+    }
+
+    fn separator() -> u8 {
+        if cfg!(windows) {';' as u8} else {':' as u8}
+    }
+
+    /// Returns the current search path for dynamic libraries being used by this
+    /// process
+    pub fn search_path() -> Vec<Path> {
+        let mut ret = Vec::new();
+        match os::getenv_as_bytes(DynamicLibrary::envvar()) {
+            Some(env) => {
+                for portion in
+                        env.as_slice()
+                           .split(|a| *a == DynamicLibrary::separator()) {
+                    ret.push(Path::new(portion));
+                }
+            }
+            None => {}
+        }
+        return ret;
+    }
+
+    /// Access the value at the symbol of the dynamic library
+    pub unsafe fn symbol<T>(&self, symbol: &str) -> Result<T, String> {
+        // This function should have a lifetime constraint of 'a on
+        // T but that feature is still unimplemented
+
+        let maybe_symbol_value = dl::check_for_errors_in(|| {
+            symbol.with_c_str(|raw_string| {
+                dl::symbol(self.handle, raw_string)
+            })
+        });
+
+        // The value must not be constructed if there is an error so
+        // the destructor does not run.
+        match maybe_symbol_value {
+            Err(err) => Err(err),
+            Ok(symbol_value) => Ok(mem::transmute(symbol_value))
+        }
+    }
+}
+
+#[cfg(test)]
+mod test {
+    use super::*;
+    use prelude::*;
+    use libc;
+
+    #[test]
+    #[ignore(cfg(windows))] // FIXME #8818
+    #[ignore(cfg(target_os="android"))] // FIXME(#10379)
+    fn test_loading_cosine() {
+        // The math library does not need to be loaded since it is already
+        // statically linked in
+        let none: Option<Path> = None; // appease the typechecker
+        let libm = match DynamicLibrary::open(none) {
+            Err(error) => fail!("Could not load self as module: {}", error),
+            Ok(libm) => libm
+        };
+
+        let cosine: extern fn(libc::c_double) -> libc::c_double = unsafe {
+            match libm.symbol("cos") {
+                Err(error) => fail!("Could not load function cos: {}", error),
+                Ok(cosine) => cosine
+            }
+        };
+
+        let argument = 0.0;
+        let expected_result = 1.0;
+        let result = cosine(argument);
+        if result != expected_result {
+            fail!("cos({:?}) != {:?} but equaled {:?} instead", argument,
+                   expected_result, result)
+        }
+    }
+
+    #[test]
+    #[cfg(target_os = "linux")]
+    #[cfg(target_os = "macos")]
+    #[cfg(target_os = "freebsd")]
+    fn test_errors_do_not_crash() {
+        // Open /dev/null as a library to get an error, and make sure
+        // that only causes an error, and not a crash.
+        let path = Path::new("/dev/null");
+        match DynamicLibrary::open(Some(&path)) {
+            Err(_) => {}
+            Ok(_) => fail!("Successfully opened the empty library.")
+        }
+    }
+}
+
+#[cfg(target_os = "linux")]
+#[cfg(target_os = "android")]
+#[cfg(target_os = "macos")]
+#[cfg(target_os = "freebsd")]
+pub mod dl {
+    use prelude::*;
+
+    use c_str::{CString, ToCStr};
+    use libc;
+    use ptr;
+    use result::*;
+    use str::StrAllocating;
+    use string::String;
+
+    pub unsafe fn open_external<T: ToCStr>(filename: T) -> *u8 {
+        filename.with_c_str(|raw_name| {
+            dlopen(raw_name, Lazy as libc::c_int) as *u8
+        })
+    }
+
+    pub unsafe fn open_internal() -> *u8 {
+        dlopen(ptr::null(), Lazy as libc::c_int) as *u8
+    }
+
+    pub fn check_for_errors_in<T>(f: || -> T) -> Result<T, String> {
+        use rt::mutex::{StaticNativeMutex, NATIVE_MUTEX_INIT};
+        static mut lock: StaticNativeMutex = NATIVE_MUTEX_INIT;
+        unsafe {
+            // dlerror isn't thread safe, so we need to lock around this entire
+            // sequence
+            let _guard = lock.lock();
+            let _old_error = dlerror();
+
+            let result = f();
+
+            let last_error = dlerror();
+            let ret = if ptr::null() == last_error {
+                Ok(result)
+            } else {
+                Err(CString::new(last_error, false).as_str()
+                                                   .unwrap()
+                                                   .to_string())
+            };
+
+            ret
+        }
+    }
+
+    pub unsafe fn symbol(handle: *u8, symbol: *libc::c_char) -> *u8 {
+        dlsym(handle as *libc::c_void, symbol) as *u8
+    }
+    pub unsafe fn close(handle: *u8) {
+        dlclose(handle as *libc::c_void); ()
+    }
+
+    pub enum RTLD {
+        Lazy = 1,
+        Now = 2,
+        Global = 256,
+        Local = 0,
+    }
+
+    #[link_name = "dl"]
+    extern {
+        fn dlopen(filename: *libc::c_char, flag: libc::c_int) -> *libc::c_void;
+        fn dlerror() -> *libc::c_char;
+        fn dlsym(handle: *libc::c_void, symbol: *libc::c_char) -> *libc::c_void;
+        fn dlclose(handle: *libc::c_void) -> libc::c_int;
+    }
+}
+
+#[cfg(target_os = "win32")]
+pub mod dl {
+    use c_str::ToCStr;
+    use libc;
+    use os;
+    use ptr;
+    use result::{Ok, Err, Result};
+    use str::StrAllocating;
+    use str;
+    use string::String;
+
+    pub unsafe fn open_external<T: ToCStr>(filename: T) -> *u8 {
+        // Windows expects Unicode data
+        let filename_cstr = filename.to_c_str();
+        let filename_str = str::from_utf8(filename_cstr.as_bytes_no_nul()).unwrap();
+        let filename_str = filename_str.to_utf16().append_one(0);
+        LoadLibraryW(filename_str.as_ptr() as *libc::c_void) as *u8
+    }
+
+    pub unsafe fn open_internal() -> *u8 {
+        let handle = ptr::null();
+        GetModuleHandleExW(0 as libc::DWORD, ptr::null(), &handle as **libc::c_void);
+        handle as *u8
+    }
+
+    pub fn check_for_errors_in<T>(f: || -> T) -> Result<T, String> {
+        unsafe {
+            SetLastError(0);
+
+            let result = f();
+
+            let error = os::errno();
+            if 0 == error {
+                Ok(result)
+            } else {
+                Err(format!("Error code {}", error))
+            }
+        }
+    }
+
+    pub unsafe fn symbol(handle: *u8, symbol: *libc::c_char) -> *u8 {
+        GetProcAddress(handle as *libc::c_void, symbol) as *u8
+    }
+    pub unsafe fn close(handle: *u8) {
+        FreeLibrary(handle as *libc::c_void); ()
+    }
+
+    #[allow(non_snake_case_functions)]
+    extern "system" {
+        fn SetLastError(error: libc::size_t);
+        fn LoadLibraryW(name: *libc::c_void) -> *libc::c_void;
+        fn GetModuleHandleExW(dwFlags: libc::DWORD, name: *u16,
+                              handle: **libc::c_void) -> *libc::c_void;
+        fn GetProcAddress(handle: *libc::c_void, name: *libc::c_char) -> *libc::c_void;
+        fn FreeLibrary(handle: *libc::c_void);
+    }
+}
index 0d4217601624f760a7a562d5f39e7c258eb4f7a1..9450f7798edcf97c3db3c59cde615ffea6eec4b0 100644 (file)
@@ -11,7 +11,7 @@
 //! Buffering wrappers for I/O traits
 
 use cmp;
-use container::Container;
+use collections::Collection;
 use io::{Reader, Writer, Stream, Buffer, DEFAULT_BUF_SIZE, IoResult};
 use iter::ExactSize;
 use ops::Drop;
index 45f783698cd3b9b2f3812ced16d1927b5ba07ecc..529536b0a0da78317bae8db7fedef77408c70f4f 100644 (file)
 
 use clone::Clone;
 use cmp;
-use container::Container;
+use collections::Collection;
 use comm::{Sender, Receiver};
 use io;
 use option::{None, Option, Some};
 use result::{Ok, Err};
 use super::{Reader, Writer, IoResult};
 use str::StrSlice;
-use slice::{bytes, CloneableVector, MutableVector, ImmutableVector};
+use slice::{bytes, MutableVector, ImmutableVector};
+use vec::Vec;
 
 /// Allows reading from a rx.
 ///
 /// # drop(tx);
 /// let mut reader = ChanReader::new(rx);
 ///
-/// let mut buf = ~[0u8, ..100];
+/// let mut buf = [0u8, ..100];
 /// match reader.read(buf) {
 ///     Ok(nread) => println!("Read {} bytes", nread),
 ///     Err(e) => println!("read error: {}", e),
 /// }
 /// ```
 pub struct ChanReader {
-    buf: Option<~[u8]>,  // A buffer of bytes received but not consumed.
-    pos: uint,           // How many of the buffered bytes have already be consumed.
-    rx: Receiver<~[u8]>,   // The rx to pull data from.
-    closed: bool,        // Whether the pipe this rx connects to has been closed.
+    buf: Option<Vec<u8>>,  // A buffer of bytes received but not consumed.
+    pos: uint,             // How many of the buffered bytes have already be consumed.
+    rx: Receiver<Vec<u8>>, // The Receiver to pull data from.
+    closed: bool,          // Whether the channel this Receiver connects to has been closed.
 }
 
 impl ChanReader {
     /// Wraps a `Port` in a `ChanReader` structure
-    pub fn new(rx: Receiver<~[u8]>) -> ChanReader {
+    pub fn new(rx: Receiver<Vec<u8>>) -> ChanReader {
         ChanReader {
             buf: None,
             pos: 0,
@@ -99,12 +100,12 @@ fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
 /// writer.write("hello, world".as_bytes());
 /// ```
 pub struct ChanWriter {
-    tx: Sender<~[u8]>,
+    tx: Sender<Vec<u8>>,
 }
 
 impl ChanWriter {
     /// Wraps a channel in a `ChanWriter` structure
-    pub fn new(tx: Sender<~[u8]>) -> ChanWriter {
+    pub fn new(tx: Sender<Vec<u8>>) -> ChanWriter {
         ChanWriter { tx: tx }
     }
 }
@@ -117,7 +118,7 @@ fn clone(&self) -> ChanWriter {
 
 impl Writer for ChanWriter {
     fn write(&mut self, buf: &[u8]) -> IoResult<()> {
-        self.tx.send_opt(buf.to_owned()).map_err(|_| {
+        self.tx.send_opt(Vec::from_slice(buf)).map_err(|_| {
             io::IoError {
                 kind: io::BrokenPipe,
                 desc: "Pipe closed",
@@ -139,40 +140,40 @@ mod test {
     fn test_rx_reader() {
         let (tx, rx) = channel();
         task::spawn(proc() {
-          tx.send(box [1u8, 2u8]);
-          tx.send(box []);
-          tx.send(box [3u8, 4u8]);
-          tx.send(box [5u8, 6u8]);
-          tx.send(box [7u8, 8u8]);
+          tx.send(vec![1u8, 2u8]);
+          tx.send(vec![]);
+          tx.send(vec![3u8, 4u8]);
+          tx.send(vec![5u8, 6u8]);
+          tx.send(vec![7u8, 8u8]);
         });
 
         let mut reader = ChanReader::new(rx);
-        let mut buf = box [0u8, ..3];
+        let mut buf = [0u8, ..3];
 
 
         assert_eq!(Ok(0), reader.read([]));
 
         assert_eq!(Ok(3), reader.read(buf));
-        assert_eq!(box [1,2,3], buf);
+        assert_eq!(&[1,2,3], buf.as_slice());
 
         assert_eq!(Ok(3), reader.read(buf));
-        assert_eq!(box [4,5,6], buf);
+        assert_eq!(&[4,5,6], buf.as_slice());
 
         assert_eq!(Ok(2), reader.read(buf));
-        assert_eq!(box [7,8,6], buf);
+        assert_eq!(&[7,8,6], buf.as_slice());
 
         match reader.read(buf) {
             Ok(..) => fail!(),
             Err(e) => assert_eq!(e.kind, io::EndOfFile),
         }
-        assert_eq!(box [7,8,6], buf);
+        assert_eq!(&[7,8,6], buf.as_slice());
 
         // Ensure it continues to fail in the same way.
         match reader.read(buf) {
             Ok(..) => fail!(),
             Err(e) => assert_eq!(e.kind, io::EndOfFile),
         }
-        assert_eq!(box [7,8,6], buf);
+        assert_eq!(&[7,8,6], buf.as_slice());
     }
 
     #[test]
@@ -181,7 +182,7 @@ fn test_chan_writer() {
         let mut writer = ChanWriter::new(tx);
         writer.write_be_u32(42).unwrap();
 
-        let wanted = box [0u8, 0u8, 0u8, 42u8];
+        let wanted = vec![0u8, 0u8, 0u8, 42u8];
         let got = task::try(proc() { rx.recv() }).unwrap();
         assert_eq!(wanted, got);
 
index 29afd2b1d9b2b95c5d97ca2ee9379bfdb9a972d9..d61518d4ee76f9aa36db766b634eebdf4c3a8402 100644 (file)
@@ -15,7 +15,7 @@
 // FIXME: Not sure how this should be structured
 // FIXME: Iteration should probably be considered separately
 
-use container::Container;
+use collections::Collection;
 use iter::Iterator;
 use option::{Option, Some, None};
 use result::{Ok, Err};
@@ -504,7 +504,7 @@ fn test_u64_from_be_bytes() {
 mod bench {
     extern crate test;
 
-    use container::Container;
+    use collections::Collection;
     use prelude::*;
     use self::test::Bencher;
 
index 49e8d37923661bf2c614768af0ebbb8d139e4a81..5259200133ae1974e1af84e02146849f8a2110ed 100644 (file)
@@ -51,7 +51,7 @@
 
 use c_str::ToCStr;
 use clone::Clone;
-use container::Container;
+use collections::Collection;
 use io;
 use iter::Iterator;
 use kinds::Send;
index 735966d812b92f8c0ec59d18eeda2b312ba03e89..f0fbe4529b0e959c3b6aeb88155400332cf2fdd8 100644 (file)
@@ -11,7 +11,7 @@
 //! Readers and Writers for in-memory buffers
 
 use cmp::min;
-use container::Container;
+use collections::Collection;
 use option::None;
 use result::{Err, Ok};
 use io;
index c72cc0ded9bc3ca7c5f0210de3de15f75c394302..a1e0fa889789f39b3b59a1f3a50c6cdd781d1641 100644 (file)
 
 * Make a simple TCP client connection and request
 
-    ```rust,should_fail
+    ```rust
     # #![allow(unused_must_use)]
     use std::io::net::tcp::TcpStream;
 
+    # // connection doesn't fail if a server is running on 8080
+    # // locally, we still want to be type checking this code, so lets
+    # // just stop it running (#11576)
+    # if false {
     let mut socket = TcpStream::connect("127.0.0.1", 8080).unwrap();
     socket.write(bytes!("GET / HTTP/1.0\n\n"));
     let response = socket.read_to_end();
+    # }
     ```
 
 * Make a simple TCP server
@@ -214,7 +219,7 @@ fn file_product(p: &Path) -> IoResult<u32> {
 #![deny(unused_must_use)]
 
 use char::Char;
-use container::Container;
+use collections::Collection;
 use fmt;
 use int;
 use iter::Iterator;
@@ -910,7 +915,7 @@ fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> { self.read(buf) }
 
 /// Returns a slice of `v` between `start` and `end`.
 ///
-/// Similar to `slice()` except this function only bounds the sclie on the
+/// Similar to `slice()` except this function only bounds the slice on the
 /// capacity of `v`, not the length.
 ///
 /// # Failure
index bdc4b6071fab420e17893ea9333e754e9f193ba7..2c54bd895e952f59a635bf2041f0cd8d7cb324de 100644 (file)
@@ -15,7 +15,7 @@
 
 #![allow(missing_doc)]
 
-use container::Container;
+use collections::Collection;
 use fmt;
 use from_str::FromStr;
 use iter::Iterator;
index 059286339a6fa2db624ed892dc33b838737e4099..3cb2fe1c8f1b3bc35a446b05ceafe465f628a2ef 100644 (file)
@@ -873,7 +873,7 @@ pub fn sleeper() -> Process {
     pub fn sleeper() -> Process {
         // There's a `timeout` command on windows, but it doesn't like having
         // its output piped, so instead just ping ourselves a few times with
-        // gaps inbetweeen so we're sure this process is alive for awhile
+        // gaps in between so we're sure this process is alive for awhile
         Command::new("ping").arg("127.0.0.1").arg("-n").arg("1000").spawn().unwrap()
     }
 
index 5db09076c98e0316e67ecee567d5861e433bbff7..84b91814c877902571a87c6bccee98dc93dba925 100644 (file)
@@ -102,7 +102,7 @@ fn src<T>(fd: libc::c_int, readable: bool, f: |StdSource| -> T) -> T {
 pub fn stdin() -> BufferedReader<StdReader> {
     // The default buffer capacity is 64k, but apparently windows doesn't like
     // 64k reads on stdin. See #13304 for details, but the idea is that on
-    // windows we use a slighly smaller buffer that's been seen to be
+    // windows we use a slightly smaller buffer that's been seen to be
     // acceptable.
     if cfg!(windows) {
         BufferedReader::with_capacity(8 * 1024, stdin_raw())
index 67b6d3c476c8c23093d752b6f1413f4a8e86cba0..1529cf8f92d6b50af9683b741d9929d83ab5c103 100644 (file)
@@ -218,7 +218,7 @@ mod test {
     iotest!(fn test_io_timer_oneshot_then_sleep() {
         let mut timer = Timer::new().unwrap();
         let rx = timer.oneshot(100000000000);
-        timer.sleep(1); // this should inalidate rx
+        timer.sleep(1); // this should invalidate rx
 
         assert_eq!(rx.recv_opt(), Err(()));
     })
@@ -352,7 +352,7 @@ mod test {
         let mut timer1 = Timer::new().unwrap();
         timer1.oneshot(1);
         let mut timer2 = Timer::new().unwrap();
-        // while sleeping, the prevous timer should fire and not have its
+        // while sleeping, the previous timer should fire and not have its
         // callback do something terrible.
         timer2.sleep(2);
     })
@@ -361,7 +361,7 @@ mod test {
         let mut timer1 = Timer::new().unwrap();
         timer1.periodic(1);
         let mut timer2 = Timer::new().unwrap();
-        // while sleeping, the prevous timer should fire and not have its
+        // while sleeping, the previous timer should fire and not have its
         // callback do something terrible.
         timer2.sleep(2);
     })
index bac4d26b4e49a6e8ce114fd5ce816efd671c449b..e147997334ccc4259296366d347a96c18824c427 100644 (file)
 #[cfg(test)] extern crate native;
 #[cfg(test)] extern crate green;
 #[cfg(test)] extern crate debug;
-#[cfg(test)] #[phase(syntax, link)] extern crate log;
+#[cfg(test, stage0)] #[phase(syntax, link)] extern crate log;
+#[cfg(test, not(stage0))] #[phase(plugin, link)] extern crate log;
 
 extern crate alloc;
 extern crate core;
 pub use core::char;
 pub use core::clone;
 #[cfg(not(test))] pub use core::cmp;
-pub use core::container;
 pub use core::default;
 pub use core::finally;
 pub use core::intrinsics;
@@ -241,15 +241,12 @@ fn start(argc: int, argv: **u8) -> int {
 /* Runtime and platform support */
 
 pub mod c_vec;
+pub mod dynamic_lib;
 pub mod os;
 pub mod io;
 pub mod path;
 pub mod fmt;
 
-// Private APIs
-#[unstable]
-pub mod unstable;
-
 // FIXME #7809: This shouldn't be pub, and it should be reexported under 'unstable'
 // but name resolution doesn't work without it being pub.
 #[unstable]
@@ -279,3 +276,11 @@ mod std {
     // The test runner requires std::slice::Vector, so re-export std::slice just for it.
     #[cfg(test)] pub use slice;
 }
+
+#[deprecated]
+#[allow(missing_doc)]
+#[doc(hiden)]
+pub mod unstable {
+    #[deprecated = "use std::dynamic_lib"]
+    pub use dynamic_lib;
+}
index 805da8021ed2c0cafd7af5ea0ec7e62b1441d26c..58f65c90b3b105fecb1dd98d79ee601a97a81deb 100644 (file)
@@ -425,8 +425,8 @@ macro_rules! format_args( ($closure:expr, $fmt:expr $($args:tt)*) => ({
     /// # Example
     ///
     /// ```rust
-    /// let user: &'static str = env!("USER");
-    /// println!("the user who compiled this code is: {}", user);
+    /// let home: &'static str = env!("HOME");
+    /// println!("the home directory at the time of compiling was: {}", home);
     /// ```
     #[macro_export]
     macro_rules! env( ($name:expr) => ({ /* compiler built-in */ }) )
index 133a8db90facc6832ab16c6ff82ef74b59c44d95..5028987f44fdd239e85d9421e6867e5482d68fb1 100644 (file)
@@ -12,7 +12,7 @@
 
 use char;
 use clone::Clone;
-use container::Container;
+use collections::Collection;
 use num::{NumCast, Zero, One, cast, Int};
 use num::{Float, FPNaN, FPInfinite, ToPrimitive};
 use num;
@@ -636,7 +636,7 @@ pub fn from_str_bytes_common<T:NumCast+Zero+One+PartialEq+PartialOrd+Div<T,T>+
                     if accum_positive && accum <= last_accum { return NumStrConv::inf(); }
                     if !accum_positive && accum >= last_accum { return NumStrConv::neg_inf(); }
 
-                    // Detect overflow by reversing the shift-and-add proccess
+                    // Detect overflow by reversing the shift-and-add process
                     if accum_positive &&
                         (last_accum != ((accum - cast(digit as int).unwrap())/radix_gen.clone())) {
                         return NumStrConv::inf();
index 9a7e061c47282b260cc02b6ec79746e1a1c4d1fa..fa882e7d016fe21783efe91b2ed1cebd09c62af4 100644 (file)
@@ -30,7 +30,7 @@
 #![allow(non_snake_case_functions)]
 
 use clone::Clone;
-use container::Container;
+use collections::Collection;
 use fmt;
 use iter::Iterator;
 use libc::{c_void, c_int};
@@ -133,7 +133,7 @@ pub mod win32 {
     use os::TMPBUF_SZ;
     use slice::{MutableVector, ImmutableVector};
     use string::String;
-    use str::{StrSlice, StrAllocating};
+    use str::StrSlice;
     use str;
     use vec::Vec;
 
@@ -171,17 +171,6 @@ pub fn fill_utf16_buf_and_decode(f: |*mut u16, DWORD| -> DWORD)
             return res;
         }
     }
-
-    pub fn as_utf16_p<T>(s: &str, f: |*u16| -> T) -> T {
-        as_mut_utf16_p(s, |t| { f(t as *u16) })
-    }
-
-    pub fn as_mut_utf16_p<T>(s: &str, f: |*mut u16| -> T) -> T {
-        let mut t = s.to_utf16();
-        // Null terminate before passing on.
-        t.push(0u16);
-        f(t.as_mut_ptr())
-    }
 }
 
 /*
@@ -320,7 +309,7 @@ fn env_convert(input: Vec<Vec<u8>>) -> Vec<(Vec<u8>, Vec<u8>)> {
 /// let key = "HOME";
 /// match std::os::getenv(key) {
 ///     Some(val) => println!("{}: {}", key, val),
-///     None => println!("{} is not defined in the environnement.", key)
+///     None => println!("{} is not defined in the environment.", key)
 /// }
 /// ```
 pub fn getenv(n: &str) -> Option<String> {
@@ -356,11 +345,10 @@ pub fn getenv_as_bytes(n: &str) -> Option<Vec<u8>> {
 pub fn getenv(n: &str) -> Option<String> {
     unsafe {
         with_env_lock(|| {
-            use os::win32::{as_utf16_p, fill_utf16_buf_and_decode};
-            as_utf16_p(n, |u| {
-                fill_utf16_buf_and_decode(|buf, sz| {
-                    libc::GetEnvironmentVariableW(u, buf, sz)
-                })
+            use os::win32::{fill_utf16_buf_and_decode};
+            let n = n.to_utf16().append_one(0);
+            fill_utf16_buf_and_decode(|buf, sz| {
+                libc::GetEnvironmentVariableW(n.as_ptr(), buf, sz)
             })
         })
     }
@@ -398,14 +386,11 @@ pub fn setenv(n: &str, v: &str) {
 /// Sets the environment variable `n` to the value `v` for the currently running
 /// process
 pub fn setenv(n: &str, v: &str) {
+    let n = n.to_utf16().append_one(0);
+    let v = v.to_utf16().append_one(0);
     unsafe {
         with_env_lock(|| {
-            use os::win32::as_utf16_p;
-            as_utf16_p(n, |nbuf| {
-                as_utf16_p(v, |vbuf| {
-                    libc::SetEnvironmentVariableW(nbuf, vbuf);
-                })
-            })
+            libc::SetEnvironmentVariableW(n.as_ptr(), v.as_ptr());
         })
     }
 }
@@ -428,12 +413,10 @@ fn _unsetenv(n: &str) {
     }
     #[cfg(windows)]
     fn _unsetenv(n: &str) {
+        let n = n.to_utf16().append_one(0);
         unsafe {
             with_env_lock(|| {
-                use os::win32::as_utf16_p;
-                as_utf16_p(n, |nbuf| {
-                    libc::SetEnvironmentVariableW(nbuf, ptr::null());
-                })
+                libc::SetEnvironmentVariableW(n.as_ptr(), ptr::null());
             })
         }
     }
@@ -732,11 +715,12 @@ pub fn change_dir(p: &Path) -> bool {
 
     #[cfg(windows)]
     fn chdir(p: &Path) -> bool {
+        let p = match p.as_str() {
+            Some(s) => s.to_utf16().append_one(0),
+            None => return false,
+        };
         unsafe {
-            use os::win32::as_utf16_p;
-            return as_utf16_p(p.as_str().unwrap(), |buf| {
-                libc::SetCurrentDirectoryW(buf) != (0 as libc::BOOL)
-            });
+            libc::SetCurrentDirectoryW(p.as_ptr()) != (0 as libc::BOOL)
         }
     }
 
index 681b19a2d1ab5eb3c3a06eb4bfefdcab89e198da..a101f0432126e2ff4de213bd9303071fc42f9514 100644 (file)
@@ -65,7 +65,7 @@
 
 #![deny(deprecated_owned_vector)]
 
-use container::Container;
+use collections::Collection;
 use c_str::CString;
 use clone::Clone;
 use fmt;
index 8dfb64194e7977d1b0809d5fcbe9cf96583e1e99..171535edbeb346b2ac4ce429a9e4f3609db81eba 100644 (file)
@@ -13,7 +13,7 @@
 use c_str::{CString, ToCStr};
 use clone::Clone;
 use cmp::{PartialEq, Eq};
-use container::Container;
+use collections::Collection;
 use from_str::FromStr;
 use hash;
 use io::Writer;
index e53842ecd8faf741443369a0122d41b4719ab393..011dfa6eeacc1e5f629164ff2b1d69b3b89fa86e 100644 (file)
@@ -14,7 +14,7 @@
 use c_str::{CString, ToCStr};
 use clone::Clone;
 use cmp::{PartialEq, Eq};
-use container::Container;
+use collections::Collection;
 use from_str::FromStr;
 use hash;
 use io::Writer;
@@ -186,7 +186,7 @@ unsafe fn new_unchecked<T: BytesContainer>(path: T) -> Path {
         ret
     }
 
-    /// See `GenericPathUnsafe::set_filename_unchecekd`.
+    /// See `GenericPathUnsafe::set_filename_unchecked`.
     ///
     /// # Failure
     ///
index 54dcbd1812fccaad8feb7eb32ec90580e9d9a34f..485c2140a8d1b035f8b2271a8dba3f4394ff6517 100644 (file)
@@ -60,8 +60,8 @@
 #[doc(no_inline)] pub use clone::Clone;
 #[doc(no_inline)] pub use cmp::{PartialEq, PartialOrd, Eq, Ord};
 #[doc(no_inline)] pub use cmp::{Ordering, Less, Equal, Greater, Equiv};
-#[doc(no_inline)] pub use container::{Container, Mutable, Map, MutableMap};
-#[doc(no_inline)] pub use container::{Set, MutableSet};
+#[doc(no_inline)] pub use collections::{Collection, Mutable, Map, MutableMap};
+#[doc(no_inline)] pub use collections::{Set, MutableSet};
 #[doc(no_inline)] pub use iter::{FromIterator, Extendable, ExactSize};
 #[doc(no_inline)] pub use iter::{Iterator, DoubleEndedIterator};
 #[doc(no_inline)] pub use iter::{RandomAccessIterator, CloneableIterator};
index 284d41d3208a382ed72974cda74b4adef7538744..2654b7a1acc6af5145592e931b67a66e1ccb071d 100644 (file)
@@ -62,7 +62,7 @@ fn fill_bytes(&mut self, v: &mut [u8]) {
 mod imp {
     extern crate libc;
 
-    use container::Container;
+    use core_collections::Collection;
     use io::{IoResult, IoError};
     use mem;
     use ops::Drop;
index 170884073f3c3310df9bb277752fe82c0f4a0f76..8655d1e47d51a01772f112c8fde0102bc45c2a82 100644 (file)
@@ -10,7 +10,7 @@
 
 //! A wrapper around any Reader to treat it as an RNG.
 
-use container::Container;
+use collections::Collection;
 use io::Reader;
 use rand::Rng;
 use result::{Ok, Err};
index 766901fa04f32f663e559c16cda477b6ee2f9606..a1372b51d472a51e5e1b5bc8785d15ffd2e0451c 100644 (file)
@@ -13,7 +13,7 @@
 #![allow(non_camel_case_types)]
 
 use char::Char;
-use container::Container;
+use collections::Collection;
 use from_str::from_str;
 use io::{IoResult, Writer};
 use iter::Iterator;
@@ -325,6 +325,7 @@ pub fn write(w: &mut Writer) -> IoResult<()> {
     #[cfg(target_os = "macos")]
     fn print(w: &mut Writer, idx: int, addr: *libc::c_void) -> IoResult<()> {
         use intrinsics;
+        #[repr(C)]
         struct Dl_info {
             dli_fname: *libc::c_char,
             dli_fbase: *libc::c_void,
@@ -348,7 +349,7 @@ fn dladdr(addr: *libc::c_void,
 
     #[cfg(not(target_os = "macos"))]
     fn print(w: &mut Writer, idx: int, addr: *libc::c_void) -> IoResult<()> {
-        use container::Container;
+        use collections::Collection;
         use iter::Iterator;
         use os;
         use path::GenericPath;
@@ -602,7 +603,7 @@ pub unsafe fn _Unwind_FindEnclosingFunction(pc: *libc::c_void)
 #[allow(dead_code, uppercase_variables)]
 mod imp {
     use c_str::CString;
-    use container::Container;
+    use core_collections::Collection;
     use intrinsics;
     use io::{IoResult, Writer};
     use libc;
@@ -614,7 +615,7 @@ mod imp {
     use rt::mutex::{StaticNativeMutex, NATIVE_MUTEX_INIT};
     use slice::ImmutableVector;
     use str::StrSlice;
-    use unstable::dynamic_lib::DynamicLibrary;
+    use dynamic_lib::DynamicLibrary;
 
     #[allow(non_snake_case_functions)]
     extern "system" {
index 81dcf909706dd3263e7e68c77284fd58c553ad30..5a077e511c0d482ea4336a02e538ee381cf21827 100644 (file)
@@ -243,7 +243,7 @@ pub unsafe fn create(stack: uint, p: Box<proc():Send>) -> rust_thread {
                 // EINVAL means |stack_size| is either too small or not a
                 // multiple of the system page size.  Because it's definitely
                 // >= PTHREAD_STACK_MIN, it must be an alignment issue.
-                // Round up to the neareast page and try again.
+                // Round up to the nearest page and try again.
                 let page_size = os::page_size();
                 let stack_size = (stack_size + page_size - 1) & (-(page_size - 1) - 1);
                 assert_eq!(pthread_attr_setstacksize(&mut attr, stack_size as libc::size_t), 0);
index 9ee62ee3d81b6c5269e1b2ecc06d5c4b993ea5ea..a4e1ad84252b1295a2154af3f65bac1ad747dd53 100644 (file)
@@ -84,7 +84,7 @@ pub struct TaskBuilder {
     /// Options to spawn the new task with
     pub opts: TaskOpts,
     gen_body: Option<proc(v: proc():Send):Send -> proc():Send>,
-    nocopy: Option<marker::NoCopy>,
+    nocopy: marker::NoCopy,
 }
 
 impl TaskBuilder {
@@ -94,7 +94,7 @@ pub fn new() -> TaskBuilder {
         TaskBuilder {
             opts: TaskOpts::new(),
             gen_body: None,
-            nocopy: None,
+            nocopy: marker::NoCopy,
         }
     }
 
diff --git a/src/libstd/unstable/dynamic_lib.rs b/src/libstd/unstable/dynamic_lib.rs
deleted file mode 100644 (file)
index c05cdc8..0000000
+++ /dev/null
@@ -1,329 +0,0 @@
-// 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.
-
-/*!
-
-Dynamic library facilities.
-
-A simple wrapper over the platform's dynamic library facilities
-
-*/
-
-use clone::Clone;
-use c_str::ToCStr;
-use iter::Iterator;
-use mem;
-use ops::*;
-use option::*;
-use os;
-use path::{Path,GenericPath};
-use result::*;
-use slice::{Vector,ImmutableVector};
-use str;
-use string::String;
-use vec::Vec;
-
-pub struct DynamicLibrary { handle: *u8}
-
-impl Drop for DynamicLibrary {
-    fn drop(&mut self) {
-        match dl::check_for_errors_in(|| {
-            unsafe {
-                dl::close(self.handle)
-            }
-        }) {
-            Ok(()) => {},
-            Err(str) => fail!("{}", str)
-        }
-    }
-}
-
-impl DynamicLibrary {
-    // FIXME (#12938): Until DST lands, we cannot decompose &str into
-    // & and str, so we cannot usefully take ToCStr arguments by
-    // reference (without forcing an additional & around &str). So we
-    // are instead temporarily adding an instance for &Path, so that
-    // we can take ToCStr as owned. When DST lands, the &Path instance
-    // should be removed, and arguments bound by ToCStr should be
-    // passed by reference. (Here: in the `open` method.)
-
-    /// Lazily open a dynamic library. When passed None it gives a
-    /// handle to the calling process
-    pub fn open<T: ToCStr>(filename: Option<T>)
-                        -> Result<DynamicLibrary, String> {
-        unsafe {
-            let mut filename = filename;
-            let maybe_library = dl::check_for_errors_in(|| {
-                match filename.take() {
-                    Some(name) => dl::open_external(name),
-                    None => dl::open_internal()
-                }
-            });
-
-            // The dynamic library must not be constructed if there is
-            // an error opening the library so the destructor does not
-            // run.
-            match maybe_library {
-                Err(err) => Err(err),
-                Ok(handle) => Ok(DynamicLibrary { handle: handle })
-            }
-        }
-    }
-
-    /// Prepends a path to this process's search path for dynamic libraries
-    pub fn prepend_search_path(path: &Path) {
-        let mut search_path = DynamicLibrary::search_path();
-        search_path.insert(0, path.clone());
-        let newval = DynamicLibrary::create_path(search_path.as_slice());
-        os::setenv(DynamicLibrary::envvar(),
-                   str::from_utf8(newval.as_slice()).unwrap());
-    }
-
-    /// From a slice of paths, create a new vector which is suitable to be an
-    /// environment variable for this platforms dylib search path.
-    pub fn create_path(path: &[Path]) -> Vec<u8> {
-        let mut newvar = Vec::new();
-        for (i, path) in path.iter().enumerate() {
-            if i > 0 { newvar.push(DynamicLibrary::separator()); }
-            newvar.push_all(path.as_vec());
-        }
-        return newvar;
-    }
-
-    /// Returns the environment variable for this process's dynamic library
-    /// search path
-    pub fn envvar() -> &'static str {
-        if cfg!(windows) {
-            "PATH"
-        } else if cfg!(target_os = "macos") {
-            "DYLD_LIBRARY_PATH"
-        } else {
-            "LD_LIBRARY_PATH"
-        }
-    }
-
-    fn separator() -> u8 {
-        if cfg!(windows) {';' as u8} else {':' as u8}
-    }
-
-    /// Returns the current search path for dynamic libraries being used by this
-    /// process
-    pub fn search_path() -> Vec<Path> {
-        let mut ret = Vec::new();
-        match os::getenv_as_bytes(DynamicLibrary::envvar()) {
-            Some(env) => {
-                for portion in
-                        env.as_slice()
-                           .split(|a| *a == DynamicLibrary::separator()) {
-                    ret.push(Path::new(portion));
-                }
-            }
-            None => {}
-        }
-        return ret;
-    }
-
-    /// Access the value at the symbol of the dynamic library
-    pub unsafe fn symbol<T>(&self, symbol: &str) -> Result<T, String> {
-        // This function should have a lifetime constraint of 'a on
-        // T but that feature is still unimplemented
-
-        let maybe_symbol_value = dl::check_for_errors_in(|| {
-            symbol.with_c_str(|raw_string| {
-                dl::symbol(self.handle, raw_string)
-            })
-        });
-
-        // The value must not be constructed if there is an error so
-        // the destructor does not run.
-        match maybe_symbol_value {
-            Err(err) => Err(err),
-            Ok(symbol_value) => Ok(mem::transmute(symbol_value))
-        }
-    }
-}
-
-#[cfg(test)]
-mod test {
-    use super::*;
-    use prelude::*;
-    use libc;
-
-    #[test]
-    #[ignore(cfg(windows))] // FIXME #8818
-    #[ignore(cfg(target_os="android"))] // FIXME(#10379)
-    fn test_loading_cosine() {
-        // The math library does not need to be loaded since it is already
-        // statically linked in
-        let none: Option<Path> = None; // appease the typechecker
-        let libm = match DynamicLibrary::open(none) {
-            Err(error) => fail!("Could not load self as module: {}", error),
-            Ok(libm) => libm
-        };
-
-        let cosine: extern fn(libc::c_double) -> libc::c_double = unsafe {
-            match libm.symbol("cos") {
-                Err(error) => fail!("Could not load function cos: {}", error),
-                Ok(cosine) => cosine
-            }
-        };
-
-        let argument = 0.0;
-        let expected_result = 1.0;
-        let result = cosine(argument);
-        if result != expected_result {
-            fail!("cos({:?}) != {:?} but equaled {:?} instead", argument,
-                   expected_result, result)
-        }
-    }
-
-    #[test]
-    #[cfg(target_os = "linux")]
-    #[cfg(target_os = "macos")]
-    #[cfg(target_os = "freebsd")]
-    fn test_errors_do_not_crash() {
-        // Open /dev/null as a library to get an error, and make sure
-        // that only causes an error, and not a crash.
-        let path = Path::new("/dev/null");
-        match DynamicLibrary::open(Some(&path)) {
-            Err(_) => {}
-            Ok(_) => fail!("Successfully opened the empty library.")
-        }
-    }
-}
-
-#[cfg(target_os = "linux")]
-#[cfg(target_os = "android")]
-#[cfg(target_os = "macos")]
-#[cfg(target_os = "freebsd")]
-pub mod dl {
-    use prelude::*;
-
-    use c_str::{CString, ToCStr};
-    use libc;
-    use ptr;
-    use result::*;
-    use str::StrAllocating;
-    use string::String;
-
-    pub unsafe fn open_external<T: ToCStr>(filename: T) -> *u8 {
-        filename.with_c_str(|raw_name| {
-            dlopen(raw_name, Lazy as libc::c_int) as *u8
-        })
-    }
-
-    pub unsafe fn open_internal() -> *u8 {
-        dlopen(ptr::null(), Lazy as libc::c_int) as *u8
-    }
-
-    pub fn check_for_errors_in<T>(f: || -> T) -> Result<T, String> {
-        use rt::mutex::{StaticNativeMutex, NATIVE_MUTEX_INIT};
-        static mut lock: StaticNativeMutex = NATIVE_MUTEX_INIT;
-        unsafe {
-            // dlerror isn't thread safe, so we need to lock around this entire
-            // sequence
-            let _guard = lock.lock();
-            let _old_error = dlerror();
-
-            let result = f();
-
-            let last_error = dlerror();
-            let ret = if ptr::null() == last_error {
-                Ok(result)
-            } else {
-                Err(CString::new(last_error, false).as_str()
-                                                   .unwrap()
-                                                   .to_string())
-            };
-
-            ret
-        }
-    }
-
-    pub unsafe fn symbol(handle: *u8, symbol: *libc::c_char) -> *u8 {
-        dlsym(handle as *libc::c_void, symbol) as *u8
-    }
-    pub unsafe fn close(handle: *u8) {
-        dlclose(handle as *libc::c_void); ()
-    }
-
-    pub enum RTLD {
-        Lazy = 1,
-        Now = 2,
-        Global = 256,
-        Local = 0,
-    }
-
-    #[link_name = "dl"]
-    extern {
-        fn dlopen(filename: *libc::c_char, flag: libc::c_int) -> *libc::c_void;
-        fn dlerror() -> *libc::c_char;
-        fn dlsym(handle: *libc::c_void, symbol: *libc::c_char) -> *libc::c_void;
-        fn dlclose(handle: *libc::c_void) -> libc::c_int;
-    }
-}
-
-#[cfg(target_os = "win32")]
-pub mod dl {
-    use libc;
-    use os;
-    use ptr;
-    use result::{Ok, Err, Result};
-    use string::String;
-    use str;
-    use c_str::ToCStr;
-
-    pub unsafe fn open_external<T: ToCStr>(filename: T) -> *u8 {
-        // Windows expects Unicode data
-        let filename_cstr = filename.to_c_str();
-        let filename_str = str::from_utf8(filename_cstr.as_bytes_no_nul()).unwrap();
-        os::win32::as_utf16_p(filename_str, |raw_name| {
-            LoadLibraryW(raw_name as *libc::c_void) as *u8
-        })
-    }
-
-    pub unsafe fn open_internal() -> *u8 {
-        let handle = ptr::null();
-        GetModuleHandleExW(0 as libc::DWORD, ptr::null(), &handle as **libc::c_void);
-        handle as *u8
-    }
-
-    pub fn check_for_errors_in<T>(f: || -> T) -> Result<T, String> {
-        unsafe {
-            SetLastError(0);
-
-            let result = f();
-
-            let error = os::errno();
-            if 0 == error {
-                Ok(result)
-            } else {
-                Err(format!("Error code {}", error))
-            }
-        }
-    }
-
-    pub unsafe fn symbol(handle: *u8, symbol: *libc::c_char) -> *u8 {
-        GetProcAddress(handle as *libc::c_void, symbol) as *u8
-    }
-    pub unsafe fn close(handle: *u8) {
-        FreeLibrary(handle as *libc::c_void); ()
-    }
-
-    #[allow(non_snake_case_functions)]
-    extern "system" {
-        fn SetLastError(error: libc::size_t);
-        fn LoadLibraryW(name: *libc::c_void) -> *libc::c_void;
-        fn GetModuleHandleExW(dwFlags: libc::DWORD, name: *u16,
-                              handle: **libc::c_void) -> *libc::c_void;
-        fn GetProcAddress(handle: *libc::c_void, name: *libc::c_char) -> *libc::c_void;
-        fn FreeLibrary(handle: *libc::c_void);
-    }
-}
diff --git a/src/libstd/unstable/mod.rs b/src/libstd/unstable/mod.rs
deleted file mode 100644 (file)
index 985ef2e..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <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.
-
-#![doc(hidden)]
-
-pub mod dynamic_lib;
index fc4d5fec5f52a06e861232dce288da04ee610a2a..44d17e6fb95ce13bb7d446aa8f3e8e7b556f7119 100644 (file)
 
 #![deny(missing_doc)]
 
-#[cfg(test)]
+#[cfg(test, stage0)]
 #[phase(syntax, link)] extern crate log;
 
+#[cfg(test, not(stage0))]
+#[phase(plugin, link)] extern crate log;
+
 extern crate alloc;
 
 pub use comm::{DuplexStream, duplex};
index 8fd10cdfa8b346a2751623ad73263e186dbd2ed6..821afeaa1f2e4b487b57bf0a04578ed873fe6ec8 100644 (file)
@@ -355,7 +355,7 @@ pub struct Semaphore {
 /// dropped, this value will release the resource back to the semaphore.
 #[must_use]
 pub struct SemaphoreGuard<'a> {
-    guard: SemGuard<'a, ()>,
+    _guard: SemGuard<'a, ()>,
 }
 
 impl Semaphore {
@@ -375,7 +375,7 @@ pub fn release(&self) { self.sem.release() }
     /// Acquire a resource of this semaphore, returning an RAII guard which will
     /// release the resource when dropped.
     pub fn access<'a>(&'a self) -> SemaphoreGuard<'a> {
-        SemaphoreGuard { guard: self.sem.access() }
+        SemaphoreGuard { _guard: self.sem.access() }
     }
 }
 
@@ -398,7 +398,7 @@ pub struct Mutex {
 /// corresponding mutex is also unlocked.
 #[must_use]
 pub struct MutexGuard<'a> {
-    guard: SemGuard<'a, Vec<WaitQueue>>,
+    _guard: SemGuard<'a, Vec<WaitQueue>>,
     /// Inner condition variable which is connected to the outer mutex, and can
     /// be used for atomic-unlock-and-deschedule.
     pub cond: Condvar<'a>,
@@ -421,7 +421,7 @@ pub fn new_with_condvars(num_condvars: uint) -> Mutex {
     /// also be accessed through the returned guard.
     pub fn lock<'a>(&'a self) -> MutexGuard<'a> {
         let SemCondGuard { guard, cvar } = self.sem.access_cond();
-        MutexGuard { guard: guard, cond: cvar }
+        MutexGuard { _guard: guard, cond: cvar }
     }
 }
 
index 2bc24fd1eb36994fa3801ed3cbfc6b6ebea0b044..2f5459b6f2e1b47801c1efcf6193f5495f95b26d 100644 (file)
@@ -175,6 +175,7 @@ pub struct DefId {
 pub enum TyParamBound {
     TraitTyParamBound(TraitRef),
     StaticRegionTyParamBound,
+    UnboxedFnTyParamBound(UnboxedFnTy),
     OtherRegionTyParamBound(Span) // FIXME -- just here until work for #5723 lands
 }
 
@@ -769,6 +770,11 @@ pub struct BareFnTy {
     pub decl: P<FnDecl>
 }
 
+#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
+pub struct UnboxedFnTy {
+    pub decl: P<FnDecl>,
+}
+
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
 pub enum Ty_ {
     TyNil,
@@ -782,6 +788,7 @@ pub enum Ty_ {
     TyClosure(@ClosureTy, Option<Lifetime>),
     TyProc(@ClosureTy),
     TyBareFn(@BareFnTy),
+    TyUnboxedFn(@UnboxedFnTy),
     TyTup(Vec<P<Ty>> ),
     TyPath(Path, Option<OwnedSlice<TyParamBound>>, NodeId), // for #7264; see above
     TyTypeof(@Expr),
@@ -1046,6 +1053,15 @@ pub struct StructField_ {
     pub attrs: Vec<Attribute>,
 }
 
+impl StructField_ {
+    pub fn ident(&self) -> Option<Ident> {
+        match self.kind {
+            NamedField(ref ident, _) => Some(ident.clone()),
+            UnnamedField(_) => None
+        }
+    }
+}
+
 pub type StructField = Spanned<StructField_>;
 
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
index 521b7ee00631c6cb369d8b410506a0ee7cf5b993..e81421cff043deb894c9bf60bba926c1473565ae 100644 (file)
@@ -95,9 +95,6 @@ fn expand(&self,
 pub type IdentMacroExpanderFn =
     fn(&mut ExtCtxt, Span, ast::Ident, Vec<ast::TokenTree>) -> Box<MacResult>;
 
-pub type MacroCrateRegistrationFun =
-    fn(|ast::Name, SyntaxExtension|);
-
 /// The result of a macro expansion. The return values of the various
 /// methods are spliced into the AST at the callsite of the macro (or
 /// just into the compiler's internal macro table, for `make_def`).
@@ -268,6 +265,8 @@ pub enum SyntaxExtension {
     IdentTT(Box<IdentMacroExpander:'static>, Option<Span>),
 }
 
+pub type NamedSyntaxExtension = (Name, SyntaxExtension);
+
 pub struct BlockInfo {
     // should macros escape from this scope?
     pub macros_escape: bool,
@@ -392,16 +391,6 @@ fn builtin_normal_expander(f: MacroExpanderFn) -> SyntaxExtension {
     syntax_expanders
 }
 
-pub struct MacroCrate {
-    pub lib: Option<Path>,
-    pub macros: Vec<String>,
-    pub registrar_symbol: Option<String>,
-}
-
-pub trait CrateLoader {
-    fn load_crate(&mut self, krate: &ast::ViewItem) -> MacroCrate;
-}
-
 // One of these is made during expansion and incrementally updated as we go;
 // when a macro expansion occurs, the resulting nodes have the backtrace()
 // -> expn_info of their expansion context stored into their span.
@@ -409,7 +398,7 @@ pub struct ExtCtxt<'a> {
     pub parse_sess: &'a parse::ParseSess,
     pub cfg: ast::CrateConfig,
     pub backtrace: Option<@ExpnInfo>,
-    pub ecfg: expand::ExpansionConfig<'a>,
+    pub ecfg: expand::ExpansionConfig,
 
     pub mod_path: Vec<ast::Ident> ,
     pub trace_mac: bool,
@@ -417,7 +406,7 @@ pub struct ExtCtxt<'a> {
 
 impl<'a> ExtCtxt<'a> {
     pub fn new<'a>(parse_sess: &'a parse::ParseSess, cfg: ast::CrateConfig,
-                   ecfg: expand::ExpansionConfig<'a>) -> ExtCtxt<'a> {
+                   ecfg: expand::ExpansionConfig) -> ExtCtxt<'a> {
         ExtCtxt {
             parse_sess: parse_sess,
             cfg: cfg,
index 7b25f4db98075ad10cb29bbb4ec921e2752a5346..14769e3e510673aceb3ff5bf3a04dd04a0ea3aad 100644 (file)
 use parse::token::InternedString;
 use parse::token;
 
-pub struct Field {
-    ident: ast::Ident,
-    ex: @ast::Expr
-}
-
 // Transitional reexports so qquote can find the paths it is looking for
 mod syntax {
     pub use ext;
@@ -1000,9 +995,7 @@ fn view_use_glob(&self, sp: Span,
     }
 }
 
-struct Duplicator<'a> {
-    cx: &'a ExtCtxt<'a>,
-}
+struct Duplicator<'a>;
 
 impl<'a> Folder for Duplicator<'a> {
     fn new_id(&mut self, _: NodeId) -> NodeId {
@@ -1021,10 +1014,8 @@ pub trait Duplicate {
 }
 
 impl Duplicate for @ast::Expr {
-    fn duplicate(&self, cx: &ExtCtxt) -> @ast::Expr {
-        let mut folder = Duplicator {
-            cx: cx,
-        };
+    fn duplicate(&self, _: &ExtCtxt) -> @ast::Expr {
+        let mut folder = Duplicator;
         folder.fold_expr(*self)
     }
 }
index 03001acc5d04d47e6914d640bce40c29691f67f0..bb335e7bed0cf9bf8b9dd91fbc470c59899bb113 100644 (file)
 use visit::Visitor;
 use util::small_vector::SmallVector;
 
-use std::mem;
-use std::os;
-use std::unstable::dynamic_lib::DynamicLibrary;
-
 pub fn expand_expr(e: @ast::Expr, fld: &mut MacroExpander) -> @ast::Expr {
     match e.node {
         // expr_mac should really be expr_ext or something; it's the
@@ -497,96 +493,6 @@ pub fn expand_item_mac(it: @ast::Item, fld: &mut MacroExpander)
     return items;
 }
 
-// load macros from syntax-phase crates
-pub fn expand_view_item(vi: &ast::ViewItem,
-                        fld: &mut MacroExpander)
-                        -> ast::ViewItem {
-    match vi.node {
-        ast::ViewItemExternCrate(..) => {
-            let should_load = vi.attrs.iter().any(|attr| {
-                attr.check_name("phase") &&
-                    attr.meta_item_list().map_or(false, |phases| {
-                        attr::contains_name(phases, "syntax")
-                    })
-            });
-
-            if should_load {
-                load_extern_macros(vi, fld);
-            }
-        }
-        ast::ViewItemUse(_) => {}
-    }
-
-    noop_fold_view_item(vi, fld)
-}
-
-fn load_extern_macros(krate: &ast::ViewItem, fld: &mut MacroExpander) {
-    let MacroCrate { lib, macros, registrar_symbol } =
-        fld.cx.ecfg.loader.load_crate(krate);
-
-    let crate_name = match krate.node {
-        ast::ViewItemExternCrate(name, _, _) => name,
-        _ => unreachable!()
-    };
-    let name = format!("<{} macros>", token::get_ident(crate_name));
-    let name = name.to_string();
-
-    for source in macros.iter() {
-        let item = parse::parse_item_from_source_str(name.clone(),
-                                                     (*source).clone(),
-                                                     fld.cx.cfg(),
-                                                     fld.cx.parse_sess())
-                .expect("expected a serialized item");
-        expand_item_mac(item, fld);
-    }
-
-    let path = match lib {
-        Some(path) => path,
-        None => return
-    };
-    // Make sure the path contains a / or the linker will search for it.
-    let path = os::make_absolute(&path);
-
-    let registrar = match registrar_symbol {
-        Some(registrar) => registrar,
-        None => return
-    };
-
-    debug!("load_extern_macros: mapped crate {} to path {} and registrar {:s}",
-           crate_name, path.display(), registrar);
-
-    let lib = match DynamicLibrary::open(Some(&path)) {
-        Ok(lib) => lib,
-        // this is fatal: there are almost certainly macros we need
-        // inside this crate, so continue would spew "macro undefined"
-        // errors
-        Err(err) => fld.cx.span_fatal(krate.span, err.as_slice())
-    };
-
-    unsafe {
-        let registrar: MacroCrateRegistrationFun =
-            match lib.symbol(registrar.as_slice()) {
-                Ok(registrar) => registrar,
-                // again fatal if we can't register macros
-                Err(err) => fld.cx.span_fatal(krate.span, err.as_slice())
-            };
-        registrar(|name, extension| {
-            let extension = match extension {
-                NormalTT(ext, _) => NormalTT(ext, Some(krate.span)),
-                IdentTT(ext, _) => IdentTT(ext, Some(krate.span)),
-                ItemDecorator(ext) => ItemDecorator(ext),
-                ItemModifier(ext) => ItemModifier(ext),
-            };
-            fld.extsbox.insert(name, extension);
-        });
-
-        // Intentionally leak the dynamic library. We can't ever unload it
-        // since the library can do things that will outlive the expansion
-        // phase (e.g. make an @-box cycle or launch a task).
-        mem::forget(lib);
-    }
-}
-
 // expand a stmt
 pub fn expand_stmt(s: &Stmt, fld: &mut MacroExpander) -> SmallVector<@Stmt> {
     // why the copying here and not in expand_expr?
@@ -969,10 +875,6 @@ fn fold_item(&mut self, item: @ast::Item) -> SmallVector<@ast::Item> {
         expand_item(item, self)
     }
 
-    fn fold_view_item(&mut self, vi: &ast::ViewItem) -> ast::ViewItem {
-        expand_view_item(vi, self)
-    }
-
     fn fold_stmt(&mut self, stmt: &ast::Stmt) -> SmallVector<@ast::Stmt> {
         expand_stmt(stmt, self)
     }
@@ -986,14 +888,20 @@ fn new_span(&mut self, span: Span) -> Span {
     }
 }
 
-pub struct ExpansionConfig<'a> {
-    pub loader: &'a mut CrateLoader,
+pub struct ExpansionConfig {
     pub deriving_hash_type_parameter: bool,
     pub crate_id: CrateId,
 }
 
+pub struct ExportedMacros {
+    pub crate_name: Ident,
+    pub macros: Vec<String>,
+}
+
 pub fn expand_crate(parse_sess: &parse::ParseSess,
                     cfg: ExpansionConfig,
+                    macros: Vec<ExportedMacros>,
+                    user_exts: Vec<NamedSyntaxExtension>,
                     c: Crate) -> Crate {
     let mut cx = ExtCtxt::new(parse_sess, c.config.clone(), cfg);
     let mut expander = MacroExpander {
@@ -1001,6 +909,24 @@ pub fn expand_crate(parse_sess: &parse::ParseSess,
         cx: &mut cx,
     };
 
+    for ExportedMacros { crate_name, macros } in macros.move_iter() {
+        let name = format!("<{} macros>", token::get_ident(crate_name))
+            .into_string();
+
+        for source in macros.move_iter() {
+            let item = parse::parse_item_from_source_str(name.clone(),
+                                                         source,
+                                                         expander.cx.cfg(),
+                                                         expander.cx.parse_sess())
+                    .expect("expected a serialized item");
+            expand_item_mac(item, &mut expander);
+        }
+    }
+
+    for (name, extension) in user_exts.move_iter() {
+        expander.extsbox.insert(name, extension);
+    }
+
     let ret = expander.fold_crate(c);
     parse_sess.span_diagnostic.handler().abort_if_errors();
     return ret;
@@ -1093,7 +1019,6 @@ mod test {
     use attr;
     use codemap;
     use codemap::Spanned;
-    use ext::base::{CrateLoader, MacroCrate};
     use ext::mtwt;
     use parse;
     use parse::token;
@@ -1137,14 +1062,6 @@ pub fn new_path_finder(paths: Vec<ast::Path> ) -> NewPathExprFinderContext {
         }
     }
 
-    struct ErrLoader;
-
-    impl CrateLoader for ErrLoader {
-        fn load_crate(&mut self, _: &ast::ViewItem) -> MacroCrate {
-            fail!("lolwut")
-        }
-    }
-
     // these following tests are quite fragile, in that they don't test what
     // *kind* of failure occurs.
 
@@ -1159,13 +1076,11 @@ fn load_crate(&mut self, _: &ast::ViewItem) -> MacroCrate {
             src,
             Vec::new(), &sess);
         // should fail:
-        let mut loader = ErrLoader;
         let cfg = ::syntax::ext::expand::ExpansionConfig {
-            loader: &mut loader,
             deriving_hash_type_parameter: false,
             crate_id: from_str("test").unwrap(),
         };
-        expand_crate(&sess,cfg,crate_ast);
+        expand_crate(&sess,cfg,vec!(),vec!(),crate_ast);
     }
 
     // make sure that macros can leave scope for modules
@@ -1178,14 +1093,11 @@ fn load_crate(&mut self, _: &ast::ViewItem) -> MacroCrate {
             "<test>".to_string(),
             src,
             Vec::new(), &sess);
-        // should fail:
-        let mut loader = ErrLoader;
         let cfg = ::syntax::ext::expand::ExpansionConfig {
-            loader: &mut loader,
             deriving_hash_type_parameter: false,
             crate_id: from_str("test").unwrap(),
         };
-        expand_crate(&sess,cfg,crate_ast);
+        expand_crate(&sess,cfg,vec!(),vec!(),crate_ast);
     }
 
     // macro_escape modules shouldn't cause macros to leave scope
@@ -1198,13 +1110,11 @@ fn load_crate(&mut self, _: &ast::ViewItem) -> MacroCrate {
             src,
             Vec::new(), &sess);
         // should fail:
-        let mut loader = ErrLoader;
         let cfg = ::syntax::ext::expand::ExpansionConfig {
-            loader: &mut loader,
             deriving_hash_type_parameter: false,
             crate_id: from_str("test").unwrap(),
         };
-        expand_crate(&sess, cfg, crate_ast);
+        expand_crate(&sess, cfg, vec!(), vec!(), crate_ast);
     }
 
     #[test] fn test_contains_flatten (){
@@ -1237,13 +1147,11 @@ fn expand_crate_str(crate_str: String) -> ast::Crate {
         let ps = parse::new_parse_sess();
         let crate_ast = string_to_parser(&ps, crate_str).parse_crate_mod();
         // the cfg argument actually does matter, here...
-        let mut loader = ErrLoader;
         let cfg = ::syntax::ext::expand::ExpansionConfig {
-            loader: &mut loader,
             deriving_hash_type_parameter: false,
             crate_id: from_str("test").unwrap(),
         };
-        expand_crate(&ps,cfg,crate_ast)
+        expand_crate(&ps,cfg,vec!(),vec!(),crate_ast)
     }
 
     //fn expand_and_resolve(crate_str: @str) -> ast::crate {
diff --git a/src/libsyntax/ext/registrar.rs b/src/libsyntax/ext/registrar.rs
deleted file mode 100644 (file)
index b767081..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <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 ast;
-use attr;
-use codemap::Span;
-use diagnostic;
-use visit;
-use visit::Visitor;
-
-struct MacroRegistrarContext {
-    registrars: Vec<(ast::NodeId, Span)> ,
-}
-
-impl Visitor<()> for MacroRegistrarContext {
-    fn visit_item(&mut self, item: &ast::Item, _: ()) {
-        match item.node {
-            ast::ItemFn(..) => {
-                if attr::contains_name(item.attrs.as_slice(),
-                                       "macro_registrar") {
-                    self.registrars.push((item.id, item.span));
-                }
-            }
-            _ => {}
-        }
-
-        visit::walk_item(self, item, ());
-    }
-}
-
-pub fn find_macro_registrar(diagnostic: &diagnostic::SpanHandler,
-                            krate: &ast::Crate) -> Option<ast::NodeId> {
-    let mut ctx = MacroRegistrarContext { registrars: Vec::new() };
-    visit::walk_crate(&mut ctx, krate, ());
-
-    match ctx.registrars.len() {
-        0 => None,
-        1 => {
-            let (node_id, _) = ctx.registrars.pop().unwrap();
-            Some(node_id)
-        },
-        _ => {
-            diagnostic.handler().err("multiple macro registration functions found");
-            for &(_, span) in ctx.registrars.iter() {
-                diagnostic.span_note(span, "one is here");
-            }
-            diagnostic.handler().abort_if_errors();
-            unreachable!();
-        }
-    }
-}
index 8903eb80829b4d7efd61bf0b48401d8a797470bb..03d0c283bcc5c522a81027e61cb6592fe9ad5707 100644 (file)
@@ -185,6 +185,11 @@ fn fold_ty(&mut self, t: P<Ty>) -> P<Ty> {
                     decl: self.fold_fn_decl(f.decl)
                 })
             }
+            TyUnboxedFn(ref f) => {
+                TyUnboxedFn(@UnboxedFnTy {
+                    decl: self.fold_fn_decl(f.decl),
+                })
+            }
             TyTup(ref tys) => TyTup(tys.iter().map(|&ty| self.fold_ty(ty)).collect()),
             TyPath(ref path, ref bounds, id) => {
                 let id = self.new_id(id);
@@ -440,6 +445,11 @@ fn fold_ty_param_bound<T: Folder>(tpb: &TyParamBound, fld: &mut T)
     match *tpb {
         TraitTyParamBound(ref ty) => TraitTyParamBound(fold_trait_ref(ty, fld)),
         StaticRegionTyParamBound => StaticRegionTyParamBound,
+        UnboxedFnTyParamBound(ref unboxed_function_type) => {
+            UnboxedFnTyParamBound(UnboxedFnTy {
+                decl: fld.fold_fn_decl(unboxed_function_type.decl),
+            })
+        }
         OtherRegionTyParamBound(s) => OtherRegionTyParamBound(s)
     }
 }
index 1ab420eb69be68bce61aa0a4e3f21a804745d481..754518f5fea3192f8cd7239757b63f8f38706a89 100644 (file)
 
 extern crate serialize;
 extern crate term;
+
+#[cfg(stage0)]
 #[phase(syntax, link)]
 extern crate log;
+
+#[cfg(not(stage0))]
+#[phase(plugin, link)]
+extern crate log;
+
 extern crate fmt_macros;
 extern crate debug;
 
@@ -74,7 +81,6 @@ pub mod ext {
     pub mod asm;
     pub mod base;
     pub mod expand;
-    pub mod registrar;
 
     pub mod quote;
 
index 28d63ea071a757c02721a9c57e9883de4b9d6ec9..016dd879dcd838c3ee2f915a29fe269b6117daf6 100644 (file)
@@ -121,7 +121,7 @@ fn eq(&self, other: &OwnedSlice<T>) -> bool {
 
 impl<T: Eq> Eq for OwnedSlice<T> {}
 
-impl<T> Container for OwnedSlice<T> {
+impl<T> Collection for OwnedSlice<T> {
     fn len(&self) -> uint { self.len }
 }
 
index 4af4385e3c1da3bc05ef14ab47f02b5574155079..360b8daa948f3647d54bede0d22f5db24f70e571 100644 (file)
@@ -52,9 +52,9 @@
 use ast::{TypeField, TyFixedLengthVec, TyClosure, TyProc, TyBareFn};
 use ast::{TyTypeof, TyInfer, TypeMethod};
 use ast::{TyNil, TyParam, TyParamBound, TyPath, TyPtr, TyRptr};
-use ast::{TyTup, TyU32, TyUniq, TyVec, UnUniq};
-use ast::{UnnamedField, UnsafeBlock, UnsafeFn, ViewItem};
-use ast::{ViewItem_, ViewItemExternCrate, ViewItemUse};
+use ast::{TyTup, TyU32, TyUnboxedFn, TyUniq, TyVec, UnUniq};
+use ast::{UnboxedFnTy, UnboxedFnTyParamBound, UnnamedField, UnsafeBlock};
+use ast::{UnsafeFn, ViewItem, ViewItem_, ViewItemExternCrate, ViewItemUse};
 use ast::{ViewPath, ViewPathGlob, ViewPathList, ViewPathSimple};
 use ast::Visibility;
 use ast;
@@ -1058,15 +1058,27 @@ pub fn parse_ty_closure(&mut self) -> Ty_ {
             Vec::new()
         };
 
-        let inputs = if self.eat(&token::OROR) {
-            Vec::new()
+        let (is_unboxed, inputs) = if self.eat(&token::OROR) {
+            (false, 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 inputs = self.parse_seq_to_before_or(
                 &token::COMMA,
                 |p| p.parse_arg_general(false));
             self.expect_or();
-            inputs
+            (is_unboxed, inputs)
         };
 
         let (region, bounds) = self.parse_optional_ty_param_bounds(true);
@@ -1079,13 +1091,19 @@ pub fn parse_ty_closure(&mut self) -> Ty_ {
             variadic: false
         });
 
-        TyClosure(@ClosureTy {
-            fn_style: fn_style,
-            onceness: onceness,
-            bounds: bounds,
-            decl: decl,
-            lifetimes: lifetimes,
-        }, region)
+        if is_unboxed {
+            TyUnboxedFn(@UnboxedFnTy {
+                decl: decl,
+            })
+        } else {
+            TyClosure(@ClosureTy {
+                fn_style: fn_style,
+                onceness: onceness,
+                bounds: bounds,
+                decl: decl,
+                lifetimes: lifetimes,
+            }, region)
+        }
     }
 
     pub fn parse_unsafety(&mut self) -> FnStyle {
@@ -3345,6 +3363,41 @@ 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();
+
+            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 inputs = self.parse_seq_to_before_or(&token::COMMA,
+                                                     |p| {
+                p.parse_arg_general(false)
+            });
+            self.expect_or();
+            inputs
+        };
+
+        let (return_style, output) = self.parse_ret_ty();
+        UnboxedFnTy {
+            decl: P(FnDecl {
+                inputs: inputs,
+                output: output,
+                cf: return_style,
+                variadic: false,
+            })
+        }
+    }
+
     // matches optbounds = ( ( : ( boundseq )? )? )
     // where   boundseq  = ( bound + boundseq ) | bound
     // and     bound     = 'static | ty
@@ -3394,6 +3447,11 @@ fn parse_optional_ty_param_bounds(&mut self, allow_any_lifetime: bool)
                     let tref = self.parse_trait_ref();
                     result.push(TraitTyParamBound(tref));
                 }
+                token::BINOP(token::OR) | token::OROR => {
+                    let unboxed_function_type =
+                        self.parse_unboxed_function_type();
+                    result.push(UnboxedFnTyParamBound(unboxed_function_type));
+                }
                 _ => break,
             }
 
index 05c2558da486f80a45d909b39b4172df68c19f87..7cdc93c7314be097ea0475f6970136fdaf7a2b1d 100644 (file)
@@ -10,7 +10,7 @@
 
 use abi;
 use ast::{P, StaticRegionTyParamBound, OtherRegionTyParamBound,
-          TraitTyParamBound, Required, Provided};
+          TraitTyParamBound, UnboxedFnTyParamBound, Required, Provided};
 use ast;
 use ast_util;
 use owned_slice::OwnedSlice;
@@ -19,7 +19,6 @@
 use codemap;
 use diagnostic;
 use parse::classify::expr_is_simple_block;
-use parse::token::IdentInterner;
 use parse::token;
 use parse::lexer::comments;
 use parse;
@@ -30,7 +29,6 @@
 use std::io::{IoResult, MemWriter};
 use std::io;
 use std::mem;
-use std::rc::Rc;
 use std::str;
 use std::string::String;
 
@@ -58,7 +56,6 @@ pub struct CurrentCommentAndLiteral {
 pub struct State<'a> {
     pub s: pp::Printer,
     cm: Option<&'a CodeMap>,
-    intr: Rc<token::IdentInterner>,
     comments: Option<Vec<comments::Comment> >,
     literals: Option<Vec<comments::Literal> >,
     cur_cmnt_and_lit: CurrentCommentAndLiteral,
@@ -76,7 +73,6 @@ pub fn rust_printer_annotated<'a>(writer: Box<io::Writer>,
     State {
         s: pp::mk_printer(writer, default_columns),
         cm: None,
-        intr: token::get_ident_interner(),
         comments: None,
         literals: None,
         cur_cmnt_and_lit: CurrentCommentAndLiteral {
@@ -111,7 +107,6 @@ pub fn print_crate<'a>(cm: &'a CodeMap,
     let mut s = State {
         s: pp::mk_printer(out, default_columns),
         cm: Some(cm),
-        intr: token::get_ident_interner(),
         comments: Some(cmnts),
         // If the code is post expansion, don't use the table of
         // literals, since it doesn't correspond with the literals
@@ -505,27 +500,64 @@ pub fn print_type(&mut self, ty: &ast::Ty) -> IoResult<()> {
                     lifetimes: f.lifetimes.clone(),
                     ty_params: OwnedSlice::empty()
                 };
-                try!(self.print_ty_fn(Some(f.abi), None, &None,
-                                   f.fn_style, ast::Many, f.decl, None, &None,
-                                   Some(&generics), None));
+                try!(self.print_ty_fn(Some(f.abi),
+                                      None,
+                                      &None,
+                                      f.fn_style,
+                                      ast::Many,
+                                      f.decl,
+                                      None,
+                                      &None,
+                                      Some(&generics),
+                                      None,
+                                      false));
             }
             ast::TyClosure(f, ref region) => {
                 let generics = ast::Generics {
                     lifetimes: f.lifetimes.clone(),
                     ty_params: OwnedSlice::empty()
                 };
-                try!(self.print_ty_fn(None, Some('&'), region, f.fn_style,
-                                      f.onceness, f.decl, None, &f.bounds,
-                                      Some(&generics), None));
+                try!(self.print_ty_fn(None,
+                                      Some('&'),
+                                      region,
+                                      f.fn_style,
+                                      f.onceness,
+                                      f.decl,
+                                      None,
+                                      &f.bounds,
+                                      Some(&generics),
+                                      None,
+                                      false));
             }
             ast::TyProc(f) => {
                 let generics = ast::Generics {
                     lifetimes: f.lifetimes.clone(),
                     ty_params: OwnedSlice::empty()
                 };
-                try!(self.print_ty_fn(None, Some('~'), &None, f.fn_style,
-                                      f.onceness, f.decl, None, &f.bounds,
-                                      Some(&generics), None));
+                try!(self.print_ty_fn(None,
+                                      Some('~'),
+                                      &None,
+                                      f.fn_style,
+                                      f.onceness,
+                                      f.decl,
+                                      None,
+                                      &f.bounds,
+                                      Some(&generics),
+                                      None,
+                                      false));
+            }
+            ast::TyUnboxedFn(f) => {
+                try!(self.print_ty_fn(None,
+                                      None,
+                                      &None,
+                                      ast::NormalFn,
+                                      ast::Many,
+                                      f.decl,
+                                      None,
+                                      &None,
+                                      None,
+                                      None,
+                                      true));
             }
             ast::TyPath(ref path, ref bounds, _) => {
                 try!(self.print_bounded_path(path, bounds));
@@ -930,7 +962,8 @@ pub fn print_ty_method(&mut self, m: &ast::TypeMethod) -> IoResult<()> {
                               Some(m.ident),
                               &None,
                               Some(&m.generics),
-                              Some(m.explicit_self.node)));
+                              Some(m.explicit_self.node),
+                              false));
         word(&mut self.s, ";")
     }
 
@@ -1925,6 +1958,19 @@ pub fn print_bounds(&mut self,
                 try!(match *bound {
                     TraitTyParamBound(ref tref) => self.print_trait_ref(tref),
                     StaticRegionTyParamBound => word(&mut self.s, "'static"),
+                    UnboxedFnTyParamBound(ref unboxed_function_type) => {
+                        self.print_ty_fn(None,
+                                         None,
+                                         &None,
+                                         ast::NormalFn,
+                                         ast::Many,
+                                         unboxed_function_type.decl,
+                                         None,
+                                         &None,
+                                         None,
+                                         None,
+                                         true)
+                    }
                     OtherRegionTyParamBound(_) => Ok(())
                 })
             }
@@ -2112,8 +2158,9 @@ pub fn print_ty_fn(&mut self,
                        id: Option<ast::Ident>,
                        opt_bounds: &Option<OwnedSlice<ast::TyParamBound>>,
                        generics: Option<&ast::Generics>,
-                       opt_explicit_self: Option<ast::ExplicitSelf_>)
-        -> IoResult<()> {
+                       opt_explicit_self: Option<ast::ExplicitSelf_>,
+                       is_unboxed: bool)
+                       -> IoResult<()> {
         try!(self.ibox(indent_unit));
 
         // Duplicates the logic in `print_fn_header_info()`.  This is because that
@@ -2129,7 +2176,9 @@ 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));
-            try!(word(&mut self.s, "fn"));
+            if !is_unboxed {
+                try!(word(&mut self.s, "fn"));
+            }
         }
 
         match id {
@@ -2143,15 +2192,20 @@ pub fn print_ty_fn(&mut self,
         match generics { Some(g) => try!(self.print_generics(g)), _ => () }
         try!(zerobreak(&mut self.s));
 
-        if opt_sigil == Some('&') {
+        if is_unboxed || 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(":"));
+        }
+
         try!(self.print_fn_args(decl, opt_explicit_self));
 
-        if opt_sigil == Some('&') {
+        if is_unboxed || opt_sigil == Some('&') {
             try!(word(&mut self.s, "|"));
         } else {
             if decl.variadic {
index 693407b854fb923e9a3038333071d435cbaabd4c..a3b2c23dfdf2d9b7219fdb187171a7023c187735 100644 (file)
@@ -23,7 +23,7 @@ enum SmallVectorRepr<T> {
     Many(Vec<T> ),
 }
 
-impl<T> Container for SmallVector<T> {
+impl<T> Collection for SmallVector<T> {
     fn len(&self) -> uint {
         match self.repr {
             Zero => 0,
index 906f0c16f396478e0b904bc496962bf048a1c03d..b5ae8a3dea0e9e8aa98914ec6d955ccf23c8a269 100644 (file)
@@ -383,6 +383,12 @@ pub fn walk_ty<E: Clone, V: Visitor<E>>(visitor: &mut V, typ: &Ty, env: E) {
             walk_lifetime_decls(visitor, &function_declaration.lifetimes,
                                 env.clone());
         }
+        TyUnboxedFn(ref function_declaration) => {
+            for argument in function_declaration.decl.inputs.iter() {
+                visitor.visit_ty(argument.ty, env.clone())
+            }
+            visitor.visit_ty(function_declaration.decl.output, env.clone());
+        }
         TyPath(ref path, ref bounds, id) => {
             visitor.visit_path(path, id, env.clone());
             for bounds in bounds.iter() {
@@ -501,6 +507,13 @@ pub fn walk_ty_param_bounds<E: Clone, V: Visitor<E>>(visitor: &mut V,
                 walk_trait_ref_helper(visitor, typ, env.clone())
             }
             StaticRegionTyParamBound => {}
+            UnboxedFnTyParamBound(ref function_declaration) => {
+                for argument in function_declaration.decl.inputs.iter() {
+                    visitor.visit_ty(argument.ty, env.clone())
+                }
+                visitor.visit_ty(function_declaration.decl.output,
+                                 env.clone());
+            }
             OtherRegionTyParamBound(..) => {}
         }
     }
index cc813262576ad9d7d28493a7198b4c434edd048f..76118f642abe0480722ffed527cd58ac3aeb7640 100644 (file)
@@ -52,7 +52,8 @@
 
 #![deny(missing_doc)]
 
-#[phase(syntax, link)] extern crate log;
+#[cfg(stage0)] #[phase(syntax, link)] extern crate log;
+#[cfg(not(stage0))] #[phase(plugin, link)] extern crate log;
 
 pub use terminfo::TerminfoTerminal;
 #[cfg(windows)]
index 9e562a08ff95e9a1ee893e1fba41804490711227..7d94e46a88a6e74b5769e57e1f5fc4e979422482 100644 (file)
@@ -271,6 +271,12 @@ pub fn test_main_static_x(args: &[~str], tests: &[TestDescAndFn]) {
                      tests)
 }
 
+pub enum ColorConfig {
+    AutoColor,
+    AlwaysColor,
+    NeverColor,
+}
+
 pub struct TestOpts {
     pub filter: Option<Regex>,
     pub run_ignored: bool,
@@ -282,6 +288,7 @@ pub struct TestOpts {
     pub test_shard: Option<(uint,uint)>,
     pub logfile: Option<Path>,
     pub nocapture: bool,
+    pub color: ColorConfig,
 }
 
 impl TestOpts {
@@ -298,6 +305,7 @@ fn new() -> TestOpts {
             test_shard: None,
             logfile: None,
             nocapture: false,
+            color: AutoColor,
         }
     }
 }
@@ -324,7 +332,11 @@ fn optgroups() -> Vec<getopts::OptGroup> {
       getopts::optopt("", "test-shard", "run shard A, of B shards, worth of the testsuite",
                      "A.B"),
       getopts::optflag("", "nocapture", "don't capture stdout/stderr of each \
-                                         task, allow printing directly"))
+                                         task, allow printing directly"),
+      getopts::optopt("", "color", "Configure coloring of output:
+            auto   = colorize if stdout is a tty and tests are run on serially (default);
+            always = always colorize output;
+            never  = never colorize output;", "auto|always|never"))
 }
 
 fn usage(binary: &str) {
@@ -406,6 +418,16 @@ pub fn parse_opts(args: &[String]) -> Option<OptRes> {
         nocapture = os::getenv("RUST_TEST_NOCAPTURE").is_some();
     }
 
+    let color = match matches.opt_str("color").as_ref().map(|s| s.as_slice()) {
+        Some("auto") | None => AutoColor,
+        Some("always") => AlwaysColor,
+        Some("never") => NeverColor,
+
+        Some(v) => return Some(Err(format!("argument for --color must be \
+                                            auto, always, or never (was {})",
+                                            v))),
+    };
+
     let test_opts = TestOpts {
         filter: filter,
         run_ignored: run_ignored,
@@ -417,6 +439,7 @@ pub fn parse_opts(args: &[String]) -> Option<OptRes> {
         test_shard: test_shard,
         logfile: logfile,
         nocapture: nocapture,
+        color: color,
     };
 
     Some(Ok(test_opts))
@@ -492,7 +515,7 @@ pub fn new(opts: &TestOpts,
         Ok(ConsoleTestState {
             out: out,
             log_out: log_out,
-            use_color: use_color(),
+            use_color: use_color(opts),
             total: 0u,
             passed: 0u,
             failed: 0u,
@@ -867,8 +890,12 @@ fn should_sort_failures_before_printing_them() {
     assert!(apos < bpos);
 }
 
-fn use_color() -> bool {
-    get_concurrency() == 1 && io::stdout().get_ref().isatty()
+fn use_color(opts: &TestOpts) -> bool {
+    match opts.color {
+        AutoColor => get_concurrency() == 1 && io::stdout().get_ref().isatty(),
+        AlwaysColor => true,
+        NeverColor => false,
+    }
 }
 
 #[deriving(Clone)]
index f087b9289c3d723432601ad54e92df23f8a34a4f..f2af59433358e44bc1cfeba8f9fa91b0d87aa169 100644 (file)
@@ -23,7 +23,9 @@
 #![deny(deprecated_owned_vector)]
 
 #[cfg(test)] extern crate debug;
-#[cfg(test)] #[phase(syntax, link)] extern crate log;
+
+#[cfg(test, stage0)] #[phase(syntax, link)] extern crate log;
+#[cfg(test, not(stage0))] #[phase(plugin, link)] extern crate log;
 
 extern crate serialize;
 extern crate libc;
index 3b77b244ce879be5262fff90b7ba3393e7bf6d01..dfd13851774ebd150c5c4dd1afb61310077e60b5 100644 (file)
@@ -13,6 +13,6 @@
 #![crate_type = "rlib"]
 #![feature(phase)]
 
-#[phase(syntax)] extern crate t1 = "issue-13560-1";
-#[phase(syntax, link)] extern crate t2 = "issue-13560-2";
+#[phase(plugin)] extern crate t1 = "issue-13560-1";
+#[phase(plugin, link)] extern crate t2 = "issue-13560-2";
 
index 4ae0b6f14f59d4fcd009a629edf46aa8f0e38b55..0b4bea49fa2499d0481dbdcbe5178c20c8401fe9 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::unstable::dynamic_lib::DynamicLibrary;
+use std::dynamic_lib::DynamicLibrary;
 
 #[no_mangle]
 pub fn foo() { bar(); }
index 3f0da3e344af2c5def69faf28e16309022414743..0c4af97b4100d9a183e134da2bfcab85a6b624a2 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 #![feature(phase)]
-#[phase(syntax, link)] extern crate log;
+#[phase(plugin, link)] extern crate log;
 extern crate debug;
 
 pub fn foo<T>() {
diff --git a/src/test/auxiliary/macro_crate_outlive_expansion_phase.rs b/src/test/auxiliary/macro_crate_outlive_expansion_phase.rs
deleted file mode 100644 (file)
index 670673f..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// force-host
-
-#![feature(macro_registrar)]
-
-extern crate syntax;
-
-use std::any::Any;
-use syntax::ast::Name;
-use syntax::ext::base::SyntaxExtension;
-
-struct Foo {
-    foo: int
-}
-
-impl Drop for Foo {
-    fn drop(&mut self) {}
-}
-
-#[macro_registrar]
-pub fn registrar(_: |Name, SyntaxExtension|) {
-    local_data_key!(foo: Box<Any:Send>);
-    foo.replace(Some(box Foo { foo: 10 } as Box<Any:Send>));
-}
-
index 95f2a8c1ca1522ea9a77c42a95ab9a0839a7740d..805b8a894cb7e24a15a84a7ff341044417e65291 100644 (file)
 
 // force-host
 
-#![feature(globs, macro_registrar, macro_rules, quote, managed_boxes)]
+#![feature(globs, plugin_registrar, macro_rules, quote, managed_boxes)]
 
 extern crate syntax;
+extern crate rustc;
 
-use syntax::ast::{Name, TokenTree, Item, MetaItem};
+use syntax::ast::{TokenTree, Item, MetaItem};
 use syntax::codemap::Span;
 use syntax::ext::base::*;
 use syntax::parse::token;
+use rustc::plugin::Registry;
 
 #[macro_export]
 macro_rules! exported_macro (() => (2))
 
 macro_rules! unexported_macro (() => (3))
 
-#[macro_registrar]
-pub fn macro_registrar(register: |Name, SyntaxExtension|) {
-    register(token::intern("make_a_1"),
-        NormalTT(box BasicMacroExpander {
-            expander: expand_make_a_1,
-            span: None,
-        },
-        None));
-    register(token::intern("into_foo"), ItemModifier(expand_into_foo));
+#[plugin_registrar]
+pub fn plugin_registrar(reg: &mut Registry) {
+    reg.register_macro("make_a_1", expand_make_a_1);
+    reg.register_syntax_extension(
+        token::intern("into_foo"),
+        ItemModifier(expand_into_foo));
 }
 
 fn expand_make_a_1(cx: &mut ExtCtxt, sp: Span, tts: &[TokenTree])
diff --git a/src/test/auxiliary/plugin_crate_outlive_expansion_phase.rs b/src/test/auxiliary/plugin_crate_outlive_expansion_phase.rs
new file mode 100644 (file)
index 0000000..213fdd6
--- /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.
+
+// force-host
+
+#![feature(plugin_registrar)]
+
+extern crate rustc;
+
+use std::any::Any;
+use rustc::plugin::Registry;
+
+struct Foo {
+    foo: int
+}
+
+impl Drop for Foo {
+    fn drop(&mut self) {}
+}
+
+#[plugin_registrar]
+pub fn registrar(_: &mut Registry) {
+    local_data_key!(foo: Box<Any:Send>);
+    foo.replace(Some(box Foo { foo: 10 } as Box<Any:Send>));
+}
+
index 93b56a7600d09936f6859d4a124a24ae88477825..04318fcae2733d2dbf2cbbdd3e56397bd3d6adc2 100644 (file)
 // no-prefer-dynamic
 
 #![crate_type = "dylib"]
-#![feature(macro_registrar, quote, globs)]
+#![feature(plugin_registrar, quote, globs)]
 
 extern crate other = "syntax-extension-with-dll-deps-1";
 extern crate syntax;
+extern crate rustc;
 
-use syntax::ast::{Name, TokenTree, Item, MetaItem};
+use syntax::ast::{TokenTree, Item, MetaItem};
 use syntax::codemap::Span;
 use syntax::ext::base::*;
-use syntax::parse::token;
+use rustc::plugin::Registry;
 
-#[macro_registrar]
-pub fn macro_registrar(register: |Name, SyntaxExtension|) {
-    register(token::intern("foo"),
-        NormalTT(box BasicMacroExpander {
-            expander: expand_foo,
-            span: None,
-        },
-        None));
+#[plugin_registrar]
+pub fn plugin_registrar(reg: &mut Registry) {
+    reg.register_macro("foo", expand_foo);
 }
 
 fn expand_foo(cx: &mut ExtCtxt, sp: Span, tts: &[TokenTree])
index 68a2ae24b8563309fdaf3643a9a4128c0ba04879..c998e362d7e34f96a3a93a3a16da8fd6d8e9e265 100644 (file)
@@ -17,7 +17,7 @@
 #![feature(phase)]
 #![crate_type = "rlib"]
 
-#[phase(syntax, link)]
+#[phase(plugin, link)]
 extern crate core;
 
 struct A;
index baf02feb5b80a827510c6c16725a40976662a25d..28786f1e163d965898cebb37e67aad8b386ada68 100644 (file)
@@ -11,7 +11,7 @@
 // no-pretty-expanded
 
 #![feature(phase)]
-#[phase(syntax)] extern crate green;
+#[phase(plugin)] extern crate green;
 
 use std::string::String;
 use std::fmt;
index 9cc8f2f23ff26aa4a3a24f422d86a94fe34aa43a..99eb2e5484d72c6f2bc2e50661c694e0ea3b9835 100644 (file)
@@ -1,12 +1,42 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
+// The Computer Language Benchmarks Game
+// http://benchmarksgame.alioth.debian.org/
 //
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
+// contributed by the Rust Project Developers
+
+// Copyright (c) 2014 The Rust Project Developers
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// - Redistributions of source code must retain the above copyright
+//   notice, this list of conditions and the following disclaimer.
+//
+// - Redistributions in binary form must reproduce the above copyright
+//   notice, this list of conditions and the following disclaimer in
+//   the documentation and/or other materials provided with the
+//   distribution.
+//
+// - Neither the name of "The Computer Language Benchmarks Game" nor
+//   the name of "The Computer Language Shootout Benchmarks" nor the
+//   names of its contributors may be used to endorse or promote
+//   products derived from this software without specific prior
+//   written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+// OF THE POSSIBILITY OF SUCH DAMAGE.
 
 use std::cmp::max;
 
index 6f4aef27b63d45f59812c68072ff44497df91495..afefaf2b5353c1832728ec1e88d4bf02dd3a41a3 100644 (file)
@@ -39,7 +39,7 @@
 // OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #![feature(phase)]
-#[phase(syntax)] extern crate green;
+#[phase(plugin)] extern crate green;
 extern crate sync;
 
 use sync::Arc;
index c2f0a58a288e5e5c769b8c41f39f7f0272c5e0d7..ca0248bcf5deacbfceed66fb3f6ad8ca62d9a31a 100644 (file)
@@ -46,7 +46,7 @@
 #![feature(macro_rules, phase)]
 
 extern crate regex;
-#[phase(syntax)]extern crate regex_macros;
+#[phase(plugin)]extern crate regex_macros;
 extern crate sync;
 
 use std::io;
index c038a056569b9918f5108b1dd9a2272092cbb536..15b7ff1e81e8a812ba6dace0960edb135a8da3d6 100644 (file)
@@ -10,7 +10,7 @@
 
 #![feature(phase)]
 #![allow(non_snake_case_functions)]
-#[phase(syntax)] extern crate green;
+#[phase(plugin)] extern crate green;
 extern crate sync;
 
 use std::from_str::FromStr;
index 1a6582927caf2bbc7429c0fa25c5fe276b87e233..a001ff78ba0bfb8e1cc5c2fdcf0ff416049aefe8 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 #![feature(phase)]
-#[phase(syntax)] extern crate green;
+#[phase(plugin)] extern crate green;
 green_start!(main)
 
 fn start(n_tasks: int, token: int) {
index c8763899269ccefbcbbe98e62e9969cd5a5d1a03..1f384b856334c0340b5e5b3156f45d05678635bd 100644 (file)
@@ -11,7 +11,7 @@
 // aux-build:macro_crate_test.rs
 // ignore-stage1
 
-#[phase(syntax)]
+#[phase(plugin)]
 //~^ ERROR compile time crate loading is experimental and possibly buggy
 extern crate macro_crate_test;
 
index f8eb9868a5b69413047261f344dfd11aeb957be9..39c2accaddf3327dd0259ac7b5344720b4ab4ad6 100644 (file)
@@ -14,7 +14,7 @@
 
 #![feature(phase)]
 
-#[phase(syntax)]
+#[phase(plugin)]
 extern crate macro_crate_test;
 
 fn main() {
index 84c915f267ec26fd78c3ccc59f2f804c37a501fe..7a7eac7b709250ab1d991ebb739e9efde6980575 100644 (file)
@@ -10,7 +10,7 @@
 
 #![feature(phase)]
 
-#[phase(syntax)]
+#[phase(plugin)]
 extern crate doesnt_exist; //~ ERROR can't find crate
 
 fn main() {}
index 2053f81683d7a3d50582dc9276c74da5cbd5766d..274fbf797e1ef96c14a337d9c34b07f82a262513 100644 (file)
@@ -14,7 +14,7 @@
 
 #![feature(phase)]
 
-#[phase(syntax)]
+#[phase(plugin)]
 extern crate macro_crate_test;
 
 fn main() {
index fbcdf55f1acbfca0380ef9f9861feaf62fda58e3..3ad17618fc0b31e33830f5ced682c7e7e69ff4e0 100644 (file)
@@ -13,7 +13,7 @@
 
 #![feature(phase)]
 
-#[phase(syntax)]
+#[phase(plugin)]
 extern crate fourcc;
 
 fn main() {
index 569b54b93fb097f346853b3e4839b7efd4dfbfc9..4d425d9a2056a62f8e7cbf3b019d4a3bd7592e73 100644 (file)
@@ -13,7 +13,7 @@
 
 #![feature(phase)]
 
-#[phase(syntax)]
+#[phase(plugin)]
 extern crate fourcc;
 
 fn main() {
index c0e2304354cc478d74260c3a32fb9c5054bbbef5..1a6d747c1e8368ee7c84ddec51a33e154c1ba00f 100644 (file)
@@ -13,7 +13,7 @@
 
 #![feature(phase)]
 
-#[phase(syntax)]
+#[phase(plugin)]
 extern crate fourcc;
 
 fn main() {
index 536594f3063111ce1c0345418322999de5bbd8b6..885d8dd1ec326fcd76ca10634498807e6debb13f 100644 (file)
@@ -13,7 +13,7 @@
 
 #![feature(phase)]
 
-#[phase(syntax)]
+#[phase(plugin)]
 extern crate fourcc;
 
 fn main() {
index 8a0b0856d24de8897e0b03b22d7ffd615c5c41e1..da1c0070715686c13e14238171bd70a9ed047019 100644 (file)
@@ -13,7 +13,7 @@
 
 #![feature(phase)]
 
-#[phase(syntax)]
+#[phase(plugin)]
 extern crate fourcc;
 
 fn main() {
index 1cd4f654d2e37106192cca90b5fd161cabcdcccd..191042f5f5639f6876b2c66e2e2cf664916a6417 100644 (file)
@@ -13,7 +13,7 @@
 
 #![feature(phase)]
 
-#[phase(syntax)]
+#[phase(plugin)]
 extern crate hexfloat;
 
 fn main() {
index 4a6475cea96722b2998d4a7bb4120d1b3952da9b..f0ace43ec9e8d34ad66d8b35c601feca8646d0b0 100644 (file)
@@ -13,7 +13,7 @@
 
 #![feature(phase)]
 
-#[phase(syntax)]
+#[phase(plugin)]
 extern crate hexfloat;
 
 fn main() {
index 0e072dc1c060b512cebddc1545015027409cdb25..bccba74e05c70e5dd20988758f68aaabc47bdc01 100644 (file)
@@ -15,7 +15,7 @@
 #![feature(phase)]
 
 extern crate regex;
-#[phase(syntax)] extern crate regex_macros;
+#[phase(plugin)] extern crate regex_macros;
 
 // Tests to make sure that `regex!` will produce a compile error when given
 // an invalid regular expression.
index 300e7e524df2543fb94d676e042bca0868b5c002..819c9e6b0fe2f9bf103e75c9e81621957175f13d 100644 (file)
@@ -15,7 +15,7 @@
 #![feature(phase)]
 
 extern crate regex;
-#[phase(syntax)] extern crate regex_macros;
+#[phase(plugin)] extern crate regex_macros;
 
 #[deny(unused_variable)]
 #[deny(dead_code)]
index c77bd52d9e56cfa1f94f8ccca901030b1ce527f7..d96b3f6f224cfb35c10c0d6ef99052bdcd875e2e 100644 (file)
@@ -15,7 +15,7 @@
 #![feature(phase)]
 
 extern crate regex;
-#[phase(syntax)] extern crate regex_macros;
+#[phase(plugin)] extern crate regex_macros;
 
 #[deny(unused_variable)]
 #[deny(dead_code)]
diff --git a/src/test/compile-fail/gated-macro_registrar.rs b/src/test/compile-fail/gated-macro_registrar.rs
deleted file mode 100644 (file)
index 54274cc..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// the registration function isn't typechecked yet
-#[macro_registrar]
-pub fn registrar() {} //~ ERROR cross-crate macro exports are experimental
-
-fn main() {}
diff --git a/src/test/compile-fail/gated-plugin_registrar.rs b/src/test/compile-fail/gated-plugin_registrar.rs
new file mode 100644 (file)
index 0000000..f6e11ff
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// the registration function isn't typechecked yet
+#[plugin_registrar]
+pub fn registrar() {} //~ ERROR compiler plugins are experimental
+
+fn main() {}
diff --git a/src/test/compile-fail/issue-13446.rs b/src/test/compile-fail/issue-13446.rs
new file mode 100644 (file)
index 0000000..0bb6ded
--- /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.
+
+
+// Used to cause ICE
+
+static VEC: [u32, ..256] = vec!(); //~ ERROR mismatched types
+
+fn main() {}
+
index 10734f1f2430ae9ff323648bdb9438eb4d79c148..bca2a5d7edc864cb871726e4603157fbe8bdc424 100644 (file)
@@ -39,7 +39,10 @@ mod foo2 {
 pub type typ = *UsedStruct4;
 pub struct PubStruct();
 struct PrivStruct; //~ ERROR: code is never used
-struct UsedStruct1 { x: int }
+struct UsedStruct1 {
+    #[allow(dead_code)]
+    x: int
+}
 struct UsedStruct2(int);
 struct UsedStruct3;
 struct UsedStruct4;
@@ -53,6 +56,7 @@ fn la_la_la() {}
 struct StructUsedInEnum;
 struct StructUsedInGeneric;
 pub struct PubStruct2 {
+    #[allow(dead_code)]
     struct_used_as_field: *StructUsedAsField
 }
 
diff --git a/src/test/compile-fail/lint-dead-code-4.rs b/src/test/compile-fail/lint-dead-code-4.rs
new file mode 100644 (file)
index 0000000..718af18
--- /dev/null
@@ -0,0 +1,67 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <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(struct_variant)]
+#![allow(unused_variable)]
+#![allow(non_camel_case_types)]
+#![deny(dead_code)]
+
+extern crate libc;
+
+use std::num;
+
+struct Foo {
+    x: uint,
+    b: bool, //~ ERROR: code is never used
+    marker: std::kinds::marker::NoCopy
+}
+
+fn field_read(f: Foo) -> uint {
+    num::pow(f.x, 2)
+}
+
+enum XYZ {
+    X,
+    Y {
+        a: String,
+        b: int //~ ERROR: code is never used
+    },
+    Z
+}
+
+fn field_match_in_patterns(b: XYZ) -> String {
+    match b {
+        Y { a: a, .. } => a,
+        _ => "".to_string()
+    }
+}
+
+struct Bar {
+    x: uint, //~ ERROR: code is never used
+    b: bool,
+    _guard: ()
+}
+
+#[repr(C)]
+struct Baz {
+    x: libc::c_uint
+}
+
+fn field_match_in_let(f: Bar) -> bool {
+    let Bar { b, .. } = f;
+    b
+}
+
+fn main() {
+    field_read(Foo { x: 1, b: false, marker: std::kinds::marker::NoCopy });
+    field_match_in_patterns(Z);
+    field_match_in_let(Bar { x: 42u, b: true, _guard: () });
+    let _ = Baz { x: 0 };
+}
index d9a79d7597592c286ad66b9a024ab941fd4e019c..ff382cb46c7624ec123d956f592915110341a523 100644 (file)
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![allow(dead_code)]
 #![feature(managed_boxes)]
 #![forbid(managed_heap_memory)]
 
index 57b051e1beac581a2c98210c8dda076094e868c8..537c7d625554fc89383be292a547c7d15c3f976f 100644 (file)
 #![forbid(non_camel_case_types)]
 #![allow(dead_code)]
 
-struct foo { //~ ERROR type `foo` should have a camel case identifier
+struct foo { //~ ERROR type `foo` should have a camel case name such as `Foo`
     bar: int,
 }
 
-enum foo2 { //~ ERROR type `foo2` should have a camel case identifier
+enum foo2 { //~ ERROR type `foo2` should have a camel case name such as `Foo2`
     Bar
 }
 
-struct foo3 { //~ ERROR type `foo3` should have a camel case identifier
+struct foo3 { //~ ERROR type `foo3` should have a camel case name such as `Foo3`
     bar: int
 }
 
-type foo4 = int; //~ ERROR type `foo4` should have a camel case identifier
+type foo4 = int; //~ ERROR type `foo4` should have a camel case name such as `Foo4`
 
 enum Foo5 {
-    bar //~ ERROR variant `bar` should have a camel case identifier
+    bar //~ ERROR variant `bar` should have a camel case name such as `Bar`
 }
 
-trait foo6 { //~ ERROR trait `foo6` should have a camel case identifier
+trait foo6 { //~ ERROR trait `foo6` should have a camel case name such as `Foo6`
 }
 
 fn main() { }
index 02ab85aff3bdfa22aa0a498f10e9d1e767976eba..4253286996c5a9efca64688a18992d3e84618b6b 100644 (file)
 
 impl Foo {
     fn Foo_Method() {}
-    //~^ ERROR method `Foo_Method` should have a snake case identifier
+    //~^ ERROR method `Foo_Method` should have a snake case name such as `foo_method`
 
     // Don't allow two underscores in a row
     fn foo__method(&self) {}
-    //~^ ERROR method `foo__method` should have a snake case identifier
+    //~^ ERROR method `foo__method` should have a snake case name such as `foo_method`
 
     pub fn xyZ(&mut self) {}
-    //~^ ERROR method `xyZ` should have a snake case identifier
+    //~^ ERROR method `xyZ` should have a snake case name such as `xy_z`
 }
 
 trait X {
     fn ABC();
-    //~^ ERROR trait method `ABC` should have a snake case identifier
+    //~^ ERROR trait method `ABC` should have a snake case name such as `a_b_c`
 
     fn a_b_C(&self) {}
-    //~^ ERROR trait method `a_b_C` should have a snake case identifier
+    //~^ ERROR trait method `a_b_C` should have a snake case name such as `a_b_c`
 
     fn something__else(&mut self);
-    //~^ ERROR trait method `something__else` should have a snake case identifier
+    //~^ ERROR trait method `something__else` should have a snake case name such as `something_else`
 }
 
 impl X for Foo {
@@ -43,9 +43,9 @@ fn something__else(&mut self) {}
 }
 
 fn Cookie() {}
-//~^ ERROR function `Cookie` should have a snake case identifier
+//~^ ERROR function `Cookie` should have a snake case name such as `cookie`
 
 pub fn bi_S_Cuit() {}
-//~^ ERROR function `bi_S_Cuit` should have a snake case identifier
+//~^ ERROR function `bi_S_Cuit` should have a snake case name such as `bi_s_cuit`
 
 fn main() { }
index 6eca7c3ed3d544b556aa2fed2a039886bec173ed..2d9f2d8fc1c2a422e7219142f893bd3c917be832 100644 (file)
@@ -11,6 +11,6 @@
 #![forbid(non_uppercase_statics)]
 #![allow(dead_code)]
 
-static foo: int = 1; //~ ERROR static constant should have an uppercase identifier
+static foo: int = 1; //~ ERROR static constant `foo` should have an uppercase name such as `FOO`
 
 fn main() { }
index c9688ad49d77e3609eef7431c2fe2926c5bc2d20..8f20999a56c8d7064d6848bf29e8ed1e63da4539 100644 (file)
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![allow(dead_code)]
 #![forbid(owned_heap_memory)]
 
 
index 386b4019485a91cc66a59795371b175bb33cbaae..f1b36d719e9591603450e80b089e4a3d031aa4ea 100644 (file)
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![allow(dead_code)]
 #![deny(uppercase_variables)]
 
 use std::io::File;
index 0c9a7cc8bde4fbf691c00f97b24a4a3b5325b40e..bb5f020e78c9d9ac1d1bd78f805e15278575f580 100644 (file)
@@ -18,6 +18,6 @@ fn main() {
     let x: Box<HashMap<int, int>> = box HashMap::new();
     let x: Box<Map<int, int>> = x;
     let y: Box<Map<uint, int>> = box x;
-    //~^ ERROR failed to find an implementation of trait core::container::Map<uint,int>
-    //         for ~core::container::Map<int,int>:Send
+    //~^ ERROR failed to find an implementation of trait collections::Map<uint,int>
+    //         for ~collections::Map<int,int>:Send
 }
index f77ea2db8c02b4ebeb3b95190e04ac7ec35c84bc..a409ae60ccaa1e8077b68253907fb4a63f37423a 100644 (file)
@@ -18,7 +18,7 @@
 fn f() {
     let r = match (0,0) {
         (0, a) => 0,
-        //~^ ERROR static constant in pattern should be all caps
+        //~^ ERROR static constant in pattern `a` should have an uppercase name such as `A`
         (x, y) => 1 + x + y,
     };
     assert!(r == 1);
@@ -32,7 +32,7 @@ fn g() {
     use self::m::aha;
     let r = match (0,0) {
         (0, aha) => 0,
-        //~^ ERROR static constant in pattern should be all caps
+        //~^ ERROR static constant in pattern `aha` should have an uppercase name such as `AHA`
         (x, y)   => 1 + x + y,
     };
     assert!(r == 1);
@@ -46,7 +46,7 @@ fn h() {
     use not_okay = self::n::OKAY;
     let r = match (0,0) {
         (0, not_okay) => 0,
-        //~^ ERROR static constant in pattern should be all caps
+//~^ ERROR static constant in pattern `not_okay` should have an uppercase name such as `NOT_OKAY`
         (x, y)   => 1 + x + y,
     };
     assert!(r == 1);
diff --git a/src/test/compile-fail/multiple-macro-registrars.rs b/src/test/compile-fail/multiple-macro-registrars.rs
deleted file mode 100644 (file)
index 321c0ff..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <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.
-
-// error-pattern: multiple macro registration functions found
-
-#![feature(macro_registrar)]
-
-// the registration function isn't typechecked yet
-#[macro_registrar]
-pub fn one() {}
-
-#[macro_registrar]
-pub fn two() {}
-
-fn main() {}
diff --git a/src/test/compile-fail/multiple-plugin-registrars.rs b/src/test/compile-fail/multiple-plugin-registrars.rs
new file mode 100644 (file)
index 0000000..f5ebf84
--- /dev/null
@@ -0,0 +1,22 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <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.
+
+// error-pattern: multiple plugin registration functions found
+
+#![feature(plugin_registrar)]
+
+// the registration function isn't typechecked yet
+#[plugin_registrar]
+pub fn one() {}
+
+#[plugin_registrar]
+pub fn two() {}
+
+fn main() {}
diff --git a/src/test/compile-fail/overloaded-calls-bad.rs b/src/test/compile-fail/overloaded-calls-bad.rs
new file mode 100644 (file)
index 0000000..3c03c87
--- /dev/null
@@ -0,0 +1,35 @@
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(overloaded_calls)]
+
+use std::ops::FnMut;
+
+struct S {
+    x: int,
+    y: int,
+}
+
+impl FnMut<(int,),int> for S {
+    fn call_mut(&mut self, (z,): (int,)) -> int {
+        self.x * self.y * z
+    }
+}
+
+fn main() {
+    let mut s = S {
+        x: 3,
+        y: 3,
+    };
+    let ans = s("what");    //~ ERROR mismatched types
+    let ans = s();  //~ ERROR this function takes 1 parameter but 0 parameters were supplied
+    let ans = s("burma", "shave");
+    //~^ ERROR this function takes 1 parameter but 2 parameters were supplied
+}
diff --git a/src/test/compile-fail/overloaded-calls-nontuple.rs b/src/test/compile-fail/overloaded-calls-nontuple.rs
new file mode 100644 (file)
index 0000000..9bbc4ab
--- /dev/null
@@ -0,0 +1,33 @@
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(overloaded_calls)]
+
+use std::ops::FnMut;
+
+struct S {
+    x: int,
+    y: int,
+}
+
+impl FnMut<int,int> for S {
+    fn call_mut(&mut self, z: int) -> int {
+        self.x + self.y + z
+    }
+}
+
+fn main() {
+    let mut s = S {
+        x: 1,
+        y: 2,
+    };
+    drop(s(3))  //~ ERROR cannot use call notation
+}
+
index 385bc1452048704772a66b97f6978fa61e08c6ec..c960679a43f1e074e56667b13c7cc1f3ac893cfe 100644 (file)
@@ -11,7 +11,7 @@
 // error-pattern:whatever
 
 #![feature(phase)]
-#[phase(syntax, link)] extern crate log;
+#[phase(plugin, link)] extern crate log;
 use std::os;
 
 fn main() {
index 3b5e27027b43c96b12814faf17299fb909865c88..22985d57936a29a1237b5c898dffc022fa097a1c 100644 (file)
@@ -11,7 +11,7 @@
 // error-pattern:whatever
 
 #![feature(phase)]
-#[phase(syntax, link)] extern crate log;
+#[phase(plugin, link)] extern crate log;
 use std::os;
 use std::task;
 
index b94045e5d124225d42ad181bd4aa17cccdae23d4..d08cb198802ad38892d5fb9c91a3b67659ae3e4e 100644 (file)
@@ -11,7 +11,7 @@
 // error-pattern:whatever
 
 #![feature(phase)]
-#[phase(syntax, link)] extern crate log;
+#[phase(plugin, link)] extern crate log;
 use std::os;
 
 fn main() {
index e05d43145d7e2e365d3004113989ca814dde77da..0f759efb02539bc874d624f4511cd767b819f89e 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::unstable::dynamic_lib::DynamicLibrary;
+use std::dynamic_lib::DynamicLibrary;
 use std::os;
 
 pub fn main() {
index 0c55d5fd3144d9e4f3a1fb9657cd0e563d6a2edf..ec4fbca48f8de393128045daf59c5ba99adf9980 100644 (file)
@@ -11,7 +11,7 @@
 #![feature(phase)]
 
 extern crate lib;
-#[phase(syntax)] extern crate fourcc;
+#[phase(plugin)] extern crate fourcc;
 
 fn main() {
     fourcc!("1234");
index 58663bb44c7440efac69ba493d6155b520240a29..dd585ea979408ec30e1abd46f9a4960296439bf1 100644 (file)
@@ -8,12 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// aux-build:macro_crate_outlive_expansion_phase.rs
+// aux-build:plugin_crate_outlive_expansion_phase.rs
 // ignore-stage1
 
 #![feature(phase)]
 
-#[phase(syntax)]
-extern crate macro_crate_outlive_expansion_phase;
+#[phase(plugin)]
+extern crate plugin_crate_outlive_expansion_phase;
 
 pub fn main() {}
index 3c620c5e5720935d6b42a24aad289c5a144fcfc7..1e796d9d724c66f1e150752fcdd74d1d56cc33e3 100644 (file)
@@ -13,7 +13,7 @@
 
 #![feature(phase)]
 
-#[phase(syntax)]
+#[phase(plugin)]
 extern crate macro_crate_test;
 
 #[into_foo]
index b8d3ab2383100010a96a9f97a6426885838c74e0..47ff7d31df5f3f2c5744b8a926b6a159033a2b26 100644 (file)
@@ -17,7 +17,7 @@
 
 #![feature(phase)]
 
-#[phase(syntax, link)]
+#[phase(plugin, link)]
 extern crate macro_crate_test;
 
 fn main() {
index 0681ec63b9ed08c7ac61964ef6964ee490919db2..b16975fe6eea7068f74f1ab4b702b1f7123663d5 100644 (file)
@@ -13,7 +13,7 @@
 
 #![feature(phase)]
 
-#[phase(syntax)]
+#[phase(plugin)]
 extern crate fourcc;
 
 static static_val: u32 = fourcc!("foo ");
index 3601b6101159890dd577389652af4372d693fd5b..496b01113638b180e4963f92602e73d8e2bf474b 100644 (file)
@@ -12,7 +12,7 @@
 // ignore-pretty
 
 #![feature(phase)]
-#[phase(syntax)]
+#[phase(plugin)]
 extern crate hexfloat;
 
 pub fn main() {
index efae04ea4fc7a017b951a326500e7b97ad9a4de9..275463f5d7fc4ee6cc3e3d564dc89293a0dc3507 100644 (file)
@@ -14,7 +14,7 @@
 
 #![feature(phase)]
 
-#[phase(syntax)]
+#[phase(plugin)]
 extern crate extension = "syntax-extension-with-dll-deps-2";
 
 fn main() {
index 636e879fe32a8283fa414bacf1f268df7ff4badd..3402db7c355a942ac93127554baa1ccec5665c36 100644 (file)
@@ -13,7 +13,7 @@
 
 #![feature(phase)]
 
-#[phase(syntax, link)]
+#[phase(plugin, link)]
 extern crate log;
 extern crate native;
 
index 865984844c0b54314766c68be80ade3cd3a59017..924625faa1010a87338d6f025674716ae56bcee9 100644 (file)
@@ -48,7 +48,7 @@ pub fn eat(&mut self) -> bool {
     }
 }
 
-impl<T> Container for cat<T> {
+impl<T> Collection for cat<T> {
     fn len(&self) -> uint { self.meows as uint }
     fn is_empty(&self) -> bool { self.meows == 0 }
 }
index 56b38033c8327813204848e710cf2bf8556e2d9c..b7c4ccb3c2a360196165b5cd5be80184f92d4064 100644 (file)
@@ -12,7 +12,7 @@
 // exec-env:RUST_LOG=conditional-debug-macro-off=4
 
 #![feature(phase)]
-#[phase(syntax, link)]
+#[phase(plugin, link)]
 extern crate log;
 extern crate debug;
 
diff --git a/src/test/run-pass/deprecated-phase-syntax.rs b/src/test/run-pass/deprecated-phase-syntax.rs
new file mode 100644 (file)
index 0000000..df835da
--- /dev/null
@@ -0,0 +1,19 @@
+// 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.
+
+#![feature(phase)]
+
+//~ WARNING phase(syntax) is a deprecated synonym for phase(plugin)
+#[phase(syntax, link)]
+extern crate log;
+
+fn main() {
+    debug!("foo");
+}
diff --git a/src/test/run-pass/fn-trait-sugar.rs b/src/test/run-pass/fn-trait-sugar.rs
new file mode 100644 (file)
index 0000000..b0c8d84
--- /dev/null
@@ -0,0 +1,38 @@
+
+// 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)]
+
+use std::ops::FnMut;
+
+struct S;
+
+impl FnMut<(int,),int> for S {
+    fn call_mut(&mut self, (x,): (int,)) -> int {
+        x * x
+    }
+}
+
+fn call_it<F:|int|->int>(mut f: F, x: int) -> int {
+    f.call_mut((x,)) + 3
+}
+
+fn call_box(f: &mut |&mut: int|->int, x: int) -> int {
+    f.call_mut((x,)) + 3
+}
+
+fn main() {
+    let x = call_it(S, 1);
+    let y = call_box(&mut S, 1);
+    assert!(x == 4);
+    assert!(y == 4);
+}
+
index 79203503373effbb6d668817aee5310285d6260a..96290386ccc11e4911d802513016464eb3362890 100644 (file)
@@ -10,7 +10,7 @@
 
 #![feature(phase)]
 
-#[phase(syntax, link)]
+#[phase(plugin, link)]
 extern crate green;
 extern crate native;
 
index e263767990a65d188dd08e823a41788308d8fd4f..58f66314e4430dd7fca25b6b6046b192787d9eb1 100644 (file)
@@ -10,7 +10,7 @@
 
 // aux-build:linkage-visibility.rs
 // ignore-android: FIXME(#10379)
-// ignore-win32: std::unstable::dynamic_lib does not work on win32 well
+// ignore-win32: std::dynamic_lib does not work on win32 well
 
 extern crate foo = "linkage-visibility";
 
index 9320c77a285b43d7285398a75baee7bfa3e8d0e5..7975af434d2846339e1a8f9196ecdd17caf34697 100644 (file)
@@ -12,7 +12,7 @@
 // exec-env:RUST_LOG=logging-enabled-debug=debug
 
 #![feature(phase)]
-#[phase(syntax, link)]
+#[phase(plugin, link)]
 extern crate log;
 
 pub fn main() {
index b1d24e8b9b6df476edd380f50110aa5cc7f59e6c..184ac713c899bfa178e0dd1f5ea2193f7d44344a 100644 (file)
@@ -11,7 +11,7 @@
 // exec-env:RUST_LOG=logging-enabled=info
 
 #![feature(phase)]
-#[phase(syntax, link)]
+#[phase(plugin, link)]
 extern crate log;
 
 pub fn main() {
index 7f9a4593780a5a35ebfe93645fd28b233dad3931..989a8d4bde57aa58bd6473348d8477b24318735b 100644 (file)
@@ -13,7 +13,7 @@
 
 #![feature(phase)]
 
-#[phase(syntax, link)]
+#[phase(plugin, link)]
 extern crate log;
 
 use std::io::Command;
index abf8edc274cf7ecdec9c03d917ccb79450f4a444..25da809babd4391f172cd57ebfec83d77a3a42d4 100644 (file)
@@ -12,7 +12,7 @@
 
 #![feature(phase)]
 
-#[phase(syntax)]
+#[phase(plugin)]
 extern crate macro_crate_def_only;
 
 pub fn main() {
index 179c65cd046b2ecc6c4e292bc4221a4f320d4a0e..c7911a69ce46a8f16df81115284c367cdf2e316b 100644 (file)
@@ -13,7 +13,7 @@
 
 #![feature(phase)]
 
-#[phase(syntax)]
+#[phase(plugin)]
 extern crate macro_export_inner_module;
 
 pub fn main() {
diff --git a/src/test/run-pass/overloaded-calls-simple.rs b/src/test/run-pass/overloaded-calls-simple.rs
new file mode 100644 (file)
index 0000000..33120de
--- /dev/null
@@ -0,0 +1,70 @@
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(overloaded_calls)]
+
+use std::ops::{Fn, FnMut, FnOnce};
+
+struct S1 {
+    x: int,
+    y: int,
+}
+
+impl FnMut<(int,),int> for S1 {
+    fn call_mut(&mut self, (z,): (int,)) -> int {
+        self.x * self.y * z
+    }
+}
+
+struct S2 {
+    x: int,
+    y: int,
+}
+
+impl Fn<(int,),int> for S2 {
+    fn call(&self, (z,): (int,)) -> int {
+        self.x * self.y * z
+    }
+}
+
+struct S3 {
+    x: int,
+    y: int,
+}
+
+impl FnOnce<(int,int),int> for S3 {
+    fn call_once(self, (z,zz): (int,int)) -> int {
+        self.x * self.y * z * zz
+    }
+}
+
+fn main() {
+    let mut s = S1 {
+        x: 3,
+        y: 3,
+    };
+    let ans = s(3);
+    assert_eq!(ans, 27);
+
+    let s = S2 {
+        x: 3,
+        y: 3,
+    };
+    let ans = s(3);
+    assert_eq!(ans, 27);
+
+    let s = S3 {
+        x: 3,
+        y: 3,
+    };
+    let ans = s(3, 1);
+    assert_eq!(ans, 27);
+}
+
diff --git a/src/test/run-pass/overloaded-calls-zero-args.rs b/src/test/run-pass/overloaded-calls-zero-args.rs
new file mode 100644 (file)
index 0000000..f8f7df6
--- /dev/null
@@ -0,0 +1,35 @@
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(overloaded_calls)]
+
+use std::ops::{FnMut};
+
+struct S {
+    x: int,
+    y: int,
+}
+
+impl FnMut<(),int> for S {
+    fn call_mut(&mut self, (): ()) -> int {
+        self.x * self.y
+    }
+}
+
+fn main() {
+    let mut s = S {
+        x: 3,
+        y: 3,
+    };
+    let ans = s();
+    assert_eq!(ans, 9);
+}
+
+
index 60f2619fffd9bb09aa9f0977742d5051aa211f35..5015e43fa3f346b26cb1f0ecf4489425782cc606 100644 (file)
@@ -11,7 +11,7 @@
 
 #![feature(phase)]
 
-#[phase(syntax)]
+#[phase(plugin)]
 use std::mem;
 
 fn main() {}
index 750235ce6afedaa33caf6755081e157e76330071..8b041ed3a3e768bba07762abe4d789cec5838de3 100644 (file)
@@ -10,7 +10,7 @@
 
 extern crate collections;
 
-use std::container::{Map, MutableMap};
+use std::collections::{Map, MutableMap};
 use std::str::{SendStr, Owned, Slice};
 use std::collections::HashMap;
 use std::option::Some;
index 5604093ea9c8add7e0e0c4930b17a76c36bb2b49..68eca8f21a7f5d37c9b4a94e55a96034593bd648 100644 (file)
@@ -10,7 +10,7 @@
 
 extern crate collections;
 
-use std::container::{ Map, MutableMap};
+use std::collections::{ Map, MutableMap};
 use std::str::{SendStr, Owned, Slice};
 use std::to_str::ToStr;
 use self::collections::TreeMap;
index a9a6e25adf38b88809efe909b35e9f4eee1f09a8..9c4716e5f4d3805aa28877d4b5d41dfd34fc024e 100644 (file)
@@ -13,7 +13,7 @@
 // exec-env:RUST_LOG=debug
 
 #![feature(phase)]
-#[phase(syntax, link)]
+#[phase(plugin, link)]
 extern crate log;
 extern crate libc;
 extern crate green;