]> git.lizzy.rs Git - rust.git/commitdiff
auto merge of #16327 : mdinger/rust/typo, r=steveklabnik
authorbors <bors@rust-lang.org>
Fri, 8 Aug 2014 14:36:10 +0000 (14:36 +0000)
committerbors <bors@rust-lang.org>
Fri, 8 Aug 2014 14:36:10 +0000 (14:36 +0000)
Fix typo. It's possible it's `These modules` but I think it's supposed to be singular because it's not refering to nested modules.

91 files changed:
configure
src/doc/complement-design-faq.md
src/doc/guide-unsafe.md
src/doc/guide.md
src/doc/rust.md
src/doc/tutorial.md
src/etc/vim/syntax/rust.vim
src/liballoc/arc.rs
src/liballoc/rc.rs
src/libcollections/slice.rs
src/libcollections/vec.rs
src/libcore/cell.rs
src/libcore/char.rs
src/libcore/failure.rs
src/libcore/fmt/float.rs
src/libcore/fmt/num.rs
src/libcore/kinds.rs
src/libcore/ops.rs
src/libcore/prelude.rs
src/libcore/ptr.rs
src/libcore/str.rs
src/libgreen/message_queue.rs
src/librustc/metadata/encoder.rs
src/librustc/metadata/tydecode.rs
src/librustc/metadata/tyencode.rs
src/librustc/middle/lang_items.rs
src/librustc/middle/trans/base.rs
src/librustc/middle/trans/debuginfo.rs
src/librustc/middle/trans/foreign.rs
src/librustc/middle/trans/monomorphize.rs
src/librustc/middle/ty.rs
src/librustc/middle/typeck/collect.rs
src/librustc/util/ppaux.rs
src/librustdoc/clean/mod.rs
src/librustrt/local_data.rs
src/librustrt/unwind.rs
src/libstd/io/tempfile.rs
src/libstd/macros.rs
src/libstd/prelude.rs
src/libsync/atomic.rs
src/libsync/comm/mod.rs
src/libsync/deque.rs
src/libsync/lock.rs
src/libsync/raw.rs
src/libsyntax/ast.rs
src/libsyntax/ext/deriving/bounds.rs
src/libsyntax/ext/deriving/mod.rs
src/libunicode/normalize.rs
src/snapshots.txt
src/test/auxiliary/issue-2526.rs
src/test/auxiliary/trait_superkinds_in_metadata.rs
src/test/compile-fail/builtin-superkinds-double-superkind.rs
src/test/compile-fail/builtin-superkinds-in-metadata.rs
src/test/compile-fail/builtin-superkinds-self-type.rs
src/test/compile-fail/builtin-superkinds-typaram-not-send.rs
src/test/compile-fail/closure-bounds-subtype.rs
src/test/compile-fail/comm-not-freeze.rs
src/test/compile-fail/deriving-bounds.rs
src/test/compile-fail/generic-extern.rs
src/test/compile-fail/generic-no-mangle.rs [new file with mode: 0644]
src/test/compile-fail/issue-2611-4.rs
src/test/compile-fail/marker-no-share.rs
src/test/compile-fail/mut-not-freeze.rs
src/test/compile-fail/mutable-enum-indirect.rs
src/test/compile-fail/no_share-enum.rs
src/test/compile-fail/no_share-rc.rs
src/test/compile-fail/no_share-struct.rs
src/test/compile-fail/proc-bounds.rs
src/test/compile-fail/trait-bounds-cant-coerce.rs
src/test/compile-fail/trait-bounds-sugar.rs
src/test/compile-fail/typeck-unsafe-always-share.rs
src/test/pretty/path-type-bounds.rs
src/test/run-make/extern-fn-generic/Makefile [new file with mode: 0644]
src/test/run-make/extern-fn-generic/test.c [new file with mode: 0644]
src/test/run-make/extern-fn-generic/test.rs [new file with mode: 0644]
src/test/run-make/extern-fn-generic/testcrate.rs [new file with mode: 0644]
src/test/run-make/extern-fn-mangle/Makefile [new file with mode: 0644]
src/test/run-make/extern-fn-mangle/test.c [new file with mode: 0644]
src/test/run-make/extern-fn-mangle/test.rs [new file with mode: 0644]
src/test/run-pass/builtin-superkinds-capabilities-xc.rs
src/test/run-pass/builtin-superkinds-in-metadata.rs
src/test/run-pass/closure-syntax.rs
src/test/run-pass/const-bound.rs
src/test/run-pass/deriving-bounds.rs
src/test/run-pass/generic-extern-mangle.rs [new file with mode: 0644]
src/test/run-pass/issue-2611-3.rs
src/test/run-pass/parameterized-trait-with-bounds.rs
src/test/run-pass/proc-bounds.rs
src/test/run-pass/spawn-stack-too-big.rs [deleted file]
src/test/run-pass/trait-bounds-basic.rs
src/test/run-pass/trait-bounds-in-arc.rs

index e08e28e0aece0eecae3c97da8ca41244d511418e..636d50276ff543baf97facc4896ec0100d6d6a1e 100755 (executable)
--- a/configure
+++ b/configure
@@ -557,13 +557,21 @@ fi
 
 if [ ! -z "$CFG_ENABLE_LOCAL_RUST" ]
 then
-    if [ ! -f ${CFG_LOCAL_RUST_ROOT}/bin/rustc${BIN_SUF} ]
+    system_rustc=$(which rustc)
+    if [ -f ${CFG_LOCAL_RUST_ROOT}/bin/rustc${BIN_SUF} ]
     then
-        err "no local rust to use"
+        : # everything already configured
+    elif [ -n "$system_rustc" ]
+    then
+        # we assume that rustc is in a /bin directory
+        CFG_LOCAL_RUST_ROOT=${system_rustc%/bin/rustc}
     else
-        LRV=`${CFG_LOCAL_RUST_ROOT}/bin/rustc${BIN_SUF} --version`
-        step_msg "using rustc at: ${CFG_LOCAL_RUST_ROOT} with version: $LRV"
+        err "no local rust to use"
     fi
+
+    LRV=`${CFG_LOCAL_RUST_ROOT}/bin/rustc${BIN_SUF} --version`
+    step_msg "using rustc at: ${CFG_LOCAL_RUST_ROOT} with version: $LRV"
+    putvar CFG_LOCAL_RUST_ROOT
 fi
 
 # Force freebsd to build with clang; gcc doesn't like us there
index 447a3e25808fb0ad3693f8fe959c58e941ddb225..eb060d06cc4ff3fc33b3aee7c907b77c8804d449 100644 (file)
@@ -50,15 +50,15 @@ non-deterministic behavior. Rust provides the tools to make using a GC
 possible and even pleasant, but it should not be a requirement for
 implementing the language.
 
-## Non-`Share` `static mut` is unsafe
+## Non-`Sync` `static mut` is unsafe
 
-Types which are [`Share`][share] are thread-safe when multiple shared
-references to them are used concurrently. Types which are not `Share` are not
+Types which are [`Sync`][sync] are thread-safe when multiple shared
+references to them are used concurrently. Types which are not `Sync` are not
 thread-safe, and thus when used in a global require unsafe code to use.
 
-[share]: http://doc.rust-lang.org/core/kinds/trait.Share.html
+[sync]: http://doc.rust-lang.org/core/kinds/trait.Sync.html
 
-### If mutable static items that implement `Share` are safe, why is taking &mut SHARABLE unsafe?
+### If mutable static items that implement `Sync` are safe, why is taking &mut SHARABLE unsafe?
 
 Having multiple aliasing `&mut T`s is never allowed. Due to the nature of
 globals, the borrow checker cannot possibly ensure that a static obeys the
index dd69a5f07feac5c2135925074d0894dde4331756..8349c8ebcb6489e72d288c967186b6e9a1722cf8 100644 (file)
@@ -699,10 +699,10 @@ Other features provided by lang items include:
 - stack unwinding and general failure; the `eh_personality`, `fail_`
   and `fail_bounds_checks` lang items.
 - the traits in `std::kinds` used to indicate types that satisfy
-  various kinds; lang items `send`, `share` and `copy`.
+  various kinds; lang items `send`, `sync` and `copy`.
 - the marker types and variance indicators found in
   `std::kinds::markers`; lang items `covariant_type`,
-  `contravariant_lifetime`, `no_share_bound`, etc.
+  `contravariant_lifetime`, `no_sync_bound`, etc.
 
 Lang items are loaded lazily by the compiler; e.g. if one never uses
 `Box` then there is no need to define functions for `exchange_malloc`
index a64783b8b5e2129f3ee11644c0adb0a1ece002b4..b821f0de47b9ce88660347c2894b00f19a3cba7d 100644 (file)
@@ -3614,18 +3614,856 @@ guide](http://doc.rust-lang.org/guide-pointers.html#rc-and-arc).
 
 # Patterns
 
-# Lambdas
+# Closures
+
+So far, we've made lots of functions in Rust. But we've given them all names.
+Rust also allows us to create anonymous functions too. Rust's anonymous
+functions are called **closure**s. By themselves, closures aren't all that
+interesting, but when you combine them with functions that take closures as
+arguments, really powerful things are possible.
+
+Let's make a closure:
+
+```{rust}
+let add_one = |x| { 1i + x };
+
+println!("The 5 plus 1 is {}.", add_one(5i));
+```
+
+We create a closure using the `|...| { ... }` syntax, and then we create a
+binding so we can use it later. Note that we call the function using the
+binding name and two parentheses, just like we would for a named function.
+
+Let's compare syntax. The two are pretty close:
+
+```{rust}
+let add_one = |x: int| -> int { 1i + x };
+fn  add_one   (x: int) -> int { 1i + x }
+```
+
+As you may have noticed, closures infer their argument and return types, so you
+don't need to declare one. This is different from named functions, which
+default to returning unit (`()`).
+
+There's one big difference between a closure and named functions, and it's in
+the name: a function "closes over its environment." What's that mean? It means
+this:
+
+```{rust}
+fn main() {
+    let x = 5i;
+
+    let printer = || { println!("x is: {}", x); };
+
+    printer(); // prints "x is: 5"
+}
+```
+
+The `||` syntax means this is an anonymous closure that takes no arguments.
+Without it, we'd just have a block of code in `{}`s.
+
+In other words, a closure has access to variables in the scope that it's
+defined. The closure borrows any variables that it uses. This will error:
+
+```{rust,ignore}
+fn main() {
+    let mut x = 5i;
+
+    let printer = || { println!("x is: {}", x); };
+
+    x = 6i; // error: cannot assign to `x` because it is borrowed
+}
+```
+
+## Procs
+
+Rust has a second type of closure, called a **proc**. Procs are created
+with the `proc` keyword:
+
+```{rust}
+let x = 5i;
+
+let p = proc() { x * x };
+println!("{}", p()); // prints 25
+```
+
+Procs have a big difference from closures: they may only be called once. This
+will error when we try to compile:
+
+```{rust,ignore}
+let x = 5i;
+
+let p = proc() { x * x };
+println!("{}", p());
+println!("{}", p()); // error: use of moved value `p`
+```
+
+This restriction is important. Procs are allowed to consume values that they
+capture, and thus have to be restricted to being called once for soundness
+reasons: any value consumed would be invalid on a second call.
+
+Procs are most useful with Rust's concurrency features, and so we'll just leave
+it at this for now. We'll talk about them more in the "Tasks" section of the
+guide.
+
+## Accepting closures as arguments
+
+Closures are most useful as an argument to another function. Here's an example:
+
+```{rust}
+fn twice(x: int, f: |int| -> int) -> int {
+    f(x) + f(x)
+}
+
+fn main() {
+    let square = |x: int| { x * x };
+
+    twice(5i, square); // evaluates to 50
+}
+```
+
+Let's break example down, starting with `main`:
+
+```{rust}
+let square = |x: int| { x * x };
+```
+
+We've seen this before. We make a closure that takes an integer, and returns
+its square.
+
+```{rust,ignore}
+twice(5i, square); // evaluates to 50
+```
+
+This line is more interesting. Here, we call our function, `twice`, and we pass
+it two arguments: an integer, `5`, and our closure, `square`. This is just like
+passing any other two variable bindings to a function, but if you've never
+worked with closures before, it can seem a little complex. Just think: "I'm
+passing two variables, one is an int, and one is a function."
+
+Next, let's look at how `twice` is defined:
+
+```{rust,ignore}
+fn twice(x: int, f: |int| -> int) -> int {
+```
+
+`twice` takes two arguments, `x` and `f`. That's why we called it with two
+arguments. `x` is an `int`, we've done that a ton of times. `f` is a function,
+though, and that function takes an `int` and returns an `int`. Notice
+how the `|int| -> int` syntax looks a lot like our definition of `square`
+above, if we added the return type in:
+
+```{rust}
+let square = |x: int| -> int { x * x };
+//           |int|    -> int
+```
+
+This function takes an `int` and returns an `int`.
+
+This is the most complicated function signature we've seen yet! Give it a read
+a few times until you can see how it works. It takes a teeny bit of practice, and
+then it's easy.
+
+Finally, `twice` returns an `int` as well.
+
+Okay, let's look at the body of `twice`:
+
+```{rust}
+fn twice(x: int, f: |int| -> int) -> int {
+  f(x) + f(x)
+}
+```
+
+Since our closure is named `f`, we can call it just like we called our closures
+before. And we pass in our `x` argument to each one. Hence 'twice.'
+
+If you do the math, `(5 * 5) + (5 * 5) == 50`, so that's the output we get.
+
+Play around with this concept until you're comfortable with it. Rust's standard
+library uses lots of closures, where appropriate, so you'll be using
+this technique a lot.
+
+If we didn't want to give `square` a name, we could also just define it inline.
+This example is the same as the previous one:
+
+```{rust}
+fn twice(x: int, f: |int| -> int) -> int {
+    f(x) + f(x)
+}
+
+fn main() {
+    twice(5i, |x: int| { x * x }); // evaluates to 50
+}
+```
+
+A named function's name can be used wherever you'd use a closure. Another
+way of writing the previous example:
+
+```{rust}
+fn twice(x: int, f: |int| -> int) -> int {
+    f(x) + f(x)
+}
+
+fn square(x: int) -> int { x * x }
+
+fn main() {
+    twice(5i, square); // evaluates to 50
+}
+```
+
+Doing this is not particularly common, but every once in a while, it's useful.
+
+That's all you need to get the hang of closures! Closures are a little bit
+strange at first, but once you're used to using them, you'll miss them in any
+language that doesn't have them. Passing functions to other functions is
+incredibly powerful.  Next, let's look at one of those things: iterators.
 
 # iterators
 
 # Generics
 
+Sometimes, when writing a function or data type, we may want it to work for
+multiple types of arguments. For example, remember our `OptionalInt` type?
+
+```{rust}
+enum OptionalInt {
+    Value(int),
+    Missing,
+}
+```
+
+If we wanted to also have an `OptionalFloat64`, we would need a new enum:
+
+```{rust}
+enum OptionalFloat64 {
+    Valuef64(f64),
+    Missingf64,
+}
+```
+
+This is really unfortunate. Luckily, Rust has a feature that gives us a better
+way: generics. Generics are called **parametric polymorphism** in type theory,
+which means that they are types or functions that have multiple forms ("poly"
+is multiple, "morph" is form) over a given parameter ("parametric").
+
+Anyway, enough with type theory declarations, let's check out the generic form
+of `OptionalInt`. It is actually provided by Rust itself, and looks like this:
+
+```rust
+enum Option<T> {
+    Some(T),
+    None,
+}
+```
+
+The `<T>` part, which you've seen a few times before, indicates that this is
+a generic data type. Inside the declaration of our enum, wherever we see a `T`,
+we substitute that type for the same type used in the generic. Here's an
+example of using `Option<T>`, with some extra type annotations:
+
+```{rust}
+let x: Option<int> = Some(5i);
+```
+
+In the type declaration, we say `Option<int>`. Note how similar this looks to
+`Option<T>`. So, in this particular `Option`, `T` has the value of `int`. On
+the right hand side of the binding, we do make a `Some(T)`, where `T` is `5i`.
+Since that's an `int`, the two sides match, and Rust is happy. If they didn't
+match, we'd get an error:
+
+```{rust,ignore}
+let x: Option<f64> = Some(5i);
+// error: mismatched types: expected `core::option::Option<f64>`
+// but found `core::option::Option<int>` (expected f64 but found int)
+```
+
+That doesn't mean we can't make `Option<T>`s that hold an `f64`! They just have to
+match up:
+
+```{rust}
+let x: Option<int> = Some(5i);
+let y: Option<f64> = Some(5.0f64);
+```
+
+This is just fine. One definition, multiple uses.
+
+Generics don't have to only be generic over one type. Consider Rust's built-in
+`Result<T, E>` type:
+
+```{rust}
+enum Result<T, E> {
+    Ok(T),
+    Err(E),
+}
+```
+
+This type is generic over _two_ types: `T` and `E`. By the way, the capital letters
+can be any letter you'd like. We could define `Result<T, E>` as:
+
+```{rust}
+enum Result<H, N> {
+    Ok(H),
+    Err(N),
+}
+```
+
+if we wanted to. Convention says that the first generic parameter should be
+`T`, for 'type,' and that we use `E` for 'error.' Rust doesn't care, however.
+
+The `Result<T, E>` type is intended to
+be used to return the result of a computation, and to have the ability to
+return an error if it didn't work out. Here's an example:
+
+```{rust}
+let x: Result<f64, String> = Ok(2.3f64);
+let y: Result<f64, String> = Err("There was an error.".to_string());
+```
+
+This particular Result will return an `f64` if there's a success, and a
+`String` if there's a failure. Let's write a function that uses `Result<T, E>`:
+
+```{rust}
+fn inverse(x: f64) -> Result<f64, String> {
+    if x == 0.0f64 { return Err("x cannot be zero!".to_string()); }
+
+    Ok(1.0f64 / x)
+}
+```
+
+We don't want to take the inverse of zero, so we check to make sure that we
+weren't passed one. If we weren't, then we return an `Err`, with a message. If
+it's okay, we return an `Ok`, with the answer.
+
+Why does this matter? Well, remember how `match` does exhaustive matches?
+Here's how this function gets used:
+
+```{rust}
+# fn inverse(x: f64) -> Result<f64, String> {
+#     if x == 0.0f64 { return Err("x cannot be zero!".to_string()); }
+#     Ok(1.0f64 / x)
+# }
+let x = inverse(25.0f64);
+
+match x {
+    Ok(x) => println!("The inverse of 25 is {}", x),
+    Err(msg) => println!("Error: {}", msg),
+}
+```
+
+The `match` enforces that we handle the `Err` case. In addition, because the
+answer is wrapped up in an `Ok`, we can't just use the result without doing
+the match:
+
+```{rust,ignore}
+let x = inverse(25.0f64);
+println!("{}", x + 2.0f64); // error: binary operation `+` cannot be applied 
+           // to type `core::result::Result<f64,collections::string::String>`
+```
+
+This function is great, but there's one other problem: it only works for 64 bit
+floating point values. What if we wanted to handle 32 bit floating point as
+well? We'd have to write this:
+
+```{rust}
+fn inverse32(x: f32) -> Result<f32, String> {
+    if x == 0.0f32 { return Err("x cannot be zero!".to_string()); }
+
+    Ok(1.0f32 / x)
+}
+```
+
+Bummer. What we need is a **generic function**. Luckily, we can write one!
+However, it won't _quite_ work yet. Before we get into that, let's talk syntax.
+A generic version of `inverse` would look something like this:
+
+```{rust,ignore}
+fn inverse<T>(x: T) -> Result<T, String> {
+    if x == 0.0 { return Err("x cannot be zero!".to_string()); }
+
+    Ok(1.0 / x)
+}
+```
+
+Just like how we had `Option<T>`, we use a similar syntax for `inverse<T>`.
+We can then use `T` inside the rest of the signature: `x` has type `T`, and half
+of the `Result` has type `T`. However, if we try to compile that example, we'll get
+an error:
+
+```{notrust,ignore}
+error: binary operation `==` cannot be applied to type `T`
+```
+
+Because `T` can be _any_ type, it may be a type that doesn't implement `==`,
+and therefore, the first line would be wrong. What do we do?
+
+To fix this example, we need to learn about another Rust feature: traits.
+
 # Traits
 
-# Operators and built-in Traits
+Do you remember the `impl` keyword, used to call a function with method
+syntax?
+
+```{rust}
+struct Circle {
+    x: f64,
+    y: f64,
+    radius: f64,
+}
+
+impl Circle {
+    fn area(&self) -> f64 {
+        std::f64::consts::PI * (self.radius * self.radius)
+    }
+}
+```
+
+Traits are similar, except that we define a trait with just the method
+signature, then implement the trait for that struct. Like this:
+
+```{rust}
+struct Circle {
+    x: f64,
+    y: f64,
+    radius: f64,
+}
+
+trait HasArea {
+    fn area(&self) -> f64;
+}
+
+impl HasArea for Circle {
+    fn area(&self) -> f64 {
+        std::f64::consts::PI * (self.radius * self.radius)
+    }
+}
+```
+
+As you can see, the `trait` block looks very similar to the `impl` block,
+but we don't define a body, just a type signature. When we `impl` a trait,
+we use `impl Trait for Item`, rather than just `impl Item`.
+
+So what's the big deal? Remember the error we were getting with our generic
+`inverse` function?
+
+```{notrust,ignore}
+error: binary operation `==` cannot be applied to type `T`
+```
+
+We can use traits to constrain our generics. Consider this function, which
+does not compile, and gives us a similar error:
+
+```{rust,ignore}
+fn print_area<T>(shape: T) {
+    println!("This shape has an area of {}", shape.area());
+}
+```
+
+Rust complains:
+
+```{notrust,ignore}
+error: type `T` does not implement any method in scope named `area`
+```
+
+Because `T` can be any type, we can't be sure that it implements the `area`
+method. But we can add a **trait constraint** to our generic `T`, ensuring
+that it does:
+
+```{rust}
+# trait HasArea {
+#     fn area(&self) -> f64;
+# }
+fn print_area<T: HasArea>(shape: T) {
+    println!("This shape has an area of {}", shape.area());
+}
+```
+
+The syntax `<T: HasArea>` means `any type that implements the HasArea trait`.
+Because traits define function type signatures, we can be sure that any type
+which implements `HasArea` will have an `.area()` method.
+
+Here's an extended example of how this works:
+
+```{rust}
+trait HasArea {
+    fn area(&self) -> f64;
+}
+
+struct Circle {
+    x: f64,
+    y: f64,
+    radius: f64,
+}
+
+impl HasArea for Circle {
+    fn area(&self) -> f64 {
+        std::f64::consts::PI * (self.radius * self.radius)
+    }
+}
+
+struct Square {
+    x: f64,
+    y: f64,
+    side: f64,
+}
+
+impl HasArea for Square {
+    fn area(&self) -> f64 {
+        self.side * self.side
+    }
+}
+
+fn print_area<T: HasArea>(shape: T) {
+    println!("This shape has an area of {}", shape.area());
+}
+
+fn main() {
+    let c = Circle {
+        x: 0.0f64,
+        y: 0.0f64,
+        radius: 1.0f64,
+    };
+
+    let s = Square {
+        x: 0.0f64,
+        y: 0.0f64,
+        side: 1.0f64,
+    };
+
+    print_area(c);
+    print_area(s);
+}
+```
+
+This program outputs:
+
+```{notrust,ignore}
+This shape has an area of 3.141593
+This shape has an area of 1
+```
+
+As you can see, `print_area` is now generic, but also ensures that we
+have passed in the correct types. If we pass in an incorrect type:
+
+```{rust,ignore}
+print_area(5i);
+```
+
+We get a compile-time error:
+
+```{notrust,ignore}
+error: failed to find an implementation of trait main::HasArea for int
+```
+
+So far, we've only added trait implementations to structs, but you can
+implement a trait for any type. So technically, we _could_ implement
+`HasArea` for `int`:
+
+```{rust}
+trait HasArea {
+    fn area(&self) -> f64;
+}
+
+impl HasArea for int {
+    fn area(&self) -> f64 {
+        println!("this is silly");
+
+        *self as f64
+    }
+}
+
+5i.area();
+```
+
+It is considered poor style to implement methods on such primitive types, even
+though it is possible.
+
+This may seem like the Wild West, but there are two other restrictions around
+implementing traits that prevent this from getting out of hand. First, traits
+must be `use`d in any scope where you wish to use the trait's method. So for
+example, this does not work:
+
+```{rust,ignore}
+mod shapes {
+    use std::f64::consts;
+
+    trait HasArea {
+        fn area(&self) -> f64;
+    }
+
+    struct Circle {
+        x: f64,
+        y: f64,
+        radius: f64,
+    }
+
+    impl HasArea for Circle {
+        fn area(&self) -> f64 {
+            consts::PI * (self.radius * self.radius)
+        }
+    }
+}
+
+fn main() {
+    let c = shapes::Circle {
+        x: 0.0f64,
+        y: 0.0f64,
+        radius: 1.0f64,
+    };
+
+    println!("{}", c.area());
+}
+```
+
+Now that we've moved the structs and traits into their own module, we get an
+error:
+
+```{notrust,ignore}
+error: type `shapes::Circle` does not implement any method in scope named `area`
+```
+
+If we add a `use` line right above `main` and make the right things public,
+everything is fine:
+
+```{rust}
+use shapes::HasArea;
+
+mod shapes {
+    use std::f64::consts;
+
+    pub trait HasArea {
+        fn area(&self) -> f64;
+    }
+
+    pub struct Circle {
+        pub x: f64,
+        pub y: f64,
+        pub radius: f64,
+    }
+
+    impl HasArea for Circle {
+        fn area(&self) -> f64 {
+            consts::PI * (self.radius * self.radius)
+        }
+    }
+}
+
+
+fn main() {
+    let c = shapes::Circle {
+        x: 0.0f64,
+        y: 0.0f64,
+        radius: 1.0f64,
+    };
+
+    println!("{}", c.area());
+}
+```
+
+This means that even if someone does something bad like add methods to `int`,
+it won't affect you, unless you `use` that trait.
+
+There's one more restriction on implementing traits. Either the trait or the
+type you're writing the `impl` for must be inside your crate. So, we could
+implement the `HasArea` type for `int`, because `HasArea` is in our crate.  But
+if we tried to implement `Float`, a trait provided by Rust, for `int`, we could
+not, because both the trait and the type aren't in our crate.
+
+One last thing about traits: generic functions with a trait bound use
+**monomorphization** ("mono": one, "morph": form), so they are statically
+dispatched. What's that mean? Well, let's take a look at `print_area` again:
+
+```{rust,ignore}
+fn print_area<T: HasArea>(shape: T) {
+    println!("This shape has an area of {}", shape.area());
+}
+
+fn main() {
+    let c = Circle { ... };
+
+    let s = Square { ... };
+
+    print_area(c);
+    print_area(s);
+}
+```
+
+When we use this trait with `Circle` and `Square`, Rust ends up generating
+two different functions with the concrete type, and replacing the call sites with
+calls to the concrete implementations. In other words, you get something like
+this:
+
+```{rust,ignore}
+fn __print_area_circle(shape: Circle) {
+    println!("This shape has an area of {}", shape.area());
+}
+
+fn __print_area_square(shape: Square) {
+    println!("This shape has an area of {}", shape.area());
+}
+
+fn main() {
+    let c = Circle { ... };
+
+    let s = Square { ... };
+
+    __print_area_circle(c);
+    __print_area_square(s);
+}
+```
+
+The names don't actually change to this, it's just for illustration. But
+as you can see, there's no overhead of deciding which version to call here,
+hence 'statically dispatched.' The downside is that we have two copies of
+the same function, so our binary is a little bit larger.
 
 # Tasks
 
+Concurrency and parallelism are topics that are of increasing interest to a
+broad subsection of software developers. Modern computers are often multi-core,
+to the point that even embedded devices like cell phones have more than one
+processor. Rust's semantics lend themselves very nicely to solving a number of
+issues that programmers have with concurrency. Many concurrency errors that are
+runtime errors in other languages are compile-time errors in Rust.
+
+Rust's concurrency primitive is called a **task**. Tasks are lightweight, and
+do not share memory in an unsafe manner, preferring message passing to
+communicate.  It's worth noting that tasks are implemented as a library, and
+not part of the language.  This means that in the future, other concurrency
+libraries can be written for Rust to help in specific scenarios.  Here's an
+example of creating a task:
+
+```{rust}
+spawn(proc() {
+    println!("Hello from a task!");
+});
+```
+
+The `spawn` function takes a proc as an argument, and runs that proc in a new
+task. A proc takes ownership of its entire environment, and so any variables
+that you use inside the proc will not be usable afterward:
+
+```{rust,ignore}
+let mut x = vec![1i, 2i, 3i];
+
+spawn(proc() {
+    println!("The value of x[0] is: {}", x[0]);
+});
+
+println!("The value of x[0] is: {}", x[0]); // error: use of moved value: `x`
+```
+
+`x` is now owned by the proc, and so we can't use it anymore. Many other
+languages would let us do this, but it's not safe to do so. Rust's type system
+catches the error.
+
+If tasks were only able to capture these values, they wouldn't be very useful.
+Luckily, tasks can communicate with each other through **channel**s. Channels
+work like this:
+
+```{rust}
+let (tx, rx) = channel();
+
+spawn(proc() {
+    tx.send("Hello from a task!".to_string());
+});
+
+let message = rx.recv();
+println!("{}", message);
+```
+
+The `channel()` function returns two endpoints: a `Receiver<T>` and a
+`Sender<T>`. You can use the `.send()` method on the `Sender<T>` end, and
+receive the message on the `Receiver<T>` side with the `recv()` method.  This
+method blocks until it gets a message. There's a similar method, `.try_recv()`,
+which returns an `Option<T>` and does not block.
+
+If you want to send messages to the task as well, create two channels!
+
+```{rust}
+let (tx1, rx1) = channel();
+let (tx2, rx2) = channel();
+
+spawn(proc() {
+    tx1.send("Hello from a task!".to_string());
+    let message = rx2.recv();
+    println!("{}", message);
+});
+
+let message = rx1.recv();
+println!("{}", message);
+
+tx2.send("Goodbye from main!".to_string());
+```
+
+The proc has one sending end and one receiving end, and the main task has one
+of each as well. Now they can talk back and forth in whatever way they wish.
+
+Notice as well that because `Sender` and `Receiver` are generic, while you can
+pass any kind of information through the channel, the ends are strongly typed.
+If you try to pass a string, and then an integer, Rust will complain.
+
+## Futures
+
+With these basic primitives, many different concurrency patterns can be
+developed. Rust includes some of these types in its standard library. For
+example, if you wish to compute some value in the background, `Future` is
+a useful thing to use:
+
+```{rust}
+use std::sync::Future;
+
+let mut delayed_value = Future::spawn(proc() {
+    // just return anything for examples' sake
+
+    12345i
+});
+println!("value = {}", delayed_value.get());
+```
+
+Calling `Future::spawn` works just like `spawn()`: it takes a proc. In this
+case, though, you don't need to mess with the channel: just have the proc
+return the value.
+
+`Future::spawn` will return a value which we can bind with `let`. It needs
+to be mutable, because once the value is computed, it saves a copy of the
+value, and if it were immutable, it couldn't update itself.
+
+The proc will go on processing in the background, and when we need the final
+value, we can call `get()` on it. This will block until the result is done,
+but if it's finished computing in the background, we'll just get the value
+immediately.
+
+## Success and failure
+
+Tasks don't always succeed, they can also fail. A task that wishes to fail
+can call the `fail!` macro, passing a message:
+
+```{rust}
+spawn(proc() {
+    fail!("Nope.");
+});
+```
+
+If a task fails, it is not possible for it to recover. However, it can
+notify other tasks that it has failed. We can do this with `task::try`:
+
+```{rust}
+use std::task;
+use std::rand;
+
+let result = task::try(proc() {
+    if rand::random() {
+        println!("OK");
+    } else {
+        fail!("oops!");
+    }
+});
+```
+
+This task will randomly fail or succeed. `task::try` returns a `Result`
+type, so we can handle the response like any other computation that may
+fail.
+
 # Macros
 
 # Unsafe
index a07b8a42dc00493bde26a07d0186f9e37efb90d5..9061a623c03f024256c5af2a8fae9cf67f5b0efe 100644 (file)
@@ -2111,7 +2111,7 @@ A complete list of the built-in language items follows:
   : Has a size known at compile time.
 * `copy`
   : Types that do not move ownership when used by-value.
-* `share`
+* `sync`
   : Able to be safely shared between tasks when aliased.
 * `drop`
   : Have destructors.
@@ -2191,8 +2191,8 @@ These types help drive the compiler's analysis
   : This type does not implement "send", even if eligible
 * `no_copy_bound`
   : This type does not implement "copy", even if eligible
-* `no_share_bound`
-  : This type does not implement "share", even if eligible
+* `no_sync_bound`
+  : This type does not implement "sync", even if eligible
 * `managed_bound`
   : This type implements "managed"
 
index e4480e26cccd7d1d8c254e18b6b099cbf8d5606d..1a004e31c7d7a63e47074db782a0f85c86f835f3 100644 (file)
@@ -76,7 +76,7 @@ OS X, the install page provides links to native installers.
 > the precise details of which are not discussed here.
 
 For Linux and OS X, the install page provides links to binary tarballs.
-To install the Rust compiler from the from a binary tarball, download
+To install the Rust compiler from a binary tarball, download
 the binary package, extract it, and execute the `install.sh` script in
 the root directory of the package.
 
@@ -2196,7 +2196,7 @@ and may not be overridden:
 Types are sendable
 unless they contain references.
 
-* `Share` - Types that are *threadsafe*.
+* `Sync` - Types that are *threadsafe*.
 These are types that are safe to be used across several threads with access to
 a `&T` pointer. `Mutex<T>` is an example of a *sharable* type with internal mutable data.
 
@@ -2250,7 +2250,7 @@ We say that the `Printable` trait _provides_ a `print` method with the
 given signature.  This means that we can call `print` on an argument
 of any type that implements the `Printable` trait.
 
-Rust's built-in `Send` and `Share` types are examples of traits that
+Rust's built-in `Send` and `Sync` types are examples of traits that
 don't provide any methods.
 
 Traits may be implemented for specific types with [impls]. An impl for
@@ -2535,7 +2535,7 @@ select the method to call at runtime.
 
 This usage of traits is similar to Java interfaces.
 
-There are some built-in bounds, such as `Send` and `Share`, which are properties
+There are some built-in bounds, such as `Send` and `Sync`, which are properties
 of the components of types. By design, trait objects don't know the exact type
 of their contents and so the compiler cannot reason about those properties.
 
@@ -2548,7 +2548,7 @@ trait Foo {}
 trait Bar<T> {}
 
 fn sendable_foo(f: Box<Foo + Send>) { /* ... */ }
-fn shareable_bar<T: Share>(b: &Bar<T> + Share) { /* ... */ }
+fn sync_bar<T: Sync>(b: &Bar<T> + Sync) { /* ... */ }
 ~~~
 
 When no colon is specified (such as the type `Box<Foo>`), it is inferred that the
index 0204d42a726ffa8e2aa464ea8f8422f7dee2e0cb..d8330b84f31191585ac5fc2dfe45dcd5c158bd5e 100644 (file)
@@ -76,7 +76,7 @@ syn keyword   rustType        f64 i8 i16 i32 i64 str Self
 " to make it easy to update.
 
 " Core operators {{{3
-syn keyword   rustTrait       Copy Send Sized Share
+syn keyword   rustTrait       Copy Send Sized Sync
 syn keyword   rustTrait       Add Sub Mul Div Rem Neg Not
 syn keyword   rustTrait       BitAnd BitOr BitXor
 syn keyword   rustTrait       Drop Deref DerefMut
index 3b0ed52806008ebb7d67b522a73d866a36f3d400..1d6714430a8ed70b7c12882755cd8d69558787de 100644 (file)
@@ -15,7 +15,7 @@
 
 use core::atomic;
 use core::clone::Clone;
-use core::kinds::{Share, Send};
+use core::kinds::{Sync, Send};
 use core::mem::{min_align_of, size_of, drop};
 use core::mem;
 use core::ops::{Drop, Deref};
@@ -76,7 +76,7 @@ struct ArcInner<T> {
     data: T,
 }
 
-impl<T: Share + Send> Arc<T> {
+impl<T: Sync + Send> Arc<T> {
     /// Create an atomically reference counted wrapper.
     #[inline]
     #[stable]
@@ -95,8 +95,8 @@ pub fn new(data: T) -> Arc<T> {
     fn inner(&self) -> &ArcInner<T> {
         // This unsafety is ok because while this arc is alive we're guaranteed
         // that the inner pointer is valid. Furthermore, we know that the
-        // `ArcInner` structure itself is `Share` because the inner data is
-        // `Share` as well, so we're ok loaning out an immutable pointer to
+        // `ArcInner` structure itself is `Sync` because the inner data is
+        // `Sync` as well, so we're ok loaning out an immutable pointer to
         // these contents.
         unsafe { &*self._ptr }
     }
@@ -115,7 +115,7 @@ pub fn downgrade(&self) -> Weak<T> {
 }
 
 #[unstable = "waiting on stability of Clone"]
-impl<T: Share + Send> Clone for Arc<T> {
+impl<T: Sync + Send> Clone for Arc<T> {
     /// Duplicate an atomically reference counted wrapper.
     ///
     /// The resulting two `Arc` objects will point to the same underlying data
@@ -140,14 +140,14 @@ fn clone(&self) -> Arc<T> {
 }
 
 #[experimental = "Deref is experimental."]
-impl<T: Send + Share> Deref<T> for Arc<T> {
+impl<T: Send + Sync> Deref<T> for Arc<T> {
     #[inline]
     fn deref(&self) -> &T {
         &self.inner().data
     }
 }
 
-impl<T: Send + Share + Clone> Arc<T> {
+impl<T: Send + Sync + Clone> Arc<T> {
     /// Acquires a mutable pointer to the inner contents by guaranteeing that
     /// the reference count is one (no sharing is possible).
     ///
@@ -175,7 +175,7 @@ pub fn make_unique(&mut self) -> &mut T {
 
 #[unsafe_destructor]
 #[experimental = "waiting on stability of Drop"]
-impl<T: Share + Send> Drop for Arc<T> {
+impl<T: Sync + Send> Drop for Arc<T> {
     fn drop(&mut self) {
         // This structure has #[unsafe_no_drop_flag], so this drop glue may run
         // more than once (but it is guaranteed to be zeroed after the first if
@@ -219,7 +219,7 @@ fn drop(&mut self) {
 }
 
 #[experimental = "Weak pointers may not belong in this module."]
-impl<T: Share + Send> Weak<T> {
+impl<T: Sync + Send> Weak<T> {
     /// Attempts to upgrade this weak reference to a strong reference.
     ///
     /// This method will fail to upgrade this reference if the strong reference
@@ -245,7 +245,7 @@ fn inner(&self) -> &ArcInner<T> {
 }
 
 #[experimental = "Weak pointers may not belong in this module."]
-impl<T: Share + Send> Clone for Weak<T> {
+impl<T: Sync + Send> Clone for Weak<T> {
     #[inline]
     fn clone(&self) -> Weak<T> {
         // See comments in Arc::clone() for why this is relaxed
@@ -256,7 +256,7 @@ fn clone(&self) -> Weak<T> {
 
 #[unsafe_destructor]
 #[experimental = "Weak pointers may not belong in this module."]
-impl<T: Share + Send> Drop for Weak<T> {
+impl<T: Sync + Send> Drop for Weak<T> {
     fn drop(&mut self) {
         // see comments above for why this check is here
         if self._ptr.is_null() { return }
index 022928ce743314ce25f8b73775985844cf2cf13c..060f9875bfcf9a154cd9b91f766fc9da557f9c4d 100644 (file)
@@ -179,7 +179,7 @@ pub struct Rc<T> {
     // field accesses of the contained type via Deref
     _ptr: *mut RcBox<T>,
     _nosend: marker::NoSend,
-    _noshare: marker::NoShare
+    _noshare: marker::NoSync
 }
 
 #[stable]
@@ -199,7 +199,7 @@ pub fn new(value: T) -> Rc<T> {
                     weak: Cell::new(1)
                 }),
                 _nosend: marker::NoSend,
-                _noshare: marker::NoShare
+                _noshare: marker::NoSync
             }
         }
     }
@@ -213,7 +213,7 @@ pub fn downgrade(&self) -> Weak<T> {
         Weak {
             _ptr: self._ptr,
             _nosend: marker::NoSend,
-            _noshare: marker::NoShare
+            _noshare: marker::NoSync
         }
     }
 }
@@ -348,7 +348,7 @@ impl<T> Clone for Rc<T> {
     #[inline]
     fn clone(&self) -> Rc<T> {
         self.inc_strong();
-        Rc { _ptr: self._ptr, _nosend: marker::NoSend, _noshare: marker::NoShare }
+        Rc { _ptr: self._ptr, _nosend: marker::NoSend, _noshare: marker::NoSync }
     }
 }
 
@@ -412,7 +412,7 @@ pub struct Weak<T> {
     // field accesses of the contained type via Deref
     _ptr: *mut RcBox<T>,
     _nosend: marker::NoSend,
-    _noshare: marker::NoShare
+    _noshare: marker::NoSync
 }
 
 #[experimental = "Weak pointers may not belong in this module."]
@@ -423,7 +423,7 @@ pub fn upgrade(&self) -> Option<Rc<T>> {
             None
         } else {
             self.inc_strong();
-            Some(Rc { _ptr: self._ptr, _nosend: marker::NoSend, _noshare: marker::NoShare })
+            Some(Rc { _ptr: self._ptr, _nosend: marker::NoSend, _noshare: marker::NoSync })
         }
     }
 }
@@ -451,7 +451,7 @@ impl<T> Clone for Weak<T> {
     #[inline]
     fn clone(&self) -> Weak<T> {
         self.inc_weak();
-        Weak { _ptr: self._ptr, _nosend: marker::NoSend, _noshare: marker::NoShare }
+        Weak { _ptr: self._ptr, _nosend: marker::NoSend, _noshare: marker::NoSync }
     }
 }
 
index 5b1722b2769168d396a86de7f23a20cc3480c66d..e616824d944243e62daf7a782bc92cd388ad3fd1 100644 (file)
 
 /*!
 
-Utilities for vector manipulation
+Utilities for slice manipulation
 
-The `vec` module contains useful code to help work with vector values.
-Vectors are Rust's list type. Vectors contain zero or more values of
-homogeneous types:
+The `slice` module contains useful code to help work with slice values.
+Slices are a view into a block of memory represented as a pointer and a length.
 
 ```rust
-let int_vector = [1i, 2i, 3i];
-let str_vector = ["one", "two", "three"];
+// slicing a Vec
+let vec = vec!(1i, 2, 3);
+let int_slice = vec.as_slice();
+// coercing an array to a slice
+let str_slice: &[&str] = ["one", "two", "three"];
 ```
 
-This is a big module, but for a high-level overview:
+Slices are either mutable or shared. The shared slice type is `&[T]`,
+while the mutable slice type is `&mut[T]`. For example, you can mutate the
+block of memory that a mutable slice points to:
+
+```rust
+let x: &mut[int] = [1i, 2, 3];
+x[1] = 7;
+assert_eq!(x[0], 1);
+assert_eq!(x[1], 7);
+assert_eq!(x[2], 3);
+```
+
+Here are some of the things this module contains:
 
 ## Structs
 
-Several structs that are useful for vectors, such as `Items`, which
-represents iteration over a vector.
+There are several structs that are useful for slices, such as `Items`, which
+represents iteration over a slice.
 
 ## Traits
 
-A number of traits add methods that allow you to accomplish tasks with vectors.
-
-Traits defined for the `&[T]` type (a vector slice), have methods that can be
-called on either owned vectors, denoted `~[T]`, or on vector slices themselves.
-These traits include `ImmutableVector`, and `MutableVector` for the `&mut [T]`
-case.
+A number of traits add methods that allow you to accomplish tasks with slices.
+These traits include `ImmutableVector`, which is defined for `&[T]` types,
+and `MutableVector`, defined for `&mut [T]` types.
 
 An example is the method `.slice(a, b)` that returns an immutable "view" into
-a vector or a vector slice from the index interval `[a, b)`:
+a `Vec` or another slice from the index interval `[a, b)`:
 
 ```rust
 let numbers = [0i, 1i, 2i];
 // last_numbers is now &[1i, 2i]
 ```
 
-Traits defined for the `~[T]` type, like `OwnedVector`, can only be called
-on such vectors. These methods deal with adding elements or otherwise changing
-the allocation of the vector.
-
-An example is the method `.push(element)` that will add an element at the end
-of the vector:
-
-```rust
-let mut numbers = vec![0i, 1i, 2i];
-numbers.push(7);
-// numbers is now vec![0i, 1i, 2i, 7i];
-```
-
 ## Implementations of other traits
 
-Vectors are a very useful type, and so there's several implementations of
-traits from other modules. Some notable examples:
+There are several implementations of common traits for slices. Some examples
+include:
 
 * `Clone`
-* `Eq`, `Ord`, `Eq`, `Ord` -- vectors can be compared,
-  if the element type defines the corresponding trait.
+* `Eq`, `Ord` - for immutable slices whose element type are `Eq` or `Ord`.
+* `Hash` - for slices whose element type is `Hash`
 
 ## Iteration
 
-The method `iter()` returns an iteration value for a vector or a vector slice.
-The iterator yields references to the vector's elements, so if the element
-type of the vector is `int`, the element type of the iterator is `&int`.
+The method `iter()` returns an iteration value for a slice. The iterator
+yields references to the slice's elements, so if the element
+type of the slice is `int`, the element type of the iterator is `&int`.
 
 ```rust
 let numbers = [0i, 1i, 2i];
 ```
 
 * `.mut_iter()` returns an iterator that allows modifying each value.
-* `.move_iter()` converts an owned vector into an iterator that
-  moves out a value from the vector each iteration.
-* Further iterators exist that split, chunk or permute the vector.
-
-## Function definitions
-
-There are a number of free functions that create or take vectors, for example:
-
-* Creating a vector, like `from_elem` and `from_fn`
-* Creating a vector with a given size: `with_capacity`
-* Modifying a vector and returning it, like `append`
-* Operations on paired elements, like `unzip`.
+* Further iterators exist that split, chunk or permute the slice.
 
 */
 
index 6618906cf69dee18e8c1b7cac37a68f56ed88d8a..39fe57038b0b2f4b98fa77e2f0a476b9b3408c1b 100644 (file)
@@ -1318,7 +1318,7 @@ pub fn as_mut_ptr(&mut self) -> *mut T {
     /// Retains only the elements specified by the predicate.
     ///
     /// In other words, remove all elements `e` such that `f(&e)` returns false.
-    /// This method operates in place and preserves the order the retained elements.
+    /// This method operates in place and preserves the order of the retained elements.
     ///
     /// # Example
     ///
index becd2d3f9628cc8fc56c88c9e607b07740f72986..2a7b1630edf689a6d17df86e929cd50ad0c4e9fa 100644 (file)
 #[unstable = "likely to be renamed; otherwise stable"]
 pub struct Cell<T> {
     value: UnsafeCell<T>,
-    noshare: marker::NoShare,
+    noshare: marker::NoSync,
 }
 
 #[stable]
@@ -174,7 +174,7 @@ impl<T:Copy> Cell<T> {
     pub fn new(value: T) -> Cell<T> {
         Cell {
             value: UnsafeCell::new(value),
-            noshare: marker::NoShare,
+            noshare: marker::NoSync,
         }
     }
 
@@ -213,7 +213,7 @@ pub struct RefCell<T> {
     value: UnsafeCell<T>,
     borrow: Cell<BorrowFlag>,
     nocopy: marker::NoCopy,
-    noshare: marker::NoShare,
+    noshare: marker::NoSync,
 }
 
 // Values [1, MAX-1] represent the number of `Ref` active
@@ -230,7 +230,7 @@ pub fn new(value: T) -> RefCell<T> {
             value: UnsafeCell::new(value),
             borrow: Cell::new(UNUSED),
             nocopy: marker::NoCopy,
-            noshare: marker::NoShare,
+            noshare: marker::NoSync,
         }
     }
 
@@ -430,7 +430,7 @@ fn deref_mut<'a>(&'a mut self) -> &'a mut T {
 ///
 /// struct NotThreadSafe<T> {
 ///     value: UnsafeCell<T>,
-///     marker: marker::NoShare
+///     marker: marker::NoSync
 /// }
 /// ```
 ///
index 71144095f478bb02a89cc3b3306abcea9dc2b89d..63ffc4a046f68af72e17e1afac4a559042c73d34 100644 (file)
@@ -19,9 +19,6 @@
 use option::{None, Option, Some};
 use iter::range_step;
 
-#[cfg(stage0)]
-use iter::Iterator; // NOTE(stage0): Remove after snapshot.
-
 // UTF-8 ranges and tags for encoding characters
 static TAG_CONT: u8    = 0b1000_0000u8;
 static TAG_TWO_B: u8   = 0b1100_0000u8;
index f5cfa2611d5e66ef260a07d4be8a7aca05714bc4..e764ae17500b6898792ba94c78316046b9768d34 100644 (file)
 use fmt;
 use intrinsics;
 
-#[cfg(stage0)]
-#[cold] #[inline(never)] // this is the slow path, always
-#[lang="fail_"]
-fn fail_(expr: &'static str, file: &'static str, line: uint) -> ! {
-    format_args!(|args| -> () {
-        begin_unwind(args, &(file, line));
-    }, "{}", expr);
-
-    unsafe { intrinsics::abort() }
-}
-
-#[cfg(stage0)]
-#[cold]
-#[lang="fail_bounds_check"]
-fn fail_bounds_check(file: &'static str, line: uint,
-                     index: uint, len: uint) -> ! {
-    format_args!(|args| -> () {
-        begin_unwind(args, &(file, line));
-    }, "index out of bounds: the len is {} but the index is {}", len, index);
-    unsafe { intrinsics::abort() }
-}
-
-#[cfg(not(stage0))]
 #[cold] #[inline(never)] // this is the slow path, always
 #[lang="fail_"]
 fn fail_(expr_file_line: &(&'static str, &'static str, uint)) -> ! {
@@ -68,7 +45,6 @@ fn fail_(expr_file_line: &(&'static str, &'static str, uint)) -> ! {
     unsafe { intrinsics::abort() }
 }
 
-#[cfg(not(stage0))]
 #[cold] #[inline(never)]
 #[lang="fail_bounds_check"]
 fn fail_bounds_check(file_line: &(&'static str, uint),
index 88702e59e30d165833278b3a5851930aa6f2e0ec..1bfa5168cf7960adf8d63eb15cc975509129ec1c 100644 (file)
 use slice;
 use str::StrSlice;
 
-#[cfg(stage0)]
-use iter::Iterator;         // NOTE(stage0): Remove after snapshot.
-#[cfg(stage0)]
-use option::{Some, None};   // NOTE(stage0): Remove after snapshot.
-
 /// A flag that specifies whether to use exponential (scientific) notation.
 pub enum ExponentFormat {
     /// Do not use exponential notation.
index 99920dc7881901cc2a0eb7324b544337ef235f98..bba3e4cb9afccdef116e3419940e091cea6d4c34 100644 (file)
 use num::{Int, cast, zero};
 use slice::{ImmutableVector, MutableVector};
 
-#[cfg(stage0)]
-use iter::Iterator;         // NOTE(stage0): Remove after snapshot.
-#[cfg(stage0)]
-use option::{Some, None};   // NOTE(stage0): Remove after snapshot.
-
 /// A type that represents a specific radix
 #[doc(hidden)]
 trait GenericRadix {
index 958a2ba02f61656f9f41f01313e4dd2ff9e95907..2a6bf28cfc4b63fde6a331304c3dbc57d393c631 100644 (file)
@@ -20,6 +20,9 @@
 
 */
 
+#[deprecated = "This has been renamed to Sync"]
+pub use Share = self::Sync;
+
 /// Types able to be transferred across task boundaries.
 #[lang="send"]
 pub trait Send {
@@ -40,32 +43,32 @@ pub trait Copy {
 
 /// Types that can be safely shared between tasks when aliased.
 ///
-/// The precise definition is: a type `T` is `Share` if `&T` is
+/// The precise definition is: a type `T` is `Sync` if `&T` is
 /// thread-safe. In other words, there is no possibility of data races
 /// when passing `&T` references between tasks.
 ///
 /// As one would expect, primitive types like `u8` and `f64` are all
-/// `Share`, and so are simple aggregate types containing them (like
-/// tuples, structs and enums). More instances of basic `Share` types
+/// `Sync`, and so are simple aggregate types containing them (like
+/// tuples, structs and enums). More instances of basic `Sync` types
 /// include "immutable" types like `&T` and those with simple
 /// inherited mutability, such as `Box<T>`, `Vec<T>` and most other
-/// collection types. (Generic parameters need to be `Share` for their
-/// container to be `Share`.)
+/// collection types. (Generic parameters need to be `Sync` for their
+/// container to be `Sync`.)
 ///
 /// A somewhat surprising consequence of the definition is `&mut T` is
-/// `Share` (if `T` is `Share`) even though it seems that it might
+/// `Sync` (if `T` is `Sync`) even though it seems that it might
 /// provide unsynchronised mutation. The trick is a mutable reference
 /// stored in an aliasable reference (that is, `& &mut T`) becomes
 /// read-only, as if it were a `& &T`, hence there is no risk of a data
 /// race.
 ///
-/// Types that are not `Share` are those that have "interior
+/// Types that are not `Sync` are those that have "interior
 /// mutability" in a non-thread-safe way, such as `Cell` and `RefCell`
 /// in `std::cell`. These types allow for mutation of their contents
 /// even when in an immutable, aliasable slot, e.g. the contents of
 /// `&Cell<T>` can be `.set`, and do not ensure data races are
-/// impossible, hence they cannot be `Share`. A higher level example
-/// of a non-`Share` type is the reference counted pointer
+/// impossible, hence they cannot be `Sync`. A higher level example
+/// of a non-`Sync` type is the reference counted pointer
 /// `std::rc::Rc`, because any reference `&Rc<T>` can clone a new
 /// reference, which modifies the reference counts in a non-atomic
 /// way.
@@ -73,18 +76,25 @@ pub trait Copy {
 /// For cases when one does need thread-safe interior mutability,
 /// types like the atomics in `std::sync` and `Mutex` & `RWLock` in
 /// the `sync` crate do ensure that any mutation cannot cause data
-/// races.  Hence these types are `Share`.
+/// races.  Hence these types are `Sync`.
 ///
 /// Users writing their own types with interior mutability (or anything
-/// else that is not thread-safe) should use the `NoShare` marker type
+/// else that is not thread-safe) should use the `NoSync` marker type
 /// (from `std::kinds::marker`) to ensure that the compiler doesn't
-/// consider the user-defined type to be `Share`.  Any types with
+/// consider the user-defined type to be `Sync`.  Any types with
 /// interior mutability must also use the `std::cell::UnsafeCell` wrapper
 /// around the value(s) which can be mutated when behind a `&`
 /// reference; not doing this is undefined behaviour (for example,
 /// `transmute`-ing from `&T` to `&mut T` is illegal).
+#[lang="sync"]
+#[cfg(not(stage0))]
+pub trait Sync {
+    // Empty
+}
+/// dox
 #[lang="share"]
-pub trait Share {
+#[cfg(stage0)]
+pub trait Sync {
     // Empty
 }
 
@@ -94,7 +104,6 @@ pub trait Share {
 /// implemented using unsafe code. In that case, you may want to embed
 /// some of the marker types below into your type.
 pub mod marker {
-
     /// A marker type whose type parameter `T` is considered to be
     /// covariant with respect to the type itself. This is (typically)
     /// used to indicate that an instance of the type `T` is being stored
@@ -266,12 +275,12 @@ pub mod marker {
     #[deriving(PartialEq,Clone)]
     pub struct NoCopy;
 
-    /// A type which is considered "not shareable", meaning that
+    /// A type which is considered "not sync", meaning that
     /// its contents are not threadsafe, hence they cannot be
     /// shared between tasks.
     #[lang="no_share_bound"]
     #[deriving(PartialEq,Clone)]
-    pub struct NoShare;
+    pub struct NoSync;
 
     /// A type which is considered managed by the GC. This is typically
     /// embedded in other types.
index 839243970ac673ed40080d84c55212b76aa3b50d..23577dd29e0af0c75ee24a463e9ae5ba16e458e2 100644 (file)
@@ -771,7 +771,6 @@ pub trait FnOnce<Args,Result> {
 
 macro_rules! def_fn_mut(
     ($($args:ident)*) => (
-        #[cfg(not(stage0))]
         impl<Result$(,$args)*>
         FnMut<($($args,)*),Result>
         for extern "Rust" fn($($args: $args,)*) -> Result {
index d27689eeaf4176d445441c861450e667b175ce30..5b7c7c8f31a6f2a80a4615801c93f20ac658bdf5 100644 (file)
@@ -29,7 +29,7 @@
 //! ```
 
 // Reexported core operators
-pub use kinds::{Copy, Send, Sized, Share};
+pub use kinds::{Copy, Send, Sized, Sync};
 pub use ops::{Add, Sub, Mul, Div, Rem, Neg, Not};
 pub use ops::{BitAnd, BitOr, BitXor};
 pub use ops::{Drop, Deref, DerefMut};
index 4921802ba732eea4022f0ff63e42cbfd7d4f6800..eb9bede85d8b25cc95d8b1534c64aab526c7b2fa 100644 (file)
@@ -95,9 +95,6 @@
 
 use cmp::{PartialEq, Eq, PartialOrd, Equiv, Ordering, Less, Equal, Greater};
 
-#[cfg(stage0)]
-use iter::Iterator; // NOTE(stage0): Remove after snapshot.
-
 pub use intrinsics::copy_memory;
 pub use intrinsics::copy_nonoverlapping_memory;
 pub use intrinsics::set_memory;
index 5eb463687904c41b34119f3b0b85ca5daeba3324..c1166a7621e193e6515c1745248d0f67c5125737 100644 (file)
@@ -1030,9 +1030,6 @@ pub mod traits {
     use option::{Option, Some};
     use str::{Str, StrSlice, eq_slice};
 
-    #[cfg(stage0)]
-    use option::None;   // NOTE(stage0): Remove after snapshot.
-
     impl<'a> Ord for &'a str {
         #[inline]
         fn cmp(&self, other: & &'a str) -> Ordering {
index 137c493364520e3f3440df88c905c26c105a0895..66040633ff1929a7fe5340cc7a39730d872108c8 100644 (file)
@@ -20,18 +20,18 @@ pub enum PopResult<T> {
 
 pub fn queue<T: Send>() -> (Consumer<T>, Producer<T>) {
     let a = Arc::new(mpsc::Queue::new());
-    (Consumer { inner: a.clone(), noshare: marker::NoShare },
-     Producer { inner: a, noshare: marker::NoShare })
+    (Consumer { inner: a.clone(), noshare: marker::NoSync },
+     Producer { inner: a, noshare: marker::NoSync })
 }
 
 pub struct Producer<T> {
     inner: Arc<mpsc::Queue<T>>,
-    noshare: marker::NoShare,
+    noshare: marker::NoSync,
 }
 
 pub struct Consumer<T> {
     inner: Arc<mpsc::Queue<T>>,
-    noshare: marker::NoShare,
+    noshare: marker::NoSync,
 }
 
 impl<T: Send> Consumer<T> {
@@ -60,6 +60,6 @@ pub fn push(&self, t: T) {
 
 impl<T: Send> Clone for Producer<T> {
     fn clone(&self) -> Producer<T> {
-        Producer { inner: self.inner.clone(), noshare: marker::NoShare }
+        Producer { inner: self.inner.clone(), noshare: marker::NoSync }
     }
 }
index 6ede414e83758b5f7b801716619e7e46c4df739e..9b31d3a1b6460f7fe55a7266268568f0479dfee2 100644 (file)
@@ -1755,7 +1755,8 @@ fn encode_reachable_extern_fns(ecx: &EncodeContext, rbml_w: &mut Encoder) {
         match ecx.tcx.map.find(*id) {
             Some(ast_map::NodeItem(i)) => {
                 match i.node {
-                    ast::ItemFn(_, _, abi, _, _) if abi != abi::Rust => {
+                    ast::ItemFn(_, _, abi, ref generics, _)
+                                if abi != abi::Rust && !generics.is_type_parameterized() => {
                         rbml_w.wr_tagged_u32(tag_reachable_extern_fn_id, *id);
                     }
                     _ => {}
index ffa0cca753904b9911c614781ec931717eb1257e..fed23185c5d27388fcd58f7723c85f6d60086655 100644 (file)
@@ -633,7 +633,7 @@ fn parse_bounds(st: &mut PState, conv: conv_did) -> ty::ParamBounds {
                 param_bounds.builtin_bounds.add(ty::BoundCopy);
             }
             'T' => {
-                param_bounds.builtin_bounds.add(ty::BoundShare);
+                param_bounds.builtin_bounds.add(ty::BoundSync);
             }
             'I' => {
                 param_bounds.trait_bounds.push(Rc::new(parse_trait_ref(st, |x,y| conv(x,y))));
index f16a46ed72933e6ef8bf8b6373571618f678c57e..ba865c7ab04d01e5e9a019f250c1f568e2eba2e2 100644 (file)
@@ -352,7 +352,7 @@ fn enc_bounds(w: &mut SeekableMemWriter, cx: &ctxt, bs: &ty::ParamBounds) {
             ty::BoundStatic => mywrite!(w, "O"),
             ty::BoundSized => mywrite!(w, "Z"),
             ty::BoundCopy => mywrite!(w, "P"),
-            ty::BoundShare => mywrite!(w, "T"),
+            ty::BoundSync => mywrite!(w, "T"),
         }
     }
 
index f59909bd138b25b1274d5dd8709c5d73bba03c38..223e518fecdf7882ac8b7cbacc72dc2e2af58c7d 100644 (file)
@@ -13,7 +13,7 @@
 // Language items are items that represent concepts intrinsic to the language
 // itself. Examples are:
 //
-// * Traits that specify "kinds"; e.g. "Share", "Send".
+// * Traits that specify "kinds"; e.g. "Sync", "Send".
 //
 // * Traits that represent operators; e.g. "Add", "Sub", "Index".
 //
@@ -92,8 +92,8 @@ pub fn to_builtin_kind(&self, id: ast::DefId) -> Option<ty::BuiltinBound> {
             Some(ty::BoundSized)
         } else if Some(id) == self.copy_trait() {
             Some(ty::BoundCopy)
-        } else if Some(id) == self.share_trait() {
-            Some(ty::BoundShare)
+        } else if Some(id) == self.sync_trait() {
+            Some(ty::BoundSync)
         } else {
             None
         }
@@ -218,7 +218,7 @@ pub fn collect_language_items(krate: &ast::Crate,
     SendTraitLangItem,               "send",                    send_trait;
     SizedTraitLangItem,              "sized",                   sized_trait;
     CopyTraitLangItem,               "copy",                    copy_trait;
-    ShareTraitLangItem,              "share",                   share_trait;
+    SyncTraitLangItem,               "sync",                    sync_trait;
 
     DropTraitLangItem,               "drop",                    drop_trait;
 
@@ -296,7 +296,7 @@ pub fn collect_language_items(krate: &ast::Crate,
 
     NoSendItem,                      "no_send_bound",           no_send_bound;
     NoCopyItem,                      "no_copy_bound",           no_copy_bound;
-    NoShareItem,                     "no_share_bound",          no_share_bound;
+    NoSyncItem,                     "no_share_bound",          no_share_bound;
     ManagedItem,                     "managed_bound",           managed_bound;
 
     IteratorItem,                    "iterator",                iterator;
index e35f60d0c3ca8f021e2601469cf63a20d4f23250..7237ebeb151ae0170bec7769b1fa98a99aeb0c52 100644 (file)
@@ -171,7 +171,7 @@ fn drop(&mut self) {
 }
 
 // only use this for foreign function ABIs and glue, use `decl_rust_fn` for Rust functions
-fn decl_fn(ccx: &CrateContext, name: &str, cc: llvm::CallConv,
+pub fn decl_fn(ccx: &CrateContext, name: &str, cc: llvm::CallConv,
            ty: Type, output: ty::t) -> ValueRef {
 
     let llfn: ValueRef = name.with_c_str(|buf| {
@@ -1922,20 +1922,27 @@ pub fn trans_item(ccx: &CrateContext, item: &ast::Item) {
     let _icx = push_ctxt("trans_item");
     match item.node {
       ast::ItemFn(ref decl, _fn_style, abi, ref generics, ref body) => {
-        if abi != Rust {
-            let llfndecl = get_item_val(ccx, item.id);
-            foreign::trans_rust_fn_with_foreign_abi(
-                ccx, &**decl, &**body, item.attrs.as_slice(), llfndecl, item.id);
-        } else if !generics.is_type_parameterized() {
+        if !generics.is_type_parameterized() {
             let llfn = get_item_val(ccx, item.id);
-            trans_fn(ccx,
-                     &**decl,
-                     &**body,
-                     llfn,
-                     &param_substs::empty(),
-                     item.id,
-                     item.attrs.as_slice(),
-                     TranslateItems);
+            if abi != Rust {
+                foreign::trans_rust_fn_with_foreign_abi(ccx,
+                                                        &**decl,
+                                                        &**body,
+                                                        item.attrs.as_slice(),
+                                                        llfn,
+                                                        &param_substs::empty(),
+                                                        item.id,
+                                                        None);
+            } else {
+                trans_fn(ccx,
+                         &**decl,
+                         &**body,
+                         llfn,
+                         &param_substs::empty(),
+                         item.id,
+                         item.attrs.as_slice(),
+                         TranslateItems);
+            }
         } else {
             // Be sure to travel more than just one layer deep to catch nested
             // items in blocks and such.
index 6b3964115293032a3e78907c2dc3101c2e066059..c27b0bb8cb1ebeac5eb625248a57800331d4bcfb 100644 (file)
@@ -499,7 +499,7 @@ fn get_unique_type_id_of_type(&mut self, cx: &CrateContext, type_: ty::t) -> Uni
                         ty::BoundSend => unique_type_id.push_str("Send"),
                         ty::BoundSized => unique_type_id.push_str("Sized"),
                         ty::BoundCopy => unique_type_id.push_str("Copy"),
-                        ty::BoundShare => unique_type_id.push_str("Share"),
+                        ty::BoundSync => unique_type_id.push_str("Sync"),
                     };
                     unique_type_id.push_char('+');
                 }
index cb46d62fca9e9f56b81fdff0e432981f16ab4cf0..93e357205484882469235feb5616aa8391fb20e5 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -24,6 +24,7 @@
 use middle::trans::type_of;
 use middle::ty::FnSig;
 use middle::ty;
+use middle::subst::Subst;
 use std::cmp;
 use libc::c_uint;
 use syntax::abi::{Cdecl, Aapcs, C, Win64, Abi};
@@ -525,6 +526,26 @@ pub fn trans_foreign_mod(ccx: &CrateContext, foreign_mod: &ast::ForeignMod) {
 // inline the one into the other. Of course we could just generate the
 // correct code in the first place, but this is much simpler.
 
+pub fn decl_rust_fn_with_foreign_abi(ccx: &CrateContext,
+                                     t: ty::t,
+                                     name: &str)
+                                     -> ValueRef {
+    let tys = foreign_types_for_fn_ty(ccx, t);
+    let llfn_ty = lltype_for_fn_from_foreign_types(ccx, &tys);
+    let cconv = match ty::get(t).sty {
+        ty::ty_bare_fn(ref fn_ty) => {
+            let c = llvm_calling_convention(ccx, fn_ty.abi);
+            c.unwrap_or(llvm::CCallConv)
+        }
+        _ => fail!("expected bare fn in decl_rust_fn_with_foreign_abi")
+    };
+    let llfn = base::decl_fn(ccx, name, cconv, llfn_ty, ty::mk_nil());
+    add_argument_attributes(&tys, llfn);
+    debug!("decl_rust_fn_with_foreign_abi(llfn_ty={}, llfn={})",
+           ccx.tn.type_to_string(llfn_ty), ccx.tn.val_to_string(llfn));
+    llfn
+}
+
 pub fn register_rust_fn_with_foreign_abi(ccx: &CrateContext,
                                          sp: Span,
                                          sym: String,
@@ -554,31 +575,39 @@ pub fn trans_rust_fn_with_foreign_abi(ccx: &CrateContext,
                                       body: &ast::Block,
                                       attrs: &[ast::Attribute],
                                       llwrapfn: ValueRef,
-                                      id: ast::NodeId) {
+                                      param_substs: &param_substs,
+                                      id: ast::NodeId,
+                                      hash: Option<&str>) {
     let _icx = push_ctxt("foreign::build_foreign_fn");
-    let tys = foreign_types_for_id(ccx, id);
+
+    let fnty = ty::node_id_to_type(ccx.tcx(), id);
+    let mty = fnty.subst(ccx.tcx(), &param_substs.substs);
+    let tys = foreign_types_for_fn_ty(ccx, mty);
 
     unsafe { // unsafe because we call LLVM operations
         // Build up the Rust function (`foo0` above).
-        let llrustfn = build_rust_fn(ccx, decl, body, attrs, id);
+        let llrustfn = build_rust_fn(ccx, decl, body, param_substs, attrs, id, hash);
 
         // Build up the foreign wrapper (`foo` above).
-        return build_wrap_fn(ccx, llrustfn, llwrapfn, &tys, id);
+        return build_wrap_fn(ccx, llrustfn, llwrapfn, &tys, mty);
     }
 
     fn build_rust_fn(ccx: &CrateContext,
                      decl: &ast::FnDecl,
                      body: &ast::Block,
+                     param_substs: &param_substs,
                      attrs: &[ast::Attribute],
-                     id: ast::NodeId)
+                     id: ast::NodeId,
+                     hash: Option<&str>)
                      -> ValueRef {
         let _icx = push_ctxt("foreign::foreign::build_rust_fn");
         let tcx = ccx.tcx();
-        let t = ty::node_id_to_type(tcx, id);
+        let t = ty::node_id_to_type(tcx, id).subst(
+            ccx.tcx(), &param_substs.substs);
 
         let ps = ccx.tcx.map.with_path(id, |path| {
             let abi = Some(ast_map::PathName(special_idents::clownshoe_abi.name));
-            link::mangle(path.chain(abi.move_iter()), None)
+            link::mangle(path.chain(abi.move_iter()), hash)
         });
 
         // Compute the type that the function would have if it were just a
@@ -601,8 +630,7 @@ fn build_rust_fn(ccx: &CrateContext,
 
         let llfn = base::decl_internal_rust_fn(ccx, t, ps.as_slice());
         base::set_llvm_fn_attrs(attrs, llfn);
-        base::trans_fn(ccx, decl, body, llfn, &param_substs::empty(), id, [],
-                       TranslateItems);
+        base::trans_fn(ccx, decl, body, llfn, param_substs, id, [], TranslateItems);
         llfn
     }
 
@@ -610,13 +638,11 @@ unsafe fn build_wrap_fn(ccx: &CrateContext,
                             llrustfn: ValueRef,
                             llwrapfn: ValueRef,
                             tys: &ForeignTypes,
-                            id: ast::NodeId) {
+                            t: ty::t) {
         let _icx = push_ctxt(
             "foreign::trans_rust_fn_with_foreign_abi::build_wrap_fn");
         let tcx = ccx.tcx();
 
-        let t = ty::node_id_to_type(tcx, id);
-
         debug!("build_wrap_fn(llrustfn={}, llwrapfn={}, t={})",
                ccx.tn.val_to_string(llrustfn),
                ccx.tn.val_to_string(llwrapfn),
index 986d3328f2c3a7a97f8ab94660909cfd54cb9530..97f0f1beeace6d2b0076ad10e08bf8af32a08211 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -18,6 +18,7 @@
 use middle::trans::base::{trans_fn, decl_internal_rust_fn};
 use middle::trans::base;
 use middle::trans::common::*;
+use middle::trans::foreign;
 use middle::ty;
 use middle::typeck;
 use util::ppaux::Repr;
@@ -123,19 +124,29 @@ pub fn monomorphic_fn(ccx: &CrateContext,
         monomorphizing.insert(fn_id, depth + 1);
     }
 
-    let s = ccx.tcx.map.with_path(fn_id.node, |path| {
+    let hash;
+    let s = {
         let mut state = sip::SipState::new();
         hash_id.hash(&mut state);
         mono_ty.hash(&mut state);
 
-        exported_name(path, format!("h{}", state.result()).as_slice())
-    });
+        hash = format!("h{}", state.result());
+        ccx.tcx.map.with_path(fn_id.node, |path| {
+            exported_name(path, hash.as_slice())
+        })
+    };
+
     debug!("monomorphize_fn mangled to {}", s);
 
     // This shouldn't need to option dance.
     let mut hash_id = Some(hash_id);
-    let mk_lldecl = || {
-        let lldecl = decl_internal_rust_fn(ccx, mono_ty, s.as_slice());
+    let mk_lldecl = |abi: abi::Abi| {
+        let lldecl = if abi != abi::Rust {
+            foreign::decl_rust_fn_with_foreign_abi(ccx, mono_ty, s.as_slice())
+        } else {
+            decl_internal_rust_fn(ccx, mono_ty, s.as_slice())
+        };
+
         ccx.monomorphized.borrow_mut().insert(hash_id.take_unwrap(), lldecl);
         lldecl
     };
@@ -144,13 +155,21 @@ pub fn monomorphic_fn(ccx: &CrateContext,
         ast_map::NodeItem(i) => {
             match *i {
               ast::Item {
-                  node: ast::ItemFn(ref decl, _, _, _, ref body),
+                  node: ast::ItemFn(ref decl, _, abi, _, ref body),
                   ..
               } => {
-                  let d = mk_lldecl();
+                  let d = mk_lldecl(abi);
                   set_llvm_fn_attrs(i.attrs.as_slice(), d);
-                  trans_fn(ccx, &**decl, &**body, d, &psubsts, fn_id.node, [],
-                           IgnoreItems);
+
+                  if abi != abi::Rust {
+                      foreign::trans_rust_fn_with_foreign_abi(
+                          ccx, &**decl, &**body, [], d, &psubsts, fn_id.node,
+                          Some(hash.as_slice()));
+                  } else {
+                      trans_fn(ccx, &**decl, &**body, d, &psubsts, fn_id.node, [],
+                               IgnoreItems);
+                  }
+
                   d
               }
               _ => {
@@ -162,7 +181,7 @@ pub fn monomorphic_fn(ccx: &CrateContext,
             let parent = ccx.tcx.map.get_parent(fn_id.node);
             let tvs = ty::enum_variants(ccx.tcx(), local_def(parent));
             let this_tv = tvs.iter().find(|tv| { tv.id.node == fn_id.node}).unwrap();
-            let d = mk_lldecl();
+            let d = mk_lldecl(abi::Rust);
             set_inline_hint(d);
             match v.node.kind {
                 ast::TupleVariantKind(ref args) => {
@@ -180,7 +199,7 @@ pub fn monomorphic_fn(ccx: &CrateContext,
             d
         }
         ast_map::NodeMethod(mth) => {
-            let d = mk_lldecl();
+            let d = mk_lldecl(abi::Rust);
             set_llvm_fn_attrs(mth.attrs.as_slice(), d);
             trans_fn(ccx, &*mth.pe_fn_decl(), &*mth.pe_body(), d, &psubsts, mth.id, [],
                      IgnoreItems);
@@ -189,7 +208,7 @@ pub fn monomorphic_fn(ccx: &CrateContext,
         ast_map::NodeTraitMethod(method) => {
             match *method {
                 ast::Provided(mth) => {
-                    let d = mk_lldecl();
+                    let d = mk_lldecl(abi::Rust);
                     set_llvm_fn_attrs(mth.attrs.as_slice(), d);
                     trans_fn(ccx, &*mth.pe_fn_decl(), &*mth.pe_body(), d,
                              &psubsts, mth.id, [], IgnoreItems);
@@ -202,7 +221,7 @@ pub fn monomorphic_fn(ccx: &CrateContext,
             }
         }
         ast_map::NodeStructCtor(struct_def) => {
-            let d = mk_lldecl();
+            let d = mk_lldecl(abi::Rust);
             set_inline_hint(d);
             base::trans_tuple_struct(ccx,
                                      struct_def.fields.as_slice(),
@@ -230,7 +249,7 @@ pub fn monomorphic_fn(ccx: &CrateContext,
     ccx.monomorphizing.borrow_mut().insert(fn_id, depth);
 
     debug!("leaving monomorphic fn {}", ty::item_path_str(ccx.tcx(), fn_id));
-    (lldecl, false)
+    (lldecl, true)
 }
 
 // Used to identify cached monomorphized functions and vtables
index ce8f37514a4cdd80e7847c62b724150e402640d2..0cc5486013aac8f152e1e3dcc0aaf92d2290c0b3 100644 (file)
@@ -833,7 +833,7 @@ pub enum BuiltinBound {
     BoundSend,
     BoundSized,
     BoundCopy,
-    BoundShare,
+    BoundSync,
 }
 
 pub fn empty_builtin_bounds() -> BuiltinBounds {
@@ -845,7 +845,7 @@ pub fn all_builtin_bounds() -> BuiltinBounds {
     set.add(BoundStatic);
     set.add(BoundSend);
     set.add(BoundSized);
-    set.add(BoundShare);
+    set.add(BoundSync);
     set
 }
 
@@ -1804,7 +1804,7 @@ mod TC {
         ReachesBorrowed                     = 0b0000_0010__0000_0000__0000,
         // ReachesManaged /* see [1] below */  = 0b0000_0100__0000_0000__0000,
         ReachesMutable                      = 0b0000_1000__0000_0000__0000,
-        ReachesNoShare                      = 0b0001_0000__0000_0000__0000,
+        ReachesNoSync                       = 0b0001_0000__0000_0000__0000,
         ReachesAll                          = 0b0001_1111__0000_0000__0000,
 
         // Things that cause values to *move* rather than *copy*
@@ -1828,8 +1828,8 @@ mod TC {
         // Things that prevent values from being considered sized
         Nonsized                            = 0b0000_0000__0000_0000__0001,
 
-        // Things that prevent values from being shared
-        Nonsharable                         = 0b0001_0000__0000_0000__0000,
+        // Things that prevent values from being sync
+        Nonsync                             = 0b0001_0000__0000_0000__0000,
 
         // Things that make values considered not POD (would be same
         // as `Moves`, but for the fact that managed data `@` is
@@ -1855,7 +1855,7 @@ pub fn meets_bound(&self, cx: &ctxt, bb: BuiltinBound) -> bool {
             BoundSend => self.is_sendable(cx),
             BoundSized => self.is_sized(cx),
             BoundCopy => self.is_copy(cx),
-            BoundShare => self.is_sharable(cx),
+            BoundSync => self.is_sync(cx),
         }
     }
 
@@ -1875,8 +1875,8 @@ pub fn is_sendable(&self, _: &ctxt) -> bool {
         !self.intersects(TC::Nonsendable)
     }
 
-    pub fn is_sharable(&self, _: &ctxt) -> bool {
-        !self.intersects(TC::Nonsharable)
+    pub fn is_sync(&self, _: &ctxt) -> bool {
+        !self.intersects(TC::Nonsync)
     }
 
     pub fn owns_managed(&self) -> bool {
@@ -2169,11 +2169,11 @@ fn apply_lang_items(cx: &ctxt,
         } else if Some(did) == cx.lang_items.no_copy_bound() {
             tc | TC::OwnsAffine
         } else if Some(did) == cx.lang_items.no_share_bound() {
-            tc | TC::ReachesNoShare
+            tc | TC::ReachesNoSync
         } else if Some(did) == cx.lang_items.unsafe_type() {
             // FIXME(#13231): This shouldn't be needed after
             // opt-in built-in bounds are implemented.
-            (tc | TC::InteriorUnsafe) - TC::Nonsharable
+            (tc | TC::InteriorUnsafe) - TC::Nonsync
         } else {
             tc
         }
@@ -2237,7 +2237,7 @@ fn kind_bounds_to_contents(cx: &ctxt,
                 BoundSend => TC::Nonsendable,
                 BoundSized => TC::Nonsized,
                 BoundCopy => TC::Noncopy,
-                BoundShare => TC::Nonsharable,
+                BoundSync => TC::Nonsync,
             };
         });
         return tc;
index fb0a9e32df916e7f2f1aed9d13d2446e67251ca5..a81c6344cc9c6014002af35656940c1511cbd1d6 100644 (file)
@@ -444,17 +444,6 @@ pub fn ensure_no_ty_param_bounds(ccx: &CrateCtxt,
     }
 }
 
-fn ensure_generics_abi(ccx: &CrateCtxt,
-                       span: Span,
-                       abi: abi::Abi,
-                       generics: &ast::Generics) {
-    if generics.ty_params.len() > 0 &&
-       !(abi == abi::Rust || abi == abi::RustIntrinsic) {
-        span_err!(ccx.tcx.sess, span, E0123,
-                  "foreign functions may not use type parameters");
-    }
-}
-
 pub fn convert(ccx: &CrateCtxt, it: &ast::Item) {
     let tcx = ccx.tcx;
     debug!("convert: item {} with id {}", token::get_ident(it.ident), it.id);
@@ -572,13 +561,8 @@ pub fn convert(ccx: &CrateCtxt, it: &ast::Item) {
         },
         ast::ItemTy(_, ref generics) => {
             ensure_no_ty_param_bounds(ccx, it.span, generics, "type");
-            let pty = ty_of_item(ccx, it);
-            write_ty_to_tcx(tcx, it.id, pty.ty);
-        },
-        ast::ItemFn(_, _, abi, ref generics, _) => {
-            ensure_generics_abi(ccx, it.span, abi, generics);
-            let pty = ty_of_item(ccx, it);
-            write_ty_to_tcx(tcx, it.id, pty.ty);
+            let tpt = ty_of_item(ccx, it);
+            write_ty_to_tcx(tcx, it.id, tpt.ty);
         },
         _ => {
             // This call populates the type cache with the converted type
index c3986d01d3da5ef74c8d296f0985ba43fce246d3..4e193f0f1d952f816ce290d7a97883fe0c2b733f 100644 (file)
@@ -646,7 +646,7 @@ fn repr(&self, tcx: &ctxt) -> String {
                 ty::BoundSend => "Send".to_string(),
                 ty::BoundSized => "Sized".to_string(),
                 ty::BoundCopy => "Copy".to_string(),
-                ty::BoundShare => "Share".to_string(),
+                ty::BoundSync => "Sync".to_string(),
             });
         }
         for t in self.trait_bounds.iter() {
@@ -931,7 +931,7 @@ fn user_string(&self, _tcx: &ctxt) -> String {
             ty::BoundSend => "Send".to_string(),
             ty::BoundSized => "Sized".to_string(),
             ty::BoundCopy => "Copy".to_string(),
-            ty::BoundShare => "Share".to_string(),
+            ty::BoundSync => "Sync".to_string(),
         }
     }
 }
index 8dc57d3e574ad985dc50875d9657ce7db94746c7..a1f486b3b31b81a92f14fabccda514d6c0632a9f 100644 (file)
@@ -535,9 +535,9 @@ fn clean(&self) -> TyParamBound {
             ty::BoundCopy =>
                 (tcx.lang_items.copy_trait().unwrap(),
                  external_path("Copy", &empty)),
-            ty::BoundShare =>
-                (tcx.lang_items.share_trait().unwrap(),
-                 external_path("Share", &empty)),
+            ty::BoundSync =>
+                (tcx.lang_items.sync_trait().unwrap(),
+                 external_path("Sync", &empty)),
         };
         let fqn = csearch::get_item_path(tcx, did);
         let fqn = fqn.move_iter().map(|i| i.to_string()).collect();
index c290b59b61b7a69e2b9dbd69b18b86cd462cb85c..27858b025c6cb5d7d7af2f8a1945080a10d2a643 100644 (file)
@@ -112,7 +112,7 @@ struct TLDValueBox<T> {
     // refcount of 0 means uninitialized value, 1 means initialized, 2+ means
     // borrowed.
     // NB: we use UnsafeCell instead of Cell because Ref should be allowed to
-    // be Share. The only mutation occurs when a Ref is created or destroyed,
+    // be Sync. The only mutation occurs when a Ref is created or destroyed,
     // so there's no issue with &Ref being thread-safe.
     refcount: UnsafeCell<uint>
 }
index 117f680011e5bac64ace4dbeb5391e89eb4d9d5f..79f83df5be8097257760f145eef89a2a0538cf3f 100644 (file)
@@ -523,22 +523,6 @@ fn write(&mut self, buf: &[u8]) -> fmt::Result {
 }
 
 /// This is the entry point of unwinding for fail!() and assert!().
-#[cfg(stage0)]
-#[inline(never)] #[cold] // avoid code bloat at the call sites as much as possible
-pub fn begin_unwind<M: Any + Send>(msg: M, file: &'static str, line: uint) -> ! {
-    // Note that this should be the only allocation performed in this code path.
-    // Currently this means that fail!() on OOM will invoke this code path,
-    // but then again we're not really ready for failing on OOM anyway. If
-    // we do start doing this, then we should propagate this allocation to
-    // be performed in the parent of this task instead of the task that's
-    // failing.
-
-    // see below for why we do the `Any` coercion here.
-    begin_unwind_inner(box msg, &(file, line))
-}
-
-/// This is the entry point of unwinding for fail!() and assert!().
-#[cfg(not(stage0))]
 #[inline(never)] #[cold] // avoid code bloat at the call sites as much as possible
 pub fn begin_unwind<M: Any + Send>(msg: M, file_line: &(&'static str, uint)) -> ! {
     // Note that this should be the only allocation performed in this code path.
index 1d53ed814377e605b197e30966ef68ed088a2688..2faa23a6aa0a5feb008bd9d79a312a0d26d83f98 100644 (file)
@@ -21,9 +21,6 @@
 use result::{Ok, Err};
 use sync::atomic;
 
-#[cfg(stage0)]
-use iter::Iterator; // NOTE(stage0): Remove after snapshot.
-
 /// A wrapper for a path to temporary directory implementing automatic
 /// scope-based deletion.
 pub struct TempDir {
index 3184c151bd2c74e9c138344a5da481862f133d6a..f2d7fb0cea68acb5fa63736da196a069c6fbe4f2 100644 (file)
@@ -37,7 +37,6 @@
 /// fail!("this is a {} {message}", "fancy", message = "message");
 /// ```
 #[macro_export]
-#[cfg(not(stage0))]
 macro_rules! fail(
     () => ({
         fail!("explicit failure")
@@ -68,39 +67,6 @@ fn run_fmt(fmt: &::std::fmt::Arguments) -> ! {
     });
 )
 
-#[macro_export]
-#[cfg(stage0)]
-macro_rules! fail(
-    () => ({
-        fail!("explicit failure")
-    });
-    ($msg:expr) => ({
-        // static requires less code at runtime, more constant data
-        static FILE_LINE: (&'static str, uint) = (file!(), line!());
-        let (file, line) = FILE_LINE;
-        ::std::rt::begin_unwind($msg, file, line)
-    });
-    ($fmt:expr, $($arg:tt)*) => ({
-        // a closure can't have return type !, so we need a full
-        // function to pass to format_args!, *and* we need the
-        // file and line numbers right here; so an inner bare fn
-        // is our only choice.
-        //
-        // LLVM doesn't tend to inline this, presumably because begin_unwind_fmt
-        // is #[cold] and #[inline(never)] and because this is flagged as cold
-        // as returning !. We really do want this to be inlined, however,
-        // because it's just a tiny wrapper. Small wins (156K to 149K in size)
-        // were seen when forcing this to be inlined, and that number just goes
-        // up with the number of calls to fail!()
-        #[inline(always)]
-        fn run_fmt(fmt: &::std::fmt::Arguments) -> ! {
-            static FILE_LINE: (&'static str, uint) = (file!(), line!());
-            ::std::rt::begin_unwind_fmt(fmt, &FILE_LINE)
-        }
-        format_args!(run_fmt, $fmt, $($arg)*)
-    });
-)
-
 /// Ensure that a boolean expression is `true` at runtime.
 ///
 /// This will invoke the `fail!` macro if the provided expression cannot be
index 96d5c0785f47774650696b43ad0b9f9ef2816983..aa407ce8e0ccbb9de5d5e2637dab8b898ad10bb7 100644 (file)
@@ -40,7 +40,7 @@
 #![experimental]
 
 // Reexported core operators
-#[doc(no_inline)] pub use kinds::{Copy, Send, Sized, Share};
+#[doc(no_inline)] pub use kinds::{Copy, Send, Sized, Sync};
 #[doc(no_inline)] pub use ops::{Add, Sub, Mul, Div, Rem, Neg, Not};
 #[doc(no_inline)] pub use ops::{BitAnd, BitOr, BitXor};
 #[doc(no_inline)] pub use ops::{Drop, Deref, DerefMut};
index 101d869451c6d6107ab1d7521a102ceb6a6f0ab1..31b993d8bab468b3f795ac8727c8b858cf855002 100644 (file)
@@ -25,7 +25,7 @@
 //!
 //! [1]: http://gcc.gnu.org/wiki/Atomic/GCCMM/AtomicSync
 //!
-//! Atomic variables are safe to share between threads (they implement `Share`)
+//! Atomic variables are safe to share between threads (they implement `Sync`)
 //! but they do not themselves provide the mechanism for sharing. The most
 //! common way to share an atomic variable is to put it into an `Arc` (an
 //! atomically-reference-counted shared pointer).
index eff4cea1c43f0c394e9bd0c5cd35aa26e6b3448c..45016b97566ceab20dbbf8d46302fdecd0ed90d0 100644 (file)
@@ -375,7 +375,7 @@ pub struct Receiver<T> {
     inner: UnsafeCell<Flavor<T>>,
     receives: Cell<uint>,
     // can't share in an arc
-    marker: marker::NoShare,
+    marker: marker::NoSync,
 }
 
 /// An iterator over messages on a receiver, this iterator will block
@@ -393,7 +393,7 @@ pub struct Sender<T> {
     inner: UnsafeCell<Flavor<T>>,
     sends: Cell<uint>,
     // can't share in an arc
-    marker: marker::NoShare,
+    marker: marker::NoSync,
 }
 
 /// The sending-half of Rust's synchronous channel type. This half can only be
@@ -402,7 +402,7 @@ pub struct Sender<T> {
 pub struct SyncSender<T> {
     inner: Arc<UnsafeCell<sync::Packet<T>>>,
     // can't share in an arc
-    marker: marker::NoShare,
+    marker: marker::NoSync,
 }
 
 /// This enumeration is the list of the possible reasons that try_recv could not
@@ -537,7 +537,7 @@ fn new(inner: Flavor<T>) -> Sender<T> {
         Sender {
             inner: UnsafeCell::new(inner),
             sends: Cell::new(0),
-            marker: marker::NoShare,
+            marker: marker::NoSync,
         }
     }
 
@@ -713,7 +713,7 @@ fn drop(&mut self) {
 
 impl<T: Send> SyncSender<T> {
     fn new(inner: Arc<UnsafeCell<sync::Packet<T>>>) -> SyncSender<T> {
-        SyncSender { inner: inner, marker: marker::NoShare }
+        SyncSender { inner: inner, marker: marker::NoSync }
     }
 
     /// Sends a value on this synchronous channel.
@@ -801,7 +801,7 @@ fn drop(&mut self) {
 
 impl<T: Send> Receiver<T> {
     fn new(inner: Flavor<T>) -> Receiver<T> {
-        Receiver { inner: UnsafeCell::new(inner), receives: Cell::new(0), marker: marker::NoShare }
+        Receiver { inner: UnsafeCell::new(inner), receives: Cell::new(0), marker: marker::NoSync }
     }
 
     /// Blocks waiting for a value on this receiver
index d5a05e7a68175a5e6a10668103d5dcaf89b7af11..e70a730dc3a13823044466005bd25e806e8a2a13 100644 (file)
@@ -87,7 +87,7 @@ struct Deque<T> {
 /// There may only be one worker per deque.
 pub struct Worker<T> {
     deque: Arc<Deque<T>>,
-    noshare: marker::NoShare,
+    noshare: marker::NoSync,
 }
 
 /// The stealing half of the work-stealing deque. Stealers have access to the
@@ -95,7 +95,7 @@ pub struct Worker<T> {
 /// `steal` method.
 pub struct Stealer<T> {
     deque: Arc<Deque<T>>,
-    noshare: marker::NoShare,
+    noshare: marker::NoSync,
 }
 
 /// When stealing some data, this is an enumeration of the possible outcomes.
@@ -153,8 +153,8 @@ pub fn new() -> BufferPool<T> {
     pub fn deque(&self) -> (Worker<T>, Stealer<T>) {
         let a = Arc::new(Deque::new(self.clone()));
         let b = a.clone();
-        (Worker { deque: a, noshare: marker::NoShare },
-         Stealer { deque: b, noshare: marker::NoShare })
+        (Worker { deque: a, noshare: marker::NoSync },
+         Stealer { deque: b, noshare: marker::NoSync })
     }
 
     fn alloc(&mut self, bits: uint) -> Box<Buffer<T>> {
@@ -217,7 +217,7 @@ pub fn pool<'a>(&'a self) -> &'a BufferPool<T> {
 
 impl<T: Send> Clone for Stealer<T> {
     fn clone(&self) -> Stealer<T> {
-        Stealer { deque: self.deque.clone(), noshare: marker::NoShare }
+        Stealer { deque: self.deque.clone(), noshare: marker::NoSync }
     }
 }
 
index 665cd48a278df68a26c8424a90e048baea60ea57..b07d06ca18e541589f1da8d3141b94acf804b1ea 100644 (file)
@@ -298,7 +298,7 @@ pub struct RWLockReadGuard<'a, T> {
     _guard: raw::RWLockReadGuard<'a>,
 }
 
-impl<T: Send + Share> RWLock<T> {
+impl<T: Send + Sync> RWLock<T> {
     /// Create a reader/writer lock with the supplied data.
     pub fn new(user_data: T) -> RWLock<T> {
         RWLock::new_with_condvars(user_data, 1)
@@ -359,7 +359,7 @@ pub fn read<'a>(&'a self) -> RWLockReadGuard<'a, T> {
     }
 }
 
-impl<'a, T: Send + Share> RWLockWriteGuard<'a, T> {
+impl<'a, T: Send + Sync> RWLockWriteGuard<'a, T> {
     /// Consumes this write lock token, returning a new read lock token.
     ///
     /// This will allow pending readers to come into the lock.
@@ -375,13 +375,13 @@ pub fn downgrade(self) -> RWLockReadGuard<'a, T> {
     }
 }
 
-impl<'a, T: Send + Share> Deref<T> for RWLockReadGuard<'a, T> {
+impl<'a, T: Send + Sync> Deref<T> for RWLockReadGuard<'a, T> {
     fn deref<'a>(&'a self) -> &'a T { self._data }
 }
-impl<'a, T: Send + Share> Deref<T> for RWLockWriteGuard<'a, T> {
+impl<'a, T: Send + Sync> Deref<T> for RWLockWriteGuard<'a, T> {
     fn deref<'a>(&'a self) -> &'a T { &*self._data }
 }
-impl<'a, T: Send + Share> DerefMut<T> for RWLockWriteGuard<'a, T> {
+impl<'a, T: Send + Sync> DerefMut<T> for RWLockWriteGuard<'a, T> {
     fn deref_mut<'a>(&'a mut self) -> &'a mut T { &mut *self._data }
 }
 
index 49f60fe6f005fb24f4369c1650fb0d37691a1a97..c42d567fc18cee23134c0e2cc8723d6b6b258a47 100644 (file)
@@ -87,7 +87,7 @@ fn wait_end(&self) -> WaitEnd {
 // The building-block used to make semaphores, mutexes, and rwlocks.
 struct Sem<Q> {
     lock: mutex::Mutex,
-    // n.b, we need Sem to be `Share`, but the WaitQueue type is not send/share
+    // n.b, we need Sem to be `Sync`, but the WaitQueue type is not send/share
     //      (for good reason). We have an internal invariant on this semaphore,
     //      however, that the queue is never accessed outside of a locked
     //      context.
index fc000d2357e3007d65b6b5d9df2498a7940c0f13..629b21875c9b61b37904f3e65f52e2c5e35009e8 100644 (file)
@@ -214,7 +214,7 @@ pub struct DefId {
 /// The AST represents all type param bounds as types.
 /// typeck::collect::compute_bounds matches these against
 /// the "special" built-in traits (see middle::lang_items) and
-/// detects Copy, Send and Share.
+/// detects Copy, Send and Sync.
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
 pub enum TyParamBound {
     TraitTyParamBound(TraitRef),
index fac9f37c462cca8328c69458eb6ed93210a2b735..7cff6e8ff3c01c1ccf33f1fe3cbc6e24dd3ecbd2 100644 (file)
@@ -27,7 +27,7 @@ pub fn expand_deriving_bound(cx: &mut ExtCtxt,
             match tname.get() {
                 "Copy" => "Copy",
                 "Send" => "Send",
-                "Share" => "Share",
+                "Sync" => "Sync",
                 ref tname => {
                     cx.span_bug(span,
                                 format!("expected built-in trait name but \
index edfe54db0c760e1ebd039bfb83bf8d0712ab369b..a9b5c8a413463ee453c3bdcaf44589bcabfb8bac 100644 (file)
@@ -94,7 +94,7 @@ macro_rules! expand(($func:path) => ($func(cx, titem.span,
                             "FromPrimitive" => expand!(primitive::expand_deriving_from_primitive),
 
                             "Send" => expand!(bounds::expand_deriving_bound),
-                            "Share" => expand!(bounds::expand_deriving_bound),
+                            "Sync" => expand!(bounds::expand_deriving_bound),
                             "Copy" => expand!(bounds::expand_deriving_bound),
 
                             ref tname => {
index df0be09aea1f7f058c4baddd11ee1abd1d62447f..ec31181e8a7483f93ce1219b0fafde67ba39aeb4 100644 (file)
@@ -39,9 +39,6 @@ fn bsearch_table<T>(c: char, r: &'static [(char, &'static [T])]) -> Option<&'sta
 pub fn decompose_compatible(c: char, i: |char|) { d(c, i, true); }
 
 fn d(c: char, i: |char|, k: bool) {
-    #[cfg(stage0)]
-    use core::iter::Iterator;
-
     // 7-bit ASCII never decomposes
     if c <= '\x7f' { i(c); return; }
 
index 623f8f8bcc00d3097c4f4f02bba9cad9a6ba489c..a07be82d58ef91f0cae09074ac8a5c4513e4088d 100644 (file)
@@ -1,3 +1,11 @@
+S 2014-08-07 12e0f72
+  freebsd-x86_64 e55055a876ebbde0d3ed3bcb97579afab9264def
+  linux-i386 2665e45879f2ef77ce0c9015f971642fe424ac33
+  linux-x86_64 51ed1f4cf0707585a136bb149a443394067c074c
+  macos-i386 78f1996954a6e0718d684a3756b4870a6f8771ee
+  macos-x86_64 216f46f65866207a9f41c3ed654f5c1e085cb7f3
+  winnt-i386 95a9b8a8bf587761ae954392aee2ccee3758a533
+
 S 2014-07-17 9fc8394
   freebsd-x86_64 5a4b645e2b42ae06224cc679d4a43b3d89be1482
   linux-i386 a5e1bb723020ac35173d49600e76b0935e257a6a
index c6ca0f3ed7bdda799a50543bcc6d27a6a24f17d5..c2e1dd69a900ce0b97b4fad4aad35260531f9089 100644 (file)
@@ -18,17 +18,17 @@ struct arc_destruct<T> {
 }
 
 #[unsafe_destructor]
-impl<T: Share> Drop for arc_destruct<T> {
+impl<T: Sync> Drop for arc_destruct<T> {
     fn drop(&mut self) {}
 }
 
-fn arc_destruct<T: Share>(data: int) -> arc_destruct<T> {
+fn arc_destruct<T: Sync>(data: int) -> arc_destruct<T> {
     arc_destruct {
         _data: data
     }
 }
 
-fn arc<T: Share>(_data: T) -> arc_destruct<T> {
+fn arc<T: Sync>(_data: T) -> arc_destruct<T> {
     arc_destruct(0)
 }
 
index 2efb8a17239da8c0eeb877e36d899c5294026eb2..0fa2d3459f433f9395fb4b89b695c93d65c566a2 100644 (file)
@@ -13,6 +13,6 @@
 
 #![crate_type="lib"]
 
-pub trait RequiresShare : Share { }
+pub trait RequiresShare : Sync { }
 pub trait RequiresRequiresShareAndSend : RequiresShare + Send { }
 pub trait RequiresCopy : Copy { }
index 7de38e6173be1ee3628fb07ccd76a092870ef29b..d5a648e3e20017c56130eac56c3257f76fe7f7e0 100644 (file)
 // Test for traits that inherit from multiple builtin kinds at once,
 // testing that all such kinds must be present on implementing types.
 
-trait Foo : Send+Share { }
+trait Foo : Send+Sync { }
 
-impl <T: Share> Foo for (T,) { } //~ ERROR cannot implement this trait
+impl <T: Sync> Foo for (T,) { } //~ ERROR cannot implement this trait
 
 impl <T: Send> Foo for (T,T) { } //~ ERROR cannot implement this trait
 
-impl <T: Send+Share> Foo for (T,T,T) { } // (ok)
+impl <T: Send+Sync> Foo for (T,T,T) { } // (ok)
 
 fn main() { }
index 66809aa72dc8ddc0e52e0c9a5881bcd1a5c8dc08..889d82383e74e465e37b63a415edba377d8d80b3 100644 (file)
@@ -19,8 +19,8 @@
 
 struct X<T>(T);
 
-impl <T:Share> RequiresShare for X<T> { }
+impl <T:Sync> RequiresShare for X<T> { }
 
-impl <T:Share> RequiresRequiresShareAndSend for X<T> { } //~ ERROR cannot implement this trait
+impl <T:Sync> RequiresRequiresShareAndSend for X<T> { } //~ ERROR cannot implement this trait
 
 fn main() { }
index bea025df6fc859ca5a90e7086dd2ab70ae70f33d..67222bdafbf947faceb68a9825ee4d19848ee976 100644 (file)
 // Tests (negatively) the ability for the Self type in default methods
 // to use capabilities granted by builtin kinds as supertraits.
 
-trait Foo : Share {
+trait Foo : Sync {
     fn foo(self, mut chan: Sender<Self>) {
         chan.send(self); //~ ERROR does not fulfill `Send`
     }
 }
 
-impl <T: Share> Foo for T { }
+impl <T: Sync> Foo for T { }
 
 fn main() {
     let (tx, rx) = channel();
index bc0ad6dbb2938a2329b03dc953cc0ff6367de290..166ca10ee187594d81971f79c7d47174e4d652fe 100644 (file)
@@ -12,6 +12,6 @@
 
 trait Foo : Send { }
 
-impl <T: Share> Foo for T { } //~ ERROR cannot implement this trait
+impl <T: Sync> Foo for T { } //~ ERROR cannot implement this trait
 
 fn main() { }
index 5ffaebe405e1c2398d4b8d447f3aff5d70ab947e..51188e5dce4120d5831257458f6dd59b2494a450 100644 (file)
@@ -12,7 +12,7 @@
 fn take_any(_: ||:) {
 }
 
-fn take_const_owned(_: ||:Share+Send) {
+fn take_const_owned(_: ||:Sync+Send) {
 }
 
 fn give_any(f: ||:) {
@@ -21,7 +21,7 @@ fn give_any(f: ||:) {
 
 fn give_owned(f: ||:Send) {
     take_any(f);
-    take_const_owned(f); //~ ERROR expected bounds `Send+Share` but found bounds `Send`
+    take_const_owned(f); //~ ERROR expected bounds `Send+Sync` but found bounds `Send`
 }
 
 fn main() {}
index 3550922dc1462e97d5aadd1f37335e003b8bbbf2..5820818167cbdd4902c8cf530e60b0c064ec211a 100644 (file)
@@ -8,10 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn test<T: Share>() {}
+fn test<T: Sync>() {}
 
 fn main() {
-    test::<Sender<int>>();        //~ ERROR: does not fulfill `Share`
-    test::<Receiver<int>>();        //~ ERROR: does not fulfill `Share`
-    test::<Sender<int>>();  //~ ERROR: does not fulfill `Share`
+    test::<Sender<int>>();        //~ ERROR: does not fulfill `Sync`
+    test::<Receiver<int>>();        //~ ERROR: does not fulfill `Sync`
+    test::<Sender<int>>();  //~ ERROR: does not fulfill `Sync`
 }
index dc0bd5d028a42ff9e746fde9484e1f511cd0847d..1f9bd881afe2d5aa6c3ca6a7d44b64f56f6b9579 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#[deriving(Share(Bad),Send,Copy)]
+#[deriving(Sync(Bad),Send,Copy)]
 //~^ ERROR unexpected value in deriving, expected a trait
 struct Test;
 
index ce8099d64a0f11dfe93a5d1af034945637b8c4d6..a7140d1be87ad180ec66aeddf39a6aff5a3233a3 100644 (file)
@@ -8,8 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-extern "C" fn foo<T>() {}  //~ERROR foreign functions may not use type parameters
+extern {
+    fn foo<T>(); //~ ERROR foreign items may not have type parameters
+}
 
 fn main() {
-    let _ = foo::<int>;
+    foo::<i32>();
 }
diff --git a/src/test/compile-fail/generic-no-mangle.rs b/src/test/compile-fail/generic-no-mangle.rs
new file mode 100644 (file)
index 0000000..f4ead18
--- /dev/null
@@ -0,0 +1,18 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-test this should fail to compile (#15844)
+
+#[no_mangle]
+fn foo<T>() {} //~ ERROR generic functions must be mangled
+
+#[no_mangle]
+extern fn foo<T>() {} //~ ERROR generic functions must be mangled
+
index b159337765e5f5844447a045e6902f86a1822e58..42b70c28be6045cdd944be8771bb50fdf392e394 100644 (file)
@@ -20,7 +20,7 @@ struct E {
 }
 
 impl A for E {
-  fn b<F: Share, G>(_x: F) -> F { fail!() } //~ ERROR type parameter 0 requires `Share`
+  fn b<F: Sync, G>(_x: F) -> F { fail!() } //~ ERROR type parameter 0 requires `Sync`
 }
 
 fn main() {}
index 84e856f5ac915dc618d881f971ced398edf4ab10..25fe95b80c42c445155a8897df4f9bd0ccee6cd1 100644 (file)
@@ -10,9 +10,9 @@
 
 use std::kinds::marker;
 
-fn foo<P: Share>(p: P) { }
+fn foo<P: Sync>(p: P) { }
 
 fn main()
 {
-    foo(marker::NoShare); //~ ERROR does not fulfill `Share`
+    foo(marker::NoSync); //~ ERROR does not fulfill `Sync`
 }
index 985bfec392c7f128dffc14bdbef6af3a7de201f8..a5b6acc447f84b3e359352f1633ee3894247cdd5 100644 (file)
@@ -10,9 +10,9 @@
 
 use std::cell::RefCell;
 
-fn f<T: Share>(_: T) {}
+fn f<T: Sync>(_: T) {}
 
 fn main() {
     let x = RefCell::new(0i);
-    f(x); //~ ERROR: which does not fulfill `Share`
+    f(x); //~ ERROR: which does not fulfill `Sync`
 }
index e480ebfd3781f1406af53effbe047918c21bd9d7..9d4c35baea38b7a27ccc62561f67b761825a4f71 100644 (file)
 
 use std::kinds::marker;
 
-enum Foo { A(marker::NoShare) }
+enum Foo { A(marker::NoSync) }
 
-fn bar<T: Share>(_: T) {}
+fn bar<T: Sync>(_: T) {}
 
 fn main() {
-    let x = A(marker::NoShare);
+    let x = A(marker::NoSync);
     bar(&x); //~ ERROR type parameter with an incompatible type
 }
index e68274fcb7940579ad82b9caa60985e292628e1d..f96d751af7e9deca318787101689c5a3e28fa319 100644 (file)
 
 use std::kinds::marker;
 
-enum Foo { A(marker::NoShare) }
+enum Foo { A(marker::NoSync) }
 
-fn bar<T: Share>(_: T) {}
+fn bar<T: Sync>(_: T) {}
 
 fn main() {
-    let x = A(marker::NoShare);
+    let x = A(marker::NoSync);
     bar(x);
     //~^ ERROR instantiating a type parameter with an incompatible type `Foo`,
-    //         which does not fulfill `Share`
+    //         which does not fulfill `Sync`
 }
index f49592b173587d750f366607a8f04ecd59c436ea..7a840674be6f010a723107b75f720cb3afdbf3ce 100644 (file)
 use std::rc::Rc;
 use std::cell::RefCell;
 
-fn bar<T: Share>(_: T) {}
+fn bar<T: Sync>(_: T) {}
 
 fn main() {
     let x = Rc::new(RefCell::new(5i));
     bar(x);
     //~^ ERROR instantiating a type parameter with an incompatible type
-    //         `std::rc::Rc<std::cell::RefCell<int>>`, which does not fulfill `Share`
+    //         `std::rc::Rc<std::cell::RefCell<int>>`, which does not fulfill `Sync`
 }
index 7bb7d86e8d870d309a50a6bafdf6fce54b00fe35..6b87a5fa09c98e4ca63873a0260bb5454bfe20f7 100644 (file)
 
 use std::kinds::marker;
 
-struct Foo { a: int, m: marker::NoShare }
+struct Foo { a: int, m: marker::NoSync }
 
-fn bar<T: Share>(_: T) {}
+fn bar<T: Sync>(_: T) {}
 
 fn main() {
-    let x = Foo { a: 5, m: marker::NoShare };
+    let x = Foo { a: 5, m: marker::NoSync };
     bar(x);
     //~^ ERROR instantiating a type parameter with an incompatible type `Foo`,
-    //         which does not fulfill `Share`
+    //         which does not fulfill `Sync`
 }
index 0875212b7dee35b296368a01e300c33d623ef85b..e8c6a3ba19174ad295f0d2f96c6c38b5d8a206e8 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 fn is_send<T: Send>() {}
-fn is_freeze<T: Share>() {}
+fn is_freeze<T: Sync>() {}
 fn is_static<T: 'static>() {}
 
 fn main() {
index 0b9f09d9482f1b0c24a2a02f3acbb0bcd1663d01..4f405e2558d2399c95512c227d2195c698649acb 100644 (file)
@@ -15,7 +15,7 @@ trait Foo {
 fn a(_x: Box<Foo+Send>) {
 }
 
-fn c(x: Box<Foo+Share+Send>) {
+fn c(x: Box<Foo+Sync+Send>) {
     a(x);
 }
 
index d548098ebe13ed8dadb9a9a48b7e4ac1303a0932..c3d608b48f3c61dad462456b07e0a91290da8ffb 100644 (file)
@@ -19,11 +19,11 @@ fn a(_x: Box<Foo+Send>) {
 fn b(_x: &'static Foo) { // should be same as &'static Foo+'static
 }
 
-fn c(x: Box<Foo+Share>) {
+fn c(x: Box<Foo+Sync>) {
     a(x); //~ ERROR expected bounds `Send`
 }
 
-fn d(x: &'static Foo+Share) {
+fn d(x: &'static Foo+Sync) {
     b(x); //~ ERROR expected bounds `'static`
 }
 
index a57654b029d164a5bf498dca660f0ed1bc2c979f..826fec27929938cf2c2e88397d4c9078b5cc18c1 100644 (file)
@@ -8,36 +8,36 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// Verify that UnsafeCell is *always* share regardles `T` is share.
+// Verify that UnsafeCell is *always* sync regardles `T` is sync.
 
 // ignore-tidy-linelength
 
 use std::cell::UnsafeCell;
 use std::kinds::marker;
 
-struct MyShare<T> {
+struct MySync<T> {
     u: UnsafeCell<T>
 }
 
-struct NoShare {
-    m: marker::NoShare
+struct NoSync {
+    m: marker::NoSync
 }
 
-fn test<T: Share>(s: T){
+fn test<T: Sync>(s: T){
 
 }
 
 fn main() {
-    let us = UnsafeCell::new(MyShare{u: UnsafeCell::new(0i)});
+    let us = UnsafeCell::new(MySync{u: UnsafeCell::new(0i)});
     test(us);
 
-    let uns = UnsafeCell::new(NoShare{m: marker::NoShare});
+    let uns = UnsafeCell::new(NoSync{m: marker::NoSync});
     test(uns);
 
-    let ms = MyShare{u: uns};
+    let ms = MySync{u: uns};
     test(ms);
 
-    let ns = NoShare{m: marker::NoShare};
+    let ns = NoSync{m: marker::NoSync};
     test(ns);
-    //~^ ERROR instantiating a type parameter with an incompatible type `NoShare`, which does not fulfill `Share`
+    //~^ ERROR instantiating a type parameter with an incompatible type `NoSync`, which does not fulfill `Sync`
 }
index 94383d9724cbe57b11ff60c35a68becafd2f4079..7c05e6d606546edec7a2f31582f4da15f2bddbc9 100644 (file)
 trait Tr { }
 impl Tr for int { }
 
-fn foo(x: Box<Tr+ Share>) -> Box<Tr+ Share> { x }
+fn foo(x: Box<Tr+ Sync>) -> Box<Tr+ Sync> { x }
 
 fn main() {
-    let x: Box<Tr+ Share>;
+    let x: Box<Tr+ Sync>;
 
-    box() 1i as Box<Tr+ Share>;
+    box() 1i as Box<Tr+ Sync>;
 }
 
diff --git a/src/test/run-make/extern-fn-generic/Makefile b/src/test/run-make/extern-fn-generic/Makefile
new file mode 100644 (file)
index 0000000..a325acb
--- /dev/null
@@ -0,0 +1,8 @@
+-include ../tools.mk
+
+all:
+       $(CC) -std=c99 test.c -c -o $(TMPDIR)/test.o
+       $(AR) rcs $(TMPDIR)/libtest.a $(TMPDIR)/test.o
+       $(RUSTC) testcrate.rs -L $(TMPDIR)
+       $(RUSTC) test.rs -L $(TMPDIR)
+       $(call RUN,test) || exit 1
diff --git a/src/test/run-make/extern-fn-generic/test.c b/src/test/run-make/extern-fn-generic/test.c
new file mode 100644 (file)
index 0000000..f23dd1e
--- /dev/null
@@ -0,0 +1,16 @@
+#include <stdint.h>
+
+typedef struct TestStruct {
+       uint8_t x;
+       int32_t y;
+} TestStruct;
+
+typedef int callback(TestStruct s);
+
+uint32_t call(callback *c) {
+       TestStruct s;
+       s.x = 'a';
+       s.y = 3;
+
+       return c(s);
+}
diff --git a/src/test/run-make/extern-fn-generic/test.rs b/src/test/run-make/extern-fn-generic/test.rs
new file mode 100644 (file)
index 0000000..ee04856
--- /dev/null
@@ -0,0 +1,32 @@
+// 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.
+
+extern crate testcrate;
+
+extern "C" fn bar<T>(ts: testcrate::TestStruct<T>) -> T { ts.y }
+
+#[link(name = "test")]
+extern {
+    fn call(c: extern "C" fn(testcrate::TestStruct<i32>) -> i32) -> i32;
+}
+
+fn main() {
+    // Let's test calling it cross crate
+    let back = unsafe {
+        testcrate::call(testcrate::foo::<i32>)
+    };
+    assert_eq!(3, back);
+
+    // And just within this crate
+    let back = unsafe {
+        call(bar::<i32>)
+    };
+    assert_eq!(3, back);
+}
diff --git a/src/test/run-make/extern-fn-generic/testcrate.rs b/src/test/run-make/extern-fn-generic/testcrate.rs
new file mode 100644 (file)
index 0000000..5fd61bb
--- /dev/null
@@ -0,0 +1,24 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![crate_type = "lib"]
+
+#[repr(C)]
+pub struct TestStruct<T> {
+    pub x: u8,
+    pub y: T
+}
+
+pub extern "C" fn foo<T>(ts: TestStruct<T>) -> T { ts.y }
+
+#[link(name = "test")]
+extern {
+    pub fn call(c: extern "C" fn(TestStruct<i32>) -> i32) -> i32;
+}
diff --git a/src/test/run-make/extern-fn-mangle/Makefile b/src/test/run-make/extern-fn-mangle/Makefile
new file mode 100644 (file)
index 0000000..ea69718
--- /dev/null
@@ -0,0 +1,7 @@
+-include ../tools.mk
+
+all:
+       $(CC) -std=c99 test.c -c -o $(TMPDIR)/test.o
+       $(AR) rcs $(TMPDIR)/libtest.a $(TMPDIR)/test.o
+       $(RUSTC) test.rs -L $(TMPDIR)
+       $(call RUN,test) || exit 1
diff --git a/src/test/run-make/extern-fn-mangle/test.c b/src/test/run-make/extern-fn-mangle/test.c
new file mode 100644 (file)
index 0000000..8d93917
--- /dev/null
@@ -0,0 +1,8 @@
+#include <stdint.h>
+
+uint32_t foo();
+uint32_t bar();
+
+uint32_t add() {
+       return foo() + bar();
+}
diff --git a/src/test/run-make/extern-fn-mangle/test.rs b/src/test/run-make/extern-fn-mangle/test.rs
new file mode 100644 (file)
index 0000000..35b5a92
--- /dev/null
@@ -0,0 +1,25 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#[no_mangle]
+pub extern "C" fn foo() -> i32 { 3 }
+
+#[no_mangle]
+pub extern "C" fn bar() -> i32 { 5 }
+
+#[link(name = "test", kind = "static")]
+extern {
+    fn add() -> i32;
+}
+
+fn main() {
+    let back = unsafe { add() };
+    assert_eq!(8, back);
+}
index 51238b0ee52c98b2f5111202f0c8290882f94ee2..c2b874c61a77fb1bcf364f32a546500ec92ad029 100644 (file)
@@ -20,8 +20,8 @@
 #[deriving(PartialEq)]
 struct X<T>(T);
 
-impl <T: Share> RequiresShare for X<T> { }
-impl <T: Share+Send> RequiresRequiresShareAndSend for X<T> { }
+impl <T: Sync> RequiresShare for X<T> { }
+impl <T: Sync+Send> RequiresRequiresShareAndSend for X<T> { }
 
 fn foo<T: RequiresRequiresShareAndSend>(val: T, chan: Sender<T>) {
     chan.send(val);
index ba57f095e1a99a82a662b58add0ab69a4b87782b..683e7ece8717d714d0b3704094d06d91ab6a19b2 100644 (file)
@@ -19,9 +19,9 @@
 
 struct X<T>(T);
 
-impl <T:Share> RequiresShare for X<T> { }
+impl <T:Sync> RequiresShare for X<T> { }
 
-impl <T:Share+Send> RequiresRequiresShareAndSend for X<T> { }
+impl <T:Sync+Send> RequiresRequiresShareAndSend for X<T> { }
 
 impl <T:Copy> RequiresCopy for X<T> { }
 
index df7d59e25608bdd9c0619ab0d592c77819e126b6..7b8d1dd7576b9f6cb0a426566cea18edcbcef52b 100644 (file)
@@ -28,11 +28,11 @@ struct Foo<'a> {
     a: ||: 'a,
     b: ||: 'static,
     c: <'b>||: 'a,
-    d: ||: 'a + Share,
-    e: <'b>|int|: 'a + Share -> &'b f32,
+    d: ||: 'a + Sync,
+    e: <'b>|int|: 'a + Sync -> &'b f32,
     f: proc(),
-    g: proc(): 'static + Share,
-    h: proc<'b>(int): Share -> &'b f32,
+    g: proc(): 'static + Sync,
+    h: proc<'b>(int): Sync -> &'b f32,
 }
 
 fn f<'a>(a: &'a int, f: <'b>|&'b int| -> &'b int) -> &'a int {
@@ -54,14 +54,14 @@ fn bar<'b>() {
     foo::<|| -> ()>();
     foo::<||:>();
     foo::<||:'b>();
-    foo::<||:'b + Share>();
-    foo::<||:Share>();
-    foo::< <'a>|int, f32, &'a int|:'b + Share -> &'a int>();
+    foo::<||:'b + Sync>();
+    foo::<||:Sync>();
+    foo::< <'a>|int, f32, &'a int|:'b + Sync -> &'a int>();
     foo::<proc()>();
     foo::<proc() -> ()>();
     foo::<proc():'static>();
-    foo::<proc():Share>();
-    foo::<proc<'a>(int, f32, &'a int):'static + Share -> &'a int>();
+    foo::<proc():Sync>();
+    foo::<proc<'a>(int, f32, &'a int):'static + Sync -> &'a int>();
 
     foo::<<'a>||>();
 
index 08912419b5c9fe530f375263ea7d0594f80f90cd..e24bc1dbff9d57cd004138307a15770e23de92c9 100644 (file)
@@ -12,7 +12,7 @@
 // are const.
 
 
-fn foo<T: Share>(x: T) -> T { x }
+fn foo<T: Sync>(x: T) -> T { x }
 
 struct F { field: int }
 
index ad7ded215af787e1fb2f02107d35b5c8dfbd1437..d120b8030c1cfd4138f2be2c2084ca0a4b2beafd 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#[deriving(Share,Send,Copy)]
+#[deriving(Sync,Send,Copy)]
 struct Test;
 
 pub fn main() {}
diff --git a/src/test/run-pass/generic-extern-mangle.rs b/src/test/run-pass/generic-extern-mangle.rs
new file mode 100644 (file)
index 0000000..6984675
--- /dev/null
@@ -0,0 +1,16 @@
+// 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.
+
+extern "C" fn foo<T: Int>(a: T, b: T) -> T { a + b }
+
+fn main() {
+    assert_eq!(99u8, foo(255u8, 100u8));
+    assert_eq!(99u16, foo(65535u16, 100u16));
+}
index f48a49a15eb3d805ffa0dbd6c11d6f526d425426..8a9e2d28776a78fb3e0309075b86bf914f8ee1c4 100644 (file)
@@ -12,7 +12,7 @@
 // than the traits require.
 
 trait A {
-  fn b<C:Share,D>(x: C) -> C;
+  fn b<C:Sync,D>(x: C) -> C;
 }
 
 struct E {
index fbc2829816567b9e50f00e1bd83a1409eff7ae00..339c9e3c490c7ab008b931ee75ec15456889befe 100644 (file)
@@ -20,7 +20,7 @@ pub trait D<'a, T> {}
 }
 
 fn foo1<T>(_: &A<T> + Send) {}
-fn foo2<T>(_: Box<A<T> + Send + Share>) {}
+fn foo2<T>(_: Box<A<T> + Send + Sync>) {}
 fn foo3<T>(_: Box<B<int, uint> + 'static>) {}
 fn foo4<'a, T>(_: Box<C<'a, T> + 'static + Send>) {}
 fn foo5<'a, T>(_: Box<foo::D<'a, T> + 'static + Send>) {}
index 8968b700540d58ea03f98ca761b823f334efd6f4..7241b0b88b96b66e04a2b0b1c9ad5b5fb1007d68 100644 (file)
@@ -12,18 +12,18 @@ fn foo<T>() {}
 fn bar<T>(_: T) {}
 
 fn is_send<T: Send>() {}
-fn is_freeze<T: Share>() {}
+fn is_freeze<T: Sync>() {}
 fn is_static<T: 'static>() {}
 
 pub fn main() {
     foo::<proc()>();
     foo::<proc()>();
     foo::<proc():Send>();
-    foo::<proc():Send + Share>();
-    foo::<proc():'static + Send + Share>();
+    foo::<proc():Send + Sync>();
+    foo::<proc():'static + Send + Sync>();
 
     is_send::<proc():Send>();
-    is_freeze::<proc():Share>();
+    is_freeze::<proc():Sync>();
     is_static::<proc():'static>();
 
 
diff --git a/src/test/run-pass/spawn-stack-too-big.rs b/src/test/run-pass/spawn-stack-too-big.rs
deleted file mode 100644 (file)
index e1c4a48..0000000
+++ /dev/null
@@ -1,47 +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.
-
-// ignore-macos apparently gargantuan mmap requests are ok?
-
-#![feature(phase)]
-
-#[phase(plugin)]
-extern crate green;
-extern crate native;
-
-use std::task::TaskBuilder;
-use native::NativeTaskBuilder;
-
-green_start!(main)
-
-fn main() {
-    test();
-
-    let (tx, rx) = channel();
-    TaskBuilder::new().native().spawn(proc() {
-        tx.send(test());
-    });
-    rx.recv();
-}
-
-#[cfg(not(target_word_size = "64"))]
-fn test() {}
-
-#[cfg(target_word_size = "64")]
-fn test() {
-    let (tx, rx) = channel();
-    spawn(proc() {
-        TaskBuilder::new().stack_size(1024 * 1024 * 1024 * 64).spawn(proc() {
-        });
-        tx.send(());
-    });
-
-    assert!(rx.recv_opt().is_err());
-}
index 013a8dcf60e7acb966898880a72871560bb72468..d03496403ad2a629a349cbb94f14f59f4fc801f4 100644 (file)
@@ -15,7 +15,7 @@ trait Foo {
 fn b(_x: Box<Foo+Send>) {
 }
 
-fn c(x: Box<Foo+Share+Send>) {
+fn c(x: Box<Foo+Sync+Send>) {
     e(x);
 }
 
index cfe9a772b2ee84de751ea38d3528d420f32b3bf1..50d3531b632f4589ed5fb0ea2ae6d81c872bda5f 100644 (file)
@@ -71,10 +71,10 @@ pub fn main() {
         swim_speed: 998,
         name: "alec_guinness".to_string(),
     };
-    let arc = Arc::new(vec!(box catte  as Box<Pet+Share+Send>,
-                            box dogge1 as Box<Pet+Share+Send>,
-                            box fishe  as Box<Pet+Share+Send>,
-                            box dogge2 as Box<Pet+Share+Send>));
+    let arc = Arc::new(vec!(box catte  as Box<Pet+Sync+Send>,
+                            box dogge1 as Box<Pet+Sync+Send>,
+                            box fishe  as Box<Pet+Sync+Send>,
+                            box dogge2 as Box<Pet+Sync+Send>));
     let (tx1, rx1) = channel();
     let arc1 = arc.clone();
     task::spawn(proc() { check_legs(arc1); tx1.send(()); });
@@ -89,21 +89,21 @@ pub fn main() {
     rx3.recv();
 }
 
-fn check_legs(arc: Arc<Vec<Box<Pet+Share+Send>>>) {
+fn check_legs(arc: Arc<Vec<Box<Pet+Sync+Send>>>) {
     let mut legs = 0;
     for pet in arc.iter() {
         legs += pet.num_legs();
     }
     assert!(legs == 12);
 }
-fn check_names(arc: Arc<Vec<Box<Pet+Share+Send>>>) {
+fn check_names(arc: Arc<Vec<Box<Pet+Sync+Send>>>) {
     for pet in arc.iter() {
         pet.name(|name| {
             assert!(name.as_bytes()[0] == 'a' as u8 && name.as_bytes()[1] == 'l' as u8);
         })
     }
 }
-fn check_pedigree(arc: Arc<Vec<Box<Pet+Share+Send>>>) {
+fn check_pedigree(arc: Arc<Vec<Box<Pet+Sync+Send>>>) {
     for pet in arc.iter() {
         assert!(pet.of_good_pedigree());
     }