$(PKG_EXE): rust.iss modpath.iss upgrade.iss LICENSE.txt rust-logo.ico \
$(CSREQ3_T_$(CFG_BUILD)_H_$(CFG_BUILD)) \
dist-prepare-win
- $(CFG_PYTHON) $(S)src/etc/make-win-dist.py tmp/dist/win $(CFG_BUILD)
+ $(Q)rm -rf tmp/dist/win/gcc
+ $(CFG_PYTHON) $(S)src/etc/make-win-dist.py tmp/dist/win/rust tmp/dist/win/gcc $(CFG_BUILD)
@$(call E, ISCC: $@)
$(Q)$(CFG_ISCC) $<
dist-prepare-win: PREPARE_HOST=$(CFG_BUILD)
dist-prepare-win: PREPARE_TARGETS=$(CFG_BUILD)
-dist-prepare-win: PREPARE_DEST_DIR=tmp/dist/win
+dist-prepare-win: PREPARE_DEST_DIR=tmp/dist/win/rust
dist-prepare-win: PREPARE_DIR_CMD=$(DEFAULT_PREPARE_DIR_CMD)
dist-prepare-win: PREPARE_BIN_CMD=$(DEFAULT_PREPARE_BIN_CMD)
dist-prepare-win: PREPARE_LIB_CMD=$(DEFAULT_PREPARE_LIB_CMD)
Codegen
}
+impl Copy for Mode {}
+
impl FromStr for Mode {
fn from_str(s: &str) -> Option<Mode> {
match s {
+---------+ | +-----------+
| +---| farewells |
+---------+ | +-----------+
-| phrases |---+
+| phrases |---+
+---------+ | +-----------+
| +---| greetings |
+----------+ | +-----------+
fn hello() -> String {
"Hello!".to_string()
-}
+}
```
Put this in `src/english/farewells.rs`:
fn goodbye() -> String {
"Goodbye.".to_string()
-}
+}
```
Put this in `src/japanese/greetings.rs`:
fn hello() -> String {
"こんにちは".to_string()
-}
+}
```
Of course, you can copy and paste this from this web page, or just type
fn goodbye() -> String {
"さようなら".to_string()
-}
+}
```
(This is "Sayoonara", if you're curious.)
/home/you/projects/phrases/src/japanese/greetings.rs:1:1: 3:2 warning: code is never used: `hello`, #[warn(dead_code)] on by default
/home/you/projects/phrases/src/japanese/greetings.rs:1 fn hello() -> String {
/home/you/projects/phrases/src/japanese/greetings.rs:2 "こんにちは".to_string()
-/home/you/projects/phrases/src/japanese/greetings.rs:3 }
+/home/you/projects/phrases/src/japanese/greetings.rs:3 }
/home/you/projects/phrases/src/japanese/farewells.rs:1:1: 3:2 warning: code is never used: `goodbye`, #[warn(dead_code)] on by default
/home/you/projects/phrases/src/japanese/farewells.rs:1 fn goodbye() -> String {
/home/you/projects/phrases/src/japanese/farewells.rs:2 "さようなら".to_string()
-/home/you/projects/phrases/src/japanese/farewells.rs:3 }
+/home/you/projects/phrases/src/japanese/farewells.rs:3 }
Running `target/phrases`
Hello in English: Hello!
Goodbye in English: Goodbye.
Rust will give us a compile-time error:
-```{notrust,ignore}
+```{notrust}
Compiling phrases v0.0.1 (file:///home/you/projects/phrases)
/home/you/projects/phrases/src/main.rs:4:5: 4:40 error: a value named `hello` has already been imported in this module
/home/you/projects/phrases/src/main.rs:4 use phrases::japanese::greetings::hello;
> The best-laid plans of mice and men
> Often go awry
->
+>
> "Tae a Moose", Robert Burns
Sometimes, things just go wrong. It's important to have a plan for when the
This will give us an error:
-```{notrust,ignore}
+```{notrust}
error: non-exhaustive patterns: `_` not covered [E0004]
```
gives
-```{notrust,ignore}
+```{notrust}
task '<main>' panicked at 'boom', hello.rs:2
```
knows that our handle, `x`, is the owning reference to our box. Rust knows that
`x` will go out of scope at the end of the block, and so it inserts a call to
deallocate the memory at the end of the scope. Because the compiler does this
-for us, it's impossible to forget. We always exaclty one deallocations paired
+for us, it's impossible to forget. We always have exactly one deallocation paired
with each of our allocations.
This is pretty straightforward, but what happens when we want to pass our box
This does not compile, and gives us an error:
-```{notrust,ignore}
+```{notrust}
error: use of moved value: `x`
println!("{}", x);
^
contents. But then we give ownership right back.
In the physical world, you can give one of your possessions to someone for a
-short period of time. You still own your posession, you're just letting someone
+short period of time. You still own your possession, you're just letting someone
else use it for a while. We call that 'lending' something to someone, and that
person is said to be 'borrowing' that something from you.
-Rust's ownershp system also allows an owner to lend out a handle for a limited
+Rust's ownership system also allows an owner to lend out a handle for a limited
period. This is also called 'borrowing.' Here's a version of `add_one` which
borrows its argument rather than taking ownership:
Rust has a feature called 'lifetime elision,' which allows you to not write
lifetime annotations in certain circumstances. This is one of them. Without
-eliding the liftimes, `add_one` looks like this:
+eliding the lifetimes, `add_one` looks like this:
```rust
fn add_one<'a>(num: &'a int) -> int {
fn add_two<'a, 'b>(...)
```
-Then in our parameter list, we use the liftimes we've named:
+Then in our parameter list, we use the lifetimes we've named:
```{rust,ignore}
...(num: &'a int) -> ...
}
```
-As you can see, `struct`s can also have liftimes. In a similar way to functions,
+As you can see, `struct`s can also have lifetimes. In a similar way to functions,
```{rust}
struct Foo<'a> {
# }
```
-uses it. So why do we need a liftime here? We need to ensure that any reference
+uses it. So why do we need a lifetime here? We need to ensure that any reference
to a `Foo` cannot outlive the reference to an `int` it contains.
## Thinking in scopes
We try to make four `Wheel`s, each with a `Car` that it's attached to. But the
compiler knows that on the second iteration of the loop, there's a problem:
-```{notrust,ignore}
+```{notrust}
error: use of moved value: `car`
Wheel { size: 360, owner: car };
^~~
This gives us an error:
-```{notrust,ignore}
+```{notrust}
hello.rs:6:24: 6:25 error: mismatched types: expected `int` but found `&int` (expected int but found &-ptr)
hello.rs:6 println!("{}", x + z);
^
pass-by-reference. Basically, languages can make two choices (this is made
up syntax, it's not Rust):
-```{notrust,ignore}
+```{ignore}
func foo(x) {
x = 5
}
So what do pointers have to do with this? Well, since pointers point to a
location in memory...
-```{notrust,ignore}
+```{ignore}
func foo(&int x) {
*x = 5
}
Uninitialized pointers can cause a problem. For example, what does this program
do?
-```{notrust,ignore}
+```{ignore}
&int x;
*x = 5; // whoops!
```
When you combine pointers and functions, it's easy to accidentally invalidate
the memory the pointer is pointing to. For example:
-```{notrust,ignore}
+```{ignore}
func make_pointer(): &int {
x = 5;
issue. Two pointers are said to alias when they point at the same location
in memory. Like this:
-```{notrust,ignore}
+```{ignore}
func mutate(&int i, int j) {
*i = j;
}
It gives this error:
-```{notrust,ignore}
+```{notrust}
test.rs:5:8: 5:10 error: cannot assign to `*x` because it is borrowed
test.rs:5 *x -= 1;
^~
As being similar to this C code:
-```{notrust,ignore}
+```{ignore}
{
int *x;
x = (int *)malloc(sizeof(int));
This prints:
-```{notrust,ignore}
+```{ignore}
Cons(1, box Cons(2, box Cons(3, box Nil)))
```
This prints:
-```{notrust,ignore}
+```{text}
u͔
n͈̰̎
i̙̮͚̦
This prints:
-```{notrust,ignore}
+```{text}
u
͔
n
This will print:
-```{notrust,ignore}
+```{text}
117
205
148
fn abort() -> !;
}
+#[lang = "owned_box"]
+pub struct Box<T>(*mut T);
+
#[lang="exchange_malloc"]
unsafe fn allocate(size: uint, _align: uint) -> *mut u8 {
let p = libc::malloc(size as libc::size_t) as *mut u8;
You'll also notice that Cargo has created a new file: `Cargo.lock`.
-```{ignore,notrust}
+```{ignore}
[root]
name = "hello_world"
version = "0.0.1"
It will give you this error:
-```{ignore,notrust}
+```{notrust}
error: re-assignment of immutable variable `x`
x = 10i;
^~~~~~~
You can use `cargo build` on the command line to build it. You'll get a warning,
but it will still print "Hello, world!":
-```{ignore,notrust}
+```{notrust}
Compiling hello_world v0.0.1 (file:///home/you/projects/hello_world)
src/main.rs:2:9: 2:10 warning: unused variable: `x`, #[warn(unused_variable)] on by default
src/main.rs:2 let x: int;
Note the semicolons after the 10 and 15. Rust will give us the following error:
-```{ignore,notrust}
+```{notrust}
error: mismatched types: expected `int` but found `()` (expected int but found ())
```
You get this error:
-```{ignore,notrust}
+```{notrust}
hello.rs:5:18: 5:19 error: expected `:` but found `,`
hello.rs:5 fn print_number(x, y) {
```
We would get an error:
-```{ignore,notrust}
+```{ignore}
error: not all control paths return a value
fn add_one(x: int) -> int {
x + 1;
`ErrorReason` with a `String` explaining what caused the computation to fail. These kinds of
`enum`s are actually very useful and are even part of the standard library.
+Enum variants are namespaced under the enum names. For example, here is an example of using
+our `StringResult`:
+
+```rust
+# enum StringResult {
+# StringOK(String),
+# ErrorReason(String),
+# }
+fn respond(greeting: &str) -> StringResult {
+ if greeting == "Hello" {
+ StringResult::StringOK("Good morning!".to_string())
+ } else {
+ StringResult::ErrorReason("I didn't understand you!".to_string())
+ }
+}
+```
+
+Notice that we need both the enum name and the variant name: `StringResult::StringOK`, but
+we didn't need to with `Ordering`, we just said `Greater` rather than `Ordering::Greater`.
+There's a reason: the Rust prelude imports the variants of `Ordering` as well as the enum
+itself. We can use the `use` keyword to do something similar with `StringResult`:
+
+```rust
+use StringResult::StringOK;
+use StringResult::ErrorReason;
+
+enum StringResult {
+ StringOK(String),
+ ErrorReason(String),
+}
+
+# fn main() {}
+
+fn respond(greeting: &str) -> StringResult {
+ if greeting == "Hello" {
+ StringOK("Good morning!".to_string())
+ } else {
+ ErrorReason("I didn't understand you!".to_string())
+ }
+}
+```
+
+We'll learn more about `use` later, but it's used to bring names into scope. `use` declarations
+must come before anything else, which looks a little strange in this example, since we `use`
+the variants before we define them. Anyway, in the body of `respond`, we can just say `StringOK`
+now, rather than the full `StringResult::StringOK`. Importing variants can be convenient, but can
+also cause name conflicts, so do this with caution. It's considered good style to rarely import
+variants for this reason.
+
As you can see `enum`s with values are quite a powerful tool for data representation,
and can be even more useful when they're generic across types. But before we get to
generics, let's talk about how to use them with pattern matching, a tool that will
enforces 'exhaustiveness checking.' Do you see that last arm, the one with the
underscore (`_`)? If we remove that arm, Rust will give us an error:
-```{ignore,notrust}
+```{notrust}
error: non-exhaustive patterns: `_` not covered
```
In slightly more abstract terms,
-```{ignore,notrust}
+```{ignore}
for var in expression {
code
}
is kind of like `cargo build`, but it also then runs the produced executable.
Try it out:
-```{notrust,ignore}
+```{notrust}
$ cargo run
Compiling guessing_game v0.0.1 (file:///home/you/projects/guessing_game)
Running `target/guessing_game`
Let's try to compile this using `cargo build`:
-```{notrust,no_run}
+```{notrust}
$ cargo build
Compiling guessing_game v0.0.1 (file:///home/you/projects/guessing_game)
src/main.rs:7:26: 7:34 error: the type of this value must be known in this context
Try running our new program a few times:
-```{notrust,ignore}
+```{notrust}
$ cargo run
Compiling guessing_game v0.0.1 (file:///home/you/projects/guessing_game)
Running `target/guessing_game`
And trying it out:
-```{notrust,ignore}
+```{notrust}
$ cargo run
Compiling guessing_game v0.0.1 (file:///home/you/projects/guessing_game)
Running `target/guessing_game`
If we try to compile, we'll get some errors:
-```{notrust,ignore}
+```{notrust}
$ cargo build
Compiling guessing_game v0.0.1 (file:///home/you/projects/guessing_game)
src/main.rs:20:15: 20:20 error: mismatched types: expected `int` but found `collections::string::String` (expected int but found struct collections::string::String)
And try compiling again:
-```{notrust,ignore}
+```{notrust}
$ cargo build
Compiling guessing_game v0.0.1 (file:///home/you/projects/guessing_game)
src/main.rs:20:15: 20:20 error: mismatched types: expected `uint` but found `collections::string::String` (expected uint but found struct collections::string::String)
a `String` instead! That's because our `input` variable is coming from the
standard input, and you can guess anything. Try it:
-```{notrust,ignore}
+```{notrust}
$ ./target/guessing_game
Guess the number!
The secret number is: 73
Let's try it out!
-```{notrust,ignore}
+```{notrust}
$ cargo build
Compiling guessing_game v0.0.1 (file:///home/you/projects/guessing_game)
src/main.rs:22:15: 22:24 error: mismatched types: expected `uint` but found `core::option::Option<uint>` (expected uint but found enum core::option::Option)
We use a `match` to either give us the `uint` inside of the `Option`, or we
print an error message and return. Let's give this a shot:
-```{notrust,ignore}
+```{notrust}
$ cargo run
Compiling guessing_game v0.0.1 (file:///home/you/projects/guessing_game)
Running `target/guessing_game`
Let's try it!
-```{notrust,ignore}
+```{notrust}
$ cargo run
Compiling guessing_game v0.0.1 (file:///home/you/projects/guessing_game)
Running `target/guessing_game`
And try it out. But wait, didn't we just add an infinite loop? Yup. Remember
that `return`? If we give a non-number answer, we'll `return` and quit. Observe:
-```{notrust,ignore}
+```{notrust}
$ cargo run
Compiling guessing_game v0.0.1 (file:///home/you/projects/guessing_game)
Running `target/guessing_game`
Now we should be good! Let's try:
-```{notrust,ignore}
+```{notrust}
$ cargo run
Compiling guessing_game v0.0.1 (file:///home/you/projects/guessing_game)
Running `target/guessing_game`
Let's double check our work by compiling:
-```{bash,notrust}
+```{bash}
$ cargo run
Compiling modules v0.0.1 (file:///home/you/projects/modules)
Running `target/modules`
It gives an error:
-```{notrust,ignore}
+```{notrust}
Compiling modules v0.0.1 (file:///home/you/projects/modules)
src/main.rs:2:5: 2:23 error: function `print_hello` is private
src/main.rs:2 hello::print_hello();
Usage of the `pub` keyword is sometimes called 'exporting', because
we're making the function available for other modules. This will work:
-```{notrust,ignore}
+```{notrust}
$ cargo run
Compiling modules v0.0.1 (file:///home/you/projects/modules)
Running `target/modules`
And try it out:
-```{notrust,ignore}
+```{notrust}
$ cargo run
Compiling testing v0.0.1 (file:///home/you/projects/testing)
Running `target/testing`
macro, `assert!`, to assert that something is true. In this case, we're giving
it `false`, so this test should fail. Let's try it!
-```{notrust,ignore}
+```{notrust}
$ cargo test
Compiling testing v0.0.1 (file:///home/you/projects/testing)
/home/you/projects/testing/src/main.rs:1:1: 3:2 warning: function is never used: `main`, #[warn(dead_code)] on by default
Lots of output! Let's break this down:
-```{notrust,ignore}
+```{ignore}
$ cargo test
Compiling testing v0.0.1 (file:///home/you/projects/testing)
```
You can run all of your tests with `cargo test`. This runs both your tests in
`tests`, as well as the tests you put inside of your crate.
-```{notrust,ignore}
+```{notrust}
/home/you/projects/testing/src/main.rs:1:1: 3:2 warning: function is never used: `main`, #[warn(dead_code)] on by default
/home/you/projects/testing/src/main.rs:1 fn main() {
/home/you/projects/testing/src/main.rs:2 println!("Hello, world!")
We'll turn this lint off for just this function soon. For now, just ignore this
output.
-```{notrust,ignore}
+```{ignore}
Running target/lib-654ce120f310a3a5
running 1 test
test 'foo.' If we had given it a good name, it'd be more clear which test
failed, especially as we accumulate more tests.
-```{notrust,ignore}
+```{notrust}
failures:
---- foo stdout ----
And then try to run our tests again:
-```{notrust,ignore}
+```{ignore}
$ cargo test
Compiling testing v0.0.1 (file:///home/you/projects/testing)
Running target/lib-654ce120f310a3a5
With this attribute we won't get the warning (even
though `src/main.rs` gets recompiled this time):
-```{notrust,ignore}
+```{ignore}
$ cargo test
Compiling testing v0.0.1 (file:///home/you/projects/testing)
Running target/lib-654ce120f310a3a5
And try to run the test:
-```{notrust,ignore}
+```{notrust}
$ cargo test
Compiling testing v0.0.1 (file:///home/you/projects/testing)
/home/you/projects/testing/tests/lib.rs:3:18: 3:38 error: unresolved name `add_three_times_four`.
Let's give it a run:
-```{ignore,notrust}
+```{ignore}
$ cargo test
Compiling testing v0.0.1 (file:///home/you/projects/testing)
Running target/lib-654ce120f310a3a5
If you run `cargo test`, you should get the same output:
-```{ignore,notrust}
+```{ignore}
$ cargo test
Compiling testing v0.0.1 (file:///home/you/projects/testing)
Running target/lib-654ce120f310a3a5
We'd get this error:
-```{notrust,ignore}
+```{notrust}
Compiling testing v0.0.1 (file:///home/you/projects/testing)
/home/you/projects/testing/tests/lib.rs:3:5: 3:24 error: function `add_three` is private
/home/you/projects/testing/tests/lib.rs:3 use testing::add_three;
Let's give it a shot:
-```{ignore,notrust}
+```{ignore}
$ cargo test
Compiling testing v0.0.1 (file:///home/you/projects/testing)
Running target/lib-654ce120f310a3a5
Rust will complain:
-```{ignore,notrust}
+```{notrust}
error: cannot borrow immutable local variable `x` as mutable
let y = &mut x;
^
It gives us this error:
-```{notrust,ignore}
+```{notrust}
error: cannot borrow `x` as mutable more than once at a time
let z = &mut x;
^
The error:
-```{notrust,ignore}
+```{notrust}
error: cannot borrow `x` as mutable more than once at a time
let z = &mut x;
^
This error comes in three parts. Let's go over each in turn.
-```{notrust,ignore}
+```{notrust}
error: cannot borrow `x` as mutable more than once at a time
let z = &mut x;
^
This error states the restriction: you cannot lend out something mutable more
than once at the same time. The borrow checker knows the rules!
-```{notrust,ignore}
+```{notrust}
note: previous borrow of `x` occurs here; the mutable borrow prevents subsequent moves, borrows, or modification of `x` until the borrow ends
let y = &mut x;
^
see both parts of the problem. It also alludes to rule #3, by reminding us that
we can't change `x` until the borrow is over.
-```{notrust,ignore}
+```{ignore}
note: previous borrow ends here
fn main() {
let mut x = 5i;
This is useful, because if we wait to try to borrow `x` after this borrow is
over, then everything will work.
-For more advanced patterns, please consult the [Lifetime
-Guide](guide-lifetimes.html). You'll also learn what this type signature with
+For more advanced patterns, please consult the [Ownership
+Guide](guide-ownership.html). You'll also learn what this type signature with
the `'a` syntax is:
```{rust,ignore}
This gives us this error:
-```{notrust,ignore}
+```{notrust}
error: cannot use `*x` because it was mutably borrowed
*x;
^~
So this would give us the numbers from `2-100`. Well, almost! If you
compile the example, you'll get a warning:
-```{notrust,ignore}
+```{ignore}
warning: unused result which must be used: iterator adaptors are lazy and
do nothing unless consumed, #[warn(unused_must_use)] on by default
range(1i, 100i).map(|x| x + 1i);
This will print
-```{notrust,ignore}
+```{ignore}
1
6
11
of the `Result` has type `T`. However, if we try to compile that example, we'll get
an error:
-```{notrust,ignore}
+```{notrust}
error: binary operation `==` cannot be applied to type `T`
```
So what's the big deal? Remember the error we were getting with our generic
`inverse` function?
-```{notrust,ignore}
+```{notrust}
error: binary operation `==` cannot be applied to type `T`
```
Rust complains:
-```{notrust,ignore}
+```{notrust}
error: type `T` does not implement any method in scope named `area`
```
This program outputs:
-```{notrust,ignore}
+```{ignore}
This shape has an area of 3.141593
This shape has an area of 1
```
We get a compile-time error:
-```{notrust,ignore}
+```{ignore}
error: failed to find an implementation of trait main::HasArea for int
```
Now that we've moved the structs and traits into their own module, we get an
error:
-```{notrust,ignore}
+```{notrust}
error: type `shapes::Circle` does not implement any method in scope named `area`
```
```
This is called a **manifest**, and it contains all of the metadata that Cargo
-needs to compile your project.
+needs to compile your project.
Here's what's in `src/main.rs`:
```{rust}
fn main() {
- println!("Hello, world!")
+ println!("Hello, world!");
}
```
```{bash}
$ g++ hello.cpp -Wall -Werror
-$ ./a.out
+$ ./a.out
Segmentation fault (core dumped)
```
Neither. It refuses to compile:
-```{notrust,ignore}
+```{notrust}
$ cargo run
Compiling hello_world v0.0.1 (file:///Users/you/src/hello_world)
main.rs:8:5: 8:6 error: cannot borrow `v` as mutable because it is also borrowed as immutable
It gives us this error:
-```{notrust,ignore}
+```{notrust}
6:71 error: capture of moved value: `numbers`
for j in range(0, 3) { numbers[j] += 1 }
^~~~~~~
A _floating-point literal_ has one of two forms:
-* Two _decimal literals_ separated by a period
- character `U+002E` (`.`), with an optional _exponent_ trailing after the
- second decimal literal.
+* A _decimal literal_ followed by a period character `U+002E` (`.`). This is
+ optionally followed by another decimal literal, with an optional _exponent_.
* A single _decimal literal_ followed by an _exponent_.
By default, a floating-point literal has a generic type, and, like integer
Examples of floating-point literals of various forms:
```
-123.0f64; // type f64
-0.1f64; // type f64
-0.1f32; // type f32
-12E+99_f64; // type f64
+123.0f64; // type f64
+0.1f64; // type f64
+0.1f32; // type f32
+12E+99_f64; // type f64
+let x: f64 = 2.; // type f64
```
+This last example is different because it is not possible to use the suffix
+syntax with a floating point literal ending in a period. `2.f64` would attempt
+to call a method named `f64` on `2`.
+
##### Boolean literals
The two values of the boolean type are written `true` and `false`.
```
# struct Point {x: f64, y: f64};
+# impl Copy for Point {}
# type Surface = int;
# struct BoundingBox {x: f64, y: f64, width: f64, height: f64};
# trait Shape { fn draw(&self, Surface); fn bounding_box(&self) -> BoundingBox; }
center: Point,
}
+impl Copy for Circle {}
+
impl Shape for Circle {
fn draw(&self, s: Surface) { do_draw_circle(s, *self); }
fn bounding_box(&self) -> BoundingBox {
it can be thought of as being accessible to the outside world. For example:
```
+# #![allow(missing_copy_implementations)]
# fn main() {}
// Declare a private struct
struct Foo;
# option. This file may not be copied, modified, or distributed
# except according to those terms.
+# Script parameters:
+# argv[1] = rust component root,
+# argv[2] = gcc component root,
+# argv[3] = target triple
+# The first two correspond to the two installable components defined in the setup script.
+
import sys, os, shutil, subprocess
def find_files(files, path):
raise Exception("Could not find '%s' in %s" % (fname, path))
return found
-def make_win_dist(dist_root, target_triple):
+def make_win_dist(rust_root, gcc_root, target_triple):
# Ask gcc where it keeps its stuff
gcc_out = subprocess.check_output(["gcc.exe", "-print-search-dirs"])
bin_path = os.environ["PATH"].split(os.pathsep)
target_libs = find_files(target_libs, lib_path)
# Copy runtime dlls next to rustc.exe
- dist_bin_dir = os.path.join(dist_root, "bin")
+ dist_bin_dir = os.path.join(rust_root, "bin")
for src in rustc_dlls:
shutil.copy(src, dist_bin_dir)
# Copy platform tools to platform-specific bin directory
- target_bin_dir = os.path.join(dist_root, "bin", "rustlib", target_triple, "bin")
+ target_bin_dir = os.path.join(gcc_root, "bin", "rustlib", target_triple, "bin")
if not os.path.exists(target_bin_dir):
os.makedirs(target_bin_dir)
for src in target_tools:
shutil.copy(src, target_bin_dir)
# Copy platform libs to platform-spcific lib directory
- target_lib_dir = os.path.join(dist_root, "bin", "rustlib", target_triple, "lib")
+ target_lib_dir = os.path.join(gcc_root, "bin", "rustlib", target_triple, "lib")
if not os.path.exists(target_lib_dir):
os.makedirs(target_lib_dir)
for src in target_libs:
shutil.copy(src, target_lib_dir)
# Copy license files
- lic_dir = os.path.join(dist_root, "bin", "third-party")
+ lic_dir = os.path.join(rust_root, "bin", "third-party")
if os.path.exists(lic_dir):
shutil.rmtree(lic_dir) # copytree() won't overwrite existing files
shutil.copytree(os.path.join(os.path.dirname(__file__), "third-party"), lic_dir)
if __name__=="__main__":
- make_win_dist(sys.argv[1], sys.argv[2])
+ make_win_dist(sys.argv[1], sys.argv[2], sys.argv[3])
VersionInfoVersion={#CFG_VERSION_WIN}
LicenseFile=LICENSE.txt
+PrivilegesRequired=lowest
DisableWelcomePage=true
DisableProgramGroupPage=true
DisableReadyPage=true
[Tasks]
Name: modifypath; Description: &Add {app}\bin to your PATH (recommended)
+[Components]
+Name: rust; Description: "Rust compiler and standard crates"; Types: full compact custom; Flags: fixed
+Name: gcc; Description: "Linker and platform libraries"; Types: full
+
[Files]
-Source: "tmp/dist/win/*.*" ; DestDir: "{app}"; Flags: ignoreversion recursesubdirs
+Source: "tmp/dist/win/rust/*.*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs; Components: rust
+Source: "tmp/dist/win/gcc/*.*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs; Components: gcc
[Code]
const
#![stable]
+use core::borrow::BorrowFrom;
use core::cell::Cell;
use core::clone::Clone;
use core::cmp::{PartialEq, PartialOrd, Eq, Ord, Ordering};
}
}
+impl<T> BorrowFrom<Rc<T>> for T {
+ fn borrow_from(owned: &Rc<T>) -> &T {
+ &**owned
+ }
+}
+
#[experimental = "Deref is experimental."]
impl<T> Deref<T> for Rc<T> {
#[inline(always)]
}
let ptr: &mut T = unsafe {
- let ptr: &mut T = mem::transmute(self.ptr);
+ let ptr: &mut T = mem::transmute(self.ptr.clone());
ptr::write(ptr, object);
self.ptr.set(self.ptr.get().offset(1));
ptr
//! position: uint
//! }
//!
+//! impl Copy for State {}
+//!
//! // The priority queue depends on `Ord`.
//! // Explicitly implement the trait so the queue becomes a min-heap
//! // instead of a max-heap.
impl<K, V> BTreeMap<K, V> {
/// Gets an iterator over the entries of the map.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::BTreeMap;
+ ///
+ /// let mut map = BTreeMap::new();
+ /// map.insert(1u, "a");
+ /// map.insert(2u, "b");
+ /// map.insert(3u, "c");
+ ///
+ /// for (key, value) in map.iter() {
+ /// println!("{}: {}", key, value);
+ /// }
+ ///
+ /// let (first_key, first_value) = map.iter().next().unwrap();
+ /// assert_eq!((*first_key, *first_value), (1u, "a"));
+ /// ```
#[unstable = "matches collection reform specification, waiting for dust to settle"]
pub fn iter<'a>(&'a self) -> Entries<'a, K, V> {
let len = self.len();
//! A doubly-linked list with owned nodes.
//!
//! The `DList` allows pushing and popping elements at either end.
-//!
-//! `DList` implements the trait `Deque`. It should be imported with
-//! `use collections::Deque`.
// DList is constructed like a singly-linked list over the field `next`.
// including the last link being None; each Node owns its `next` field.
}
type Link<T> = Option<Box<Node<T>>>;
-struct Rawlink<T> { p: *mut T }
+
+struct Rawlink<T> {
+ p: *mut T,
+}
+
+impl<T> Copy for Rawlink<T> {}
struct Node<T> {
next: Link<T>,
fn clone(&self) -> Items<'a, T> { *self }
}
+impl<'a,T> Copy for Items<'a,T> {}
+
/// An iterator over mutable references to the items of a `DList`.
pub struct MutItems<'a, T:'a> {
list: &'a mut DList<T>,
bits: uint
}
+impl<E> Copy for EnumSet<E> {}
+
impl<E:CLike+fmt::Show> fmt::Show for EnumSet<E> {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
try!(write!(fmt, "{{"));
A, B, C
}
+ impl Copy for Foo {}
+
impl CLike for Foo {
fn to_uint(&self) -> uint {
*self as uint
V50, V51, V52, V53, V54, V55, V56, V57, V58, V59,
V60, V61, V62, V63, V64, V65, V66, V67, V68, V69,
}
+
+ impl Copy for Bar {}
+
impl CLike for Bar {
fn to_uint(&self) -> uint {
*self as uint
ntail: uint, // how many bytes in tail are valid
}
+impl Copy for SipState {}
+
// sadly, these macro definitions can't appear later,
// because they're needed in the following defs;
// this design could be improved.
/// `SipHasher` computes the SipHash algorithm from a stream of bytes.
#[deriving(Clone)]
+#[allow(missing_copy_implementations)]
pub struct SipHasher {
k0: u64,
k1: u64,
//! This crate implements a double-ended queue with `O(1)` amortized inserts and removals from both
//! ends of the container. It also has `O(1)` indexing like a vector. The contained elements are
//! not required to be copyable, and the queue will be sendable if the contained type is sendable.
-//! Its interface `Deque` is defined in `collections`.
use core::prelude::*;
// FIXME(conventions): implement shrink_to_fit. Awkward with the current design, but it should
// be scrapped anyway. Defer to rewrite?
-/// `RingBuf` is a circular buffer that implements `Deque`.
+/// `RingBuf` is a circular buffer.
pub struct RingBuf<T> {
// tail and head are pointers into the buffer. Tail always points
// to the first element that could be read, Head always points
use alloc::boxed::Box;
use core::borrow::{BorrowFrom, BorrowFromMut, ToOwned};
use core::cmp;
-use core::kinds::Sized;
+use core::kinds::{Copy, Sized};
use core::mem::size_of;
use core::mem;
use core::prelude::{Clone, Greater, Iterator, IteratorExt, Less, None, Option};
enum Direction { Pos, Neg }
+impl Copy for Direction {}
+
/// An `Index` and `Direction` together.
struct SizeDirection {
size: uint,
dir: Direction,
}
+impl Copy for SizeDirection {}
+
impl Iterator<(uint, uint)> for ElementSwaps {
#[inline]
fn next(&mut self) -> Option<(uint, uint)> {
fn clone(&self) -> S {
self.f.set(self.f.get() + 1);
if self.f.get() == 10 { panic!() }
- S { f: self.f, boxes: self.boxes.clone() }
+ S {
+ f: self.f.clone(),
+ boxes: self.boxes.clone(),
+ }
}
}
- let s = S { f: Cell::new(0), boxes: (box 0, Rc::new(0)) };
+ let s = S {
+ f: Cell::new(0),
+ boxes: (box 0, Rc::new(0)),
+ };
let _ = Vec::from_elem(100, s);
}
_ => self.sorted = false
}
- let decomposer = match self.kind {
- Canonical => unicode::char::decompose_canonical,
- Compatible => unicode::char::decompose_compatible
- };
-
if !self.sorted {
for ch in self.iter {
let buffer = &mut self.buffer;
let sorted = &mut self.sorted;
- decomposer(ch, |d| {
- let class = unicode::char::canonical_combining_class(d);
- if class == 0 && !*sorted {
- canonical_sort(buffer.as_mut_slice());
- *sorted = true;
+ {
+ let callback = |d| {
+ let class =
+ unicode::char::canonical_combining_class(d);
+ if class == 0 && !*sorted {
+ canonical_sort(buffer.as_mut_slice());
+ *sorted = true;
+ }
+ buffer.push((d, class));
+ };
+ match self.kind {
+ Canonical => {
+ unicode::char::decompose_canonical(ch, callback)
+ }
+ Compatible => {
+ unicode::char::decompose_compatible(ch, callback)
+ }
}
- buffer.push((d, class));
- });
- if *sorted { break }
+ }
+ if *sorted {
+ break
+ }
}
}
}
}
+#[experimental = "waiting on FromIterator stabilization"]
+impl<'a> FromIterator<&'a str> for String {
+ fn from_iter<I:Iterator<&'a str>>(iterator: I) -> String {
+ let mut buf = String::new();
+ buf.extend(iterator);
+ buf
+ }
+}
+
#[experimental = "waiting on Extend stabilization"]
impl Extend<char> for String {
fn extend<I:Iterator<char>>(&mut self, mut iterator: I) {
+ let (lower_bound, _) = iterator.size_hint();
+ self.reserve(lower_bound);
for ch in iterator {
self.push(ch)
}
}
}
+#[experimental = "waiting on Extend stabilization"]
+impl<'a> Extend<&'a str> for String {
+ fn extend<I: Iterator<&'a str>>(&mut self, mut iterator: I) {
+ // A guess that at least one byte per iterator element will be needed.
+ let (lower_bound, _) = iterator.size_hint();
+ self.reserve(lower_bound);
+ for s in iterator {
+ self.push_str(s)
+ }
+ }
+}
+
impl PartialEq for String {
#[inline]
fn eq(&self, other: &String) -> bool { PartialEq::eq(&**self, &**other) }
"[[], [1], [1, 1]]");
}
+ #[test]
+ fn test_from_iterator() {
+ let s = "ศไทย中华Việt Nam".to_string();
+ let t = "ศไทย中华";
+ let u = "Việt Nam";
+
+ let a: String = s.chars().collect();
+ assert_eq!(s, a);
+
+ let mut b = t.to_string();
+ b.extend(u.chars());
+ assert_eq!(s, b);
+
+ let c: String = vec![t, u].into_iter().collect();
+ assert_eq!(s, c);
+
+ let mut d = t.to_string();
+ d.extend(vec![u].into_iter());
+ assert_eq!(s, d);
+ }
+
#[bench]
fn bench_with_capacity(b: &mut Bencher) {
b.iter(|| {
use intrinsics;
use std::kinds::marker;
use cell::UnsafeCell;
+use kinds::Copy;
/// A boolean type which can be safely shared between threads.
#[stable]
SeqCst,
}
+impl Copy for Ordering {}
+
/// An `AtomicBool` initialized to `false`.
#[unstable = "may be renamed, pending conventions for static initalizers"]
pub const INIT_ATOMIC_BOOL: AtomicBool =
pub use self::Ordering::*;
-use kinds::Sized;
-use option::Option;
-use option::Option::{Some, None};
+use kinds::{Copy, Sized};
+use option::Option::{mod, Some, None};
/// Trait for values that can be compared for equality and inequality.
///
Greater = 1i,
}
+impl Copy for Ordering {}
+
impl Ordering {
/// Reverse the `Ordering`, so that `Less` becomes `Greater` and
/// vice versa.
#[experimental = "core and I/O reconciliation may alter this definition"]
pub struct Error;
+impl Copy for Error {}
+
/// A collection of methods that are required to format a message into a stream.
///
/// This trait is the type which this modules requires when formatting
}
}
+impl<'a> Copy for Argument<'a> {}
+
impl<'a> Arguments<'a> {
/// When using the format_args!() macro, this function is used to generate the
/// Arguments structure.
use fmt;
use iter::DoubleEndedIteratorExt;
+use kinds::Copy;
use num::{Int, cast};
use slice::SlicePrelude;
base: u8,
}
+impl Copy for Radix {}
+
impl Radix {
fn new(base: u8) -> Radix {
assert!(2 <= base && base <= 36, "the base must be in the range of 2..36: {}", base);
#[unstable = "may be renamed or move to a different module"]
pub struct RadixFmt<T, R>(T, R);
+impl<T,R> Copy for RadixFmt<T,R> where T: Copy, R: Copy {}
+
/// Constructs a radix formatter in the range of `2..36`.
///
/// # Example
pub use self::Count::*;
pub use self::Position::*;
pub use self::Flag::*;
+use kinds::Copy;
#[doc(hidden)]
pub struct Argument<'a> {
pub format: FormatSpec,
}
+impl<'a> Copy for Argument<'a> {}
+
#[doc(hidden)]
pub struct FormatSpec {
pub fill: char,
pub width: Count,
}
+impl Copy for FormatSpec {}
+
/// Possible alignments that can be requested as part of a formatting directive.
#[deriving(PartialEq)]
pub enum Alignment {
AlignUnknown,
}
+impl Copy for Alignment {}
+
#[doc(hidden)]
pub enum Count {
CountIs(uint), CountIsParam(uint), CountIsNextParam, CountImplied,
}
+impl Copy for Count {}
+
#[doc(hidden)]
pub enum Position {
ArgumentNext, ArgumentIs(uint)
}
+impl Copy for Position {}
+
/// Flags which can be passed to formatting via a directive.
///
/// These flags are discovered through the `flags` field of the `Formatter`
/// being aware of the sign to be printed.
FlagSignAwareZeroPad,
}
+
+impl Copy for Flag {}
#![experimental]
#![allow(missing_docs)]
+use kinds::Copy;
+
pub type GlueFn = extern "Rust" fn(*const i8);
#[lang="ty_desc"]
pub name: &'static str,
}
+impl Copy for TyDesc {}
+
extern "rust-intrinsic" {
// NB: These intrinsics take unsafe pointers because they mutate aliased
t: u64,
}
+impl Copy for TypeId {}
+
impl TypeId {
/// Returns the `TypeId` of the type this generic function has been instantiated with
pub fn of<T: 'static>() -> TypeId {
use clone::Clone;
use cmp;
use cmp::Ord;
+use kinds::Copy;
use mem;
use num::{ToPrimitive, Int};
use ops::{Add, Deref};
iter: T,
}
-#[unstable = "trait is unstable"]
+impl<T:Copy> Copy for Cycle<T> {}
+
impl<A, T: Clone + Iterator<A>> Iterator<A> for Cycle<T> {
#[inline]
fn next(&mut self) -> Option<A> {
peeked: Option<A>,
}
-#[unstable = "trait is unstable"]
+impl<T:Copy,A:Copy> Copy for Peekable<A,T> {}
+
impl<A, T: Iterator<A>> Iterator<A> for Peekable<A, T> {
#[inline]
fn next(&mut self) -> Option<A> {
step: A,
}
+impl<A:Copy> Copy for Counter<A> {}
+
/// Creates a new counter with the specified start/step
#[inline]
#[unstable = "may be renamed"]
one: A,
}
+impl<A:Copy> Copy for Range<A> {}
+
/// Returns an iterator over the given range [start, stop) (that is, starting
/// at start (inclusive), and ending at stop (exclusive)).
///
/// implemented using unsafe code. In that case, you may want to embed
/// some of the marker types below into your type.
pub mod marker {
+ use super::Copy;
+
/// 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
#[deriving(Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct CovariantType<T>;
+ impl<T> Copy for CovariantType<T> {}
+
/// A marker type whose type parameter `T` is considered to be
/// contravariant with respect to the type itself. This is (typically)
/// used to indicate that an instance of the type `T` will be consumed
#[deriving(Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct ContravariantType<T>;
+ impl<T> Copy for ContravariantType<T> {}
+
/// A marker type whose type parameter `T` is considered to be
/// invariant with respect to the type itself. This is (typically)
/// used to indicate that instances of the type `T` may be read or
#[deriving(Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct InvariantType<T>;
+ impl<T> Copy for InvariantType<T> {}
+
/// As `CovariantType`, but for lifetime parameters. Using
/// `CovariantLifetime<'a>` indicates that it is ok to substitute
/// a *longer* lifetime for `'a` than the one you originally
#[deriving(Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct CovariantLifetime<'a>;
+ impl<'a> Copy for CovariantLifetime<'a> {}
+
/// As `ContravariantType`, but for lifetime parameters. Using
/// `ContravariantLifetime<'a>` indicates that it is ok to
/// substitute a *shorter* lifetime for `'a` than the one you
#[deriving(Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct ContravariantLifetime<'a>;
+ impl<'a> Copy for ContravariantLifetime<'a> {}
+
/// As `InvariantType`, but for lifetime parameters. Using
/// `InvariantLifetime<'a>` indicates that it is not ok to
/// substitute any other lifetime for `'a` besides its original
/// their instances remain thread-local.
#[lang="no_send_bound"]
#[deriving(Clone, PartialEq, Eq, PartialOrd, Ord)]
+ #[allow(missing_copy_implementations)]
pub struct NoSend;
/// A type which is considered "not POD", meaning that it is not
/// ensure that they are never copied, even if they lack a destructor.
#[lang="no_copy_bound"]
#[deriving(Clone, PartialEq, Eq, PartialOrd, Ord)]
+ #[allow(missing_copy_implementations)]
pub struct NoCopy;
/// A type which is considered "not sync", meaning that
/// shared between tasks.
#[lang="no_sync_bound"]
#[deriving(Clone, PartialEq, Eq, PartialOrd, Ord)]
+ #[allow(missing_copy_implementations)]
pub struct NoSync;
/// A type which is considered managed by the GC. This is typically
/// embedded in other types.
#[lang="managed_bound"]
#[deriving(Clone, PartialEq, Eq, PartialOrd, Ord)]
+ #[allow(missing_copy_implementations)]
pub struct Managed;
}
+
html_playground_url = "http://play.rust-lang.org/")]
#![no_std]
-#![allow(unknown_features)]
+#![allow(unknown_features, raw_pointer_deriving)]
#![feature(globs, intrinsics, lang_items, macro_rules, phase)]
#![feature(simd, unsafe_destructor, slicing_syntax)]
-#![feature(default_type_params)]
+#![feature(default_type_params, unboxed_closures)]
#![deny(missing_docs)]
mod macros;
FPNormal,
}
+impl Copy for FPCategory {}
+
/// A built-in floating point number.
// FIXME(#5527): In a future version of Rust, many of these functions will
// become constants.
/// ```rust
/// struct Foo;
///
+/// impl Copy for Foo {}
+///
/// impl Add<Foo, Foo> for Foo {
/// fn add(&self, _rhs: &Foo) -> Foo {
/// println!("Adding!");
/// ```rust
/// struct Foo;
///
+/// impl Copy for Foo {}
+///
/// impl Sub<Foo, Foo> for Foo {
/// fn sub(&self, _rhs: &Foo) -> Foo {
/// println!("Subtracting!");
/// ```rust
/// struct Foo;
///
+/// impl Copy for Foo {}
+///
/// impl Mul<Foo, Foo> for Foo {
/// fn mul(&self, _rhs: &Foo) -> Foo {
/// println!("Multiplying!");
/// ```
/// struct Foo;
///
+/// impl Copy for Foo {}
+///
/// impl Div<Foo, Foo> for Foo {
/// fn div(&self, _rhs: &Foo) -> Foo {
/// println!("Dividing!");
/// ```
/// struct Foo;
///
+/// impl Copy for Foo {}
+///
/// impl Rem<Foo, Foo> for Foo {
/// fn rem(&self, _rhs: &Foo) -> Foo {
/// println!("Remainder-ing!");
/// ```
/// struct Foo;
///
+/// impl Copy for Foo {}
+///
/// impl Neg<Foo> for Foo {
/// fn neg(&self) -> Foo {
/// println!("Negating!");
/// ```
/// struct Foo;
///
+/// impl Copy for Foo {}
+///
/// impl Not<Foo> for Foo {
/// fn not(&self) -> Foo {
/// println!("Not-ing!");
/// ```
/// struct Foo;
///
+/// impl Copy for Foo {}
+///
/// impl BitAnd<Foo, Foo> for Foo {
/// fn bitand(&self, _rhs: &Foo) -> Foo {
/// println!("Bitwise And-ing!");
/// ```
/// struct Foo;
///
+/// impl Copy for Foo {}
+///
/// impl BitOr<Foo, Foo> for Foo {
/// fn bitor(&self, _rhs: &Foo) -> Foo {
/// println!("Bitwise Or-ing!");
/// ```
/// struct Foo;
///
+/// impl Copy for Foo {}
+///
/// impl BitXor<Foo, Foo> for Foo {
/// fn bitxor(&self, _rhs: &Foo) -> Foo {
/// println!("Bitwise Xor-ing!");
/// ```
/// struct Foo;
///
+/// impl Copy for Foo {}
+///
/// impl Shl<Foo, Foo> for Foo {
/// fn shl(&self, _rhs: &Foo) -> Foo {
/// println!("Shifting left!");
/// ```
/// struct Foo;
///
+/// impl Copy for Foo {}
+///
/// impl Shr<Foo, Foo> for Foo {
/// fn shr(&self, _rhs: &Foo) -> Foo {
/// println!("Shifting right!");
/// ```
/// struct Foo;
///
+/// impl Copy for Foo {}
+///
/// impl Index<Foo, Foo> for Foo {
/// fn index<'a>(&'a self, _index: &Foo) -> &'a Foo {
/// println!("Indexing!");
/// ```
/// struct Foo;
///
+/// impl Copy for Foo {}
+///
/// impl IndexMut<Foo, Foo> for Foo {
/// fn index_mut<'a>(&'a mut self, _index: &Foo) -> &'a mut Foo {
/// println!("Indexing!");
/// ```ignore
/// struct Foo;
///
+/// impl Copy for Foo {}
+///
/// impl Slice<Foo, Foo> for Foo {
/// fn as_slice_<'a>(&'a self) -> &'a Foo {
/// println!("Slicing!");
/// ```ignore
/// struct Foo;
///
+/// impl Copy for Foo {}
+///
/// impl SliceMut<Foo, Foo> for Foo {
/// fn as_mut_slice_<'a>(&'a mut self) -> &'a mut Foo {
/// println!("Slicing!");
/// A version of the call operator that takes a by-value receiver.
#[lang="fn_once"]
-pub trait FnOnce<Args,Result> for Sized? {
+pub trait FnOnce<Args,Result> {
/// This is called when the call operator is used.
extern "rust-call" fn call_once(self, args: Args) -> Result;
}
-impl<F,A,R> FnMut<A,R> for F
+impl<Sized? F,A,R> FnMut<A,R> for F
where F : Fn<A,R>
{
extern "rust-call" fn call_mut(&mut self, args: A) -> R {
self.call_mut(args)
}
}
+
+#[cfg(stage0)]
+mod fn_impls {
+ use super::Fn;
+
+ impl<Result> Fn<(),Result> for extern "Rust" fn() -> Result {
+ #[allow(non_snake_case)]
+ extern "rust-call" fn call(&self, _args: ()) -> Result {
+ (*self)()
+ }
+ }
+
+ impl<Result,A0> Fn<(A0,),Result> for extern "Rust" fn(A0) -> Result {
+ #[allow(non_snake_case)]
+ extern "rust-call" fn call(&self, args: (A0,)) -> Result {
+ let (a0,) = args;
+ (*self)(a0)
+ }
+ }
+
+ macro_rules! def_fn(
+ ($($args:ident)*) => (
+ impl<Result$(,$args)*>
+ Fn<($($args,)*),Result>
+ for extern "Rust" fn($($args: $args,)*) -> Result {
+ #[allow(non_snake_case)]
+ extern "rust-call" fn call(&self, args: ($($args,)*)) -> Result {
+ let ($($args,)*) = args;
+ (*self)($($args,)*)
+ }
+ }
+ )
+ )
+
+ def_fn!(A0 A1)
+ def_fn!(A0 A1 A2)
+ def_fn!(A0 A1 A2 A3)
+ def_fn!(A0 A1 A2 A3 A4)
+ def_fn!(A0 A1 A2 A3 A4 A5)
+ def_fn!(A0 A1 A2 A3 A4 A5 A6)
+ def_fn!(A0 A1 A2 A3 A4 A5 A6 A7)
+ def_fn!(A0 A1 A2 A3 A4 A5 A6 A7 A8)
+ def_fn!(A0 A1 A2 A3 A4 A5 A6 A7 A8 A9)
+ def_fn!(A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 A10)
+ def_fn!(A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11)
+ def_fn!(A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 A12)
+ def_fn!(A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 A12 A13)
+ def_fn!(A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 A12 A13 A14)
+ def_fn!(A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 A12 A13 A14 A15)
+}
#![stable]
+#[cfg(stage0)]
pub use self::Option::*;
+#[cfg(not(stage0))]
+use self::Option::*;
use cmp::{Eq, Ord};
use default::Default;
-use iter::{Iterator, IteratorExt, DoubleEndedIterator, FromIterator, ExactSizeIterator};
+use iter::{Iterator, IteratorExt, DoubleEndedIterator, FromIterator};
+use iter::{ExactSizeIterator};
+use kinds::Copy;
use mem;
use result::Result;
use result::Result::{Ok, Err};
}
}
}
+
+impl<T:Copy> Copy for Option<T> {}
+
#[inline]
fn ge(&self, other: &*mut T) -> bool { *self >= *other }
}
+
//!
//! Their definition should always match the ABI defined in `rustc::back::abi`.
+use kinds::Copy;
use mem;
use kinds::Sized;
pub len: uint,
}
+impl<T> Copy for Slice<T> {}
+
/// The representation of a Rust closure
#[repr(C)]
pub struct Closure {
pub env: *mut (),
}
+impl Copy for Closure {}
+
/// The representation of a Rust procedure (`proc()`)
#[repr(C)]
pub struct Procedure {
pub env: *mut (),
}
+impl Copy for Procedure {}
+
/// The representation of a Rust trait object.
///
/// This struct does not have a `Repr` implementation
pub vtable: *mut (),
}
+impl Copy for TraitObject {}
+
/// This trait is meant to map equivalences between raw structs and their
/// corresponding rust values.
pub trait Repr<T> for Sized? {
#![stable]
-pub use self::Result::*;
+use self::Result::*;
+use kinds::Copy;
use std::fmt::Show;
use slice;
use slice::AsSlice;
}
Ok(init)
}
+
+#[cfg(not(stage0))]
+impl<T:Copy,U:Copy> Copy for Result<T,U> {}
+
#![allow(non_camel_case_types)]
#![allow(missing_docs)]
+use kinds::Copy;
+
#[experimental]
#[simd]
#[deriving(Show)]
pub i8, pub i8, pub i8, pub i8,
pub i8, pub i8, pub i8, pub i8);
+impl Copy for i8x16 {}
+
#[experimental]
#[simd]
#[deriving(Show)]
pub struct i16x8(pub i16, pub i16, pub i16, pub i16,
pub i16, pub i16, pub i16, pub i16);
+impl Copy for i16x8 {}
+
#[experimental]
#[simd]
#[deriving(Show)]
#[repr(C)]
pub struct i32x4(pub i32, pub i32, pub i32, pub i32);
+impl Copy for i32x4 {}
+
#[experimental]
#[simd]
#[deriving(Show)]
#[repr(C)]
pub struct i64x2(pub i64, pub i64);
+impl Copy for i64x2 {}
+
#[experimental]
#[simd]
#[deriving(Show)]
pub u8, pub u8, pub u8, pub u8,
pub u8, pub u8, pub u8, pub u8);
+impl Copy for u8x16 {}
+
#[experimental]
#[simd]
#[deriving(Show)]
pub struct u16x8(pub u16, pub u16, pub u16, pub u16,
pub u16, pub u16, pub u16, pub u16);
+impl Copy for u16x8 {}
+
#[experimental]
#[simd]
#[deriving(Show)]
#[repr(C)]
pub struct u32x4(pub u32, pub u32, pub u32, pub u32);
+impl Copy for u32x4 {}
+
#[experimental]
#[simd]
#[deriving(Show)]
#[repr(C)]
pub struct u64x2(pub u64, pub u64);
+impl Copy for u64x2 {}
+
#[experimental]
#[simd]
#[deriving(Show)]
#[repr(C)]
pub struct f32x4(pub f32, pub f32, pub f32, pub f32);
+impl Copy for f32x4 {}
+
#[experimental]
#[simd]
#[deriving(Show)]
#[repr(C)]
pub struct f64x2(pub f64, pub f64);
+
+impl Copy for f64x2 {}
+
use cmp;
use default::Default;
use iter::*;
+use kinds::Copy;
use num::Int;
use ops;
use option::Option;
}
}
+impl<'a,T> Copy for Items<'a,T> {}
+
iterator!{struct Items -> *const T, &'a T}
#[experimental = "needs review"]
NotFound(uint)
}
+impl Copy for BinarySearchResult {}
+
#[experimental = "needs review"]
impl BinarySearchResult {
/// Converts a `Found` to `Some`, `NotFound` to `None`.
impl_int_slice!(u32, i32)
impl_int_slice!(u64, i64)
impl_int_slice!(uint, int)
+
use iter::{Map, Iterator, IteratorExt, DoubleEndedIterator};
use iter::{DoubleEndedIteratorExt, ExactSizeIterator};
use iter::range;
-use kinds::Sized;
+use kinds::{Copy, Sized};
use mem;
use num::Int;
use option::Option;
Section: Creating a string
*/
-/// Converts a vector to a string slice without performing any allocations.
+/// Converts a slice of bytes to a string slice without performing any allocations.
///
/// Once the slice has been validated as utf-8, it is transmuted in-place and
/// returned as a '&str' instead of a '&[u8]'
iter: slice::Items<'a, u8>
}
+impl<'a> Copy for Chars<'a> {}
+
// Return the initial codepoint accumulator for the first byte.
// The first byte is special, only want bottom 5 bits for width 2, 4 bits
// for width 3, and 3 bits for width 4
LoneSurrogate(u16)
}
+impl Copy for Utf16Item {}
+
impl Utf16Item {
/// Convert `self` to a `char`, taking `LoneSurrogate`s to the
/// replacement character (U+FFFD).
pub next: uint,
}
+impl Copy for CharRange {}
+
/// Mask of the value bits of a continuation byte
const CONT_MASK: u8 = 0b0011_1111u8;
/// Value of the tag bits (tag mask is !CONT_MASK) of a continuation byte
impl<'a> Default for &'a str {
fn default() -> &'a str { "" }
}
+
NextArgument(Argument<'a>),
}
+impl<'a> Copy for Piece<'a> {}
+
/// Representation of an argument specification.
#[deriving(PartialEq)]
pub struct Argument<'a> {
pub format: FormatSpec<'a>,
}
+impl<'a> Copy for Argument<'a> {}
+
/// Specification for the formatting of an argument in the format string.
#[deriving(PartialEq)]
pub struct FormatSpec<'a> {
pub ty: &'a str
}
+impl<'a> Copy for FormatSpec<'a> {}
+
/// Enum describing where an argument for a format can be located.
#[deriving(PartialEq)]
pub enum Position<'a> {
ArgumentNamed(&'a str),
}
+impl<'a> Copy for Position<'a> {}
+
/// Enum of alignments which are supported.
#[deriving(PartialEq)]
pub enum Alignment {
AlignUnknown,
}
+impl Copy for Alignment {}
+
/// Various flags which can be applied to format strings. The meaning of these
/// flags is defined by the formatters themselves.
#[deriving(PartialEq)]
FlagSignAwareZeroPad,
}
+impl Copy for Flag {}
+
/// A count is used for the precision and width parameters of an integer, and
/// can reference either an argument or a literal integer.
#[deriving(PartialEq)]
CountImplied,
}
+impl<'a> Copy for Count<'a> {}
+
/// The parser structure for interpreting the input format string. This is
/// modelled as an iterator over `Piece` structures to form a stream of tokens
/// being output.
use self::Occur::*;
use self::Fail::*;
use self::Optval::*;
+use self::SplitWithinState::*;
+use self::Whitespace::*;
+use self::LengthLimit::*;
use std::fmt;
use std::result::Result::{Err, Ok};
Maybe,
}
+impl Copy for HasArg {}
+
/// Describes how often an option may occur.
#[deriving(Clone, PartialEq, Eq)]
pub enum Occur {
Multi,
}
+impl Copy for Occur {}
+
/// A description of a possible option.
#[deriving(Clone, PartialEq, Eq)]
pub struct Opt {
UnexpectedArgument(String),
}
+/// The type of failure that occurred.
+#[deriving(PartialEq, Eq)]
+#[allow(missing_docs)]
+pub enum FailType {
+ ArgumentMissing_,
+ UnrecognizedOption_,
+ OptionMissing_,
+ OptionDuplicated_,
+ UnexpectedArgument_,
+}
+
+impl Copy for FailType {}
+
/// The result of parsing a command line with a set of options.
pub type Result = result::Result<Matches, Fail>;
B, // words
C, // internal and trailing whitespace
}
+impl Copy for SplitWithinState {}
enum Whitespace {
Ws, // current char is whitespace
Cr // current char is not whitespace
}
+impl Copy for Whitespace {}
enum LengthLimit {
UnderLim, // current char makes current substring still fit in limit
OverLim // current char makes current substring no longer fit in limit
}
+impl Copy for LengthLimit {}
/// Splits a string into substrings with possibly internal whitespace,
/// sequence longer than the limit.
fn each_split_within<'a>(ss: &'a str, lim: uint, it: |&'a str| -> bool)
-> bool {
- use self::SplitWithinState::*;
- use self::Whitespace::*;
- use self::LengthLimit::*;
// Just for fun, let's write this as a state machine:
let mut slice_start = 0;
#![allow(non_upper_case_globals)]
#![allow(missing_docs)]
#![allow(non_snake_case)]
+#![allow(raw_pointer_deriving)]
extern crate core;
/// variants, because the compiler complains about the repr attribute
/// otherwise.
#[repr(u8)]
+ #[allow(missing_copy_implementations)]
pub enum c_void {
__variant1,
__variant2,
}
+ #[allow(missing_copy_implementations)]
pub enum FILE {}
+ #[allow(missing_copy_implementations)]
pub enum fpos_t {}
}
pub mod c99 {
pub type uint64_t = u64;
}
pub mod posix88 {
+ #[allow(missing_copy_implementations)]
pub enum DIR {}
+ #[allow(missing_copy_implementations)]
pub enum dirent_t {}
}
pub mod posix01 {}
pub type pthread_t = c_ulong;
#[repr(C)]
- pub struct glob_t {
+ #[deriving(Copy)] pub struct glob_t {
pub gl_pathc: size_t,
pub gl_pathv: *mut *mut c_char,
pub gl_offs: size_t,
}
#[repr(C)]
- pub struct timeval {
+ #[deriving(Copy)] pub struct timeval {
pub tv_sec: time_t,
pub tv_usec: suseconds_t,
}
#[repr(C)]
- pub struct timespec {
+ #[deriving(Copy)] pub struct timespec {
pub tv_sec: time_t,
pub tv_nsec: c_long,
}
- pub enum timezone {}
+ #[deriving(Copy)] pub enum timezone {}
pub type sighandler_t = size_t;
}
pub type in_port_t = u16;
pub type in_addr_t = u32;
#[repr(C)]
- pub struct sockaddr {
+ #[deriving(Copy)] pub struct sockaddr {
pub sa_family: sa_family_t,
pub sa_data: [u8, ..14],
}
#[repr(C)]
- pub struct sockaddr_storage {
+ #[deriving(Copy)] pub struct sockaddr_storage {
pub ss_family: sa_family_t,
pub __ss_align: i64,
pub __ss_pad2: [u8, ..112],
}
#[repr(C)]
- pub struct sockaddr_in {
+ #[deriving(Copy)] pub struct sockaddr_in {
pub sin_family: sa_family_t,
pub sin_port: in_port_t,
pub sin_addr: in_addr,
pub sin_zero: [u8, ..8],
}
#[repr(C)]
- pub struct in_addr {
+ #[deriving(Copy)] pub struct in_addr {
pub s_addr: in_addr_t,
}
#[repr(C)]
- pub struct sockaddr_in6 {
+ #[deriving(Copy)] pub struct sockaddr_in6 {
pub sin6_family: sa_family_t,
pub sin6_port: in_port_t,
pub sin6_flowinfo: u32,
pub sin6_scope_id: u32,
}
#[repr(C)]
- pub struct in6_addr {
+ #[deriving(Copy)] pub struct in6_addr {
pub s6_addr: [u16, ..8]
}
#[repr(C)]
- pub struct ip_mreq {
+ #[deriving(Copy)] pub struct ip_mreq {
pub imr_multiaddr: in_addr,
pub imr_interface: in_addr,
}
#[repr(C)]
- pub struct ip6_mreq {
+ #[deriving(Copy)] pub struct ip6_mreq {
pub ipv6mr_multiaddr: in6_addr,
pub ipv6mr_interface: c_uint,
}
#[repr(C)]
- pub struct addrinfo {
+ #[deriving(Copy)] pub struct addrinfo {
pub ai_flags: c_int,
pub ai_family: c_int,
pub ai_socktype: c_int,
pub ai_next: *mut addrinfo,
}
#[repr(C)]
- pub struct sockaddr_un {
+ #[deriving(Copy)] pub struct sockaddr_un {
pub sun_family: sa_family_t,
pub sun_path: [c_char, ..108]
}
#[repr(C)]
- pub struct ifaddrs {
+ #[deriving(Copy)] pub struct ifaddrs {
pub ifa_next: *mut ifaddrs,
pub ifa_name: *mut c_char,
pub ifa_flags: c_uint,
pub type blkcnt_t = i32;
#[repr(C)]
- pub struct stat {
+ #[deriving(Copy)] pub struct stat {
pub st_dev: dev_t,
pub __pad1: c_short,
pub st_ino: ino_t,
}
#[repr(C)]
- pub struct utimbuf {
+ #[deriving(Copy)] pub struct utimbuf {
pub actime: time_t,
pub modtime: time_t,
}
#[repr(C)]
- pub struct pthread_attr_t {
+ #[deriving(Copy)] pub struct pthread_attr_t {
pub __size: [u32, ..9]
}
}
pub type blkcnt_t = u32;
#[repr(C)]
- pub struct stat {
+ #[deriving(Copy)] pub struct stat {
pub st_dev: c_ulonglong,
pub __pad0: [c_uchar, ..4],
pub __st_ino: ino_t,
}
#[repr(C)]
- pub struct utimbuf {
+ #[deriving(Copy)] pub struct utimbuf {
pub actime: time_t,
pub modtime: time_t,
}
#[repr(C)]
- pub struct pthread_attr_t {
+ #[deriving(Copy)] pub struct pthread_attr_t {
pub __size: [u32, ..9]
}
}
pub type blkcnt_t = i32;
#[repr(C)]
- pub struct stat {
+ #[deriving(Copy)] pub struct stat {
pub st_dev: c_ulong,
pub st_pad1: [c_long, ..3],
pub st_ino: ino_t,
}
#[repr(C)]
- pub struct utimbuf {
+ #[deriving(Copy)] pub struct utimbuf {
pub actime: time_t,
pub modtime: time_t,
}
#[repr(C)]
- pub struct pthread_attr_t {
+ #[deriving(Copy)] pub struct pthread_attr_t {
pub __size: [u32, ..9]
}
}
pub mod extra {
use types::os::arch::c95::{c_ushort, c_int, c_uchar};
#[repr(C)]
- pub struct sockaddr_ll {
+ #[deriving(Copy)] pub struct sockaddr_ll {
pub sll_family: c_ushort,
pub sll_protocol: c_ushort,
pub sll_ifindex: c_int,
pub type blksize_t = i64;
pub type blkcnt_t = i64;
#[repr(C)]
- pub struct stat {
+ #[deriving(Copy)] pub struct stat {
pub st_dev: dev_t,
pub st_ino: ino_t,
pub st_nlink: nlink_t,
}
#[repr(C)]
- pub struct utimbuf {
+ #[deriving(Copy)] pub struct utimbuf {
pub actime: time_t,
pub modtime: time_t,
}
#[repr(C)]
- pub struct pthread_attr_t {
+ #[deriving(Copy)] pub struct pthread_attr_t {
pub __size: [u64, ..7]
}
}
}
pub mod extra {
use types::os::arch::c95::{c_ushort, c_int, c_uchar};
- pub struct sockaddr_ll {
+ #[deriving(Copy)] pub struct sockaddr_ll {
pub sll_family: c_ushort,
pub sll_protocol: c_ushort,
pub sll_ifindex: c_int,
pub type pthread_t = uintptr_t;
#[repr(C)]
- pub struct glob_t {
+ #[deriving(Copy)] pub struct glob_t {
pub gl_pathc: size_t,
pub __unused1: size_t,
pub gl_offs: size_t,
}
#[repr(C)]
- pub struct timeval {
+ #[deriving(Copy)] pub struct timeval {
pub tv_sec: time_t,
pub tv_usec: suseconds_t,
}
#[repr(C)]
- pub struct timespec {
+ #[deriving(Copy)] pub struct timespec {
pub tv_sec: time_t,
pub tv_nsec: c_long,
}
- pub enum timezone {}
+ #[deriving(Copy)] pub enum timezone {}
pub type sighandler_t = size_t;
}
pub type in_port_t = u16;
pub type in_addr_t = u32;
#[repr(C)]
- pub struct sockaddr {
+ #[deriving(Copy)] pub struct sockaddr {
pub sa_len: u8,
pub sa_family: sa_family_t,
pub sa_data: [u8, ..14],
}
#[repr(C)]
- pub struct sockaddr_storage {
+ #[deriving(Copy)] pub struct sockaddr_storage {
pub ss_len: u8,
pub ss_family: sa_family_t,
pub __ss_pad1: [u8, ..6],
pub __ss_pad2: [u8, ..112],
}
#[repr(C)]
- pub struct sockaddr_in {
+ #[deriving(Copy)] pub struct sockaddr_in {
pub sin_len: u8,
pub sin_family: sa_family_t,
pub sin_port: in_port_t,
pub sin_zero: [u8, ..8],
}
#[repr(C)]
- pub struct in_addr {
+ #[deriving(Copy)] pub struct in_addr {
pub s_addr: in_addr_t,
}
#[repr(C)]
- pub struct sockaddr_in6 {
+ #[deriving(Copy)] pub struct sockaddr_in6 {
pub sin6_len: u8,
pub sin6_family: sa_family_t,
pub sin6_port: in_port_t,
pub sin6_scope_id: u32,
}
#[repr(C)]
- pub struct in6_addr {
+ #[deriving(Copy)] pub struct in6_addr {
pub s6_addr: [u16, ..8]
}
#[repr(C)]
- pub struct ip_mreq {
+ #[deriving(Copy)] pub struct ip_mreq {
pub imr_multiaddr: in_addr,
pub imr_interface: in_addr,
}
#[repr(C)]
- pub struct ip6_mreq {
+ #[deriving(Copy)] pub struct ip6_mreq {
pub ipv6mr_multiaddr: in6_addr,
pub ipv6mr_interface: c_uint,
}
#[repr(C)]
- pub struct addrinfo {
+ #[deriving(Copy)] pub struct addrinfo {
pub ai_flags: c_int,
pub ai_family: c_int,
pub ai_socktype: c_int,
pub ai_next: *mut addrinfo,
}
#[repr(C)]
- pub struct sockaddr_un {
+ #[deriving(Copy)] pub struct sockaddr_un {
pub sun_len: u8,
pub sun_family: sa_family_t,
pub sun_path: [c_char, ..104]
}
#[repr(C)]
- pub struct ifaddrs {
+ #[deriving(Copy)] pub struct ifaddrs {
pub ifa_next: *mut ifaddrs,
pub ifa_name: *mut c_char,
pub ifa_flags: c_uint,
pub type blkcnt_t = i64;
pub type fflags_t = u32;
#[repr(C)]
- pub struct stat {
+ #[deriving(Copy)] pub struct stat {
pub st_dev: dev_t,
pub st_ino: ino_t,
pub st_mode: mode_t,
}
#[repr(C)]
- pub struct utimbuf {
+ #[deriving(Copy)] pub struct utimbuf {
pub actime: time_t,
pub modtime: time_t,
}
pub type pthread_t = uintptr_t;
#[repr(C)]
- pub struct glob_t {
+ #[deriving(Copy)] pub struct glob_t {
pub gl_pathc: size_t,
pub __unused1: size_t,
pub gl_offs: size_t,
}
#[repr(C)]
- pub struct timeval {
+ #[deriving(Copy)] pub struct timeval {
pub tv_sec: time_t,
pub tv_usec: suseconds_t,
}
#[repr(C)]
- pub struct timespec {
+ #[deriving(Copy)] pub struct timespec {
pub tv_sec: time_t,
pub tv_nsec: c_long,
}
- pub enum timezone {}
+ #[deriving(Copy)] pub enum timezone {}
pub type sighandler_t = size_t;
}
pub type in_port_t = u16;
pub type in_addr_t = u32;
#[repr(C)]
- pub struct sockaddr {
+ #[deriving(Copy)] pub struct sockaddr {
pub sa_len: u8,
pub sa_family: sa_family_t,
pub sa_data: [u8, ..14],
}
#[repr(C)]
- pub struct sockaddr_storage {
+ #[deriving(Copy)] pub struct sockaddr_storage {
pub ss_len: u8,
pub ss_family: sa_family_t,
pub __ss_pad1: [u8, ..6],
pub __ss_pad2: [u8, ..112],
}
#[repr(C)]
- pub struct sockaddr_in {
+ #[deriving(Copy)] pub struct sockaddr_in {
pub sin_len: u8,
pub sin_family: sa_family_t,
pub sin_port: in_port_t,
pub sin_zero: [u8, ..8],
}
#[repr(C)]
- pub struct in_addr {
+ #[deriving(Copy)] pub struct in_addr {
pub s_addr: in_addr_t,
}
#[repr(C)]
- pub struct sockaddr_in6 {
+ #[deriving(Copy)] pub struct sockaddr_in6 {
pub sin6_len: u8,
pub sin6_family: sa_family_t,
pub sin6_port: in_port_t,
pub sin6_scope_id: u32,
}
#[repr(C)]
- pub struct in6_addr {
+ #[deriving(Copy)] pub struct in6_addr {
pub s6_addr: [u16, ..8]
}
#[repr(C)]
- pub struct ip_mreq {
+ #[deriving(Copy)] pub struct ip_mreq {
pub imr_multiaddr: in_addr,
pub imr_interface: in_addr,
}
#[repr(C)]
- pub struct ip6_mreq {
+ #[deriving(Copy)] pub struct ip6_mreq {
pub ipv6mr_multiaddr: in6_addr,
pub ipv6mr_interface: c_uint,
}
#[repr(C)]
- pub struct addrinfo {
+ #[deriving(Copy)] pub struct addrinfo {
pub ai_flags: c_int,
pub ai_family: c_int,
pub ai_socktype: c_int,
pub ai_next: *mut addrinfo,
}
#[repr(C)]
- pub struct sockaddr_un {
+ #[deriving(Copy)] pub struct sockaddr_un {
pub sun_len: u8,
pub sun_family: sa_family_t,
pub sun_path: [c_char, ..104]
pub type fflags_t = u32;
#[repr(C)]
- pub struct stat {
+ #[deriving(Copy)] pub struct stat {
pub st_ino: ino_t,
pub st_nlink: nlink_t,
pub st_dev: dev_t,
pub st_qspare2: int64_t,
}
#[repr(C)]
- pub struct utimbuf {
+ #[deriving(Copy)] pub struct utimbuf {
pub actime: time_t,
pub modtime: time_t,
}
// pub Note: this is the struct called stat64 in Windows. Not stat,
// nor stati64.
#[repr(C)]
- pub struct stat {
+ #[deriving(Copy)] pub struct stat {
pub st_dev: dev_t,
pub st_ino: ino_t,
pub st_mode: u16,
// note that this is called utimbuf64 in Windows
#[repr(C)]
- pub struct utimbuf {
+ #[deriving(Copy)] pub struct utimbuf {
pub actime: time64_t,
pub modtime: time64_t,
}
#[repr(C)]
- pub struct timeval {
+ #[deriving(Copy)] pub struct timeval {
pub tv_sec: c_long,
pub tv_usec: c_long,
}
#[repr(C)]
- pub struct timespec {
+ #[deriving(Copy)] pub struct timespec {
pub tv_sec: time_t,
pub tv_nsec: c_long,
}
- pub enum timezone {}
+ #[deriving(Copy)] pub enum timezone {}
}
pub mod bsd44 {
pub type in_port_t = u16;
pub type in_addr_t = u32;
#[repr(C)]
- pub struct sockaddr {
+ #[deriving(Copy)] pub struct sockaddr {
pub sa_family: sa_family_t,
pub sa_data: [u8, ..14],
}
#[repr(C)]
- pub struct sockaddr_storage {
+ #[deriving(Copy)] pub struct sockaddr_storage {
pub ss_family: sa_family_t,
pub __ss_pad1: [u8, ..6],
pub __ss_align: i64,
pub __ss_pad2: [u8, ..112],
}
#[repr(C)]
- pub struct sockaddr_in {
+ #[deriving(Copy)] pub struct sockaddr_in {
pub sin_family: sa_family_t,
pub sin_port: in_port_t,
pub sin_addr: in_addr,
pub sin_zero: [u8, ..8],
}
#[repr(C)]
- pub struct in_addr {
+ #[deriving(Copy)] pub struct in_addr {
pub s_addr: in_addr_t,
}
#[repr(C)]
- pub struct sockaddr_in6 {
+ #[deriving(Copy)] pub struct sockaddr_in6 {
pub sin6_family: sa_family_t,
pub sin6_port: in_port_t,
pub sin6_flowinfo: u32,
pub sin6_scope_id: u32,
}
#[repr(C)]
- pub struct in6_addr {
+ #[deriving(Copy)] pub struct in6_addr {
pub s6_addr: [u16, ..8]
}
#[repr(C)]
- pub struct ip_mreq {
+ #[deriving(Copy)] pub struct ip_mreq {
pub imr_multiaddr: in_addr,
pub imr_interface: in_addr,
}
#[repr(C)]
- pub struct ip6_mreq {
+ #[deriving(Copy)] pub struct ip6_mreq {
pub ipv6mr_multiaddr: in6_addr,
pub ipv6mr_interface: c_uint,
}
#[repr(C)]
- pub struct addrinfo {
+ #[deriving(Copy)] pub struct addrinfo {
pub ai_flags: c_int,
pub ai_family: c_int,
pub ai_socktype: c_int,
pub ai_next: *mut addrinfo,
}
#[repr(C)]
- pub struct sockaddr_un {
+ #[deriving(Copy)] pub struct sockaddr_un {
pub sun_family: sa_family_t,
pub sun_path: [c_char, ..108]
}
pub type LPCH = *mut CHAR;
#[repr(C)]
- pub struct SECURITY_ATTRIBUTES {
+ #[deriving(Copy)] pub struct SECURITY_ATTRIBUTES {
pub nLength: DWORD,
pub lpSecurityDescriptor: LPVOID,
pub bInheritHandle: BOOL,
pub type int64 = i64;
#[repr(C)]
- pub struct STARTUPINFO {
+ #[deriving(Copy)] pub struct STARTUPINFO {
pub cb: DWORD,
pub lpReserved: LPWSTR,
pub lpDesktop: LPWSTR,
pub type LPSTARTUPINFO = *mut STARTUPINFO;
#[repr(C)]
- pub struct PROCESS_INFORMATION {
+ #[deriving(Copy)] pub struct PROCESS_INFORMATION {
pub hProcess: HANDLE,
pub hThread: HANDLE,
pub dwProcessId: DWORD,
pub type LPPROCESS_INFORMATION = *mut PROCESS_INFORMATION;
#[repr(C)]
- pub struct SYSTEM_INFO {
+ #[deriving(Copy)] pub struct SYSTEM_INFO {
pub wProcessorArchitecture: WORD,
pub wReserved: WORD,
pub dwPageSize: DWORD,
pub type LPSYSTEM_INFO = *mut SYSTEM_INFO;
#[repr(C)]
- pub struct MEMORY_BASIC_INFORMATION {
+ #[deriving(Copy)] pub struct MEMORY_BASIC_INFORMATION {
pub BaseAddress: LPVOID,
pub AllocationBase: LPVOID,
pub AllocationProtect: DWORD,
pub type LPMEMORY_BASIC_INFORMATION = *mut MEMORY_BASIC_INFORMATION;
#[repr(C)]
- pub struct OVERLAPPED {
+ #[deriving(Copy)] pub struct OVERLAPPED {
pub Internal: *mut c_ulong,
pub InternalHigh: *mut c_ulong,
pub Offset: DWORD,
pub type LPOVERLAPPED = *mut OVERLAPPED;
#[repr(C)]
- pub struct FILETIME {
+ #[deriving(Copy)] pub struct FILETIME {
pub dwLowDateTime: DWORD,
pub dwHighDateTime: DWORD,
}
pub type LPFILETIME = *mut FILETIME;
#[repr(C)]
- pub struct GUID {
+ #[deriving(Copy)] pub struct GUID {
pub Data1: DWORD,
pub Data2: WORD,
pub Data3: WORD,
}
#[repr(C)]
- pub struct WSAPROTOCOLCHAIN {
+ #[deriving(Copy)] pub struct WSAPROTOCOLCHAIN {
pub ChainLen: c_int,
pub ChainEntries: [DWORD, ..MAX_PROTOCOL_CHAIN as uint],
}
pub type LPWSAPROTOCOLCHAIN = *mut WSAPROTOCOLCHAIN;
#[repr(C)]
- pub struct WSAPROTOCOL_INFO {
+ #[deriving(Copy)] pub struct WSAPROTOCOL_INFO {
pub dwServiceFlags1: DWORD,
pub dwServiceFlags2: DWORD,
pub dwServiceFlags3: DWORD,
pub type GROUP = c_uint;
#[repr(C)]
- pub struct WIN32_FIND_DATAW {
+ #[deriving(Copy)] pub struct WIN32_FIND_DATAW {
pub dwFileAttributes: DWORD,
pub ftCreationTime: FILETIME,
pub ftLastAccessTime: FILETIME,
pub mod common {
pub mod posix01 {
use types::common::c95::c_void;
- use types::os::arch::c95::{c_char, c_int, size_t,
- time_t, suseconds_t, c_long};
+ use types::os::arch::c95::{c_char, c_int, size_t, time_t};
+ use types::os::arch::c95::{suseconds_t, c_long};
use types::os::arch::c99::{uintptr_t};
pub type pthread_t = uintptr_t;
#[repr(C)]
- pub struct glob_t {
+ #[deriving(Copy)] pub struct glob_t {
pub gl_pathc: size_t,
pub __unused1: c_int,
pub gl_offs: size_t,
}
#[repr(C)]
- pub struct timeval {
+ #[deriving(Copy)] pub struct timeval {
pub tv_sec: time_t,
pub tv_usec: suseconds_t,
}
#[repr(C)]
- pub struct timespec {
+ #[deriving(Copy)] pub struct timespec {
pub tv_sec: time_t,
pub tv_nsec: c_long,
}
- pub enum timezone {}
+ #[deriving(Copy)] pub enum timezone {}
pub type sighandler_t = size_t;
}
pub type in_port_t = u16;
pub type in_addr_t = u32;
#[repr(C)]
- pub struct sockaddr {
+ #[deriving(Copy)] pub struct sockaddr {
pub sa_len: u8,
pub sa_family: sa_family_t,
pub sa_data: [u8, ..14],
}
+
#[repr(C)]
- pub struct sockaddr_storage {
+ #[deriving(Copy)] pub struct sockaddr_storage {
pub ss_len: u8,
pub ss_family: sa_family_t,
pub __ss_pad1: [u8, ..6],
pub __ss_align: i64,
pub __ss_pad2: [u8, ..112],
}
+
#[repr(C)]
- pub struct sockaddr_in {
+ #[deriving(Copy)] pub struct sockaddr_in {
pub sin_len: u8,
pub sin_family: sa_family_t,
pub sin_port: in_port_t,
pub sin_addr: in_addr,
pub sin_zero: [u8, ..8],
}
+
#[repr(C)]
- pub struct in_addr {
+ #[deriving(Copy)] pub struct in_addr {
pub s_addr: in_addr_t,
}
+
#[repr(C)]
- pub struct sockaddr_in6 {
+ #[deriving(Copy)] pub struct sockaddr_in6 {
pub sin6_len: u8,
pub sin6_family: sa_family_t,
pub sin6_port: in_port_t,
pub sin6_addr: in6_addr,
pub sin6_scope_id: u32,
}
+
#[repr(C)]
- pub struct in6_addr {
+ #[deriving(Copy)] pub struct in6_addr {
pub s6_addr: [u16, ..8]
}
+
#[repr(C)]
- pub struct ip_mreq {
+ #[deriving(Copy)] pub struct ip_mreq {
pub imr_multiaddr: in_addr,
pub imr_interface: in_addr,
}
+
#[repr(C)]
- pub struct ip6_mreq {
+ #[deriving(Copy)] pub struct ip6_mreq {
pub ipv6mr_multiaddr: in6_addr,
pub ipv6mr_interface: c_uint,
}
+
#[repr(C)]
- pub struct addrinfo {
+ #[deriving(Copy)] pub struct addrinfo {
pub ai_flags: c_int,
pub ai_family: c_int,
pub ai_socktype: c_int,
pub ai_addr: *mut sockaddr,
pub ai_next: *mut addrinfo,
}
+
#[repr(C)]
- pub struct sockaddr_un {
+ #[deriving(Copy)] pub struct sockaddr_un {
pub sun_len: u8,
pub sun_family: sa_family_t,
pub sun_path: [c_char, ..104]
}
+
#[repr(C)]
- pub struct ifaddrs {
+ #[deriving(Copy)] pub struct ifaddrs {
pub ifa_next: *mut ifaddrs,
pub ifa_name: *mut c_char,
pub ifa_flags: c_uint,
pub type blkcnt_t = i32;
#[repr(C)]
- pub struct stat {
+ #[deriving(Copy)] pub struct stat {
pub st_dev: dev_t,
pub st_mode: mode_t,
pub st_nlink: nlink_t,
}
#[repr(C)]
- pub struct utimbuf {
+ #[deriving(Copy)] pub struct utimbuf {
pub actime: time_t,
pub modtime: time_t,
}
#[repr(C)]
- pub struct pthread_attr_t {
+ #[deriving(Copy)] pub struct pthread_attr_t {
pub __sig: c_long,
pub __opaque: [c_char, ..36]
}
}
pub mod extra {
#[repr(C)]
- pub struct mach_timebase_info {
+ #[deriving(Copy)] pub struct mach_timebase_info {
pub numer: u32,
pub denom: u32,
}
pub type blkcnt_t = i32;
#[repr(C)]
- pub struct stat {
+ #[deriving(Copy)] pub struct stat {
pub st_dev: dev_t,
pub st_mode: mode_t,
pub st_nlink: nlink_t,
}
#[repr(C)]
- pub struct utimbuf {
+ #[deriving(Copy)] pub struct utimbuf {
pub actime: time_t,
pub modtime: time_t,
}
#[repr(C)]
- pub struct pthread_attr_t {
+ #[deriving(Copy)] pub struct pthread_attr_t {
pub __sig: c_long,
pub __opaque: [c_char, ..56]
}
}
pub mod extra {
#[repr(C)]
- pub struct mach_timebase_info {
+ #[deriving(Copy)] pub struct mach_timebase_info {
pub numer: u32,
pub denom: u32,
}
pub fn issue_14344_workaround() {} // FIXME #14344 force linkage to happen correctly
#[test] fn work_on_windows() { } // FIXME #10872 needed for a happy windows
+
+#[doc(hidden)]
+#[cfg(not(test))]
+mod std {
+ pub use core::kinds;
+}
#[deriving(PartialEq, PartialOrd)]
pub struct LogLevel(pub u32);
+impl Copy for LogLevel {}
+
impl fmt::Show for LogLevel {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
let LogLevel(level) = *self;
pub line: uint,
}
+impl Copy for LogLocation {}
+
/// Tests whether a given module's name is enabled for a particular level of
/// logging. This is the second layer of defense about determining whether a
/// module's log statement should be emitted or not.
index: uint, // Index into state
}
+impl Copy for ChaChaRng {}
+
static EMPTY: ChaChaRng = ChaChaRng {
buffer: [0, ..STATE_WORDS],
state: [0, ..STATE_WORDS],
/// security proof for a more involved example of this.
///
/// The modified word layout is:
- /// ```notrust
+ /// ```ignore
/// constant constant constant constant
/// key key key key
/// key key key key
//! The exponential distribution.
+use core::kinds::Copy;
use core::num::Float;
use {Rng, Rand};
/// College, Oxford
pub struct Exp1(pub f64);
+impl Copy for Exp1 {}
+
// This could be done via `-rng.gen::<f64>().ln()` but that is slower.
impl Rand for Exp1 {
#[inline]
lambda_inverse: f64
}
+impl Copy for Exp {}
+
impl Exp {
/// Construct a new `Exp` with the given shape parameter
/// `lambda`. Panics if `lambda <= 0`.
//! The normal and derived distributions.
+use core::kinds::Copy;
use core::num::Float;
use {Rng, Rand, Open01};
/// College, Oxford
pub struct StandardNormal(pub f64);
+impl Copy for StandardNormal {}
+
impl Rand for StandardNormal {
fn rand<R:Rng>(rng: &mut R) -> StandardNormal {
#[inline]
std_dev: f64,
}
+impl Copy for Normal {}
+
impl Normal {
/// Construct a new `Normal` distribution with the given mean and
/// standard deviation.
norm: Normal
}
+impl Copy for LogNormal {}
+
impl LogNormal {
/// Construct a new `LogNormal` distribution with the given mean
/// and standard deviation.
b: u32,
c: u32
}
+
+impl Copy for IsaacRng {}
+
static EMPTY: IsaacRng = IsaacRng {
cnt: 0,
rsl: [0, ..RAND_SIZE_UINT],
c: u64,
}
+impl Copy for Isaac64Rng {}
+
static EMPTY_64: Isaac64Rng = Isaac64Rng {
cnt: 0,
rsl: [0, .. RAND_SIZE_64],
/// [1]: Marsaglia, George (July 2003). ["Xorshift
/// RNGs"](http://www.jstatsoft.org/v08/i14/paper). *Journal of
/// Statistical Software*. Vol. 8 (Issue 14).
+#[allow(missing_copy_implementations)]
pub struct XorShiftRng {
x: u32,
y: u32,
w: u32,
}
+impl Clone for XorShiftRng {
+ fn clone(&self) -> XorShiftRng {
+ XorShiftRng {
+ x: self.x,
+ y: self.y,
+ z: self.z,
+ w: self.w,
+ }
+ }
+}
+
impl XorShiftRng {
/// Creates a new XorShiftRng instance which is not seeded.
///
/// replacing the RNG with the result of a `Default::default` call.
pub struct ReseedWithDefault;
+impl Copy for ReseedWithDefault {}
+
impl<R: Rng + Default> Reseeder<R> for ReseedWithDefault {
fn reseed(&mut self, rng: &mut R) {
*rng = Default::default();
pub end: uint,
}
+impl<'doc> Copy for Doc<'doc> {}
+
impl<'doc> Doc<'doc> {
pub fn new(data: &'doc [u8]) -> Doc<'doc> {
Doc { data: data, start: 0u, end: data.len() }
EsLabel, // Used only when debugging
}
+impl Copy for EbmlEncoderTag {}
+
#[deriving(Show)]
pub enum Error {
IntTooBig(uint),
pub next: uint
}
+ impl Copy for Res {}
+
#[inline(never)]
fn vuint_at_slow(data: &[u8], start: uint) -> DecodeResult<Res> {
let a = data[start];
Ungreedy,
}
+impl Copy for Greed {}
+
impl Greed {
pub fn is_greedy(&self) -> bool {
match *self {
pub prog: fn(MatchKind, &str, uint, uint) -> Vec<Option<uint>>
}
+impl Copy for ExNative {}
+
impl Clone for ExNative {
- fn clone(&self) -> ExNative { *self }
+ fn clone(&self) -> ExNative {
+ *self
+ }
}
impl fmt::Show for Regex {
input: &str, s: uint, e: uint) -> CaptureLocs {
match *re {
Dynamic(ExDynamic { ref prog, .. }) => vm::run(which, prog, input, s, e),
- Native(ExNative { prog, .. }) => prog(which, input, s, e),
+ Native(ExNative { ref prog, .. }) => (*prog)(which, input, s, e),
}
}
Submatches,
}
+impl Copy for MatchKind {}
+
/// Runs an NFA simulation on the compiled expression given on the search text
/// `input`. The search begins at byte index `start` and ends at byte index
/// `end`. (The range is specified here so that zero-width assertions will work
StepContinue,
}
+impl Copy for StepState {}
+
impl<'r, 't> Nfa<'r, 't> {
fn run(&mut self) -> CaptureLocs {
let ncaps = match self.which {
pub mod privacy;
pub mod reachable;
pub mod region;
+ pub mod recursion_limit;
pub mod resolve;
pub mod resolve_lifetime;
pub mod stability;
use metadata::csearch;
use middle::def::*;
+use middle::subst::Substs;
use middle::ty::{mod, Ty};
use middle::{def, pat_util, stability};
use middle::const_eval::{eval_const_expr_partial, const_int, const_uint};
use std::num::SignedInt;
use std::{i8, i16, i32, i64, u8, u16, u32, u64, f32, f64};
use syntax::{abi, ast, ast_map};
-use syntax::ast_util::{mod, is_shift_binop};
+use syntax::ast_util::is_shift_binop;
use syntax::attr::{mod, AttrMetaMethods};
use syntax::codemap::{Span, DUMMY_SP};
use syntax::parse::token;
use syntax::ast::{TyI, TyU, TyI8, TyU8, TyI16, TyU16, TyI32, TyU32, TyI64, TyU64};
+use syntax::ast_util;
use syntax::ptr::P;
use syntax::visit::{mod, Visitor};
pub struct WhileTrue;
+impl Copy for WhileTrue {}
+
impl LintPass for WhileTrue {
fn get_lints(&self) -> LintArray {
lint_array!(WHILE_TRUE)
pub struct UnusedCasts;
+impl Copy for UnusedCasts {}
+
impl LintPass for UnusedCasts {
fn get_lints(&self) -> LintArray {
lint_array!(UNUSED_TYPECASTS)
negated_expr_id: ast::NodeId,
}
+impl Copy for TypeLimits {}
+
impl TypeLimits {
pub fn new() -> TypeLimits {
TypeLimits {
pub struct ImproperCTypes;
+impl Copy for ImproperCTypes {}
+
impl LintPass for ImproperCTypes {
fn get_lints(&self) -> LintArray {
lint_array!(IMPROPER_CTYPES)
pub struct BoxPointers;
+impl Copy for BoxPointers {}
+
impl BoxPointers {
fn check_heap_type<'a, 'tcx>(&self, cx: &Context<'a, 'tcx>,
span: Span, ty: Ty<'tcx>) {
pub struct UnusedAttributes;
+impl Copy for UnusedAttributes {}
+
impl LintPass for UnusedAttributes {
fn get_lints(&self) -> LintArray {
lint_array!(UNUSED_ATTRIBUTES)
pub struct PathStatements;
+impl Copy for PathStatements {}
+
impl LintPass for PathStatements {
fn get_lints(&self) -> LintArray {
lint_array!(PATH_STATEMENTS)
pub struct UnusedResults;
+impl Copy for UnusedResults {}
+
impl LintPass for UnusedResults {
fn get_lints(&self) -> LintArray {
lint_array!(UNUSED_MUST_USE, UNUSED_RESULTS)
pub struct NonCamelCaseTypes;
+impl Copy for NonCamelCaseTypes {}
+
impl NonCamelCaseTypes {
fn check_case(&self, cx: &Context, sort: &str, ident: ast::Ident, span: Span) {
fn is_camel_case(ident: ast::Ident) -> bool {
pub struct NonSnakeCase;
+impl Copy for NonSnakeCase {}
+
impl NonSnakeCase {
fn check_snake_case(&self, cx: &Context, sort: &str, ident: ast::Ident, span: Span) {
fn is_snake_case(ident: ast::Ident) -> bool {
pub struct NonUpperCaseGlobals;
+impl Copy for NonUpperCaseGlobals {}
+
impl LintPass for NonUpperCaseGlobals {
fn get_lints(&self) -> LintArray {
lint_array!(NON_UPPER_CASE_GLOBALS)
pub struct UnusedParens;
+impl Copy for UnusedParens {}
+
impl UnusedParens {
fn check_unused_parens_core(&self, cx: &Context, value: &ast::Expr, msg: &str,
struct_lit_needs_parens: bool) {
pub struct UnusedImportBraces;
+impl Copy for UnusedImportBraces {}
+
impl LintPass for UnusedImportBraces {
fn get_lints(&self) -> LintArray {
lint_array!(UNUSED_IMPORT_BRACES)
pub struct NonShorthandFieldPatterns;
+impl Copy for NonShorthandFieldPatterns {}
+
impl LintPass for NonShorthandFieldPatterns {
fn get_lints(&self) -> LintArray {
lint_array!(NON_SHORTHAND_FIELD_PATTERNS)
pub struct UnusedUnsafe;
+impl Copy for UnusedUnsafe {}
+
impl LintPass for UnusedUnsafe {
fn get_lints(&self) -> LintArray {
lint_array!(UNUSED_UNSAFE)
pub struct UnsafeBlocks;
+impl Copy for UnsafeBlocks {}
+
impl LintPass for UnsafeBlocks {
fn get_lints(&self) -> LintArray {
lint_array!(UNSAFE_BLOCKS)
pub struct UnusedMut;
+impl Copy for UnusedMut {}
+
impl UnusedMut {
fn check_unused_mut_pat(&self, cx: &Context, pats: &[P<ast::Pat>]) {
// collect all mutable pattern and group their NodeIDs by their Identifier to
pub struct UnusedAllocation;
+impl Copy for UnusedAllocation {}
+
impl LintPass for UnusedAllocation {
fn get_lints(&self) -> LintArray {
lint_array!(UNUSED_ALLOCATION)
}
}
+pub struct MissingCopyImplementations;
+
+impl Copy for MissingCopyImplementations {}
+
+impl LintPass for MissingCopyImplementations {
+ fn get_lints(&self) -> LintArray {
+ lint_array!(MISSING_COPY_IMPLEMENTATIONS)
+ }
+
+ fn check_item(&mut self, cx: &Context, item: &ast::Item) {
+ if !cx.exported_items.contains(&item.id) {
+ return
+ }
+ if cx.tcx
+ .destructor_for_type
+ .borrow()
+ .contains_key(&ast_util::local_def(item.id)) {
+ return
+ }
+ let ty = match item.node {
+ ast::ItemStruct(_, ref ast_generics) => {
+ if ast_generics.is_parameterized() {
+ return
+ }
+ ty::mk_struct(cx.tcx,
+ ast_util::local_def(item.id),
+ Substs::empty())
+ }
+ ast::ItemEnum(_, ref ast_generics) => {
+ if ast_generics.is_parameterized() {
+ return
+ }
+ ty::mk_enum(cx.tcx,
+ ast_util::local_def(item.id),
+ Substs::empty())
+ }
+ _ => return,
+ };
+ let parameter_environment = ty::empty_parameter_environment();
+ if !ty::type_moves_by_default(cx.tcx,
+ ty,
+ ¶meter_environment) {
+ return
+ }
+ if ty::can_type_implement_copy(cx.tcx,
+ ty,
+ ¶meter_environment).is_ok() {
+ cx.span_lint(MISSING_COPY_IMPLEMENTATIONS,
+ item.span,
+ "type could implement `Copy`; consider adding `impl \
+ Copy`")
+ }
+ }
+}
+
declare_lint!(DEPRECATED, Warn,
"detects use of #[deprecated] items")
/// `#[unstable]` attributes, or no stability attribute.
pub struct Stability;
+impl Copy for Stability {}
+
impl Stability {
fn lint(&self, cx: &Context, id: ast::DefId, span: Span) {
let stability = stability::lookup(cx.tcx, id);
declare_lint!(pub FAT_PTR_TRANSMUTES, Allow,
"detects transmutes of fat pointers")
+declare_lint!(pub MISSING_COPY_IMPLEMENTATIONS, Warn,
+ "detects potentially-forgotten implementations of `Copy`")
+
/// Does nothing as a lint pass, but registers some `Lint`s
/// which are used by other parts of the compiler.
pub struct HardwiredLints;
+impl Copy for HardwiredLints {}
+
impl LintPass for HardwiredLints {
fn get_lints(&self) -> LintArray {
lint_array!(
UnusedMut,
UnusedAllocation,
Stability,
+ MissingCopyImplementations,
)
add_builtin_with_new!(sess,
pub desc: &'static str,
}
+impl Copy for Lint {}
+
impl Lint {
/// Get the lint's name, with ASCII letters converted to lowercase.
pub fn name_lower(&self) -> String {
lint: &'static Lint,
}
+impl Copy for LintId {}
+
impl PartialEq for LintId {
fn eq(&self, other: &LintId) -> bool {
(self.lint as *const Lint) == (other.lint as *const Lint)
Allow, Warn, Deny, Forbid
}
+impl Copy for Level {}
+
impl Level {
/// Convert a level to a lower-case string.
pub fn as_str(self) -> &'static str {
CommandLine,
}
+impl Copy for LintSource {}
+
pub type LevelSource = (Level, LintSource);
pub mod builtin;
tag_table_capture_modes = 0x56,
tag_table_object_cast_map = 0x57,
}
+
+impl Copy for astencode_tag {}
static first_astencode_tag: uint = tag_ast as uint;
static last_astencode_tag: uint = tag_table_object_cast_map as uint;
impl astencode_tag {
}
}
-fn register_native_lib(sess: &Session, span: Option<Span>, name: String,
- kind: cstore::NativeLibaryKind) {
+fn register_native_lib(sess: &Session,
+ span: Option<Span>,
+ name: String,
+ kind: cstore::NativeLibraryKind) {
if name.is_empty() {
match span {
Some(span) => {
pub vis: ast::Visibility,
}
+impl Copy for MethodInfo {}
+
pub fn get_symbol(cstore: &cstore::CStore, def: ast::DefId) -> String {
let cdata = cstore.get_crate_data(def.krate);
decoder::get_symbol(cdata.data(), def.node)
decoder::get_impl_vtables(&*cdata, def.node, tcx)
}
-pub fn get_native_libraries(cstore: &cstore::CStore,
- crate_num: ast::CrateNum)
- -> Vec<(cstore::NativeLibaryKind, String)> {
+pub fn get_native_libraries(cstore: &cstore::CStore, crate_num: ast::CrateNum)
+ -> Vec<(cstore::NativeLibraryKind, String)> {
let cdata = cstore.get_crate_data(crate_num);
decoder::get_native_libraries(&*cdata)
}
pub use self::MetadataBlob::*;
pub use self::LinkagePreference::*;
-pub use self::NativeLibaryKind::*;
+pub use self::NativeLibraryKind::*;
use back::svh::Svh;
use metadata::decoder;
RequireStatic,
}
-#[deriving(PartialEq, FromPrimitive, Clone)]
-pub enum NativeLibaryKind {
+impl Copy for LinkagePreference {}
+
+#[deriving(Clone, PartialEq, FromPrimitive)]
+pub enum NativeLibraryKind {
NativeStatic, // native static library (.a archive)
NativeFramework, // OSX-specific
NativeUnknown, // default way to specify a dynamic library
}
+impl Copy for NativeLibraryKind {}
+
// Where a crate came from on the local filesystem. One of these two options
// must be non-None.
#[deriving(PartialEq, Clone)]
/// Map from NodeId's of local extern crate statements to crate numbers
extern_mod_crate_map: RefCell<NodeMap<ast::CrateNum>>,
used_crate_sources: RefCell<Vec<CrateSource>>,
- used_libraries: RefCell<Vec<(String, NativeLibaryKind)>>,
+ used_libraries: RefCell<Vec<(String, NativeLibraryKind)>>,
used_link_args: RefCell<Vec<String>>,
pub intr: Rc<IdentInterner>,
}
libs
}
- pub fn add_used_library(&self, lib: String, kind: NativeLibaryKind) {
+ pub fn add_used_library(&self, lib: String, kind: NativeLibraryKind) {
assert!(!lib.is_empty());
self.used_libraries.borrow_mut().push((lib, kind));
}
pub fn get_used_libraries<'a>(&'a self)
- -> &'a RefCell<Vec<(String, NativeLibaryKind)> > {
+ -> &'a RefCell<Vec<(String,
+ NativeLibraryKind)>> {
&self.used_libraries
}
impl MetadataBlob {
pub fn as_slice<'a>(&'a self) -> &'a [u8] {
- match *self {
+ let slice = match *self {
MetadataVec(ref vec) => vec.as_slice(),
MetadataArchive(ref ar) => ar.as_slice(),
+ };
+ if slice.len() < 4 {
+ &[]
+ } else {
+ let len = ((slice[0] as u32) << 24) |
+ ((slice[1] as u32) << 16) |
+ ((slice[2] as u32) << 8) |
+ ((slice[3] as u32) << 0);
+ slice.slice(4, len as uint + 4)
}
}
}
DlField
}
+impl Copy for DefLike {}
+
/// Iterates over the language items in the given crate.
pub fn each_lang_item(cdata: Cmd, f: |ast::NodeId, uint| -> bool) -> bool {
let root = rbml::Doc::new(cdata.data());
pub fn get_native_libraries(cdata: Cmd)
- -> Vec<(cstore::NativeLibaryKind, String)> {
+ -> Vec<(cstore::NativeLibraryKind, String)> {
let libraries = reader::get_doc(rbml::Doc::new(cdata.data()),
tag_native_libraries);
let mut result = Vec::new();
reader::tagged_docs(libraries, tag_native_libraries_lib, |lib_doc| {
let kind_doc = reader::get_doc(lib_doc, tag_native_libraries_kind);
let name_doc = reader::get_doc(lib_doc, tag_native_libraries_name);
- let kind: cstore::NativeLibaryKind =
+ let kind: cstore::NativeLibraryKind =
FromPrimitive::from_u32(reader::doc_as_u32(kind_doc)).unwrap();
let name = name_doc.as_str().to_string();
result.push((kind, name));
pub fn encode_metadata(parms: EncodeParams, krate: &ast::Crate) -> Vec<u8> {
let mut wr = SeekableMemWriter::new();
encode_metadata_inner(&mut wr, parms, krate);
- wr.unwrap().into_iter().collect()
+ let mut v = wr.unwrap();
+
+ // And here we run into yet another obscure archive bug: in which metadata
+ // loaded from archives may have trailing garbage bytes. Awhile back one of
+ // our tests was failing sporadially on the OSX 64-bit builders (both nopt
+ // and opt) by having rbml generate an out-of-bounds panic when looking at
+ // metadata.
+ //
+ // Upon investigation it turned out that the metadata file inside of an rlib
+ // (and ar archive) was being corrupted. Some compilations would generate a
+ // metadata file which would end in a few extra bytes, while other
+ // compilations would not have these extra bytes appended to the end. These
+ // extra bytes were interpreted by rbml as an extra tag, so they ended up
+ // being interpreted causing the out-of-bounds.
+ //
+ // The root cause of why these extra bytes were appearing was never
+ // discovered, and in the meantime the solution we're employing is to insert
+ // the length of the metadata to the start of the metadata. Later on this
+ // will allow us to slice the metadata to the precise length that we just
+ // generated regardless of trailing bytes that end up in it.
+ let len = v.len() as u32;
+ v.insert(0, (len >> 0) as u8);
+ v.insert(0, (len >> 8) as u8);
+ v.insert(0, (len >> 16) as u8);
+ v.insert(0, (len >> 24) as u8);
+ return v;
}
fn encode_metadata_inner(wr: &mut SeekableMemWriter,
use util::fs as myfs;
-pub enum FileMatch { FileMatches, FileDoesntMatch }
+pub enum FileMatch {
+ FileMatches,
+ FileDoesntMatch,
+}
+
+impl Copy for FileMatch {}
// A module for searching for libraries
// FIXME (#2658): I'm not happy how this module turned out. Should
//!
//! The compiler accepts a flag of this form a number of times:
//!
-//! ```notrust
+//! ```ignore
//! --extern crate-name=path/to/the/crate.rlib
//! ```
//!
//!
//! and the compiler would be invoked as:
//!
-//! ```notrust
+//! ```ignore
//! rustc a.rs --extern b1=path/to/libb1.rlib --extern b2=path/to/libb2.rlib
//! ```
//!
//! dependencies, not the upstream transitive dependencies. Consider this
//! dependency graph:
//!
-//! ```notrust
+//! ```ignore
//! A.1 A.2
//! | |
//! | |
// Identifies an unboxed closure
UnboxedClosureSource
}
+
+impl Copy for DefIdSource {}
pub type conv_did<'a> =
|source: DefIdSource, ast::DefId|: 'a -> ast::DefId;
use middle::expr_use_visitor as euv;
use middle::mem_categorization as mc;
use middle::region;
+use middle::ty::ParameterEnvironment;
use middle::ty;
+use syntax::ast::NodeId;
use syntax::ast;
use syntax::codemap::Span;
use util::ppaux::Repr;
dfcx_loans: &'a LoanDataFlow<'a, 'tcx>,
move_data: move_data::FlowedMoveData<'a, 'tcx>,
all_loans: &'a [Loan<'tcx>],
+ param_env: &'a ParameterEnvironment<'tcx>,
}
impl<'a, 'tcx> euv::Delegate<'tcx> for CheckLoanCtxt<'a, 'tcx> {
dfcx_loans: &LoanDataFlow<'b, 'tcx>,
move_data: move_data::FlowedMoveData<'c, 'tcx>,
all_loans: &[Loan<'tcx>],
+ fn_id: NodeId,
decl: &ast::FnDecl,
body: &ast::Block) {
debug!("check_loans(body id={})", body.id);
+ let param_env = ParameterEnvironment::for_item(bccx.tcx, fn_id);
+
let mut clcx = CheckLoanCtxt {
bccx: bccx,
dfcx_loans: dfcx_loans,
move_data: move_data,
all_loans: all_loans,
+ param_env: ¶m_env,
};
{
- let mut euv = euv::ExprUseVisitor::new(&mut clcx, bccx.tcx);
+ let mut euv = euv::ExprUseVisitor::new(&mut clcx,
+ bccx.tcx,
+ param_env.clone());
euv.walk_fn(decl, body);
}
}
use_kind,
&**lp,
the_move,
- moved_lp);
+ moved_lp,
+ self.param_env);
false
});
}
use middle::expr_use_visitor as euv;
use middle::mem_categorization as mc;
use middle::region;
+use middle::ty::ParameterEnvironment;
use middle::ty;
use util::ppaux::{Repr};
mod move_error;
pub fn gather_loans_in_fn<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
+ fn_id: NodeId,
decl: &ast::FnDecl,
body: &ast::Block)
- -> (Vec<Loan<'tcx>>, move_data::MoveData<'tcx>)
-{
+ -> (Vec<Loan<'tcx>>,
+ move_data::MoveData<'tcx>) {
let mut glcx = GatherLoanCtxt {
bccx: bccx,
all_loans: Vec::new(),
move_error_collector: move_error::MoveErrorCollector::new(),
};
+ let param_env = ParameterEnvironment::for_item(bccx.tcx, fn_id);
+
{
- let mut euv = euv::ExprUseVisitor::new(&mut glcx, bccx.tcx);
+ let mut euv = euv::ExprUseVisitor::new(&mut glcx,
+ bccx.tcx,
+ param_env);
euv.walk_fn(decl, body);
}
Assigns,
}
+impl Copy for Variant {}
+
impl Variant {
pub fn short_name(&self) -> &'static str {
match *self {
use middle::expr_use_visitor as euv;
use middle::mem_categorization as mc;
use middle::region;
-use middle::ty::{mod, Ty};
+use middle::ty::{mod, ParameterEnvironment, Ty};
use util::ppaux::{note_and_explain_region, Repr, UserString};
use std::rc::Rc;
#[deriving(Clone)]
pub struct LoanDataFlowOperator;
+impl Copy for LoanDataFlowOperator {}
+
pub type LoanDataFlow<'a, 'tcx> = DataFlowContext<'a, 'tcx, LoanDataFlowOperator>;
impl<'a, 'tcx, 'v> Visitor<'v> for BorrowckCtxt<'a, 'tcx> {
move_data::fragments::instrument_move_fragments(&flowed_moves.move_data,
this.tcx, sp, id);
- check_loans::check_loans(this, &loan_dfcx, flowed_moves,
- all_loans.as_slice(), decl, body);
+ check_loans::check_loans(this,
+ &loan_dfcx,
+ flowed_moves,
+ all_loans.as_slice(),
+ id,
+ decl,
+ body);
visit::walk_fn(this, fk, decl, body, sp);
}
// Check the body of fn items.
let id_range = ast_util::compute_id_range_for_fn_body(fk, decl, body, sp, id);
let (all_loans, move_data) =
- gather_loans::gather_loans_in_fn(this, decl, body);
+ gather_loans::gather_loans_in_fn(this, id, decl, body);
let mut loan_dfcx =
DataFlowContext::new(this.tcx,
LpInterior(mc::InteriorKind) // `LV.f` in doc.rs
}
+impl Copy for LoanPathElem {}
+
pub fn closure_to_block(closure_id: ast::NodeId,
tcx: &ty::ctxt) -> ast::NodeId {
match tcx.map.get(closure_id) {
// Errors that can occur
#[deriving(PartialEq)]
+#[allow(missing_copy_implementations)]
pub enum bckerr_code {
err_mutbl,
err_out_of_scope(ty::Region, ty::Region), // superscope, subscope
BorrowViolation(euv::LoanCause)
}
+impl Copy for AliasableViolationKind {}
+
#[deriving(Show)]
pub enum MovedValueUseKind {
MovedInUse,
MovedInCapture,
}
+impl Copy for MovedValueUseKind {}
+
///////////////////////////////////////////////////////////////////////////
// Misc
use_kind: MovedValueUseKind,
lp: &LoanPath<'tcx>,
the_move: &move_data::Move,
- moved_lp: &LoanPath<'tcx>) {
+ moved_lp: &LoanPath<'tcx>,
+ param_env: &ParameterEnvironment<'tcx>) {
let verb = match use_kind {
MovedInUse => "use",
MovedInCapture => "capture",
r).as_slice())
}
};
- let (suggestion, _) = move_suggestion(self.tcx, expr_ty,
+ let (suggestion, _) = move_suggestion(self.tcx, param_env, expr_ty,
("moved by default", ""));
self.tcx.sess.span_note(
expr_span,
r).as_slice())
}
};
- let (suggestion, help) = move_suggestion(self.tcx, expr_ty,
+ let (suggestion, help) = move_suggestion(self.tcx,
+ param_env,
+ expr_ty,
("moved by default", "make a copy and \
capture that instead to override"));
self.tcx.sess.span_note(
}
}
- fn move_suggestion<'tcx>(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>,
+ fn move_suggestion<'tcx>(tcx: &ty::ctxt<'tcx>,
+ param_env: &ty::ParameterEnvironment<'tcx>,
+ ty: Ty<'tcx>,
default_msgs: (&'static str, &'static str))
-> (&'static str, &'static str) {
match ty.sty {
}) =>
("a non-copyable stack closure",
"capture it in a new closure, e.g. `|x| f(x)`, to override"),
- _ if ty::type_moves_by_default(tcx, ty) =>
+ _ if ty::type_moves_by_default(tcx, ty, param_env) =>
("non-copyable",
"perhaps you meant to use `clone()`?"),
_ => default_msgs,
#[deriving(PartialEq, Eq, PartialOrd, Ord, Show)]
pub struct MovePathIndex(uint);
+impl Copy for MovePathIndex {}
+
impl MovePathIndex {
fn get(&self) -> uint {
let MovePathIndex(v) = *self; v
#[deriving(PartialEq)]
pub struct MoveIndex(uint);
+impl Copy for MoveIndex {}
+
impl MoveIndex {
fn get(&self) -> uint {
let MoveIndex(v) = *self; v
Captured // Closure creation that moves a value
}
+impl Copy for MoveKind {}
+
pub struct Move {
/// Path being moved.
pub path: MovePathIndex,
pub next_move: MoveIndex
}
+impl Copy for Move {}
+
pub struct Assignment {
/// Path being assigned.
pub path: MovePathIndex,
pub span: Span,
}
+impl Copy for Assignment {}
+
pub struct VariantMatch {
/// downcast to the variant.
pub path: MovePathIndex,
pub mode: euv::MatchMode
}
+impl Copy for VariantMatch {}
+
#[deriving(Clone)]
pub struct MoveDataFlowOperator;
+impl Copy for MoveDataFlowOperator {}
+
pub type MoveDataFlow<'a, 'tcx> = DataFlowContext<'a, 'tcx, MoveDataFlowOperator>;
#[deriving(Clone)]
pub struct AssignDataFlowOperator;
+impl Copy for AssignDataFlowOperator {}
+
pub type AssignDataFlow<'a, 'tcx> = DataFlowContext<'a, 'tcx, AssignDataFlowOperator>;
fn loan_path_is_precise(loan_path: &LoanPath) -> bool {
break_index: CFGIndex, // where to go on a `break
}
+impl Copy for LoopScope {}
+
pub fn construct(tcx: &ty::ctxt,
blk: &ast::Block) -> CFG {
let mut graph = graph::Graph::new();
pub id: ast::NodeId
}
+impl Copy for CFGNodeData {}
+
pub struct CFGEdgeData {
pub exiting_scopes: Vec<ast::NodeId>
}
Normal, Loop, Closure
}
+impl Copy for Context {}
+
struct CheckLoopVisitor<'a> {
sess: &'a Session,
cx: Context
}
+impl<'a> Copy for CheckLoopVisitor<'a> {}
+
pub fn check_crate(sess: &Session, krate: &ast::Crate) {
visit::walk_crate(&mut CheckLoopVisitor { sess: sess, cx: Normal }, krate)
}
}
pub struct MatchCheckCtxt<'a, 'tcx: 'a> {
- pub tcx: &'a ty::ctxt<'tcx>
+ pub tcx: &'a ty::ctxt<'tcx>,
+ pub param_env: ParameterEnvironment<'tcx>,
}
#[deriving(Clone, PartialEq)]
LeaveOutWitness
}
+impl Copy for WitnessPreference {}
+
impl<'a, 'tcx, 'v> Visitor<'v> for MatchCheckCtxt<'a, 'tcx> {
fn visit_expr(&mut self, ex: &ast::Expr) {
check_expr(self, ex);
}
pub fn check_crate(tcx: &ty::ctxt) {
- visit::walk_crate(&mut MatchCheckCtxt { tcx: tcx }, tcx.map.krate());
+ visit::walk_crate(&mut MatchCheckCtxt {
+ tcx: tcx,
+ param_env: ty::empty_parameter_environment(),
+ }, tcx.map.krate());
tcx.sess.abort_if_errors();
}
decl: &ast::FnDecl,
body: &ast::Block,
sp: Span,
- _: NodeId) {
+ fn_id: NodeId) {
+ match kind {
+ visit::FkFnBlock => {}
+ _ => cx.param_env = ParameterEnvironment::for_item(cx.tcx, fn_id),
+ }
+
visit::walk_fn(cx, kind, decl, body, sp);
+
for input in decl.inputs.iter() {
is_refutable(cx, &*input.pat, |pat| {
span_err!(cx.tcx.sess, input.pat.span, E0006,
match p.node {
ast::PatIdent(ast::BindByValue(_), _, ref sub) => {
let pat_ty = ty::node_id_to_type(tcx, p.id);
- if ty::type_moves_by_default(tcx, pat_ty) {
+ if ty::type_moves_by_default(tcx,
+ pat_ty,
+ &cx.param_env) {
check_move(p, sub.as_ref().map(|p| &**p));
}
}
let mut checker = MutationChecker {
cx: cx,
};
- let mut visitor = ExprUseVisitor::new(&mut checker, checker.cx.tcx);
+ let mut visitor = ExprUseVisitor::new(&mut checker,
+ checker.cx.tcx,
+ cx.param_env.clone());
visitor.walk_expr(guard);
}
use middle::expr_use_visitor as euv;
use middle::mem_categorization as mc;
+use middle::ty::ParameterEnvironment;
use middle::ty;
use util::ppaux::ty_to_string;
fd: &'v ast::FnDecl,
b: &'v ast::Block,
s: Span,
- _: ast::NodeId) {
+ fn_id: ast::NodeId) {
{
- let mut euv = euv::ExprUseVisitor::new(self, self.tcx);
+ let param_env = ParameterEnvironment::for_item(self.tcx, fn_id);
+ let mut euv = euv::ExprUseVisitor::new(self, self.tcx, param_env);
euv.walk_fn(fd, b);
}
visit::walk_fn(self, fk, fd, b, s)
InNothing,
}
+impl Copy for Mode {}
+
struct CheckStaticVisitor<'a, 'tcx: 'a> {
tcx: &'a ty::ctxt<'tcx>,
mode: Mode,
checker: &'a mut GlobalChecker,
}
-struct GlobalVisitor<'a, 'b, 'tcx: 'b>(euv::ExprUseVisitor<'a, 'b, 'tcx, ty::ctxt<'tcx>>);
+struct GlobalVisitor<'a,'b,'tcx:'a+'b>(
+ euv::ExprUseVisitor<'a,'b,'tcx,ty::ctxt<'tcx>>);
struct GlobalChecker {
static_consumptions: NodeSet,
const_borrows: NodeSet,
static_local_borrows: NodeSet::new(),
};
{
- let visitor = euv::ExprUseVisitor::new(&mut checker, tcx);
+ let param_env = ty::empty_parameter_environment();
+ let visitor = euv::ExprUseVisitor::new(&mut checker, tcx, param_env);
visit::walk_crate(&mut GlobalVisitor(visitor), tcx.map.krate());
}
visit::walk_crate(&mut CheckStaticVisitor {
}
}
-impl<'a, 'b, 't, 'v> Visitor<'v> for GlobalVisitor<'a, 'b, 't> {
+impl<'a,'b,'t,'v> Visitor<'v> for GlobalVisitor<'a,'b,'t> {
fn visit_item(&mut self, item: &ast::Item) {
match item.node {
ast::ItemConst(_, ref e) |
non_const
}
+impl Copy for constness {}
+
type constness_cache = DefIdMap<constness>;
pub fn join(a: constness, b: constness) -> constness {
use util::nodemap::NodeMap;
#[deriving(Show)]
-pub enum EntryOrExit { Entry, Exit }
+pub enum EntryOrExit {
+ Entry,
+ Exit,
+}
+
+impl Copy for EntryOrExit {}
#[deriving(Clone)]
pub struct DataFlowContext<'a, 'tcx: 'a, O> {
DefMethod(ast::DefId /* method */, Option<ast::DefId> /* trait */, MethodProvenance),
}
+impl Copy for Def {}
+
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
pub enum MethodProvenance {
FromTrait(ast::DefId),
}
}
+impl Copy for MethodProvenance {}
+
impl Def {
pub fn def_id(&self) -> ast::DefId {
match *self {
UnsafeBlock(ast::NodeId),
}
+impl Copy for UnsafeContext {}
+
fn type_is_unsafe_function(ty: Ty) -> bool {
match ty.sty {
ty::ty_bare_fn(ref f) => f.fn_style == ast::UnsafeFn,
use middle::{def, region, pat_util};
use middle::mem_categorization as mc;
use middle::mem_categorization::Typer;
-use middle::ty::{mod, Ty};
+use middle::ty::{mod, ParameterEnvironment, Ty};
use middle::ty::{MethodCall, MethodObject, MethodTraitObject};
use middle::ty::{MethodOrigin, MethodParam, MethodTypeParam};
use middle::ty::{MethodStatic, MethodStaticUnboxedClosure};
use util::ppaux::Repr;
+use std::kinds;
use syntax::ast;
use syntax::ptr::P;
use syntax::codemap::Span;
MatchDiscriminant
}
+impl kinds::Copy for LoanCause {}
+
#[deriving(PartialEq, Show)]
pub enum ConsumeMode {
Copy, // reference to x where x has a type that copies
Move(MoveReason), // reference to x where x has a type that moves
}
+impl kinds::Copy for ConsumeMode {}
+
#[deriving(PartialEq,Show)]
pub enum MoveReason {
DirectRefMove,
CaptureMove,
}
+impl kinds::Copy for MoveReason {}
+
#[deriving(PartialEq,Show)]
pub enum MatchMode {
NonBindingMatch,
MovingMatch,
}
+impl kinds::Copy for MatchMode {}
+
#[deriving(PartialEq,Show)]
enum TrackMatchMode<T> {
- Unknown, Definite(MatchMode), Conflicting,
+ Unknown,
+ Definite(MatchMode),
+ Conflicting,
}
+impl<T> kinds::Copy for TrackMatchMode<T> {}
+
impl<T> TrackMatchMode<T> {
// Builds up the whole match mode for a pattern from its constituent
// parts. The lattice looks like this:
WriteAndRead, // x += y
}
+impl kinds::Copy for MutateMode {}
+
enum OverloadedCallType {
FnOverloadedCall,
FnMutOverloadedCall,
FnOnceOverloadedCall,
}
+impl kinds::Copy for OverloadedCallType {}
+
impl OverloadedCallType {
fn from_trait_id(tcx: &ty::ctxt, trait_id: ast::DefId)
-> OverloadedCallType {
typer: &'t TYPER,
mc: mc::MemCategorizationContext<'t,TYPER>,
delegate: &'d mut (Delegate<'tcx>+'d),
+ param_env: ParameterEnvironment<'tcx>,
}
// If the TYPER results in an error, it's because the type check
impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
pub fn new(delegate: &'d mut Delegate<'tcx>,
- typer: &'t TYPER)
+ typer: &'t TYPER,
+ param_env: ParameterEnvironment<'tcx>)
-> ExprUseVisitor<'d,'t,'tcx,TYPER> {
- ExprUseVisitor { typer: typer,
- mc: mc::MemCategorizationContext::new(typer),
- delegate: delegate }
+ ExprUseVisitor {
+ typer: typer,
+ mc: mc::MemCategorizationContext::new(typer),
+ delegate: delegate,
+ param_env: param_env,
+ }
}
pub fn walk_fn(&mut self,
consume_id: ast::NodeId,
consume_span: Span,
cmt: mc::cmt<'tcx>) {
- let mode = copy_or_move(self.tcx(), cmt.ty, DirectRefMove);
+ let mode = copy_or_move(self.tcx(),
+ cmt.ty,
+ &self.param_env,
+ DirectRefMove);
self.delegate.consume(consume_id, consume_span, cmt, mode);
}
ast::PatIdent(ast::BindByRef(_), _, _) =>
mode.lub(BorrowingMatch),
ast::PatIdent(ast::BindByValue(_), _, _) => {
- match copy_or_move(tcx, cmt_pat.ty, PatBindingMove) {
+ match copy_or_move(tcx,
+ cmt_pat.ty,
+ &self.param_env,
+ PatBindingMove) {
Copy => mode.lub(CopyingMatch),
Move(_) => mode.lub(MovingMatch),
}
let tcx = typer.tcx();
let def_map = &self.typer.tcx().def_map;
let delegate = &mut self.delegate;
-
+ let param_env = &mut self.param_env;
return_if_err!(mc.cat_pattern(cmt_discr.clone(), pat, |mc, cmt_pat, pat| {
if pat_util::pat_is_binding(def_map, pat) {
let tcx = typer.tcx();
r, bk, RefBinding);
}
ast::PatIdent(ast::BindByValue(_), _, _) => {
- let mode = copy_or_move(typer.tcx(), cmt_pat.ty, PatBindingMove);
+ let mode = copy_or_move(typer.tcx(),
+ cmt_pat.ty,
+ param_env,
+ PatBindingMove);
debug!("walk_pat binding consuming pat");
delegate.consume_pat(pat, cmt_pat, mode);
}
let cmt_var = return_if_err!(self.cat_captured_var(closure_expr.id,
closure_expr.span,
freevar.def));
- let mode = copy_or_move(self.tcx(), cmt_var.ty, CaptureMove);
+ let mode = copy_or_move(self.tcx(),
+ cmt_var.ty,
+ &self.param_env,
+ CaptureMove);
self.delegate.consume(closure_expr.id, freevar.span, cmt_var, mode);
}
}
}
}
-fn copy_or_move<'tcx>(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>,
- move_reason: MoveReason) -> ConsumeMode {
- if ty::type_moves_by_default(tcx, ty) { Move(move_reason) } else { Copy }
+fn copy_or_move<'tcx>(tcx: &ty::ctxt<'tcx>,
+ ty: Ty<'tcx>,
+ param_env: &ParameterEnvironment<'tcx>,
+ move_reason: MoveReason)
+ -> ConsumeMode {
+ if ty::type_moves_by_default(tcx, ty, param_env) {
+ Move(move_reason)
+ } else {
+ Copy
+ }
}
ParameterSimplifiedType,
}
+impl Copy for SimplifiedType {}
+
/// Tries to simplify a type by dropping type parameters, deref'ing away any reference types, etc.
/// The idea is to get something simple that we can use to quickly decide if two types could unify
/// during method lookup.
#[allow(non_upper_case_globals)]
pub const InvalidNodeIndex: NodeIndex = NodeIndex(uint::MAX);
+impl Copy for NodeIndex {}
+
#[deriving(PartialEq, Show)]
pub struct EdgeIndex(pub uint);
#[allow(non_upper_case_globals)]
pub const InvalidEdgeIndex: EdgeIndex = EdgeIndex(uint::MAX);
+impl Copy for EdgeIndex {}
+
// Use a private field here to guarantee no more instances are created:
#[deriving(Show)]
pub struct Direction { repr: uint }
#[allow(non_upper_case_globals)]
pub const Incoming: Direction = Direction { repr: 1 };
+impl Copy for Direction {}
+
impl NodeIndex {
fn get(&self) -> uint { let NodeIndex(v) = *self; v }
/// Returns unique id (unique with respect to the graph holding associated node).
IfExpressionWithNoElse(Span)
}
+impl Copy for TypeOrigin {}
+
/// See `error_reporting.rs` for more details
#[deriving(Clone, Show)]
pub enum ValuePairs<'tcx> {
HigherRankedType,
}
+impl Copy for LateBoundRegionConversionTime {}
+
/// Reasons to create a region inference variable
///
/// See `error_reporting.rs` for more details
unresolved_ty(TyVid)
}
+impl Copy for fixup_err {}
+
pub fn fixup_err_to_string(f: fixup_err) -> String {
match f {
unresolved_int_ty(_) => {
ConstrainVarSubReg(RegionVid, Region),
}
+impl Copy for Constraint {}
+
// Something we have to verify after region inference is done, but
// which does not directly influence the inference process
pub enum Verify<'tcx> {
b: Region,
}
+impl Copy for TwoRegions {}
+
#[deriving(PartialEq)]
pub enum UndoLogEntry {
OpenSnapshot,
AddCombination(CombineMapType, TwoRegions)
}
+impl Copy for UndoLogEntry {}
+
#[deriving(PartialEq)]
pub enum CombineMapType {
Lub, Glb
}
+impl Copy for CombineMapType {}
+
#[deriving(Clone, Show)]
pub enum RegionResolutionError<'tcx> {
/// `ConcreteFailure(o, a, b)`:
length: uint
}
+impl Copy for RegionSnapshot {}
+
#[deriving(Show)]
pub struct RegionMark {
length: uint
}
+impl Copy for RegionMark {}
+
impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
pub fn new(tcx: &'a ty::ctxt<'tcx>) -> RegionVarBindings<'a, 'tcx> {
RegionVarBindings {
#[deriving(PartialEq, Show)]
enum Classification { Expanding, Contracting }
+impl Copy for Classification {}
+
pub enum VarValue { NoValue, Value(Region), ErrorValue }
+impl Copy for VarValue {}
+
struct VarData {
classification: Classification,
value: VarValue,
SubtypeOf, SupertypeOf, EqTo
}
+impl Copy for RelationDir {}
+
impl RelationDir {
fn opposite(self) -> RelationDir {
match self {
pub struct Delegate;
+impl Copy for Delegate {}
+
// We can't use V:LatticeValue, much as I would like to,
// because frequently the pattern is that V=Option<U> for some
// other type parameter U, and we have no way to say
$($variant),*
}
+impl Copy for LangItem {}
+
pub struct LanguageItems {
pub items: Vec<Option<ast::DefId>>,
pub missing: Vec<LangItem>,
#[deriving(PartialEq)]
struct Variable(uint);
+
+impl Copy for Variable {}
+
#[deriving(PartialEq)]
struct LiveNode(uint);
+impl Copy for LiveNode {}
+
impl Variable {
fn get(&self) -> uint { let Variable(v) = *self; v }
}
ExitNode
}
+impl Copy for LiveNodeKind {}
+
fn live_node_kind_to_string(lnk: LiveNodeKind, cx: &ty::ctxt) -> String {
let cm = cx.sess.codemap();
match lnk {
ident: ast::Ident
}
+impl Copy for LocalInfo {}
+
#[deriving(Show)]
enum VarKind {
Arg(NodeId, ast::Ident),
CleanExit
}
+impl Copy for VarKind {}
+
struct IrMaps<'a, 'tcx: 'a> {
tcx: &'a ty::ctxt<'tcx>,
used: bool
}
+impl Copy for Users {}
+
fn invalid_users() -> Users {
Users {
reader: invalid_node(),
clean_exit_var: Variable
}
+impl Copy for Specials {}
+
static ACC_READ: uint = 1u;
static ACC_WRITE: uint = 2u;
static ACC_USE: uint = 4u;
pub is_unboxed: bool
}
+impl Copy for Upvar {}
+
// different kinds of pointers:
#[deriving(Clone, PartialEq, Eq, Hash, Show)]
pub enum PointerKind {
UnsafePtr(ast::Mutability)
}
+impl Copy for PointerKind {}
+
// We use the term "interior" to mean "something reachable from the
// base without a pointer dereference", e.g. a field
#[deriving(Clone, PartialEq, Eq, Hash, Show)]
InteriorElement(ElementKind),
}
+impl Copy for InteriorKind {}
+
#[deriving(Clone, PartialEq, Eq, Hash, Show)]
pub enum FieldName {
NamedField(ast::Name),
PositionalField(uint)
}
+impl Copy for FieldName {}
+
#[deriving(Clone, PartialEq, Eq, Hash, Show)]
pub enum ElementKind {
VecElement,
OtherElement,
}
+impl Copy for ElementKind {}
+
#[deriving(Clone, PartialEq, Eq, Hash, Show)]
pub enum MutabilityCategory {
McImmutable, // Immutable.
McInherited, // Inherited from the fact that owner is mutable.
}
+impl Copy for MutabilityCategory {}
+
// A note about the provenance of a `cmt`. This is used for
// special-case handling of upvars such as mutability inference.
// Upvar categorization can generate a variable number of nested
NoteNone // Nothing special
}
+impl Copy for Note {}
+
// `cmt`: "Category, Mutability, and Type".
//
// a complete categorization of a value indicating where it originated
deref_interior(InteriorKind),
}
+impl Copy for deref_kind {}
+
// Categorizes a derefable type. Note that we include vectors and strings as
// derefable (we model an index as the combination of a deref and then a
// pointer adjustment).
typer: &'t TYPER
}
+impl<'t,TYPER:'t> Copy for MemCategorizationContext<'t,TYPER> {}
+
pub type McResult<T> = Result<T, ()>;
/// The `Typer` trait provides the interface for the mem-categorization
InteriorSafe
}
+impl Copy for InteriorSafety {}
+
pub enum AliasableReason {
AliasableBorrowed,
AliasableClosure(ast::NodeId), // Aliasable due to capture Fn closure env
AliasableStaticMut(InteriorSafety),
}
+impl Copy for AliasableReason {}
+
impl<'tcx> cmt_<'tcx> {
pub fn guarantor(&self) -> cmt<'tcx> {
//! Returns `self` after stripping away any owned pointer derefs or
--- /dev/null
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Recursion limit.
+//
+// There are various parts of the compiler that must impose arbitrary limits
+// on how deeply they recurse to prevent stack overflow. Users can override
+// this via an attribute on the crate like `#![recursion_limit(22)]`. This pass
+// just peeks and looks for that attribute.
+
+use session::Session;
+use syntax::ast;
+use syntax::attr::AttrMetaMethods;
+use std::str::FromStr;
+
+pub fn update_recursion_limit(sess: &Session, krate: &ast::Crate) {
+ for attr in krate.attrs.iter() {
+ if !attr.check_name("recursion_limit") {
+ continue;
+ }
+
+ if let Some(s) = attr.value_str() {
+ if let Some(n) = FromStr::from_str(s.get()) {
+ sess.recursion_limit.set(n);
+ return;
+ }
+ }
+
+ sess.span_err(attr.span, "malformed recursion limit attribute, \
+ expected #![recursion_limit(\"N\")]");
+ }
+}
Misc(ast::NodeId)
}
+impl Copy for CodeExtent {}
+
impl CodeExtent {
/// Creates a scope that represents the dynamic extent associated
/// with `node_id`.
parent: Option<ast::NodeId>,
}
+impl Copy for Context {}
+
struct RegionResolutionVisitor<'a> {
sess: &'a Session,
binding_mode: BindingMode,
}
+impl Copy for binding_info {}
+
// Map from the name in a pattern to its binding mode.
type BindingMap = HashMap<Name,binding_info>;
type_used: ImportUse},
}
+impl Copy for LastPrivate {}
+
#[deriving(Show)]
pub enum PrivateDep {
AllPublic,
DependsOn(DefId),
}
+impl Copy for PrivateDep {}
+
// How an import is used.
#[deriving(PartialEq, Show)]
pub enum ImportUse {
Used, // The import is used.
}
+impl Copy for ImportUse {}
+
impl LastPrivate {
fn or(self, other: LastPrivate) -> LastPrivate {
match (self, other) {
ArgumentIrrefutableMode,
}
+impl Copy for PatternBindingMode {}
+
#[deriving(PartialEq, Eq, Hash, Show)]
enum Namespace {
TypeNS,
ValueNS
}
+impl Copy for Namespace {}
+
#[deriving(PartialEq)]
enum NamespaceError {
NoError,
ValueError
}
+impl Copy for NamespaceError {}
+
/// A NamespaceResult represents the result of resolving an import in
/// a particular namespace. The result is either definitely-resolved,
/// definitely- unresolved, or unknown.
GlobImport
}
+impl Copy for ImportDirectiveSubclass {}
+
/// The context that we thread through while building the reduced graph.
#[deriving(Clone)]
enum ReducedGraphParent {
RibKind)
}
+impl<'a> Copy for TypeParameters<'a> {}
+
// The rib kind controls the translation of local
// definitions (`DefLocal`) to upvars (`DefUpvar`).
ConstantItemRibKind
}
+impl Copy for RibKind {}
+
// Methods can be required or provided. RequiredMethod methods only occur in traits.
enum MethodSort {
RequiredMethod,
ProvidedMethod(NodeId)
}
+impl Copy for MethodSort {}
+
enum UseLexicalScopeFlag {
DontUseLexicalScope,
UseLexicalScope
}
+impl Copy for UseLexicalScopeFlag {}
+
enum ModulePrefixResult {
NoPrefixFound,
PrefixFound(Rc<Module>, uint)
TypeTraitItemKind,
}
+impl Copy for TraitItemKind {}
+
impl TraitItemKind {
pub fn from_explicit_self_category(explicit_self_category:
ExplicitSelfCategory)
PathSearch,
}
+impl Copy for NameSearchType {}
+
enum BareIdentifierPatternResolution {
FoundStructOrEnumVariant(Def, LastPrivate),
FoundConst(Def, LastPrivate),
BareIdentifierPatternUnresolved
}
+impl Copy for BareIdentifierPatternResolution {}
+
// Specifies how duplicates should be handled when adding a child item if
// another item exists with the same name in some namespace.
#[deriving(PartialEq)]
OverwriteDuplicates
}
+impl Copy for DuplicateCheckingMode {}
+
/// One local scope.
struct Rib {
bindings: HashMap<Name, DefLike>,
AnonymousModuleKind,
}
+impl Copy for ModuleKind {}
+
/// One node in the tree of modules.
struct Module {
parent_link: ParentLink,
}
}
+impl Copy for DefModifiers {}
+
// Records a possibly-private type definition.
#[deriving(Clone)]
struct TypeNsDef {
value_span: Option<Span>,
}
+impl Copy for ValueNsDef {}
+
// Records the definitions (at most one for each namespace) that a name is
// bound to.
struct NameBindings {
TraitQPath, // <T as SomeTrait>::
}
+impl Copy for TraitReferenceType {}
+
impl NameBindings {
fn new() -> NameBindings {
NameBindings {
/* lifetime decl */ ast::NodeId),
}
+impl Copy for DefRegion {}
+
// maps the id of each lifetime reference to the lifetime decl
// that it corresponds to
pub type NamedRegionMap = NodeMap<DefRegion>;
FnSpace, // Type parameters attached to a method or fn
}
+impl Copy for ParamSpace {}
+
impl ParamSpace {
pub fn all() -> [ParamSpace, ..4] {
[TypeSpace, SelfSpace, AssocSpace, FnSpace]
pub code: ObligationCauseCode<'tcx>
}
+impl<'tcx> Copy for ObligationCause<'tcx> {}
+
#[deriving(Clone)]
pub enum ObligationCauseCode<'tcx> {
/// Not well classified or should be obvious from span.
pub type Obligations<'tcx> = subst::VecPerParamSpace<Obligation<'tcx>>;
+impl<'tcx> Copy for ObligationCauseCode<'tcx> {}
+
pub type Selection<'tcx> = Vtable<'tcx, Obligation<'tcx>>;
#[deriving(Clone,Show)]
VtableFnPointer(ref sig) => VtableFnPointer((*sig).clone()),
VtableUnboxedClosure(d, ref s) => VtableUnboxedClosure(d, s.clone()),
VtableParam(ref p) => VtableParam((*p).clone()),
- VtableBuiltin(ref i) => VtableBuiltin(i.map_nested(op)),
+ VtableBuiltin(ref b) => VtableBuiltin(b.map_nested(op)),
}
}
VtableFnPointer(sig) => VtableFnPointer(sig),
VtableUnboxedClosure(d, s) => VtableUnboxedClosure(d, s),
VtableParam(p) => VtableParam(p),
- VtableBuiltin(i) => VtableBuiltin(i.map_move_nested(op)),
+ VtableBuiltin(no) => VtableBuiltin(no.map_move_nested(op)),
}
}
}
previous: Option<&'prev ObligationStack<'prev, 'tcx>>
}
+#[deriving(Clone)]
pub struct SelectionCache<'tcx> {
hashmap: RefCell<HashMap<Rc<ty::TraitRef<'tcx>>,
SelectionResult<'tcx, Candidate<'tcx>>>>,
CoerciveMethodMatch(/* impl we matched */ ast::DefId)
}
+impl Copy for MethodMatchedData {}
+
/// The selection process begins by considering all impls, where
/// clauses, and so forth that might resolve an obligation. Sometimes
/// we'll be able to say definitively that (e.g.) an impl does not
}
#[deriving(Show)]
-enum EvaluationResult {
+enum EvaluationResult<'tcx> {
EvaluatedToOk,
- EvaluatedToErr,
EvaluatedToAmbig,
+ EvaluatedToErr(SelectionError<'tcx>),
}
impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
bound: ty::BuiltinBound,
previous_stack: &ObligationStack<'o, 'tcx>,
ty: Ty<'tcx>)
- -> EvaluationResult
+ -> EvaluationResult<'tcx>
{
let obligation =
util::obligation_for_builtin_bound(
fn evaluate_obligation_recursively<'o>(&mut self,
previous_stack: Option<&ObligationStack<'o, 'tcx>>,
obligation: &Obligation<'tcx>)
- -> EvaluationResult
+ -> EvaluationResult<'tcx>
{
debug!("evaluate_obligation_recursively({})",
obligation.repr(self.tcx()));
fn evaluate_stack<'o>(&mut self,
stack: &ObligationStack<'o, 'tcx>)
- -> EvaluationResult
+ -> EvaluationResult<'tcx>
{
// In intercrate mode, whenever any of the types are unbound,
// there can always be an impl. Even if there are no impls in
match self.candidate_from_obligation(stack) {
Ok(Some(c)) => self.winnow_candidate(stack, &c),
Ok(None) => EvaluatedToAmbig,
- Err(_) => EvaluatedToErr,
+ Err(e) => EvaluatedToErr(e),
}
}
})
}
- ///////////////////////////////////////////////////////////////////////////
- // METHOD MATCHING
- //
- // Method matching is a variation on the normal select/evaluation
- // situation. In this scenario, rather than having a full trait
- // reference to select from, we start with an expression like
- // `receiver.method(...)`. This means that we have `rcvr_ty`, the
- // type of the receiver, and we have a possible trait that
- // supplies `method`. We must determine whether the receiver is
- // applicable, taking into account the transformed self type
- // declared on `method`. We also must consider the possibility
- // that `receiver` can be *coerced* into a suitable type (for
- // example, a receiver type like `&(Any+Send)` might be coerced
- // into a receiver like `&Any` to allow for method dispatch). See
- // the body of `evaluate_method_obligation()` for more details on
- // the algorithm.
-
- /// Determine whether a trait-method is applicable to a receiver of
- /// type `rcvr_ty`. *Does not affect the inference state.*
- ///
- /// - `rcvr_ty` -- type of the receiver
- /// - `xform_self_ty` -- transformed self type declared on the method, with `Self`
- /// to a fresh type variable
- /// - `obligation` -- a reference to the trait where the method is declared, with
- /// the input types on the trait replaced with fresh type variables
- pub fn evaluate_method_obligation(&mut self,
- rcvr_ty: Ty<'tcx>,
- xform_self_ty: Ty<'tcx>,
- obligation: &Obligation<'tcx>)
- -> MethodMatchResult
- {
- // Here is the situation. We have a trait method declared (say) like so:
- //
- // trait TheTrait {
- // fn the_method(self: Rc<Self>, ...) { ... }
- // }
- //
- // And then we have a call looking (say) like this:
- //
- // let x: Rc<Foo> = ...;
- // x.the_method()
- //
- // Now we want to decide if `TheTrait` is applicable. As a
- // human, we can see that `TheTrait` is applicable if there is
- // an impl for the type `Foo`. But how does the compiler know
- // what impl to look for, given that our receiver has type
- // `Rc<Foo>`? We need to take the method's self type into
- // account.
- //
- // On entry to this function, we have the following inputs:
- //
- // - `rcvr_ty = Rc<Foo>`
- // - `xform_self_ty = Rc<$0>`
- // - `obligation = $0 as TheTrait`
- //
- // We do the match in two phases. The first is a *precise
- // match*, which means that no coercion is required. This is
- // the preferred way to match. It works by first making
- // `rcvr_ty` a subtype of `xform_self_ty`. This unifies `$0`
- // and `Foo`. We can then evaluate (roughly as normal) the
- // trait reference `Foo as TheTrait`.
- //
- // If this fails, we fallback to a coercive match, described below.
-
- match self.infcx.probe(|| self.match_method_precise(rcvr_ty, xform_self_ty, obligation)) {
- Ok(()) => { return MethodMatched(PreciseMethodMatch); }
- Err(_) => { }
- }
-
- // Coercive matches work slightly differently and cannot
- // completely reuse the normal trait matching machinery
- // (though they employ many of the same bits and pieces). To
- // see how it works, let's continue with our previous example,
- // but with the following declarations:
- //
- // ```
- // trait Foo : Bar { .. }
- // trait Bar : Baz { ... }
- // trait Baz { ... }
- // impl TheTrait for Bar {
- // fn the_method(self: Rc<Bar>, ...) { ... }
- // }
- // ```
- //
- // Now we see that the receiver type `Rc<Foo>` is actually an
- // object type. And in fact the impl we want is an impl on the
- // supertrait `Rc<Bar>`. The precise matching procedure won't
- // find it, however, because `Rc<Foo>` is not a subtype of
- // `Rc<Bar>` -- it is *coercible* to `Rc<Bar>` (actually, such
- // coercions are not yet implemented, but let's leave that
- // aside for now).
- //
- // To handle this case, we employ a different procedure. Recall
- // that our initial state is as follows:
- //
- // - `rcvr_ty = Rc<Foo>`
- // - `xform_self_ty = Rc<$0>`
- // - `obligation = $0 as TheTrait`
- //
- // We now go through each impl and instantiate all of its type
- // variables, yielding the trait reference that the impl
- // provides. In our example, the impl would provide `Bar as
- // TheTrait`. Next we (try to) unify the trait reference that
- // the impl provides with the input obligation. This would
- // unify `$0` and `Bar`. Now we can see whether the receiver
- // type (`Rc<Foo>`) is *coercible to* the transformed self
- // type (`Rc<$0> == Rc<Bar>`). In this case, the answer is
- // yes, so the impl is considered a candidate.
- //
- // Note that there is the possibility of ambiguity here, even
- // when all types are known. In our example, this might occur
- // if there was *also* an impl of `TheTrait` for `Baz`. In
- // this case, `Rc<Foo>` would be coercible to both `Rc<Bar>`
- // and `Rc<Baz>`. (Note that it is not a *coherence violation*
- // to have impls for both `Bar` and `Baz`, despite this
- // ambiguity). In this case, we report an error, listing all
- // the applicable impls. The user can explicitly "up-coerce"
- // to the type they want.
- //
- // Note that this coercion step only considers actual impls
- // found in the source. This is because all the
- // compiler-provided impls (such as those for unboxed
- // closures) do not have relevant coercions. This simplifies
- // life immensely.
-
- let mut impls =
- self.assemble_method_candidates_from_impls(rcvr_ty, xform_self_ty, obligation);
-
- if impls.len() > 1 {
- impls.retain(|&c| self.winnow_method_impl(c, rcvr_ty, xform_self_ty, obligation));
- }
-
- if impls.len() > 1 {
- return MethodAmbiguous(impls);
- }
-
- match impls.pop() {
- Some(def_id) => MethodMatched(CoerciveMethodMatch(def_id)),
- None => MethodDidNotMatch
- }
- }
-
- /// Given the successful result of a method match, this function "confirms" the result, which
- /// basically repeats the various matching operations, but outside of any snapshot so that
- /// their effects are committed into the inference state.
- pub fn confirm_method_match(&mut self,
- rcvr_ty: Ty<'tcx>,
- xform_self_ty: Ty<'tcx>,
- obligation: &Obligation<'tcx>,
- data: MethodMatchedData)
- {
- let is_ok = match data {
- PreciseMethodMatch => {
- self.match_method_precise(rcvr_ty, xform_self_ty, obligation).is_ok()
- }
-
- CoerciveMethodMatch(impl_def_id) => {
- self.match_method_coerce(impl_def_id, rcvr_ty, xform_self_ty, obligation).is_ok()
- }
- };
-
- if !is_ok {
- self.tcx().sess.span_bug(
- obligation.cause.span,
- format!("match not repeatable: {}, {}, {}, {}",
- rcvr_ty.repr(self.tcx()),
- xform_self_ty.repr(self.tcx()),
- obligation.repr(self.tcx()),
- data)[]);
- }
- }
-
- /// Implements the *precise method match* procedure described in
- /// `evaluate_method_obligation()`.
- fn match_method_precise(&mut self,
- rcvr_ty: Ty<'tcx>,
- xform_self_ty: Ty<'tcx>,
- obligation: &Obligation<'tcx>)
- -> Result<(),()>
- {
- self.infcx.commit_if_ok(|| {
- match self.infcx.sub_types(false, infer::RelateSelfType(obligation.cause.span),
- rcvr_ty, xform_self_ty) {
- Ok(()) => { }
- Err(_) => { return Err(()); }
- }
-
- if self.evaluate_obligation(obligation) {
- Ok(())
- } else {
- Err(())
- }
- })
- }
-
- /// Assembles a list of potentially applicable impls using the *coercive match* procedure
- /// described in `evaluate_method_obligation()`.
- fn assemble_method_candidates_from_impls(&mut self,
- rcvr_ty: Ty<'tcx>,
- xform_self_ty: Ty<'tcx>,
- obligation: &Obligation<'tcx>)
- -> Vec<ast::DefId>
- {
- let mut candidates = Vec::new();
-
- let all_impls = self.all_impls(obligation.trait_ref.def_id);
- for &impl_def_id in all_impls.iter() {
- self.infcx.probe(|| {
- match self.match_method_coerce(impl_def_id, rcvr_ty, xform_self_ty, obligation) {
- Ok(_) => { candidates.push(impl_def_id); }
- Err(_) => { }
- }
- });
- }
-
- candidates
- }
-
- /// Applies the *coercive match* procedure described in `evaluate_method_obligation()` to a
- /// particular impl.
- fn match_method_coerce(&mut self,
- impl_def_id: ast::DefId,
- rcvr_ty: Ty<'tcx>,
- xform_self_ty: Ty<'tcx>,
- obligation: &Obligation<'tcx>)
- -> Result<Substs<'tcx>, ()>
- {
- // This is almost always expected to succeed. It
- // causes the impl's self-type etc to be unified with
- // the type variable that is shared between
- // obligation/xform_self_ty. In our example, after
- // this is done, the type of `xform_self_ty` would
- // change from `Rc<$0>` to `Rc<Foo>` (because $0 is
- // unified with `Foo`).
- let substs = try!(self.match_impl(impl_def_id, obligation));
-
- // Next, check whether we can coerce. For now we require
- // that the coercion be a no-op.
- let origin = infer::Misc(obligation.cause.span);
- match infer::mk_coercety(self.infcx, true, origin,
- rcvr_ty, xform_self_ty) {
- Ok(None) => { /* Fallthrough */ }
- Ok(Some(_)) | Err(_) => { return Err(()); }
- }
-
- Ok(substs)
- }
-
- /// A version of `winnow_impl` applicable to coerice method matching. This is basically the
- /// same as `winnow_impl` but it uses the method matching procedure and is specific to impls.
- fn winnow_method_impl(&mut self,
- impl_def_id: ast::DefId,
- rcvr_ty: Ty<'tcx>,
- xform_self_ty: Ty<'tcx>,
- obligation: &Obligation<'tcx>)
- -> bool
- {
- debug!("winnow_method_impl: impl_def_id={} rcvr_ty={} xform_self_ty={} obligation={}",
- impl_def_id.repr(self.tcx()),
- rcvr_ty.repr(self.tcx()),
- xform_self_ty.repr(self.tcx()),
- obligation.repr(self.tcx()));
-
- self.infcx.probe(|| {
- match self.match_method_coerce(impl_def_id, rcvr_ty, xform_self_ty, obligation) {
- Ok(substs) => {
- let vtable_impl = self.vtable_impl(impl_def_id,
- substs,
- obligation.cause,
- obligation.recursion_depth + 1);
- self.winnow_selection(None, VtableImpl(vtable_impl)).may_apply()
- }
- Err(()) => {
- false
- }
- }
- })
- }
-
///////////////////////////////////////////////////////////////////////////
// CANDIDATE ASSEMBLY
//
// and applicable impls. There is a certain set of precedence rules here.
match self.tcx().lang_items.to_builtin_kind(obligation.trait_ref.def_id) {
- Some(bound) => {
- try!(self.assemble_builtin_bound_candidates(bound, stack, &mut candidates));
+ Some(ty::BoundCopy) => {
+ debug!("obligation self ty is {}",
+ obligation.self_ty().repr(self.tcx()));
+
+ // If the user has asked for the older, compatibility
+ // behavior, ignore user-defined impls here. This will
+ // go away by the time 1.0 is released.
+ if !self.tcx().sess.features.borrow().opt_out_copy {
+ try!(self.assemble_candidates_from_impls(obligation, &mut candidates));
+ }
+
+ try!(self.assemble_builtin_bound_candidates(ty::BoundCopy,
+ stack,
+ &mut candidates));
}
None => {
- // For the time being, we ignore user-defined impls for builtin-bounds.
+ // For the time being, we ignore user-defined impls for builtin-bounds, other than
+ // `Copy`.
// (And unboxed candidates only apply to the Fn/FnMut/etc traits.)
try!(self.assemble_unboxed_closure_candidates(obligation, &mut candidates));
try!(self.assemble_fn_pointer_candidates(obligation, &mut candidates));
try!(self.assemble_candidates_from_impls(obligation, &mut candidates));
}
+
+ Some(bound) => {
+ try!(self.assemble_builtin_bound_candidates(bound, stack, &mut candidates));
+ }
}
try!(self.assemble_candidates_from_caller_bounds(obligation, &mut candidates));
+ debug!("candidate list size: {}", candidates.vec.len());
Ok(candidates)
}
fn winnow_candidate<'o>(&mut self,
stack: &ObligationStack<'o, 'tcx>,
candidate: &Candidate<'tcx>)
- -> EvaluationResult
+ -> EvaluationResult<'tcx>
{
debug!("winnow_candidate: candidate={}", candidate.repr(self.tcx()));
self.infcx.probe(|| {
let candidate = (*candidate).clone();
match self.confirm_candidate(stack.obligation, candidate) {
Ok(selection) => self.winnow_selection(Some(stack), selection),
- Err(_) => EvaluatedToErr,
+ Err(error) => EvaluatedToErr(error),
}
})
}
fn winnow_selection<'o>(&mut self,
stack: Option<&ObligationStack<'o, 'tcx>>,
selection: Selection<'tcx>)
- -> EvaluationResult
+ -> EvaluationResult<'tcx>
{
let mut result = EvaluatedToOk;
for obligation in selection.iter_nested() {
match self.evaluate_obligation_recursively(stack, obligation) {
- EvaluatedToErr => { return EvaluatedToErr; }
+ EvaluatedToErr(e) => { return EvaluatedToErr(e); }
EvaluatedToAmbig => { result = EvaluatedToAmbig; }
EvaluatedToOk => { }
}
}
ty::BoundCopy => {
- if
- Some(def_id) == tcx.lang_items.no_copy_bound() ||
- Some(def_id) == tcx.lang_items.managed_bound() ||
- ty::has_dtor(tcx, def_id)
- {
- return Err(Unimplemented);
+ // This is an Opt-In Built-In Trait. So, unless
+ // the user is asking for the old behavior, we
+ // don't supply any form of builtin impl.
+ if !this.tcx().sess.features.borrow().opt_out_copy {
+ return Ok(ParameterBuiltin)
}
}
}
}
-impl EvaluationResult {
+impl<'tcx> EvaluationResult<'tcx> {
fn may_apply(&self) -> bool {
match *self {
- EvaluatedToOk | EvaluatedToAmbig => true,
- EvaluatedToErr => false,
+ EvaluatedToOk |
+ EvaluatedToAmbig |
+ EvaluatedToErr(Overflow) |
+ EvaluatedToErr(OutputTypeParameterMismatch(..)) => {
+ true
+ }
+ EvaluatedToErr(Unimplemented) => {
+ false
+ }
}
}
}
pub use self::ExprAdjustment::*;
pub use self::vtable_origin::*;
pub use self::MethodOrigin::*;
+pub use self::CopyImplementationError::*;
use back::svh::Svh;
use session::Session;
use middle::region;
use middle::resolve;
use middle::resolve_lifetime;
+use middle::infer;
use middle::stability;
use middle::subst::{mod, Subst, Substs, VecPerParamSpace};
+use middle::traits::ObligationCause;
use middle::traits;
use middle::ty;
use middle::ty_fold::{mod, TypeFoldable, TypeFolder, HigherRankedFoldable};
use std::mem;
use std::ops;
use std::rc::Rc;
-use std::collections::hash_map::{Occupied, Vacant};
+use std::collections::hash_map::{HashMap, Occupied, Vacant};
use arena::TypedArena;
use syntax::abi;
use syntax::ast::{CrateNum, DefId, FnStyle, Ident, ItemTrait, LOCAL_CRATE};
use syntax::ast::{Visibility};
use syntax::ast_util::{mod, is_local, lit_is_str, local_def, PostExpansionMethod};
use syntax::attr::{mod, AttrMetaMethods};
-use syntax::codemap::Span;
+use syntax::codemap::{DUMMY_SP, Span};
use syntax::parse::token::{mod, InternedString};
use syntax::{ast, ast_map};
use std::collections::enum_set::{EnumSet, CLike};
pub mt: mt<'tcx>
}
+impl<'tcx> Copy for field<'tcx> {}
+
#[deriving(Clone, Show)]
pub enum ImplOrTraitItemContainer {
TraitContainer(ast::DefId),
ImplContainer(ast::DefId),
}
+impl Copy for ImplOrTraitItemContainer {}
+
impl ImplOrTraitItemContainer {
pub fn id(&self) -> ast::DefId {
match *self {
TypeTraitItemId(ast::DefId),
}
+impl Copy for ImplOrTraitItemId {}
+
impl ImplOrTraitItemId {
pub fn def_id(&self) -> ast::DefId {
match *self {
pub container: ImplOrTraitItemContainer,
}
+impl Copy for AssociatedType {}
+
#[deriving(Clone, PartialEq, Eq, Hash, Show)]
pub struct mt<'tcx> {
pub ty: Ty<'tcx>,
pub mutbl: ast::Mutability,
}
+impl<'tcx> Copy for mt<'tcx> {}
+
#[deriving(Clone, PartialEq, Eq, Hash, Encodable, Decodable, Show)]
pub enum TraitStore {
/// Box<Trait>
RegionTraitStore(Region, ast::Mutability),
}
+impl Copy for TraitStore {}
+
#[deriving(Clone, Show)]
pub struct field_ty {
pub name: Name,
pub origin: ast::DefId, // The DefId of the struct in which the field is declared.
}
+impl Copy for field_ty {}
+
// Contains information needed to resolve types and (in the future) look up
// the types of AST nodes.
#[deriving(PartialEq, Eq, Hash)]
pub len: uint
}
+impl Copy for creader_cache_key {}
+
pub enum ast_ty_to_ty_cache_entry<'tcx> {
atttce_unresolved, /* not resolved yet */
atttce_resolved(Ty<'tcx>) /* resolved to a type, irrespective of region */
}
+impl<'tcx> Copy for ast_ty_to_ty_cache_entry<'tcx> {}
+
#[deriving(Clone, PartialEq, Decodable, Encodable)]
pub struct ItemVariances {
pub types: VecPerParamSpace<Variance>,
Bivariant, // T<A> <: T<B> -- e.g., unused type parameter
}
+impl Copy for Variance {}
+
#[deriving(Clone, Show)]
pub enum AutoAdjustment<'tcx> {
AdjustAddEnv(ty::TraitStore),
pub index: uint
}
+impl Copy for param_index {}
+
#[deriving(Clone, Show)]
pub enum MethodOrigin<'tcx> {
// fully statically resolved method
pub substs: subst::Substs<'tcx>
}
+impl Copy for MethodCall {}
+
/// With method calls, we store some extra information in
/// side tables (i.e method_map). We use
/// MethodCall as a key to index into these tables instead of
AutoObject
}
+impl Copy for ExprAdjustment {}
+
impl MethodCall {
pub fn expr(id: ast::NodeId) -> MethodCall {
MethodCall {
pub id: ast::NodeId,
}
+impl<'tcx> Copy for TransmuteRestriction<'tcx> {}
+
/// The data structure to keep track of all the information that typechecker
/// generates so that so that it can be reused and doesn't have to be redone
/// later on.
/// Caches the representation hints for struct definitions.
pub repr_hint_cache: RefCell<DefIdMap<Rc<Vec<attr::ReprAttr>>>>,
+
+ /// Caches whether types move by default.
+ pub type_moves_by_default_cache: RefCell<HashMap<Ty<'tcx>,bool>>,
}
// Flags that we track on types. These flags are propagated upwards
}
}
+impl Copy for TypeFlags {}
+
#[deriving(Show)]
pub struct TyS<'tcx> {
pub sty: sty<'tcx>,
self.ty.sty == other.ty.sty
}
}
+
impl<'tcx> Eq for InternedTy<'tcx> {}
impl<'tcx, S: Writer> Hash<S> for InternedTy<'tcx> {
}
}
+impl<'tcx> Copy for FnOutput<'tcx> {}
+
/// Signature of a function type, which I have arbitrarily
/// decided to use to refer to the input/output types.
///
pub def_id: DefId
}
+impl Copy for ParamTy {}
+
/// A [De Bruijn index][dbi] is a standard means of representing
/// regions (and perhaps later types) in a higher-ranked setting. In
/// particular, imagine a type like this:
pub closure_expr_id: ast::NodeId,
}
+impl Copy for UpvarId {}
+
#[deriving(Clone, PartialEq, Eq, Hash, Show, Encodable, Decodable)]
pub enum BorrowKind {
/// Data must be immutable and is aliasable.
MutBorrow
}
+impl Copy for BorrowKind {}
+
/// Information describing the borrowing of an upvar. This is computed
/// during `typeck`, specifically by `regionck`. The general idea is
/// that the compiler analyses treat closures like:
pub type UpvarBorrowMap = FnvHashMap<UpvarId, UpvarBorrow>;
+impl Copy for UpvarBorrow {}
+
impl Region {
pub fn is_bound(&self) -> bool {
match *self {
}
}
+impl Copy for Region {}
+
#[deriving(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Encodable, Decodable, Show)]
/// A "free" region `fr` can be interpreted as "some region
/// at least as big as the scope `fr.scope`".
pub bound_region: BoundRegion
}
+impl Copy for FreeRegion {}
+
#[deriving(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Encodable, Decodable, Show)]
pub enum BoundRegion {
/// An anonymous region parameter for a given fn (&T)
BrEnv
}
+impl Copy for BoundRegion {}
+
#[inline]
pub fn mk_prim_t<'tcx>(primitive: &'tcx TyS<'static>) -> Ty<'tcx> {
// FIXME(#17596) Ty<'tcx> is incorrectly invariant w.r.t 'tcx.
UintType(ast::UintTy),
}
+impl Copy for IntVarValue {}
+
#[deriving(Clone, Show)]
pub enum terr_vstore_kind {
terr_vec,
terr_trait
}
+impl Copy for terr_vstore_kind {}
+
#[deriving(Clone, Show)]
pub struct expected_found<T> {
pub expected: T,
pub found: T
}
+impl<T:Copy> Copy for expected_found<T> {}
+
// Data structures used in type unification
#[deriving(Clone, Show)]
pub enum type_err<'tcx> {
terr_convergence_mismatch(expected_found<bool>)
}
+impl<'tcx> Copy for type_err<'tcx> {}
+
/// Bounds suitable for a named type parameter like `A` in `fn foo<A>`
/// as well as the existential type parameter in an object type.
#[deriving(PartialEq, Eq, Hash, Clone, Show)]
pub builtin_bounds: BuiltinBounds
}
+impl Copy for ExistentialBounds {}
+
pub type BuiltinBounds = EnumSet<BuiltinBound>;
#[deriving(Clone, Encodable, PartialEq, Eq, Decodable, Hash, Show)]
BoundSync,
}
+impl Copy for BuiltinBound {}
+
pub fn empty_builtin_bounds() -> BuiltinBounds {
EnumSet::new()
}
pub index: uint
}
+impl Copy for TyVid {}
+
#[deriving(Clone, PartialEq, Eq, Hash)]
pub struct IntVid {
pub index: uint
}
+impl Copy for IntVid {}
+
#[deriving(Clone, PartialEq, Eq, Hash)]
pub struct FloatVid {
pub index: uint
}
+impl Copy for FloatVid {}
+
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
pub struct RegionVid {
pub index: uint
}
+impl Copy for RegionVid {}
+
#[deriving(Clone, PartialEq, Eq, Hash)]
pub enum InferTy {
TyVar(TyVid),
SkolemizedIntTy(uint),
}
+impl Copy for InferTy {}
+
#[deriving(Clone, Encodable, Decodable, Eq, Hash, Show)]
pub enum InferRegion {
ReVar(RegionVid),
ReSkolemized(uint, BoundRegion)
}
+impl Copy for InferRegion {}
+
impl cmp::PartialEq for InferRegion {
fn eq(&self, other: &InferRegion) -> bool {
match ((*self), *other) {
/// bound lifetime parameters are replaced with free ones, but in the
/// future I hope to refine the representation of types so as to make
/// more distinctions clearer.
+#[deriving(Clone)]
pub struct ParameterEnvironment<'tcx> {
/// A substitution that can be applied to move from
/// the "outer" view of a type or method to the "inner" view.
}
TypeTraitItem(_) => {
cx.sess
- .bug("ParameterEnvironment::from_item(): \
+ .bug("ParameterEnvironment::for_item(): \
can't create a parameter environment \
for type trait items")
}
}
}
ast::TypeImplItem(_) => {
- cx.sess.bug("ParameterEnvironment::from_item(): \
+ cx.sess.bug("ParameterEnvironment::for_item(): \
can't create a parameter environment \
for type impl items")
}
match *trait_method {
ast::RequiredMethod(ref required) => {
cx.sess.span_bug(required.span,
- "ParameterEnvironment::from_item():
+ "ParameterEnvironment::for_item():
can't create a parameter \
environment for required trait \
methods")
}
TypeTraitItem(_) => {
cx.sess
- .bug("ParameterEnvironment::from_item(): \
+ .bug("ParameterEnvironment::for_item(): \
can't create a parameter environment \
for type trait items")
}
}
}
}
+ Some(ast_map::NodeExpr(..)) => {
+ // This is a convenience to allow closures to work.
+ ParameterEnvironment::for_item(cx, cx.map.get_parent(id))
+ }
_ => {
cx.sess.bug(format!("ParameterEnvironment::from_item(): \
`{}` is not an item",
FnOnceUnboxedClosureKind,
}
+impl Copy for UnboxedClosureKind {}
+
impl UnboxedClosureKind {
pub fn trait_did(&self, cx: &ctxt) -> ast::DefId {
let result = match *self {
associated_types: RefCell::new(DefIdMap::new()),
selection_cache: traits::SelectionCache::new(),
repr_hint_cache: RefCell::new(DefIdMap::new()),
+ type_moves_by_default_cache: RefCell::new(HashMap::new()),
}
}
pub bits: u64
}
+impl Copy for TypeContents {}
+
macro_rules! def_type_content_sets(
(mod $mname:ident { $($name:ident = $bits:expr),+ }) => {
#[allow(non_snake_case)]
OwnsOwned = 0b0000_0000__0000_0001__0000,
OwnsDtor = 0b0000_0000__0000_0010__0000,
OwnsManaged /* see [1] below */ = 0b0000_0000__0000_0100__0000,
- OwnsAffine = 0b0000_0000__0000_1000__0000,
OwnsAll = 0b0000_0000__1111_1111__0000,
// Things that are reachable by the value in any way (fourth nibble):
ReachesFfiUnsafe = 0b0010_0000__0000_0000__0000,
ReachesAll = 0b0011_1111__0000_0000__0000,
- // Things that cause values to *move* rather than *copy*. This
- // is almost the same as the `Copy` trait, but for managed
- // data -- atm, we consider managed data to copy, not move,
- // but it does not impl Copy as a pure memcpy is not good
- // enough. Yuck.
- Moves = 0b0000_0000__0000_1011__0000,
-
// Things that mean drop glue is necessary
NeedsDrop = 0b0000_0000__0000_0111__0000,
// Things that prevent values from being considered sized
Nonsized = 0b0000_0000__0000_0000__0001,
- // Things that make values considered not POD (would be same
- // as `Moves`, but for the fact that managed data `@` is
- // not considered POD)
- Noncopy = 0b0000_0000__0000_1111__0000,
-
// Bits to set when a managed value is encountered
//
// [1] Do not set the bits TC::OwnsManaged or
self.intersects(TC::InteriorUnsized)
}
- pub fn moves_by_default(&self, _: &ctxt) -> bool {
- self.intersects(TC::Moves)
- }
-
pub fn needs_drop(&self, _: &ctxt) -> bool {
self.intersects(TC::NeedsDrop)
}
mc | tc_ty(cx, mt.ty, cache)
}
- fn apply_lang_items(cx: &ctxt,
- did: ast::DefId,
- tc: TypeContents)
- -> TypeContents
- {
+ fn apply_lang_items(cx: &ctxt, did: ast::DefId, tc: TypeContents)
+ -> TypeContents {
if Some(did) == cx.lang_items.managed_bound() {
tc | TC::Managed
- } else if Some(did) == cx.lang_items.no_copy_bound() {
- tc | TC::OwnsAffine
} else if Some(did) == cx.lang_items.unsafe_type() {
tc | TC::InteriorUnsafe
} else {
mutbl: ast::Mutability)
-> TypeContents {
let b = match mutbl {
- ast::MutMutable => TC::ReachesMutable | TC::OwnsAffine,
+ ast::MutMutable => TC::ReachesMutable,
ast::MutImmutable => TC::None,
};
b | (TC::ReachesBorrowed).when(region != ty::ReStatic)
}
};
- // This also prohibits "@once fn" from being copied, which allows it to
- // be called. Neither way really makes much sense.
- let ot = match cty.onceness {
- ast::Once => TC::OwnsAffine,
- ast::Many => TC::None,
- };
-
- st | ot
+ st
}
fn object_contents(cx: &ctxt,
let mut tc = TC::All;
each_inherited_builtin_bound(cx, bounds, traits, |bound| {
tc = tc - match bound {
- BoundSync | BoundSend => TC::None,
+ BoundSync | BoundSend | BoundCopy => TC::None,
BoundSized => TC::Nonsized,
- BoundCopy => TC::Noncopy,
};
});
return tc;
}
}
-pub fn type_moves_by_default<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> bool {
- type_contents(cx, ty).moves_by_default(cx)
+pub fn type_moves_by_default<'tcx>(cx: &ctxt<'tcx>,
+ ty: Ty<'tcx>,
+ param_env: &ParameterEnvironment<'tcx>)
+ -> bool {
+ if !type_has_params(ty) && !type_has_self(ty) {
+ match cx.type_moves_by_default_cache.borrow().get(&ty) {
+ None => {}
+ Some(&result) => {
+ debug!("determined whether {} moves by default (cached): {}",
+ ty_to_string(cx, ty),
+ result);
+ return result
+ }
+ }
+ }
+
+ let infcx = infer::new_infer_ctxt(cx);
+ let mut fulfill_cx = traits::FulfillmentContext::new();
+ let obligation = traits::obligation_for_builtin_bound(
+ cx,
+ ObligationCause::misc(DUMMY_SP),
+ ty,
+ ty::BoundCopy).unwrap();
+ fulfill_cx.register_obligation(cx, obligation);
+ let result = !fulfill_cx.select_all_or_error(&infcx,
+ param_env,
+ cx).is_ok();
+ cx.type_moves_by_default_cache.borrow_mut().insert(ty, result);
+ debug!("determined whether {} moves by default: {}",
+ ty_to_string(cx, ty),
+ result);
+ result
}
pub fn is_ffi_safe<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> bool {
SelfRecursive,
}
+impl Copy for Representability {}
+
/// Check whether a type is representable. This means it cannot contain unboxed
/// structural recursion. This check is needed for structs and enums.
pub fn is_type_representable<'tcx>(cx: &ctxt<'tcx>, sp: Span, ty: Ty<'tcx>)
RvalueStmtExpr
}
+impl Copy for ExprKind {}
+
pub fn expr_kind(tcx: &ctxt, expr: &ast::Expr) -> ExprKind {
if tcx.method_map.borrow().contains_key(&MethodCall::expr(expr.id)) {
// Overloaded operations are generally calls, and hence they are
pub name: ast::Name,
}
+impl Copy for AssociatedTypeInfo {}
+
impl PartialOrd for AssociatedTypeInfo {
fn partial_cmp(&self, other: &AssociatedTypeInfo) -> Option<Ordering> {
Some(self.index.cmp(&other.index))
TraitDtor(DefId, bool)
}
+impl Copy for DtorKind {}
+
impl DtorKind {
pub fn is_present(&self) -> bool {
match *self {
pub ty: Ty<'tcx>,
}
+impl<'tcx> Copy for UnboxedClosureUpvar<'tcx> {}
+
// Returns a list of `UnboxedClosureUpvar`s for each upvar.
pub fn unboxed_closure_upvars<'tcx>(tcx: &ctxt<'tcx>, closure_id: ast::DefId, substs: &Substs<'tcx>)
-> Vec<UnboxedClosureUpvar<'tcx>> {
ByBoxExplicitSelfCategory,
}
+impl Copy for ExplicitSelfCategory {}
+
/// Pushes all the lifetimes in the given type onto the given list. A
/// "lifetime in a type" is a lifetime specified by a reference or a lifetime
/// in a list of type substitutions. This does *not* traverse into nominal
pub span: Span
}
+impl Copy for Freevar {}
+
pub type FreevarMap = NodeMap<Vec<Freevar>>;
pub type CaptureModeMap = NodeMap<ast::CaptureClause>;
}
}
+impl Copy for DebruijnIndex {}
+
impl<'tcx> Repr<'tcx> for AutoAdjustment<'tcx> {
fn repr(&self, tcx: &ctxt<'tcx>) -> String {
match *self {
trait_ref.substs.clone().with_method(meth_tps, meth_regions)
}
+pub enum CopyImplementationError {
+ FieldDoesNotImplementCopy(ast::Name),
+ VariantDoesNotImplementCopy(ast::Name),
+ TypeIsStructural,
+}
+
+impl Copy for CopyImplementationError {}
+
+pub fn can_type_implement_copy<'tcx>(tcx: &ctxt<'tcx>,
+ self_type: Ty<'tcx>,
+ param_env: &ParameterEnvironment<'tcx>)
+ -> Result<(),CopyImplementationError> {
+ match self_type.sty {
+ ty::ty_struct(struct_did, ref substs) => {
+ let fields = ty::struct_fields(tcx, struct_did, substs);
+ for field in fields.iter() {
+ if type_moves_by_default(tcx, field.mt.ty, param_env) {
+ return Err(FieldDoesNotImplementCopy(field.name))
+ }
+ }
+ }
+ ty::ty_enum(enum_did, ref substs) => {
+ let enum_variants = ty::enum_variants(tcx, enum_did);
+ for variant in enum_variants.iter() {
+ for variant_arg_type in variant.args.iter() {
+ let substd_arg_type =
+ variant_arg_type.subst(tcx, substs);
+ if type_moves_by_default(tcx,
+ substd_arg_type,
+ param_env) {
+ return Err(VariantDoesNotImplementCopy(variant.name))
+ }
+ }
+ }
+ }
+ _ => return Err(TypeIsStructural),
+ }
+
+ Ok(())
+}
Aggressive // -O3
}
+impl Copy for OptLevel {}
+
#[deriving(Clone, PartialEq)]
pub enum DebugInfoLevel {
NoDebugInfo,
FullDebugInfo,
}
+impl Copy for DebugInfoLevel {}
+
#[deriving(Clone, PartialEq, PartialOrd, Ord, Eq)]
pub enum OutputType {
OutputTypeBitcode,
OutputTypeExe,
}
+impl Copy for OutputType {}
+
#[deriving(Clone)]
pub struct Options {
// The crate config requested for the session, which may be combined
// parsed code. It remains mutable in case its replacements wants to use
// this.
pub addl_lib_search_paths: RefCell<Vec<Path>>,
- pub libs: Vec<(String, cstore::NativeLibaryKind)>,
+ pub libs: Vec<(String, cstore::NativeLibraryKind)>,
pub maybe_sysroot: Option<Path>,
pub target_triple: String,
// User-specified cfg meta items. The compiler itself will add additional
EntryNone,
}
+impl Copy for EntryFnType {}
+
#[deriving(PartialEq, PartialOrd, Clone, Ord, Eq, Hash)]
pub enum CrateType {
CrateTypeExecutable,
CrateTypeStaticlib,
}
+impl Copy for CrateType {}
+
macro_rules! debugging_opts(
([ $opt:ident ] $cnt:expr ) => (
pub const $opt: u64 = 1 << $cnt;
#[deriving(Clone,Show)]
pub struct ErrorReported;
+impl Copy for ErrorReported {}
+
pub fn time<T, U>(do_it: bool, what: &str, u: U, f: |U| -> T) -> T {
thread_local!(static DEPTH: Cell<uint> = Cell::new(0));
if !do_it { return f(u); }
#[deriving(Clone, Default)]
pub struct FnvHasher;
+impl Copy for FnvHasher {}
+
+#[allow(missing_copy_implementations)]
pub struct FnvState(u64);
impl Hasher<FnvState> for FnvHasher {
*sess.features.borrow_mut() = features;
});
+ time(time_passes, "recursion limit", (), |_| {
+ middle::recursion_limit::update_recursion_limit(sess, &krate);
+ });
+
// strip before expansion to allow macros to depend on
// configuration variables e.g/ in
//
PpmExpandedHygiene,
}
+impl Copy for PpSourceMode {}
+
#[deriving(PartialEq, Show)]
pub enum PpMode {
PpmSource(PpSourceMode),
PpmFlowGraph,
}
+impl Copy for PpMode {}
+
pub fn parse_pretty(sess: &Session, name: &str) -> (PpMode, Option<UserIdentifiedItem>) {
let mut split = name.splitn(1, '=');
let first = split.next().unwrap();
OptimizationFailure,
}
+impl Copy for OptimizationDiagnosticKind {}
+
impl OptimizationDiagnosticKind {
pub fn describe(self) -> &'static str {
match self {
pub message: TwineRef,
}
+impl Copy for OptimizationDiagnostic {}
+
impl OptimizationDiagnostic {
unsafe fn unpack(kind: OptimizationDiagnosticKind, di: DiagnosticInfoRef)
-> OptimizationDiagnostic {
UnknownDiagnostic(DiagnosticInfoRef),
}
+impl Copy for Diagnostic {}
+
impl Diagnostic {
pub unsafe fn unpack(di: DiagnosticInfoRef) -> Diagnostic {
let kind = super::LLVMGetDiagInfoKind(di);
X86_64_Win64 = 79,
}
+impl Copy for CallConv {}
+
pub enum Visibility {
LLVMDefaultVisibility = 0,
HiddenVisibility = 1,
ProtectedVisibility = 2,
}
+impl Copy for Visibility {}
+
// This enum omits the obsolete (and no-op) linkage types DLLImportLinkage,
// DLLExportLinkage, GhostLinkage and LinkOnceODRAutoHideLinkage.
// LinkerPrivateLinkage and LinkerPrivateWeakLinkage are not included either;
CommonLinkage = 14,
}
+impl Copy for Linkage {}
+
#[repr(C)]
#[deriving(Show)]
pub enum DiagnosticSeverity {
Note,
}
+impl Copy for DiagnosticSeverity {}
+
bitflags! {
flags Attribute : u32 {
const ZExtAttribute = 1 << 0,
}
}
+impl Copy for Attribute {}
+
#[repr(u64)]
pub enum OtherAttribute {
// The following are not really exposed in
NonNullAttribute = 1 << 44,
}
+impl Copy for OtherAttribute {}
+
pub enum SpecialAttribute {
DereferenceableAttribute(u64)
}
+impl Copy for SpecialAttribute {}
+
#[repr(C)]
pub enum AttributeSet {
ReturnIndex = 0,
FunctionIndex = !0
}
+impl Copy for AttributeSet {}
+
pub trait AttrHelper {
fn apply_llfn(&self, idx: c_uint, llfn: ValueRef);
fn apply_callsite(&self, idx: c_uint, callsite: ValueRef);
IntSLE = 41,
}
+impl Copy for IntPredicate {}
+
// enum for the LLVM RealPredicate type
pub enum RealPredicate {
RealPredicateFalse = 0,
RealPredicateTrue = 15,
}
+impl Copy for RealPredicate {}
+
// The LLVM TypeKind type - must stay in sync with the def of
// LLVMTypeKind in llvm/include/llvm-c/Core.h
#[deriving(PartialEq)]
X86_MMX = 15,
}
+impl Copy for TypeKind {}
+
#[repr(C)]
pub enum AtomicBinOp {
AtomicXchg = 0,
AtomicUMin = 10,
}
+impl Copy for AtomicBinOp {}
+
#[repr(C)]
pub enum AtomicOrdering {
NotAtomic = 0,
SequentiallyConsistent = 7
}
+impl Copy for AtomicOrdering {}
+
// Consts for the LLVMCodeGenFileType type (in include/llvm/c/TargetMachine.h)
#[repr(C)]
pub enum FileType {
ObjectFileType = 1
}
+impl Copy for FileType {}
+
pub enum MetadataType {
MD_dbg = 0,
MD_tbaa = 1,
MD_tbaa_struct = 5
}
+impl Copy for MetadataType {}
+
// Inline Asm Dialect
pub enum AsmDialect {
AD_ATT = 0,
AD_Intel = 1
}
+impl Copy for AsmDialect {}
+
#[deriving(PartialEq, Clone)]
#[repr(C)]
pub enum CodeGenOptLevel {
CodeGenLevelAggressive = 3,
}
+impl Copy for CodeGenOptLevel {}
+
#[deriving(PartialEq)]
#[repr(C)]
pub enum RelocMode {
RelocDynamicNoPic = 3,
}
+impl Copy for RelocMode {}
+
#[repr(C)]
pub enum CodeGenModel {
CodeModelDefault = 0,
CodeModelLarge = 5,
}
+impl Copy for CodeGenModel {}
+
#[repr(C)]
pub enum DiagnosticKind {
DK_InlineAsm = 0,
DK_OptimizationFailure,
}
+impl Copy for DiagnosticKind {}
+
// Opaque pointer types
+#[allow(missing_copy_implementations)]
pub enum Module_opaque {}
pub type ModuleRef = *mut Module_opaque;
+#[allow(missing_copy_implementations)]
pub enum Context_opaque {}
pub type ContextRef = *mut Context_opaque;
+#[allow(missing_copy_implementations)]
pub enum Type_opaque {}
pub type TypeRef = *mut Type_opaque;
+#[allow(missing_copy_implementations)]
pub enum Value_opaque {}
pub type ValueRef = *mut Value_opaque;
+#[allow(missing_copy_implementations)]
pub enum BasicBlock_opaque {}
pub type BasicBlockRef = *mut BasicBlock_opaque;
+#[allow(missing_copy_implementations)]
pub enum Builder_opaque {}
pub type BuilderRef = *mut Builder_opaque;
+#[allow(missing_copy_implementations)]
pub enum ExecutionEngine_opaque {}
pub type ExecutionEngineRef = *mut ExecutionEngine_opaque;
+#[allow(missing_copy_implementations)]
pub enum MemoryBuffer_opaque {}
pub type MemoryBufferRef = *mut MemoryBuffer_opaque;
+#[allow(missing_copy_implementations)]
pub enum PassManager_opaque {}
pub type PassManagerRef = *mut PassManager_opaque;
+#[allow(missing_copy_implementations)]
pub enum PassManagerBuilder_opaque {}
pub type PassManagerBuilderRef = *mut PassManagerBuilder_opaque;
+#[allow(missing_copy_implementations)]
pub enum Use_opaque {}
pub type UseRef = *mut Use_opaque;
+#[allow(missing_copy_implementations)]
pub enum TargetData_opaque {}
pub type TargetDataRef = *mut TargetData_opaque;
+#[allow(missing_copy_implementations)]
pub enum ObjectFile_opaque {}
pub type ObjectFileRef = *mut ObjectFile_opaque;
+#[allow(missing_copy_implementations)]
pub enum SectionIterator_opaque {}
pub type SectionIteratorRef = *mut SectionIterator_opaque;
+#[allow(missing_copy_implementations)]
pub enum Pass_opaque {}
pub type PassRef = *mut Pass_opaque;
+#[allow(missing_copy_implementations)]
pub enum TargetMachine_opaque {}
pub type TargetMachineRef = *mut TargetMachine_opaque;
+#[allow(missing_copy_implementations)]
pub enum Archive_opaque {}
pub type ArchiveRef = *mut Archive_opaque;
+#[allow(missing_copy_implementations)]
pub enum Twine_opaque {}
pub type TwineRef = *mut Twine_opaque;
+#[allow(missing_copy_implementations)]
pub enum DiagnosticInfo_opaque {}
pub type DiagnosticInfoRef = *mut DiagnosticInfo_opaque;
+#[allow(missing_copy_implementations)]
pub enum DebugLoc_opaque {}
pub type DebugLocRef = *mut DebugLoc_opaque;
+#[allow(missing_copy_implementations)]
pub enum SMDiagnostic_opaque {}
pub type SMDiagnosticRef = *mut SMDiagnostic_opaque;
pub use self::DIDescriptorFlags::*;
use super::{ValueRef};
+ #[allow(missing_copy_implementations)]
pub enum DIBuilder_opaque {}
pub type DIBuilderRef = *mut DIBuilder_opaque;
FlagLValueReference = 1 << 14,
FlagRValueReference = 1 << 15
}
+
+ impl Copy for DIDescriptorFlags {}
}
}
}
+#[allow(missing_copy_implementations)]
pub enum RustString_opaque {}
pub type RustStringRef = *mut RustString_opaque;
type RustStringRepr = *mut RefCell<Vec<u8>>;
use std::task::TaskBuilder;
use libc::{c_uint, c_int, c_void};
+#[deriving(Clone, PartialEq, PartialOrd, Ord, Eq)]
+pub enum OutputType {
+ OutputTypeBitcode,
+ OutputTypeAssembly,
+ OutputTypeLlvmAssembly,
+ OutputTypeObject,
+ OutputTypeExe,
+}
+
+impl Copy for OutputType {}
+
pub fn llvm_err(handler: &diagnostic::Handler, msg: String) -> ! {
unsafe {
let cstr = llvm::LLVMRustGetLastError();
self.collecting = true;
self.visit_pat(&*arg.pat);
self.collecting = false;
- let span_utils = self.span;
+ let span_utils = self.span.clone();
for &(id, ref p, _, _) in self.collected_paths.iter() {
let typ = ppaux::ty_to_string(&self.analysis.ty_cx,
(*self.analysis.ty_cx.node_types.borrow())[id]);
FnRef,
}
+impl Copy for Row {}
+
impl<'a> FmtStrs<'a> {
pub fn new(rec: Box<Recorder>, span: SpanUtils<'a>, krate: String) -> FmtStrs<'a> {
FmtStrs {
if self.recorder.dump_spans {
if dump_spans {
- self.recorder.dump_span(self.span, label, span, Some(sub_span));
+ self.recorder.dump_span(self.span.clone(),
+ label,
+ span,
+ Some(sub_span));
}
return;
}
use syntax::parse::token;
use syntax::parse::token::{keywords, Token};
+#[deriving(Clone)]
pub struct SpanUtils<'a> {
pub sess: &'a Session,
pub err_count: Cell<int>,
#[deriving(Show)]
struct ConstantExpr<'a>(&'a ast::Expr);
+impl<'a> Copy for ConstantExpr<'a> {}
+
impl<'a> ConstantExpr<'a> {
fn eq(self, other: ConstantExpr<'a>, tcx: &ty::ctxt) -> bool {
let ConstantExpr(expr) = self;
CompareSliceLength
}
+impl Copy for BranchKind {}
+
pub enum OptResult<'blk, 'tcx: 'blk> {
SingleResult(Result<'blk, 'tcx>),
RangeResult(Result<'blk, 'tcx>, Result<'blk, 'tcx>),
TrByRef,
}
+impl Copy for TransBindingMode {}
+
/// Information about a pattern binding:
/// - `llmatch` is a pointer to a stack slot. The stack slot contains a
/// pointer into the value being matched. Hence, llmatch has type `T**`
pub ty: Ty<'tcx>,
}
+impl<'tcx> Copy for BindingInfo<'tcx> {}
+
type BindingsMap<'tcx> = FnvHashMap<Ident, BindingInfo<'tcx>>;
struct ArmData<'p, 'blk, 'tcx: 'blk> {
check_match::Constructor::Variant(def_id)
};
- let mcx = check_match::MatchCheckCtxt { tcx: bcx.tcx() };
+ let param_env = ty::empty_parameter_environment();
+ let mcx = check_match::MatchCheckCtxt {
+ tcx: bcx.tcx(),
+ param_env: param_env,
+ };
enter_match(bcx, dm, m, col, val, |pats|
check_match::specialize(&mcx, pats.as_slice(), &ctor, col, variant_size)
)
node_id_type(bcx, pat_id)
};
- let mcx = check_match::MatchCheckCtxt { tcx: bcx.tcx() };
+ let mcx = check_match::MatchCheckCtxt {
+ tcx: bcx.tcx(),
+ param_env: ty::empty_parameter_environment(),
+ };
let adt_vals = if any_irrefutable_adt_pat(bcx.tcx(), m, col) {
let repr = adt::represent_type(bcx.ccx(), left_ty);
let arg_count = adt::num_args(&*repr, 0);
reassigned: false
};
{
- let mut visitor = euv::ExprUseVisitor::new(&mut rc, bcx);
+ let param_env = ty::empty_parameter_environment();
+ let mut visitor = euv::ExprUseVisitor::new(&mut rc, bcx, param_env);
visitor.walk_expr(body);
}
rc.reassigned
let variable_ty = node_id_type(bcx, p_id);
let llvariable_ty = type_of::type_of(ccx, variable_ty);
let tcx = bcx.tcx();
+ let param_env = ty::empty_parameter_environment();
let llmatch;
let trmode;
match bm {
ast::BindByValue(_)
- if !ty::type_moves_by_default(tcx, variable_ty) || reassigned => {
+ if !ty::type_moves_by_default(tcx,
+ variable_ty,
+ ¶m_env) || reassigned => {
llmatch = alloca_no_lifetime(bcx,
llvariable_ty.ptr_to(),
"__llmatch");
FatPointer(uint)
}
+impl Copy for PointerField {}
+
impl<'tcx> Case<'tcx> {
- fn is_zerolen<'a>(&self, cx: &CrateContext<'a, 'tcx>, scapegoat: Ty<'tcx>) -> bool {
+ fn is_zerolen<'a>(&self, cx: &CrateContext<'a, 'tcx>, scapegoat: Ty<'tcx>)
+ -> bool {
mk_struct(cx, self.tys.as_slice(), false, scapegoat).size == 0
}
use std::c_str::ToCStr;
use std::cell::{Cell, RefCell};
use std::collections::HashSet;
+use std::mem;
use std::rc::Rc;
use std::{i8, i16, i32, i64};
use syntax::abi::{Rust, RustCall, RustIntrinsic, Abi};
// Used only for creating scalar comparison glue.
pub enum scalar_type { nil_type, signed_int, unsigned_int, floating_point, }
+impl Copy for scalar_type {}
+
pub fn compare_scalar_types<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
lhs: ValueRef,
rhs: ValueRef,
in iter_structural_ty")
}
}
- _ => cx.sess().unimpl("type in iter_structural_ty")
+ _ => {
+ cx.sess().unimpl(format!("type in iter_structural_ty: {}",
+ ty_to_string(cx.tcx(), t)).as_slice())
+ }
}
return cx;
}
}
}
+#[deriving(Clone, Eq, PartialEq)]
+pub enum IsUnboxedClosureFlag {
+ NotUnboxedClosure,
+ IsUnboxedClosure,
+}
+
+impl Copy for IsUnboxedClosureFlag {}
+
// trans_closure: Builds an LLVM function out of a source function.
// If the function closes over its environment a closure will be
// returned.
InlinedCopy,
}
+impl Copy for ValueOrigin {}
+
/// Set the appropriate linkage for an LLVM `ValueRef` (function or global).
/// If the `llval` is the direct translation of a specific Rust item, `id`
/// should be set to the `NodeId` of that item. (This mapping should be
fn next(&mut self) -> Option<ValueRef> {
let old = self.cur;
if !old.is_null() {
- self.cur = unsafe { (self.step)(old) };
+ self.cur = unsafe {
+ let step: unsafe extern "C" fn(ValueRef) -> ValueRef =
+ mem::transmute_copy(&self.step);
+ step(old)
+ };
Some(old)
} else {
None
pub struct BasicBlock(pub BasicBlockRef);
+impl Copy for BasicBlock {}
+
pub type Preds<'a> = Map<'a, Value, BasicBlock, Filter<'a, Value, Users>>;
/// Wrapper for LLVM BasicBlockRef
Ignore,
}
+impl Copy for ArgKind {}
+
/// Information about how a specific C type
/// should be passed to or returned from a function
///
pub attr: option::Option<Attribute>
}
+impl Copy for ArgType {}
+
impl ArgType {
pub fn direct(ty: Type, cast: option::Option<Type>,
pad: option::Option<Type>,
Memory
}
+impl Copy for RegClass {}
+
trait TypeMethods {
fn is_reg_ty(&self) -> bool;
}
pub llself: ValueRef,
}
+impl Copy for MethodData {}
+
pub enum CalleeData<'tcx> {
Closure(Datum<'tcx, Lvalue>),
DoAutorefArg(ast::NodeId)
}
+impl Copy for AutorefArg {}
+
pub fn trans_arg_datum<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
formal_arg_ty: Ty<'tcx>,
arg_datum: Datum<'tcx, Expr>,
index: uint
}
+impl Copy for CustomScopeIndex {}
+
pub const EXIT_BREAK: uint = 0;
pub const EXIT_LOOP: uint = 1;
pub const EXIT_MAX: uint = 2;
LoopExit(ast::NodeId, uint)
}
+impl Copy for EarlyExitLabel {}
+
pub struct CachedEarlyExit {
label: EarlyExitLabel,
cleanup_block: BasicBlockRef,
}
+impl Copy for CachedEarlyExit {}
+
pub trait Cleanup<'tcx> {
fn must_unwind(&self) -> bool;
fn clean_on_unwind(&self) -> bool;
CustomScope(CustomScopeIndex)
}
+impl Copy for ScopeId {}
+
impl<'blk, 'tcx> CleanupMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx> {
/// Invoked when we start to trans the code contained within a new cleanup scope.
fn push_ast_cleanup_scope(&self, debug_loc: NodeInfo) {
zero: bool
}
+impl<'tcx> Copy for DropValue<'tcx> {}
+
impl<'tcx> Cleanup<'tcx> for DropValue<'tcx> {
fn must_unwind(&self) -> bool {
self.must_unwind
HeapExchange
}
+impl Copy for Heap {}
+
pub struct FreeValue<'tcx> {
ptr: ValueRef,
heap: Heap,
content_ty: Ty<'tcx>
}
+impl<'tcx> Copy for FreeValue<'tcx> {}
+
impl<'tcx> Cleanup<'tcx> for FreeValue<'tcx> {
fn must_unwind(&self) -> bool {
true
heap: Heap,
}
+impl Copy for FreeSlice {}
+
impl<'tcx> Cleanup<'tcx> for FreeSlice {
fn must_unwind(&self) -> bool {
true
ptr: ValueRef,
}
+impl Copy for LifetimeEnd {}
+
impl<'tcx> Cleanup<'tcx> for LifetimeEnd {
fn must_unwind(&self) -> bool {
false
datum: Datum<'tcx, Lvalue>
}
+impl<'tcx> Copy for EnvValue<'tcx> {}
+
impl<'tcx> EnvValue<'tcx> {
pub fn to_string<'a>(&self, ccx: &CrateContext<'a, 'tcx>) -> String {
format!("{}({})", self.action, self.datum.to_string(ccx))
debuginfo::create_captured_var_metadata(
bcx,
def_id.node,
- cdata_ty,
env_pointer_alloca,
i,
captured_by_ref,
// Store the pointer to closure data in an alloca for debug info because that's what the
// llvm.dbg.declare intrinsic expects
let env_pointer_alloca = if bcx.sess().opts.debuginfo == FullDebugInfo {
- let alloc = alloc_ty(bcx, ty::mk_mut_ptr(bcx.tcx(), self_type), "__debuginfo_env_ptr");
+ let alloc = alloca(bcx, val_ty(llenv), "__debuginfo_env_ptr");
Store(bcx, llenv, alloc);
Some(alloc)
} else {
debuginfo::create_captured_var_metadata(
bcx,
def_id.node,
- self_type,
env_pointer_alloca,
i,
captured_by_ref,
pub name: ValueRef,
}
+impl<'tcx> Copy for tydesc_info<'tcx> {}
+
/*
* A note on nomenclature of linking: "extern", "foreign", and "upcall".
*
pub span: Span,
}
+impl Copy for NodeInfo {}
+
pub fn expr_info(expr: &ast::Expr) -> NodeInfo {
NodeInfo { id: expr.id, span: expr.span }
}
MethodCall(ty::MethodCall)
}
+impl Copy for ExprOrMethodCall {}
+
pub fn node_id_substs<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
node: ExprOrMethodCall)
- -> subst::Substs<'tcx>
-{
+ -> subst::Substs<'tcx> {
let tcx = bcx.tcx();
let substs = match node {
pub kind: K,
}
+impl<'tcx,K:Copy> Copy for Datum<'tcx,K> {}
+
pub struct DatumBlock<'blk, 'tcx: 'blk, K> {
pub bcx: Block<'blk, 'tcx>,
pub datum: Datum<'tcx, K>,
#[deriving(Clone, Show)]
pub struct Lvalue;
+impl Copy for Lvalue {}
+
#[deriving(Show)]
pub struct Rvalue {
pub mode: RvalueMode
ByValue,
}
+impl Copy for RvalueMode {}
+
pub fn immediate_rvalue<'tcx>(val: ValueRef, ty: Ty<'tcx>) -> Datum<'tcx, Rvalue> {
return Datum::new(val, ty, Rvalue::new(ByValue));
}
/// Copies the value into a new location. This function always preserves the existing datum as
/// a valid value. Therefore, it does not consume `self` and, also, cannot be applied to affine
/// values (since they must never be duplicated).
- pub fn shallow_copy<'blk>(&self,
- bcx: Block<'blk, 'tcx>,
- dst: ValueRef)
- -> Block<'blk, 'tcx> {
- assert!(!ty::type_moves_by_default(bcx.tcx(), self.ty));
+ pub fn shallow_copy<'blk, 'tcx>(&self,
+ bcx: Block<'blk, 'tcx>,
+ dst: ValueRef)
+ -> Block<'blk, 'tcx> {
+ /*!
+ * Copies the value into a new location. This function always
+ * preserves the existing datum as a valid value. Therefore,
+ * it does not consume `self` and, also, cannot be applied to
+ * affine values (since they must never be duplicated).
+ */
+
+ let param_env = ty::empty_parameter_environment();
+ assert!(!ty::type_moves_by_default(bcx.tcx(), self.ty, ¶m_env));
self.shallow_copy_raw(bcx, dst)
}
#[deriving(Show, Hash, Eq, PartialEq, Clone)]
struct UniqueTypeId(ast::Name);
+impl Copy for UniqueTypeId {}
+
// The TypeMap is where the CrateDebugContext holds the type metadata nodes
// created so far. The metadata nodes are indexed by UniqueTypeId, and, for
// faster lookup, also by Ty. The TypeMap is responsible for creating
/// Adds the created metadata nodes directly to the crate's IR.
pub fn create_captured_var_metadata<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
node_id: ast::NodeId,
- env_data_type: Ty<'tcx>,
env_pointer: ValueRef,
env_index: uint,
captured_by_ref: bool,
let variable_type = node_id_type(bcx, node_id);
let scope_metadata = bcx.fcx.debug_context.get_ref(cx, span).fn_metadata;
- let llvm_env_data_type = type_of::type_of(cx, env_data_type);
+ // env_pointer is the alloca containing the pointer to the environment,
+ // so it's type is **EnvironmentType. In order to find out the type of
+ // the environment we have to "dereference" two times.
+ let llvm_env_data_type = val_ty(env_pointer).element_type().element_type();
let byte_offset_of_var_in_env = machine::llelement_offset(cx,
llvm_env_data_type,
env_index);
NoDiscriminant
}
+impl Copy for EnumDiscriminantInfo {}
+
// Returns a tuple of (1) type_metadata_stub of the variant, (2) the llvm_type
// of the variant, and (3) a MemberDescriptionFactory for producing the
// descriptions of the fields of the variant. This is a rudimentary version of a
UnknownLocation
}
+impl Copy for DebugLocation {}
+
impl DebugLocation {
fn new(scope: DIScope, line: uint, col: uint) -> DebugLocation {
KnownLocation {
Ignore,
}
+impl Copy for Dest {}
+
impl Dest {
pub fn to_string(&self, ccx: &CrateContext) -> String {
match *self {
cast_other,
}
+impl Copy for cast_kind {}
+
pub fn cast_type_kind<'tcx>(tcx: &ty::ctxt<'tcx>, t: Ty<'tcx>) -> cast_kind {
match t.sty {
ty::ty_char => cast_integral,
pub llmod: ModuleRef,
}
+impl Copy for ModuleTranslation {}
+
pub struct CrateTranslation {
pub modules: Vec<ModuleTranslation>,
pub metadata_module: ModuleTranslation,
pub llunit_alloc_size: u64
}
+impl<'tcx> Copy for VecTypes<'tcx> {}
+
impl<'tcx> VecTypes<'tcx> {
pub fn to_string<'a>(&self, ccx: &CrateContext<'a, 'tcx>) -> String {
format!("VecTypes {{unit_ty={}, llunit_ty={}, \
1 => expr::trans_into(bcx, &**element, SaveIn(lldest)),
count => {
let elem = unpack_datum!(bcx, expr::trans(bcx, &**element));
- assert!(!ty::type_moves_by_default(bcx.tcx(), elem.ty));
-
let bcx = iter_vec_loop(bcx, lldest, vt,
C_uint(bcx.ccx(), count),
|set_bcx, lleltptr, _| {
rf: TypeRef
}
+impl Copy for Type {}
+
macro_rules! ty (
($e:expr) => ( Type::from_ref(unsafe { $e }))
)
an_unboxed_closure,
}
+impl Copy for named_ty {}
+
pub fn llvm_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
what: named_ty,
did: ast::DefId,
tps: &[Ty<'tcx>])
- -> String
-{
+ -> String {
let name = match what {
a_struct => "struct",
an_enum => "enum",
pub struct Value(pub ValueRef);
+impl Copy for Value {}
+
macro_rules! opt_val ( ($e:expr) => (
unsafe {
match $e {
}
}
+/// Wrapper for LLVM UseRef
pub struct Use(UseRef);
-/// Wrapper for LLVM UseRef
+impl Copy for Use {}
+
+/**
+ * Wrapper for LLVM UseRef
+ */
impl Use {
pub fn get(&self) -> UseRef {
let Use(v) = *self; v
}
/// Iterator for the users of a value
+#[allow(missing_copy_implementations)]
pub struct Users {
next: Option<Use>
}
(regions, types)
}
+/// Returns the appropriate lifetime to use for any output lifetimes
+/// (if one exists) and a vector of the (pattern, number of lifetimes)
+/// corresponding to each input type/pattern.
+fn find_implied_output_region(input_tys: &[Ty], input_pats: Vec<String>)
+ -> (Option<ty::Region>, Vec<(String, uint)>)
+{
+ let mut lifetimes_for_params: Vec<(String, uint)> = Vec::new();
+ let mut possible_implied_output_region = None;
+
+ for (input_type, input_pat) in input_tys.iter().zip(input_pats.into_iter()) {
+ let mut accumulator = Vec::new();
+ ty::accumulate_lifetimes_in_type(&mut accumulator, *input_type);
+
+ if accumulator.len() == 1 {
+ // there's a chance that the unique lifetime of this
+ // iteration will be the appropriate lifetime for output
+ // parameters, so lets store it.
+ possible_implied_output_region = Some(accumulator[0])
+ }
+
+ lifetimes_for_params.push((input_pat, accumulator.len()));
+ }
+
+ let implied_output_region = if lifetimes_for_params.iter().map(|&(_, n)| n).sum() == 1 {
+ assert!(possible_implied_output_region.is_some());
+ possible_implied_output_region
+ } else {
+ None
+ };
+ (implied_output_region, lifetimes_for_params)
+}
+
+fn convert_ty_with_lifetime_elision<'tcx,AC>(this: &AC,
+ implied_output_region: Option<ty::Region>,
+ param_lifetimes: Vec<(String, uint)>,
+ ty: &ast::Ty)
+ -> Ty<'tcx>
+ where AC: AstConv<'tcx>
+{
+ match implied_output_region {
+ Some(implied_output_region) => {
+ let rb = SpecificRscope::new(implied_output_region);
+ ast_ty_to_ty(this, &rb, ty)
+ }
+ None => {
+ // All regions must be explicitly specified in the output
+ // if the lifetime elision rules do not apply. This saves
+ // the user from potentially-confusing errors.
+ let rb = UnelidableRscope::new(param_lifetimes);
+ ast_ty_to_ty(this, &rb, ty)
+ }
+ }
+}
+
fn convert_parenthesized_parameters<'tcx,AC>(this: &AC,
data: &ast::ParenthesizedParameterData)
-> Vec<Ty<'tcx>>
where AC: AstConv<'tcx>
{
let binding_rscope = BindingRscope::new();
-
let inputs = data.inputs.iter()
.map(|a_t| ast_ty_to_ty(this, &binding_rscope, &**a_t))
- .collect();
+ .collect::<Vec<Ty<'tcx>>>();
+
+ let input_params = Vec::from_elem(inputs.len(), String::new());
+ let (implied_output_region,
+ params_lifetimes) = find_implied_output_region(&*inputs, input_params);
+
let input_ty = ty::mk_tup(this.tcx(), inputs);
let output = match data.output {
- Some(ref output_ty) => ast_ty_to_ty(this, &binding_rscope, &**output_ty),
+ Some(ref output_ty) => convert_ty_with_lifetime_elision(this,
+ implied_output_region,
+ params_lifetimes,
+ &**output_ty),
None => ty::mk_nil(this.tcx()),
};
let self_and_input_tys: Vec<Ty> =
self_ty.into_iter().chain(input_tys).collect();
- let mut lifetimes_for_params: Vec<(String, Vec<ty::Region>)> = Vec::new();
// Second, if there was exactly one lifetime (either a substitution or a
// reference) in the arguments, then any anonymous regions in the output
// have that lifetime.
- if implied_output_region.is_none() {
- let mut self_and_input_tys_iter = self_and_input_tys.iter();
- if self_ty.is_some() {
+ let lifetimes_for_params = if implied_output_region.is_none() {
+ let input_tys = if self_ty.is_some() {
// Skip the first argument if `self` is present.
- drop(self_and_input_tys_iter.next())
- }
-
- for (input_type, input_pat) in self_and_input_tys_iter.zip(input_pats.into_iter()) {
- let mut accumulator = Vec::new();
- ty::accumulate_lifetimes_in_type(&mut accumulator, *input_type);
- lifetimes_for_params.push((input_pat, accumulator));
- }
-
- if lifetimes_for_params.iter().map(|&(_, ref x)| x.len()).sum() == 1 {
- implied_output_region =
- Some(lifetimes_for_params.iter()
- .filter_map(|&(_, ref x)|
- if x.len() == 1 { Some(x[0]) } else { None })
- .next().unwrap());
- }
- }
+ self_and_input_tys.slice_from(1)
+ } else {
+ self_and_input_tys.slice_from(0)
+ };
- let param_lifetimes: Vec<(String, uint)> = lifetimes_for_params.into_iter()
- .map(|(n, v)| (n, v.len()))
- .filter(|&(_, l)| l != 0)
- .collect();
+ let (ior, lfp) = find_implied_output_region(input_tys, input_pats);
+ implied_output_region = ior;
+ lfp
+ } else {
+ vec![]
+ };
let output_ty = match decl.output {
ast::Return(ref output) if output.node == ast::TyInfer =>
ty::FnConverging(this.ty_infer(output.span)),
ast::Return(ref output) =>
- ty::FnConverging(match implied_output_region {
- Some(implied_output_region) => {
- let rb = SpecificRscope::new(implied_output_region);
- ast_ty_to_ty(this, &rb, &**output)
- }
- None => {
- // All regions must be explicitly specified in the output
- // if the lifetime elision rules do not apply. This saves
- // the user from potentially-confusing errors.
- let rb = UnelidableRscope::new(param_lifetimes);
- ast_ty_to_ty(this, &rb, &**output)
- }
- }),
+ ty::FnConverging(convert_ty_with_lifetime_elision(this,
+ implied_output_region,
+ lifetimes_for_params,
+ &**output)),
ast::NoReturn(_) => ty::FnDiverging
};
--- /dev/null
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use syntax::ast;
+use syntax::codemap::Span;
+use CrateCtxt;
+
+/// Check that it is legal to call methods of the trait corresponding
+/// to `trait_id` (this only cares about the trait, not the specific
+/// method that is called)
+pub fn check_legal_trait_for_method_call(ccx: &CrateCtxt, span: Span, trait_id: ast::DefId) {
+ let tcx = ccx.tcx;
+ let did = Some(trait_id);
+ let li = &tcx.lang_items;
+
+ if did == li.drop_trait() {
+ span_err!(tcx.sess, span, E0040, "explicit use of destructor method");
+ } else if !tcx.sess.features.borrow().unboxed_closures {
+ // the #[feature(unboxed_closures)] feature isn't
+ // activated so we need to enforce the closure
+ // restrictions.
+
+ let method = if did == li.fn_trait() {
+ "call"
+ } else if did == li.fn_mut_trait() {
+ "call_mut"
+ } else if did == li.fn_once_trait() {
+ "call_once"
+ } else {
+ return // not a closure method, everything is OK.
+ };
+
+ span_err!(tcx.sess, span, E0174,
+ "explicit use of unboxed closure method `{}` is experimental",
+ method);
+ span_help!(tcx.sess, span,
+ "add `#![feature(unboxed_closures)]` to the crate attributes to enable");
+ }
+}
use super::probe;
-use check::{mod, FnCtxt, NoPreference, PreferMutLvalue};
+use check::{mod, FnCtxt, NoPreference, PreferMutLvalue, callee};
use middle::subst::{mod, Subst};
use middle::traits;
use middle::ty::{mod, Ty};
let self_ty = self.adjust_self_ty(unadjusted_self_ty, &pick.adjustment);
// Make sure nobody calls `drop()` explicitly.
- self.enforce_drop_trait_limitations(&pick);
+ self.enforce_illegal_method_limitations(&pick);
// Create substitutions for the method's type parameters.
let (rcvr_substs, method_origin) =
self.fcx.infcx()
}
- fn enforce_drop_trait_limitations(&self, pick: &probe::Pick) {
+ fn enforce_illegal_method_limitations(&self, pick: &probe::Pick) {
// Disallow calls to the method `drop` defined in the `Drop` trait.
match pick.method_ty.container {
ty::TraitContainer(trait_def_id) => {
- if Some(trait_def_id) == self.tcx().lang_items.drop_trait() {
- span_err!(self.tcx().sess, self.span, E0040,
- "explicit call to destructor");
- }
+ callee::check_legal_trait_for_method_call(self.fcx.ccx, self.span, trait_def_id)
}
ty::ImplContainer(..) => {
// Since `drop` is a trait method, we expect that any
TraitSource(/* trait id */ ast::DefId),
}
+impl Copy for CandidateSource {}
+
type MethodIndex = uint; // just for doc purposes
/// Determines whether the type `self_ty` supports a method name `method_name` or not.
pub mod method;
pub mod wf;
mod closure;
+mod callee;
/// Fields that are part of a `FnCtxt` which are inherited by
/// closures defined within the function. For example:
ExpectCastableToType(Ty<'tcx>),
}
+impl<'tcx> Copy for Expectation<'tcx> {}
+
#[deriving(Clone)]
pub struct FnStyleState {
pub def: ast::NodeId,
from_fn: bool
}
+impl Copy for FnStyleState {}
+
impl FnStyleState {
pub fn function(fn_style: ast::FnStyle, def: ast::NodeId) -> FnStyleState {
FnStyleState { def: def, fn_style: fn_style, from_fn: true }
decl, id, body, &inh);
vtable::select_all_fcx_obligations_or_error(&fcx);
- regionck::regionck_fn(&fcx, id, body);
+ regionck::regionck_fn(&fcx, id, decl, body);
fcx.default_diverging_type_variables_to_nil();
writeback::resolve_type_vars_in_fn(&fcx, decl, body);
}
NoPreference
}
+impl Copy for LvaluePreference {}
+
/// Executes an autoderef loop for the type `t`. At each step, invokes `should_stop` to decide
/// whether to terminate the loop. Returns the final type and number of derefs that it performed.
///
DoDerefArgs
}
+impl Copy for DerefArgs {}
+
/// Controls whether the arguments are tupled. This is used for the call
/// operator.
///
}
// Case 3. Reference to a method.
- def::DefStaticMethod(..) => {
+ def::DefStaticMethod(_, providence) |
+ def::DefMethod(_, _, providence) => {
assert!(path.segments.len() >= 2);
+
+ match providence {
+ def::FromTrait(trait_did) => {
+ callee::check_legal_trait_for_method_call(fcx.ccx, span, trait_did)
+ }
+ def::FromImpl(_) => {}
+ }
+
segment_spaces = Vec::from_elem(path.segments.len() - 2, None);
segment_spaces.push(Some(subst::TypeSpace));
segment_spaces.push(Some(subst::FnSpace));
def::DefMod(..) |
def::DefForeignMod(..) |
def::DefLocal(..) |
- def::DefMethod(..) |
def::DefUse(..) |
def::DefRegion(..) |
def::DefLabel(..) |
fcx.infcx().resolve_regions_and_report_errors();
}
-pub fn regionck_fn(fcx: &FnCtxt, id: ast::NodeId, blk: &ast::Block) {
+pub fn regionck_fn(fcx: &FnCtxt, id: ast::NodeId, decl: &ast::FnDecl, blk: &ast::Block) {
let mut rcx = Rcx::new(fcx, blk.id);
if fcx.err_count_since_creation() == 0 {
// regionck assumes typeck succeeded
- rcx.visit_fn_body(id, blk);
+ rcx.visit_fn_body(id, decl, blk);
}
// Region checking a fn can introduce new trait obligations,
fn visit_fn_body(&mut self,
id: ast::NodeId,
+ fn_decl: &ast::FnDecl,
body: &ast::Block)
{
// When we enter a function, we can derive
let len = self.region_param_pairs.len();
self.relate_free_regions(fn_sig.as_slice(), body.id);
+ link_fn_args(self, CodeExtent::from_node_id(body.id), fn_decl.inputs.as_slice());
self.visit_block(body);
self.visit_region_obligations(body.id);
self.region_param_pairs.truncate(len);
// hierarchy, and in particular the relationships between free
// regions, until regionck, as described in #3238.
- fn visit_fn(&mut self, _fk: visit::FnKind<'v>, _fd: &'v ast::FnDecl,
+ fn visit_fn(&mut self, _fk: visit::FnKind<'v>, fd: &'v ast::FnDecl,
b: &'v ast::Block, _s: Span, id: ast::NodeId) {
- self.visit_fn_body(id, b)
+ self.visit_fn_body(id, fd, b)
}
fn visit_item(&mut self, i: &ast::Item) { visit_item(self, i); }
/// then ensures that the lifetime of the resulting pointer is
/// linked to the lifetime of its guarantor (if any).
fn link_match(rcx: &Rcx, discr: &ast::Expr, arms: &[ast::Arm]) {
-
debug!("regionck::for_match()");
let mc = mc::MemCategorizationContext::new(rcx);
let discr_cmt = ignore_err!(mc.cat_expr(discr));
}
}
+/// Computes the guarantors for any ref bindings in a match and
+/// then ensures that the lifetime of the resulting pointer is
+/// linked to the lifetime of its guarantor (if any).
+fn link_fn_args(rcx: &Rcx, body_scope: CodeExtent, args: &[ast::Arg]) {
+ debug!("regionck::link_fn_args(body_scope={})", body_scope);
+ let mc = mc::MemCategorizationContext::new(rcx);
+ for arg in args.iter() {
+ let arg_ty = rcx.fcx.node_ty(arg.id);
+ let re_scope = ty::ReScope(body_scope);
+ let arg_cmt = mc.cat_rvalue(arg.id, arg.ty.span, re_scope, arg_ty);
+ debug!("arg_ty={} arg_cmt={}",
+ arg_ty.repr(rcx.tcx()),
+ arg_cmt.repr(rcx.tcx()));
+ link_pattern(rcx, mc, arg_cmt, &*arg.pat);
+ }
+}
+
/// Link lifetimes of any ref bindings in `root_pat` to the pointers found in the discriminant, if
/// needed.
fn link_pattern<'a, 'tcx>(rcx: &Rcx<'a, 'tcx>,
mc: mc::MemCategorizationContext<Rcx<'a, 'tcx>>,
discr_cmt: mc::cmt<'tcx>,
root_pat: &ast::Pat) {
+ debug!("link_pattern(discr_cmt={}, root_pat={})",
+ discr_cmt.repr(rcx.tcx()),
+ root_pat.repr(rcx.tcx()));
let _ = mc.cat_pattern(discr_cmt, root_pat, |mc, sub_cmt, sub_pat| {
match sub_pat.node {
// `ref x` pattern
"overflow evaluating the trait `{}` for the type `{}`",
trait_ref.user_string(fcx.tcx()),
self_ty.user_string(fcx.tcx())).as_slice());
+
+ let current_limit = fcx.tcx().sess.recursion_limit.get();
+ let suggested_limit = current_limit * 2;
+ fcx.tcx().sess.span_note(
+ obligation.cause.span,
+ format!(
+ "consider adding a `#![recursion_limit=\"{}\"]` attribute to your crate",
+ suggested_limit)[]);
+
note_obligation_cause(fcx, obligation);
}
Unimplemented => {
}
}
+ if fcx.tcx().lang_items.copy_trait() == Some(trait_ref.def_id) {
+ // This is checked in coherence.
+ return
+ }
+
// We are stricter on the trait-ref in an impl than the
// self-type. In particular, we enforce region
// relationships. The reason for this is that (at least
ResolvingUnboxedClosure(ast::DefId),
}
+impl Copy for ResolveReason {}
+
impl ResolveReason {
fn span(&self, tcx: &ty::ctxt) -> Span {
match *self {
use metadata::csearch::{each_impl, get_impl_trait};
use metadata::csearch;
-use middle::subst;
+use middle::subst::{mod, Subst};
use middle::ty::{ImplContainer, ImplOrTraitItemId, MethodTraitItemId};
-use middle::ty::{TypeTraitItemId, lookup_item_type};
-use middle::ty::{Ty, ty_bool, ty_char, ty_enum, ty_err};
-use middle::ty::{ty_str, ty_vec, ty_float, ty_infer, ty_int, ty_open};
+use middle::ty::{ParameterEnvironment, TypeTraitItemId, lookup_item_type};
+use middle::ty::{Ty, ty_bool, ty_char, ty_closure, ty_enum, ty_err};
use middle::ty::{ty_param, Polytype, ty_ptr};
use middle::ty::{ty_rptr, ty_struct, ty_trait, ty_tup};
+use middle::ty::{ty_str, ty_vec, ty_float, ty_infer, ty_int, ty_open};
use middle::ty::{ty_uint, ty_unboxed_closure, ty_uniq, ty_bare_fn};
-use middle::ty::{ty_closure};
-use middle::ty::type_is_ty_var;
-use middle::subst::Subst;
+use middle::ty::{type_is_ty_var};
use middle::ty;
use CrateCtxt;
use middle::infer::combine::Combine;
// do this here, but it's actually the most convenient place, since
// the coherence tables contain the trait -> type mappings.
self.populate_destructor_table();
+
+ // Check to make sure implementations of `Copy` are legal.
+ self.check_implementations_of_copy();
}
fn check_implementation(&self,
trait_ref.repr(self.crate_context.tcx),
token::get_ident(item.ident));
+ enforce_trait_manually_implementable(self.crate_context.tcx,
+ item.span,
+ trait_ref.def_id);
self.add_trait_impl(trait_ref.def_id, impl_did);
}
}
}
}
+
+ /// Ensures that implementations of the built-in trait `Copy` are legal.
+ fn check_implementations_of_copy(&self) {
+ let tcx = self.crate_context.tcx;
+ let copy_trait = match tcx.lang_items.copy_trait() {
+ Some(id) => id,
+ None => return,
+ };
+
+ let trait_impls = match tcx.trait_impls
+ .borrow()
+ .get(©_trait)
+ .cloned() {
+ None => {
+ debug!("check_implementations_of_copy(): no types with \
+ implementations of `Copy` found");
+ return
+ }
+ Some(found_impls) => found_impls
+ };
+
+ // Clone first to avoid a double borrow error.
+ let trait_impls = trait_impls.borrow().clone();
+
+ for &impl_did in trait_impls.iter() {
+ if impl_did.krate != ast::LOCAL_CRATE {
+ debug!("check_implementations_of_copy(): impl not in this \
+ crate");
+ continue
+ }
+
+ let self_type = self.get_self_type_for_implementation(impl_did);
+ let span = tcx.map.span(impl_did.node);
+ let param_env = ParameterEnvironment::for_item(tcx,
+ impl_did.node);
+ let self_type = self_type.ty.subst(tcx, ¶m_env.free_substs);
+
+ match ty::can_type_implement_copy(tcx, self_type, ¶m_env) {
+ Ok(()) => {}
+ Err(ty::FieldDoesNotImplementCopy(name)) => {
+ tcx.sess
+ .span_err(span,
+ format!("the trait `Copy` may not be \
+ implemented for this type; field \
+ `{}` does not implement `Copy`",
+ token::get_name(name)).as_slice())
+ }
+ Err(ty::VariantDoesNotImplementCopy(name)) => {
+ tcx.sess
+ .span_err(span,
+ format!("the trait `Copy` may not be \
+ implemented for this type; variant \
+ `{}` does not implement `Copy`",
+ token::get_name(name)).as_slice())
+ }
+ Err(ty::TypeIsStructural) => {
+ tcx.sess
+ .span_err(span,
+ "the trait `Copy` may not be implemented \
+ for this type; type is not a structure or \
+ enumeration")
+ }
+ }
+ }
+ }
+}
+
+fn enforce_trait_manually_implementable(tcx: &ty::ctxt, sp: Span, trait_def_id: ast::DefId) {
+ if tcx.sess.features.borrow().unboxed_closures {
+ // the feature gate allows all of them
+ return
+ }
+ let did = Some(trait_def_id);
+ let li = &tcx.lang_items;
+
+ let trait_name = if did == li.fn_trait() {
+ "Fn"
+ } else if did == li.fn_mut_trait() {
+ "FnMut"
+ } else if did == li.fn_once_trait() {
+ "FnOnce"
+ } else {
+ return // everything OK
+ };
+ span_err!(tcx.sess, sp, E0173, "manual implementations of `{}` are experimental", trait_name);
+ span_help!(tcx.sess, sp,
+ "add `#![feature(unboxed_closures)]` to the crate attributes to enable");
}
fn subst_receiver_types_in_method_ty<'tcx>(tcx: &ty::ctxt<'tcx>,
TraitConvertMethodContext(ast::DefId, &'a [ast::TraitItem]),
}
+impl<'a> Copy for ConvertMethodContext<'a> {}
+
fn convert_methods<'a,'tcx,'i,I>(ccx: &CrateCtxt<'a, 'tcx>,
convert_method_context: ConvertMethodContext,
container: ImplOrTraitItemContainer,
E0035,
E0036,
E0038,
- E0040,
+ E0040, // explicit use of destructor method
E0044,
E0045,
E0046,
E0168,
E0169,
E0171,
- E0172
+ E0172,
+ E0173, // manual implementations of unboxed closure traits are experimental
+ E0174 // explicit use of unboxed closure methods are experimental
)
// for types that appear in structs and so on.
pub struct ExplicitRscope;
+impl Copy for ExplicitRscope {}
+
impl RegionScope for ExplicitRscope {
fn default_region_bound(&self, _span: Span) -> Option<ty::Region> {
None
// A scope in which any omitted region defaults to `default`. This is
// used after the `->` in function signatures, but also for backwards
// compatibility with object types. The latter use may go away.
+#[allow(missing_copy_implementations)]
pub struct SpecificRscope {
default: ty::Region
}
#[deriving(Show)]
struct InferredIndex(uint);
+impl Copy for InferredIndex {}
+
enum VarianceTerm<'a> {
ConstantTerm(ty::Variance),
TransformTerm(VarianceTermPtr<'a>, VarianceTermPtr<'a>),
InferredTerm(InferredIndex),
}
+impl<'a> Copy for VarianceTerm<'a> {}
+
impl<'a> fmt::Show for VarianceTerm<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
RegionParam
}
+impl Copy for ParamKind {}
+
struct InferredInfo<'a> {
item_id: ast::NodeId,
kind: ParamKind,
variance: &'a VarianceTerm<'a>,
}
+impl<'a> Copy for Constraint<'a> {}
+
fn add_constraints_from_crate<'a, 'tcx>(terms_cx: TermsContext<'a, 'tcx>,
krate: &ast::Crate)
-> ConstraintContext<'a, 'tcx> {
while index < num_inferred &&
inferred_infos[index].item_id == item_id {
- let info = inferred_infos[index];
+ let info = &inferred_infos[index];
let variance = solutions[index];
debug!("Index {} Info {} / {} / {} Variance {}",
index, info.index, info.kind, info.space, variance);
PrimitiveTuple,
}
+impl Copy for PrimitiveType {}
+
#[deriving(Clone, Encodable, Decodable)]
pub enum TypeKind {
TypeEnum,
TypeTypedef,
}
+impl Copy for TypeKind {}
+
impl PrimitiveType {
fn from_str(s: &str) -> Option<PrimitiveType> {
match s.as_slice() {
Immutable,
}
+impl Copy for Mutability {}
+
impl Clean<Mutability> for ast::Mutability {
fn clean(&self, _: &DocContext) -> Mutability {
match self {
Unit
}
+impl Copy for StructType {}
+
pub enum TypeBound {
RegionBound,
TraitBound(ast::TraitRef)
/// Wrapper struct for emitting type parameter bounds.
pub struct TyParamBounds<'a>(pub &'a [clean::TyParamBound]);
+impl Copy for VisSpace {}
+impl Copy for FnStyleSpace {}
+impl Copy for MutableSpace {}
+impl Copy for RawMutableSpace {}
+
impl VisSpace {
pub fn get(&self) -> Option<ast::Visibility> {
let VisSpace(v) = *self; v
Constant = 18,
}
+impl Copy for ItemType {}
+
impl ItemType {
pub fn from_item(item: &clean::Item) -> ItemType {
match item.inner {
// Helper structs for rendering items/sidebars and carrying along contextual
// information
-struct Item<'a> { cx: &'a Context, item: &'a clean::Item, }
+struct Item<'a> {
+ cx: &'a Context,
+ item: &'a clean::Item,
+}
+
+impl<'a> Copy for Item<'a> {}
+
struct Sidebar<'a> { cx: &'a Context, item: &'a clean::Item, }
/// Struct representing one entry in the JS search index. These are all emitted
pub unmarked: uint,
}
+impl Copy for Counts {}
+
impl Add<Counts, Counts> for Counts {
fn add(&self, other: &Counts) -> Counts {
Counts {
static TASK_COUNT: atomic::AtomicUint = atomic::INIT_ATOMIC_UINT;
static TASK_LOCK: StaticNativeMutex = NATIVE_MUTEX_INIT;
+#[allow(missing_copy_implementations)]
pub struct Token { _private: () }
impl Drop for Token {
///
/// This structure wraps a `*libc::c_char`, and will automatically free the
/// memory it is pointing to when it goes out of scope.
+#[allow(missing_copy_implementations)]
pub struct CString {
buf: *const libc::c_char,
owns_buffer_: bool,
#[cfg(any(target_os = "macos", target_os = "ios"))]
mod os {
+ use core::kinds::Copy;
use libc;
#[cfg(target_arch = "x86_64")]
__sig: libc::c_long,
__opaque: [u8, ..__PTHREAD_MUTEX_SIZE__],
}
+
+ impl Copy for pthread_mutex_t {}
+
#[repr(C)]
pub struct pthread_cond_t {
__sig: libc::c_long,
__opaque: [u8, ..__PTHREAD_COND_SIZE__],
}
+ impl Copy for pthread_cond_t {}
+
pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t {
__sig: _PTHREAD_MUTEX_SIG_INIT,
__opaque: [0, ..__PTHREAD_MUTEX_SIZE__],
#[cfg(target_os = "linux")]
mod os {
+ use core::kinds::Copy;
use libc;
// minus 8 because we have an 'align' field
__align: libc::c_longlong,
size: [u8, ..__SIZEOF_PTHREAD_MUTEX_T],
}
+
+ impl Copy for pthread_mutex_t {}
+
#[repr(C)]
pub struct pthread_cond_t {
__align: libc::c_longlong,
size: [u8, ..__SIZEOF_PTHREAD_COND_T],
}
+ impl Copy for pthread_cond_t {}
+
pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t {
__align: 0,
size: [0, ..__SIZEOF_PTHREAD_MUTEX_T],
use libunwind as uw;
+#[allow(missing_copy_implementations)]
pub struct Unwinder {
unwinding: bool,
}
#[allow(non_camel_case_types, non_snake_case)]
pub mod eabi {
pub use self::EXCEPTION_DISPOSITION::*;
+ use core::prelude::*;
use libunwind as uw;
use libc::{c_void, c_int};
#[repr(C)]
+ #[allow(missing_copy_implementations)]
pub struct EXCEPTION_RECORD;
#[repr(C)]
+ #[allow(missing_copy_implementations)]
pub struct CONTEXT;
#[repr(C)]
+ #[allow(missing_copy_implementations)]
pub struct DISPATCHER_CONTEXT;
#[repr(C)]
ExceptionCollidedUnwind
}
+ impl Copy for EXCEPTION_DISPOSITION {}
+
type _Unwind_Personality_Fn =
extern "C" fn(
version: c_int,
pub struct Stdio(libc::c_int);
#[allow(non_upper_case_globals)]
+impl Copy for Stdio {}
+
+#[allow(non_uppercase_statics)]
pub const Stdout: Stdio = Stdio(libc::STDOUT_FILENO);
#[allow(non_upper_case_globals)]
pub const Stderr: Stdio = Stdio(libc::STDERR_FILENO);
-// 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.
//
UrlSafe
}
+impl Copy for CharacterSet {}
+
+/// Available newline types
+pub enum Newline {
+ /// A linefeed (i.e. Unix-style newline)
+ LF,
+ /// A carriage return and a linefeed (i.e. Windows-style newline)
+ CRLF
+}
+
+impl Copy for Newline {}
+
/// Contains configuration parameters for `to_base64`.
pub struct Config {
/// Character set to use
pub char_set: CharacterSet,
+ /// Newline to use
+ pub newline: Newline,
/// True to pad output with `=` characters
pub pad: bool,
/// `Some(len)` to wrap lines at `len`, `None` to disable line wrapping
pub line_length: Option<uint>
}
+impl Copy for Config {}
+
/// Configuration for RFC 4648 standard base64 encoding
pub static STANDARD: Config =
- Config {char_set: Standard, pad: true, line_length: None};
+ Config {char_set: Standard, newline: Newline::CRLF, pad: true, line_length: None};
/// Configuration for RFC 4648 base64url encoding
pub static URL_SAFE: Config =
- Config {char_set: UrlSafe, pad: false, line_length: None};
+ Config {char_set: UrlSafe, newline: Newline::CRLF, pad: false, line_length: None};
/// Configuration for RFC 2045 MIME base64 encoding
pub static MIME: Config =
- Config {char_set: Standard, pad: true, line_length: Some(76)};
+ Config {char_set: Standard, newline: Newline::CRLF, pad: true, line_length: Some(76)};
static STANDARD_CHARS: &'static[u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZ\
abcdefghijklmnopqrstuvwxyz\
UrlSafe => URLSAFE_CHARS
};
- let mut v = Vec::new();
+ // In general, this Vec only needs (4/3) * self.len() memory, but
+ // addition is faster than multiplication and division.
+ let mut v = Vec::with_capacity(self.len() + self.len());
let mut i = 0;
let mut cur_length = 0;
let len = self.len();
- while i < len - (len % 3) {
- match config.line_length {
- Some(line_length) =>
- if cur_length >= line_length {
- v.push(b'\r');
- v.push(b'\n');
- cur_length = 0;
- },
- None => ()
+ let mod_len = len % 3;
+ let cond_len = len - mod_len;
+ let newline = match config.newline {
+ Newline::LF => b"\n",
+ Newline::CRLF => b"\r\n"
+ };
+ while i < cond_len {
+ let (first, second, third) = (self[i], self[i + 1], self[i + 2]);
+ if let Some(line_length) = config.line_length {
+ if cur_length >= line_length {
+ v.push_all(newline);
+ cur_length = 0;
+ }
}
- let n = (self[i] as u32) << 16 |
- (self[i + 1] as u32) << 8 |
- (self[i + 2] as u32);
+ let n = (first as u32) << 16 |
+ (second as u32) << 8 |
+ (third as u32);
// This 24-bit number gets separated into four 6-bit numbers.
v.push(bytes[((n >> 18) & 63) as uint]);
i += 3;
}
- if len % 3 != 0 {
- match config.line_length {
- Some(line_length) =>
- if cur_length >= line_length {
- v.push(b'\r');
- v.push(b'\n');
- },
- None => ()
+ if mod_len != 0 {
+ if let Some(line_length) = config.line_length {
+ if cur_length >= line_length {
+ v.push_all(newline);
+ }
}
}
// Heh, would be cool if we knew this was exhaustive
// (the dream of bounded integer types)
- match len % 3 {
+ match mod_len {
0 => (),
1 => {
let n = (self[i] as u32) << 16;
InvalidBase64Length,
}
+impl Copy for FromBase64Error {}
+
impl fmt::Show for FromBase64Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
impl FromBase64 for [u8] {
fn from_base64(&self) -> Result<Vec<u8>, FromBase64Error> {
- let mut r = Vec::new();
+ let mut r = Vec::with_capacity(self.len());
let mut buf: u32 = 0;
let mut modulus = 0i;
mod tests {
extern crate test;
use self::test::Bencher;
- use base64::{Config, FromBase64, ToBase64, STANDARD, URL_SAFE};
+ use base64::{Config, Newline, FromBase64, ToBase64, STANDARD, URL_SAFE};
#[test]
fn test_to_base64_basic() {
}
#[test]
- fn test_to_base64_line_break() {
+ fn test_to_base64_crlf_line_break() {
assert!(![0u8, ..1000].to_base64(Config {line_length: None, ..STANDARD})
.contains("\r\n"));
- assert_eq!("foobar".as_bytes().to_base64(Config {line_length: Some(4),
- ..STANDARD}),
+ assert_eq!(b"foobar".to_base64(Config {line_length: Some(4),
+ ..STANDARD}),
"Zm9v\r\nYmFy");
}
+ #[test]
+ fn test_to_base64_lf_line_break() {
+ assert!(![0u8, ..1000].to_base64(Config {line_length: None,
+ newline: Newline::LF,
+ ..STANDARD})
+ .as_slice()
+ .contains("\n"));
+ assert_eq!(b"foobar".to_base64(Config {line_length: Some(4),
+ newline: Newline::LF,
+ ..STANDARD}),
+ "Zm9v\nYmFy");
+ }
+
#[test]
fn test_to_base64_padding() {
assert_eq!("f".as_bytes().to_base64(Config {pad: false, ..STANDARD}), "Zg");
b"foobar");
assert_eq!("Zm9vYg==\r\n".from_base64().unwrap(),
b"foob");
+ assert_eq!("Zm9v\nYmFy".from_base64().unwrap(),
+ b"foobar");
+ assert_eq!("Zm9vYg==\n".from_base64().unwrap(),
+ b"foob");
}
#[test]
InvalidHexLength,
}
+impl Copy for FromHexError {}
+
impl fmt::Show for FromHexError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
//! fn main() {
//! let object = TestStruct {
//! data_int: 1,
-//! data_str: "toto".to_string(),
+//! data_str: "homura".to_string(),
//! data_vector: vec![2,3,4,5],
//! };
//!
//! // Serialize using `ToJson`
//! let input_data = TestStruct {
//! data_int: 1,
-//! data_str: "toto".to_string(),
+//! data_str: "madoka".to_string(),
//! data_vector: vec![2,3,4,5],
//! };
//! let json_obj: Json = input_data.to_json();
NotUtf8,
}
+impl Copy for ErrorCode {}
+
#[deriving(Clone, PartialEq, Show)]
pub enum ParserError {
/// msg, line, col
IoError(io::IoErrorKind, &'static str),
}
+impl Copy for ParserError {}
+
// Builder and Parser have the same errors.
pub type BuilderError = ParserError;
fn fmt_number_or_null(v: f64) -> string::String {
match v.classify() {
FPNaN | FPInfinite => string::String::from_str("null"),
- _ => f64::to_str_digits(v, 6u)
+ _ if v.fract() != 0f64 => f64::to_str_digits(v, 6u),
+ _ => f64::to_str_digits(v, 6u) + ".0",
}
}
impl<'a> ::Encoder<io::IoError> for Encoder<'a> {
fn emit_nil(&mut self) -> EncodeResult { write!(self.writer, "null") }
- fn emit_uint(&mut self, v: uint) -> EncodeResult { self.emit_f64(v as f64) }
- fn emit_u64(&mut self, v: u64) -> EncodeResult { self.emit_f64(v as f64) }
- fn emit_u32(&mut self, v: u32) -> EncodeResult { self.emit_f64(v as f64) }
- fn emit_u16(&mut self, v: u16) -> EncodeResult { self.emit_f64(v as f64) }
- fn emit_u8(&mut self, v: u8) -> EncodeResult { self.emit_f64(v as f64) }
+ fn emit_uint(&mut self, v: uint) -> EncodeResult { write!(self.writer, "{}", v) }
+ fn emit_u64(&mut self, v: u64) -> EncodeResult { write!(self.writer, "{}", v) }
+ fn emit_u32(&mut self, v: u32) -> EncodeResult { write!(self.writer, "{}", v) }
+ fn emit_u16(&mut self, v: u16) -> EncodeResult { write!(self.writer, "{}", v) }
+ fn emit_u8(&mut self, v: u8) -> EncodeResult { write!(self.writer, "{}", v) }
- fn emit_int(&mut self, v: int) -> EncodeResult { self.emit_f64(v as f64) }
- fn emit_i64(&mut self, v: i64) -> EncodeResult { self.emit_f64(v as f64) }
- fn emit_i32(&mut self, v: i32) -> EncodeResult { self.emit_f64(v as f64) }
- fn emit_i16(&mut self, v: i16) -> EncodeResult { self.emit_f64(v as f64) }
- fn emit_i8(&mut self, v: i8) -> EncodeResult { self.emit_f64(v as f64) }
+ fn emit_int(&mut self, v: int) -> EncodeResult { write!(self.writer, "{}", v) }
+ fn emit_i64(&mut self, v: i64) -> EncodeResult { write!(self.writer, "{}", v) }
+ fn emit_i32(&mut self, v: i32) -> EncodeResult { write!(self.writer, "{}", v) }
+ fn emit_i16(&mut self, v: i16) -> EncodeResult { write!(self.writer, "{}", v) }
+ fn emit_i8(&mut self, v: i8) -> EncodeResult { write!(self.writer, "{}", v) }
fn emit_bool(&mut self, v: bool) -> EncodeResult {
if v {
fn emit_f64(&mut self, v: f64) -> EncodeResult {
write!(self.writer, "{}", fmt_number_or_null(v))
}
- fn emit_f32(&mut self, v: f32) -> EncodeResult { self.emit_f64(v as f64) }
+ fn emit_f32(&mut self, v: f32) -> EncodeResult {
+ self.emit_f64(v as f64)
+ }
fn emit_char(&mut self, v: char) -> EncodeResult {
escape_char(self.writer, v)
escape_str(self.writer, v)
}
- fn emit_enum(&mut self, _name: &str, f: |&mut Encoder<'a>| -> EncodeResult) -> EncodeResult {
+ fn emit_enum(&mut self,
+ _name: &str,
+ f: |&mut Encoder<'a>| -> EncodeResult) -> EncodeResult {
f(self)
}
impl<'a> ::Encoder<io::IoError> for PrettyEncoder<'a> {
fn emit_nil(&mut self) -> EncodeResult { write!(self.writer, "null") }
- fn emit_uint(&mut self, v: uint) -> EncodeResult { self.emit_f64(v as f64) }
- fn emit_u64(&mut self, v: u64) -> EncodeResult { self.emit_f64(v as f64) }
- fn emit_u32(&mut self, v: u32) -> EncodeResult { self.emit_f64(v as f64) }
- fn emit_u16(&mut self, v: u16) -> EncodeResult { self.emit_f64(v as f64) }
- fn emit_u8(&mut self, v: u8) -> EncodeResult { self.emit_f64(v as f64) }
+ fn emit_uint(&mut self, v: uint) -> EncodeResult { write!(self.writer, "{}", v) }
+ fn emit_u64(&mut self, v: u64) -> EncodeResult { write!(self.writer, "{}", v) }
+ fn emit_u32(&mut self, v: u32) -> EncodeResult { write!(self.writer, "{}", v) }
+ fn emit_u16(&mut self, v: u16) -> EncodeResult { write!(self.writer, "{}", v) }
+ fn emit_u8(&mut self, v: u8) -> EncodeResult { write!(self.writer, "{}", v) }
- fn emit_int(&mut self, v: int) -> EncodeResult { self.emit_f64(v as f64) }
- fn emit_i64(&mut self, v: i64) -> EncodeResult { self.emit_f64(v as f64) }
- fn emit_i32(&mut self, v: i32) -> EncodeResult { self.emit_f64(v as f64) }
- fn emit_i16(&mut self, v: i16) -> EncodeResult { self.emit_f64(v as f64) }
- fn emit_i8(&mut self, v: i8) -> EncodeResult { self.emit_f64(v as f64) }
+ fn emit_int(&mut self, v: int) -> EncodeResult { write!(self.writer, "{}", v) }
+ fn emit_i64(&mut self, v: i64) -> EncodeResult { write!(self.writer, "{}", v) }
+ fn emit_i32(&mut self, v: i32) -> EncodeResult { write!(self.writer, "{}", v) }
+ fn emit_i16(&mut self, v: i16) -> EncodeResult { write!(self.writer, "{}", v) }
+ fn emit_i8(&mut self, v: i8) -> EncodeResult { write!(self.writer, "{}", v) }
fn emit_bool(&mut self, v: bool) -> EncodeResult {
if v {
fn emit_enum_variant(&mut self,
name: &str,
- _: uint,
+ _id: uint,
cnt: uint,
f: |&mut PrettyEncoder<'a>| -> EncodeResult) -> EncodeResult {
if cnt == 0 {
($e:expr, Null) => ({
match $e {
Json::Null => Ok(()),
- other => Err(ExpectedError("Null".to_string(),
+ other => Err(ExpectedError("Null".into_string(),
format!("{}", other)))
}
});
($name:ident, $ty:ty) => {
fn $name(&mut self) -> DecodeResult<$ty> {
match self.pop() {
- Json::I64(f) => {
- match num::cast(f) {
- Some(f) => Ok(f),
- None => Err(ExpectedError("Number".to_string(), format!("{}", f))),
- }
- }
- Json::U64(f) => {
- match num::cast(f) {
- Some(f) => Ok(f),
- None => Err(ExpectedError("Number".to_string(), format!("{}", f))),
- }
- }
- Json::F64(f) => {
- match num::cast(f) {
- Some(f) => Ok(f),
- None => Err(ExpectedError("Number".to_string(), format!("{}", f))),
- }
- }
- Json::String(s) => {
- // re: #12967.. a type w/ numeric keys (ie HashMap<uint, V> etc)
- // is going to have a string here, as per JSON spec.
- match std::str::from_str(s.as_slice()) {
- Some(f) => Ok(f),
- None => Err(ExpectedError("Number".to_string(), s)),
- }
+ Json::I64(f) => match num::cast(f) {
+ Some(f) => Ok(f),
+ None => Err(ExpectedError("Number".into_string(), format!("{}", f))),
+ },
+ Json::U64(f) => match num::cast(f) {
+ Some(f) => Ok(f),
+ None => Err(ExpectedError("Number".into_string(), format!("{}", f))),
},
- value => Err(ExpectedError("Number".to_string(), format!("{}", value)))
+ Json::F64(f) => Err(ExpectedError("Integer".into_string(), format!("{}", f))),
+ // re: #12967.. a type w/ numeric keys (ie HashMap<uint, V> etc)
+ // is going to have a string here, as per JSON spec.
+ Json::String(s) => match std::str::from_str(s.as_slice()) {
+ Some(f) => Ok(f),
+ None => Err(ExpectedError("Number".into_string(), s)),
+ },
+ value => Err(ExpectedError("Number".into_string(), format!("{}", value))),
}
}
}
// is going to have a string here, as per JSON spec.
match std::str::from_str(s.as_slice()) {
Some(f) => Ok(f),
- None => Err(ExpectedError("Number".to_string(), s)),
+ None => Err(ExpectedError("Number".into_string(), s)),
}
},
Json::Null => Ok(f64::NAN),
- value => Err(ExpectedError("Number".to_string(), format!("{}", value)))
+ value => Err(ExpectedError("Number".into_string(), format!("{}", value)))
}
}
_ => ()
}
}
- Err(ExpectedError("single character string".to_string(), format!("{}", s)))
+ Err(ExpectedError("single character string".into_string(), format!("{}", s)))
}
fn read_str(&mut self) -> DecodeResult<string::String> {
let name = match self.pop() {
Json::String(s) => s,
Json::Object(mut o) => {
- let n = match o.remove(&"variant".to_string()) {
+ let n = match o.remove(&"variant".into_string()) {
Some(Json::String(s)) => s,
Some(val) => {
- return Err(ExpectedError("String".to_string(), format!("{}", val)))
+ return Err(ExpectedError("String".into_string(), format!("{}", val)))
}
None => {
- return Err(MissingFieldError("variant".to_string()))
+ return Err(MissingFieldError("variant".into_string()))
}
};
- match o.remove(&"fields".to_string()) {
+ match o.remove(&"fields".into_string()) {
Some(Json::Array(l)) => {
for field in l.into_iter().rev() {
self.stack.push(field);
}
},
Some(val) => {
- return Err(ExpectedError("Array".to_string(), format!("{}", val)))
+ return Err(ExpectedError("Array".into_string(), format!("{}", val)))
}
None => {
- return Err(MissingFieldError("fields".to_string()))
+ return Err(MissingFieldError("fields".into_string()))
}
}
n
}
json => {
- return Err(ExpectedError("String or Object".to_string(), format!("{}", json)))
+ return Err(ExpectedError("String or Object".into_string(), format!("{}", json)))
}
};
let idx = match names.iter()
#[test]
fn test_decode_option_malformed() {
check_err::<OptionData>("{ \"opt\": [] }",
- ExpectedError("Number".to_string(), "[]".to_string()));
+ ExpectedError("Number".into_string(), "[]".into_string()));
check_err::<OptionData>("{ \"opt\": false }",
- ExpectedError("Number".to_string(), "false".to_string()));
+ ExpectedError("Number".into_string(), "false".into_string()));
}
#[deriving(PartialEq, Encodable, Decodable, Show)]
#[test]
fn test_write_null() {
- assert_eq!(Null.to_string().into_string(), "null");
- assert_eq!(Null.to_pretty_str().into_string(), "null");
+ assert_eq!(Null.to_string(), "null");
+ assert_eq!(Null.to_pretty_str(), "null");
}
#[test]
fn test_write_i64() {
- assert_eq!(U64(0).to_string().into_string(), "0");
- assert_eq!(U64(0).to_pretty_str().into_string(), "0");
+ assert_eq!(U64(0).to_string(), "0");
+ assert_eq!(U64(0).to_pretty_str(), "0");
+
+ assert_eq!(U64(1234).to_string(), "1234");
+ assert_eq!(U64(1234).to_pretty_str(), "1234");
- assert_eq!(U64(1234).to_string().into_string(), "1234");
- assert_eq!(U64(1234).to_pretty_str().into_string(), "1234");
+ assert_eq!(I64(-5678).to_string(), "-5678");
+ assert_eq!(I64(-5678).to_pretty_str(), "-5678");
- assert_eq!(I64(-5678).to_string().into_string(), "-5678");
- assert_eq!(I64(-5678).to_pretty_str().into_string(), "-5678");
+ assert_eq!(U64(7650007200025252000).to_string(), "7650007200025252000");
+ assert_eq!(U64(7650007200025252000).to_pretty_str(), "7650007200025252000");
}
#[test]
fn test_write_f64() {
- assert_eq!(F64(3.0).to_string().into_string(), "3");
- assert_eq!(F64(3.0).to_pretty_str().into_string(), "3");
+ assert_eq!(F64(3.0).to_string(), "3.0");
+ assert_eq!(F64(3.0).to_pretty_str(), "3.0");
- assert_eq!(F64(3.1).to_string().into_string(), "3.1");
- assert_eq!(F64(3.1).to_pretty_str().into_string(), "3.1");
+ assert_eq!(F64(3.1).to_string(), "3.1");
+ assert_eq!(F64(3.1).to_pretty_str(), "3.1");
- assert_eq!(F64(-1.5).to_string().into_string(), "-1.5");
- assert_eq!(F64(-1.5).to_pretty_str().into_string(), "-1.5");
+ assert_eq!(F64(-1.5).to_string(), "-1.5");
+ assert_eq!(F64(-1.5).to_pretty_str(), "-1.5");
- assert_eq!(F64(0.5).to_string().into_string(), "0.5");
- assert_eq!(F64(0.5).to_pretty_str().into_string(), "0.5");
+ assert_eq!(F64(0.5).to_string(), "0.5");
+ assert_eq!(F64(0.5).to_pretty_str(), "0.5");
- assert_eq!(F64(f64::NAN).to_string().into_string(), "null");
- assert_eq!(F64(f64::NAN).to_pretty_str().into_string(), "null");
+ assert_eq!(F64(f64::NAN).to_string(), "null");
+ assert_eq!(F64(f64::NAN).to_pretty_str(), "null");
- assert_eq!(F64(f64::INFINITY).to_string().into_string(), "null");
- assert_eq!(F64(f64::INFINITY).to_pretty_str().into_string(), "null");
+ assert_eq!(F64(f64::INFINITY).to_string(), "null");
+ assert_eq!(F64(f64::INFINITY).to_pretty_str(), "null");
- assert_eq!(F64(f64::NEG_INFINITY).to_string().into_string(), "null");
- assert_eq!(F64(f64::NEG_INFINITY).to_pretty_str().into_string(), "null");
+ assert_eq!(F64(f64::NEG_INFINITY).to_string(), "null");
+ assert_eq!(F64(f64::NEG_INFINITY).to_pretty_str(), "null");
}
#[test]
fn test_write_str() {
- assert_eq!(String("".to_string()).to_string().into_string(), "\"\"");
- assert_eq!(String("".to_string()).to_pretty_str().into_string(), "\"\"");
+ assert_eq!(String("".into_string()).to_string(), "\"\"");
+ assert_eq!(String("".into_string()).to_pretty_str(), "\"\"");
- assert_eq!(String("foo".to_string()).to_string().into_string(), "\"foo\"");
- assert_eq!(String("foo".to_string()).to_pretty_str().into_string(), "\"foo\"");
+ assert_eq!(String("homura".into_string()).to_string(), "\"homura\"");
+ assert_eq!(String("madoka".into_string()).to_pretty_str(), "\"madoka\"");
}
#[test]
fn test_write_bool() {
- assert_eq!(Boolean(true).to_string().into_string(), "true");
- assert_eq!(Boolean(true).to_pretty_str().into_string(), "true");
+ assert_eq!(Boolean(true).to_string(), "true");
+ assert_eq!(Boolean(true).to_pretty_str(), "true");
- assert_eq!(Boolean(false).to_string().into_string(), "false");
- assert_eq!(Boolean(false).to_pretty_str().into_string(), "false");
+ assert_eq!(Boolean(false).to_string(), "false");
+ assert_eq!(Boolean(false).to_pretty_str(), "false");
}
#[test]
fn test_write_array() {
- assert_eq!(Array(vec![]).to_string().into_string(), "[]");
- assert_eq!(Array(vec![]).to_pretty_str().into_string(), "[]");
+ assert_eq!(Array(vec![]).to_string(), "[]");
+ assert_eq!(Array(vec![]).to_pretty_str(), "[]");
- assert_eq!(Array(vec![Boolean(true)]).to_string().into_string(), "[true]");
+ assert_eq!(Array(vec![Boolean(true)]).to_string(), "[true]");
assert_eq!(
- Array(vec![Boolean(true)]).to_pretty_str().into_string(),
+ Array(vec![Boolean(true)]).to_pretty_str(),
"\
[\n \
true\n\
let long_test_array = Array(vec![
Boolean(false),
Null,
- Array(vec![String("foo\nbar".to_string()), F64(3.5)])]);
+ Array(vec![String("foo\nbar".into_string()), F64(3.5)])]);
- assert_eq!(long_test_array.to_string().into_string(),
+ assert_eq!(long_test_array.to_string(),
"[false,null,[\"foo\\nbar\",3.5]]");
assert_eq!(
- long_test_array.to_pretty_str().into_string(),
+ long_test_array.to_pretty_str(),
"\
[\n \
false,\n \
#[test]
fn test_write_object() {
- assert_eq!(mk_object(&[]).to_string().into_string(), "{}");
- assert_eq!(mk_object(&[]).to_pretty_str().into_string(), "{}");
+ assert_eq!(mk_object(&[]).to_string(), "{}");
+ assert_eq!(mk_object(&[]).to_pretty_str(), "{}");
assert_eq!(
mk_object(&[
- ("a".to_string(), Boolean(true))
- ]).to_string().into_string(),
+ ("a".into_string(), Boolean(true))
+ ]).to_string(),
"{\"a\":true}"
);
assert_eq!(
- mk_object(&[("a".to_string(), Boolean(true))]).to_pretty_str(),
+ mk_object(&[("a".into_string(), Boolean(true))]).to_pretty_str(),
"\
{\n \
\"a\": true\n\
);
let complex_obj = mk_object(&[
- ("b".to_string(), Array(vec![
- mk_object(&[("c".to_string(), String("\x0c\r".to_string()))]),
- mk_object(&[("d".to_string(), String("".to_string()))])
+ ("b".into_string(), Array(vec![
+ mk_object(&[("c".into_string(), String("\x0c\r".into_string()))]),
+ mk_object(&[("d".into_string(), String("".into_string()))])
]))
]);
assert_eq!(
- complex_obj.to_string().into_string(),
+ complex_obj.to_string(),
"{\
\"b\":[\
{\"c\":\"\\f\\r\"},\
}"
);
assert_eq!(
- complex_obj.to_pretty_str().into_string(),
+ complex_obj.to_pretty_str(),
"\
{\n \
\"b\": [\n \
);
let a = mk_object(&[
- ("a".to_string(), Boolean(true)),
- ("b".to_string(), Array(vec![
- mk_object(&[("c".to_string(), String("\x0c\r".to_string()))]),
- mk_object(&[("d".to_string(), String("".to_string()))])
+ ("a".into_string(), Boolean(true)),
+ ("b".into_string(), Array(vec![
+ mk_object(&[("c".into_string(), String("\x0c\r".into_string()))]),
+ mk_object(&[("d".into_string(), String("".into_string()))])
]))
]);
"\"Dog\""
);
- let animal = Frog("Henry".to_string(), 349);
+ let animal = Frog("Henry".into_string(), 349);
assert_eq!(
with_str_writer(|writer| {
let mut encoder = Encoder::new(writer);
#[test]
fn test_write_some() {
- let value = Some("jodhpurs".to_string());
+ let value = Some("jodhpurs".into_string());
let s = with_str_writer(|writer| {
let mut encoder = Encoder::new(writer);
value.encode(&mut encoder).unwrap();
});
assert_eq!(s, "\"jodhpurs\"");
- let value = Some("jodhpurs".to_string());
+ let value = Some("jodhpurs".into_string());
let s = with_str_writer(|writer| {
let mut encoder = PrettyEncoder::new(writer);
value.encode(&mut encoder).unwrap();
let v: i64 = super::decode("9223372036854775807").unwrap();
assert_eq!(v, i64::MAX);
+
+ let res: DecodeResult<i64> = super::decode("765.25252");
+ assert_eq!(res, Err(ExpectedError("Integer".into_string(), "765.25252".into_string())));
}
#[test]
assert_eq!(from_str("\""), Err(SyntaxError(EOFWhileParsingString, 1, 2)));
assert_eq!(from_str("\"lol"), Err(SyntaxError(EOFWhileParsingString, 1, 5)));
- assert_eq!(from_str("\"\""), Ok(String("".to_string())));
- assert_eq!(from_str("\"foo\""), Ok(String("foo".to_string())));
- assert_eq!(from_str("\"\\\"\""), Ok(String("\"".to_string())));
- assert_eq!(from_str("\"\\b\""), Ok(String("\x08".to_string())));
- assert_eq!(from_str("\"\\n\""), Ok(String("\n".to_string())));
- assert_eq!(from_str("\"\\r\""), Ok(String("\r".to_string())));
- assert_eq!(from_str("\"\\t\""), Ok(String("\t".to_string())));
- assert_eq!(from_str(" \"foo\" "), Ok(String("foo".to_string())));
- assert_eq!(from_str("\"\\u12ab\""), Ok(String("\u12ab".to_string())));
- assert_eq!(from_str("\"\\uAB12\""), Ok(String("\uAB12".to_string())));
+ assert_eq!(from_str("\"\""), Ok(String("".into_string())));
+ assert_eq!(from_str("\"foo\""), Ok(String("foo".into_string())));
+ assert_eq!(from_str("\"\\\"\""), Ok(String("\"".into_string())));
+ assert_eq!(from_str("\"\\b\""), Ok(String("\x08".into_string())));
+ assert_eq!(from_str("\"\\n\""), Ok(String("\n".into_string())));
+ assert_eq!(from_str("\"\\r\""), Ok(String("\r".into_string())));
+ assert_eq!(from_str("\"\\t\""), Ok(String("\t".into_string())));
+ assert_eq!(from_str(" \"foo\" "), Ok(String("foo".into_string())));
+ assert_eq!(from_str("\"\\u12ab\""), Ok(String("\u12ab".into_string())));
+ assert_eq!(from_str("\"\\uAB12\""), Ok(String("\uAB12".into_string())));
}
#[test]
assert_eq!(t, (1u, 2, 3))
let t: (uint, string::String) = super::decode("[1, \"two\"]").unwrap();
- assert_eq!(t, (1u, "two".to_string()));
+ assert_eq!(t, (1u, "two".into_string()));
}
#[test]
assert_eq!(from_str("{}").unwrap(), mk_object(&[]));
assert_eq!(from_str("{\"a\": 3}").unwrap(),
- mk_object(&[("a".to_string(), U64(3))]));
+ mk_object(&[("a".into_string(), U64(3))]));
assert_eq!(from_str(
"{ \"a\": null, \"b\" : true }").unwrap(),
mk_object(&[
- ("a".to_string(), Null),
- ("b".to_string(), Boolean(true))]));
+ ("a".into_string(), Null),
+ ("b".into_string(), Boolean(true))]));
assert_eq!(from_str("\n{ \"a\": null, \"b\" : true }\n").unwrap(),
mk_object(&[
- ("a".to_string(), Null),
- ("b".to_string(), Boolean(true))]));
+ ("a".into_string(), Null),
+ ("b".into_string(), Boolean(true))]));
assert_eq!(from_str(
"{\"a\" : 1.0 ,\"b\": [ true ]}").unwrap(),
mk_object(&[
- ("a".to_string(), F64(1.0)),
- ("b".to_string(), Array(vec![Boolean(true)]))
+ ("a".into_string(), F64(1.0)),
+ ("b".into_string(), Array(vec![Boolean(true)]))
]));
assert_eq!(from_str(
"{\
]\
}").unwrap(),
mk_object(&[
- ("a".to_string(), F64(1.0)),
- ("b".to_string(), Array(vec![
+ ("a".into_string(), F64(1.0)),
+ ("b".into_string(), Array(vec![
Boolean(true),
- String("foo\nbar".to_string()),
+ String("foo\nbar".into_string()),
mk_object(&[
- ("c".to_string(), mk_object(&[("d".to_string(), Null)]))
+ ("c".into_string(), mk_object(&[("d".into_string(), Null)]))
])
]))
]));
v,
Outer {
inner: vec![
- Inner { a: (), b: 2, c: vec!["abc".to_string(), "xyz".to_string()] }
+ Inner { a: (), b: 2, c: vec!["abc".into_string(), "xyz".into_string()] }
]
}
);
assert_eq!(value, None);
let value: Option<string::String> = super::decode("\"jodhpurs\"").unwrap();
- assert_eq!(value, Some("jodhpurs".to_string()));
+ assert_eq!(value, Some("jodhpurs".into_string()));
}
#[test]
let s = "{\"variant\":\"Frog\",\"fields\":[\"Henry\",349]}";
let value: Animal = super::decode(s).unwrap();
- assert_eq!(value, Frog("Henry".to_string(), 349));
+ assert_eq!(value, Frog("Henry".into_string(), 349));
}
#[test]
\"fields\":[\"Henry\", 349]}}";
let mut map: TreeMap<string::String, Animal> = super::decode(s).unwrap();
- assert_eq!(map.remove(&"a".to_string()), Some(Dog));
- assert_eq!(map.remove(&"b".to_string()), Some(Frog("Henry".to_string(), 349)));
+ assert_eq!(map.remove(&"a".into_string()), Some(Dog));
+ assert_eq!(map.remove(&"b".into_string()), Some(Frog("Henry".into_string(), 349)));
}
#[test]
}
#[test]
fn test_decode_errors_struct() {
- check_err::<DecodeStruct>("[]", ExpectedError("Object".to_string(), "[]".to_string()));
+ check_err::<DecodeStruct>("[]", ExpectedError("Object".into_string(), "[]".into_string()));
check_err::<DecodeStruct>("{\"x\": true, \"y\": true, \"z\": \"\", \"w\": []}",
- ExpectedError("Number".to_string(), "true".to_string()));
+ ExpectedError("Number".into_string(), "true".into_string()));
check_err::<DecodeStruct>("{\"x\": 1, \"y\": [], \"z\": \"\", \"w\": []}",
- ExpectedError("Boolean".to_string(), "[]".to_string()));
+ ExpectedError("Boolean".into_string(), "[]".into_string()));
check_err::<DecodeStruct>("{\"x\": 1, \"y\": true, \"z\": {}, \"w\": []}",
- ExpectedError("String".to_string(), "{}".to_string()));
+ ExpectedError("String".into_string(), "{}".into_string()));
check_err::<DecodeStruct>("{\"x\": 1, \"y\": true, \"z\": \"\", \"w\": null}",
- ExpectedError("Array".to_string(), "null".to_string()));
+ ExpectedError("Array".into_string(), "null".into_string()));
check_err::<DecodeStruct>("{\"x\": 1, \"y\": true, \"z\": \"\"}",
- MissingFieldError("w".to_string()));
+ MissingFieldError("w".into_string()));
}
#[test]
fn test_decode_errors_enum() {
check_err::<DecodeEnum>("{}",
- MissingFieldError("variant".to_string()));
+ MissingFieldError("variant".into_string()));
check_err::<DecodeEnum>("{\"variant\": 1}",
- ExpectedError("String".to_string(), "1".to_string()));
+ ExpectedError("String".into_string(), "1".into_string()));
check_err::<DecodeEnum>("{\"variant\": \"A\"}",
- MissingFieldError("fields".to_string()));
+ MissingFieldError("fields".into_string()));
check_err::<DecodeEnum>("{\"variant\": \"A\", \"fields\": null}",
- ExpectedError("Array".to_string(), "null".to_string()));
+ ExpectedError("Array".into_string(), "null".into_string()));
check_err::<DecodeEnum>("{\"variant\": \"C\", \"fields\": []}",
- UnknownVariantError("C".to_string()));
+ UnknownVariantError("C".into_string()));
}
#[test]
};
let mut decoder = Decoder::new(json_obj);
let result: Result<HashMap<uint, bool>, DecoderError> = Decodable::decode(&mut decoder);
- assert_eq!(result, Err(ExpectedError("Number".to_string(), "a".to_string())));
+ assert_eq!(result, Err(ExpectedError("Number".into_string(), "a".into_string())));
}
fn assert_stream_equal(src: &str,
r#"{ "foo":"bar", "array" : [0, 1, 2, 3, 4, 5], "idents":[null,true,false]}"#,
vec![
(ObjectStart, vec![]),
- (StringValue("bar".to_string()), vec![Key("foo")]),
+ (StringValue("bar".into_string()), vec![Key("foo")]),
(ArrayStart, vec![Key("array")]),
(U64Value(0), vec![Key("array"), Index(0)]),
(U64Value(1), vec![Key("array"), Index(1)]),
(F64Value(1.0), vec![Key("a")]),
(ArrayStart, vec![Key("b")]),
(BooleanValue(true), vec![Key("b"), Index(0)]),
- (StringValue("foo\nbar".to_string()), vec![Key("b"), Index(1)]),
+ (StringValue("foo\nbar".into_string()), vec![Key("b"), Index(1)]),
(ObjectStart, vec![Key("b"), Index(2)]),
(ObjectStart, vec![Key("b"), Index(2), Key("c")]),
(NullValue, vec![Key("b"), Index(2), Key("c"), Key("d")]),
assert!(stack.last_is_index());
assert!(stack.get(0) == Index(1));
- stack.push_key("foo".to_string());
+ stack.push_key("foo".into_string());
assert!(stack.len() == 2);
assert!(stack.is_equal_to(&[Index(1), Key("foo")]));
assert!(stack.get(0) == Index(1));
assert!(stack.get(1) == Key("foo"));
- stack.push_key("bar".to_string());
+ stack.push_key("bar".into_string());
assert!(stack.len() == 3);
assert!(stack.is_equal_to(&[Index(1), Key("foo"), Key("bar")]));
let array3 = Array(vec!(U64(1), U64(2), U64(3)));
let object = {
let mut tree_map = TreeMap::new();
- tree_map.insert("a".to_string(), U64(1));
- tree_map.insert("b".to_string(), U64(2));
+ tree_map.insert("a".into_string(), U64(1));
+ tree_map.insert("b".into_string(), U64(2));
Object(tree_map)
};
assert_eq!((vec![1u, 2]).to_json(), array2);
assert_eq!(vec!(1u, 2, 3).to_json(), array3);
let mut tree_map = TreeMap::new();
- tree_map.insert("a".to_string(), 1u);
- tree_map.insert("b".to_string(), 2);
+ tree_map.insert("a".into_string(), 1u);
+ tree_map.insert("b".into_string(), 2);
assert_eq!(tree_map.to_json(), object);
let mut hash_map = HashMap::new();
- hash_map.insert("a".to_string(), 1u);
- hash_map.insert("b".to_string(), 2);
+ hash_map.insert("a".into_string(), 1u);
+ hash_map.insert("b".into_string(), 2);
assert_eq!(hash_map.to_json(), object);
assert_eq!(Some(15i).to_json(), I64(15));
assert_eq!(Some(15u).to_json(), U64(15));
}
fn big_json() -> string::String {
- let mut src = "[\n".to_string();
+ let mut src = "[\n".into_string();
for _ in range(0i, 500) {
src.push_str(r#"{ "a": true, "b": null, "c":3.1415, "d": "Hello world", "e": \
[1,2,3]},"#);
html_root_url = "http://doc.rust-lang.org/nightly/",
html_playground_url = "http://play.rust-lang.org/")]
#![allow(unknown_features)]
-#![feature(macro_rules, default_type_params, phase, slicing_syntax, globs)]
+#![feature(macro_rules, default_type_params, phase, slicing_syntax, globs, if_let)]
// test harness access
#[cfg(test)]
use core::kinds::Sized;
use fmt;
use iter::IteratorExt;
+use kinds::Copy;
use mem;
use option::Option;
use option::Option::{Some, None};
#[deriving(Clone, PartialEq, PartialOrd, Ord, Eq, Hash)]
pub struct Ascii { chr: u8 }
+impl Copy for Ascii {}
+
impl Ascii {
/// Converts an ascii character into a `u8`.
#[inline]
/// }
/// }
///
+/// impl Copy for Flags {}
+///
/// fn main() {
/// let e1 = FLAG_A | FLAG_C;
/// let e2 = FLAG_B | FLAG_C;
/// }
/// }
///
+/// impl Copy for Flags {}
+///
/// impl Flags {
/// pub fn clear(&mut self) {
/// self.bits = 0; // The `bits` field can be accessed from within the
#[cfg(test)]
#[allow(non_upper_case_globals)]
mod tests {
+ use kinds::Copy;
use hash;
use option::Option::{Some, None};
use ops::{BitOr, BitAnd, BitXor, Sub, Not};
}
}
+ impl Copy for Flags {}
+
bitflags! {
flags AnotherSetOfFlags: i8 {
const AnotherFlag = -1_i8,
}
}
+ impl Copy for AnotherSetOfFlags {}
+
#[test]
fn test_bits(){
assert_eq!(Flags::empty().bits(), 0x00000000);
use cmp;
use hash::{Hash, Hasher};
use iter::{Iterator, count};
-use kinds::{Sized, marker};
+use kinds::{Copy, Sized, marker};
use mem::{min_align_of, size_of};
use mem;
use num::{Int, UnsignedInt};
val: *mut V
}
+impl<K,V> Copy for RawBucket<K,V> {}
+
pub struct Bucket<K, V, M> {
raw: RawBucket<K, V>,
idx: uint,
table: M
}
+impl<K,V,M:Copy> Copy for Bucket<K,V,M> {}
+
pub struct EmptyBucket<K, V, M> {
raw: RawBucket<K, V>,
idx: uint,
Disconnected,
}
+impl Copy for TryRecvError {}
+
/// This enumeration is the list of the possible error outcomes for the
/// `SyncSender::try_send` method.
#[deriving(PartialEq, Clone, Show)]
use mem;
use ops::*;
use option::*;
+use option::Option::{None, Some};
use os;
use path::{Path,GenericPath};
use result::*;
+use result::Result::{Err, Ok};
use slice::{AsSlice,SlicePrelude};
use str;
use string::String;
use vec::Vec;
-pub struct DynamicLibrary { handle: *mut u8 }
+#[allow(missing_copy_implementations)]
+pub struct DynamicLibrary {
+ handle: *mut u8
+}
impl Drop for DynamicLibrary {
fn drop(&mut self) {
use c_str::{CString, ToCStr};
use libc;
+ use kinds::Copy;
use ptr;
use result::*;
+ use result::Result::{Err, Ok};
use string::String;
pub unsafe fn open_external<T: ToCStr>(filename: T) -> *mut u8 {
Local = 0,
}
+ impl Copy for Rtld {}
+
#[link_name = "dl"]
extern {
fn dlopen(filename: *const libc::c_char,
use fmt;
use int;
use iter::{Iterator, IteratorExt};
+use kinds::Copy;
use mem::transmute;
use ops::{BitOr, BitXor, BitAnd, Sub, Not};
use option::Option;
NoProgress,
}
+impl Copy for IoErrorKind {}
+
/// A trait that lets you add a `detail` to an IoError easily
trait UpdateIoError<T> {
/// Returns an IoError with updated description and detail
SeekCur,
}
+impl Copy for SeekStyle {}
+
/// An object implementing `Seek` internally has some form of cursor which can
/// be moved within a stream of bytes. The stream typically has a fixed size,
/// allowing seeking relative to either end.
Truncate,
}
+impl Copy for FileMode {}
+
/// Access permissions with which the file should be opened. `File`s
/// opened with `Read` will return an error if written to.
pub enum FileAccess {
ReadWrite,
}
+impl Copy for FileAccess {}
+
/// Different kinds of files which can be identified by a call to stat
#[deriving(PartialEq, Show, Hash, Clone)]
pub enum FileType {
Unknown,
}
+impl Copy for FileType {}
+
/// A structure used to describe metadata information about a file. This
/// structure is created through the `stat` method on a `Path`.
///
pub unstable: UnstableFileStat,
}
+impl Copy for FileStat {}
+
/// This structure represents all of the possible information which can be
/// returned from a `stat` syscall which is not contained in the `FileStat`
/// structure. This information is not necessarily platform independent, and may
pub gen: u64,
}
+impl Copy for UnstableFileStat {}
+
bitflags! {
#[doc = "A set of permissions for a file or directory is represented"]
#[doc = "by a set of flags which are or'd together."]
}
}
+impl Copy for FilePermission {}
+
impl Default for FilePermission {
#[inline]
fn default() -> FilePermission { FilePermission::empty() }
use iter::IteratorExt;
use io::{IoResult};
use io::net::ip::{SocketAddr, IpAddr};
+use kinds::Copy;
use option::Option;
use option::Option::{Some, None};
use sys;
Stream, Datagram, Raw
}
+impl Copy for SocketType {}
+
/// Flags which can be or'd into the `flags` field of a `Hint`. These are used
/// to manipulate how a query is performed.
///
V4Mapped,
}
+impl Copy for Flag {}
+
/// A transport protocol associated with either a hint or a return value of
/// `lookup`
pub enum Protocol {
TCP, UDP
}
+impl Copy for Protocol {}
+
/// This structure is used to provide hints when fetching addresses for a
/// remote host to control how the lookup is performed.
///
pub flags: uint,
}
+impl Copy for Hint {}
+
pub struct Info {
pub address: SocketAddr,
pub family: uint,
pub flags: uint,
}
+impl Copy for Info {}
+
/// Easy name resolution. Given a hostname, returns the list of IP addresses for
/// that hostname.
pub fn get_host_addresses(host: &str) -> IoResult<Vec<IpAddr>> {
pub use self::IpAddr::*;
use fmt;
+use kinds::Copy;
use io::{mod, IoResult, IoError};
use io::net;
use iter::{Iterator, IteratorExt};
Ipv6Addr(u16, u16, u16, u16, u16, u16, u16, u16)
}
+impl Copy for IpAddr {}
+
impl fmt::Show for IpAddr {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
match *self {
pub port: Port,
}
+impl Copy for SocketAddr {}
+
impl fmt::Show for SocketAddr {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self.ip {
CreatePipe(bool /* readable */, bool /* writable */),
}
+impl Copy for StdioContainer {}
+
/// Describes the result of a process after it has terminated.
/// Note that Windows have no signals, so the result is usually ExitStatus.
#[deriving(PartialEq, Eq, Clone)]
ExitSignal(int),
}
+impl Copy for ProcessExit {}
+
impl fmt::Show for ProcessExit {
/// Format a ProcessExit enum, to nicely present the information.
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
/// A `Writer` which ignores bytes written to it, like /dev/null.
pub struct NullWriter;
+impl Copy for NullWriter {}
+
impl Writer for NullWriter {
#[inline]
fn write(&mut self, _buf: &[u8]) -> io::IoResult<()> { Ok(()) }
/// A `Reader` which returns an infinite stream of 0 bytes, like /dev/zero.
pub struct ZeroReader;
+impl Copy for ZeroReader {}
+
impl Reader for ZeroReader {
#[inline]
fn read(&mut self, buf: &mut [u8]) -> io::IoResult<uint> {
/// A `Reader` which is always at EOF, like /dev/null.
pub struct NullReader;
+impl Copy for NullReader {}
+
impl Reader for NullReader {
#[inline]
fn read(&mut self, _buf: &mut [u8]) -> io::IoResult<uint> {
use char;
use char::Char;
+use kinds::Copy;
use num;
use num::{Int, Float, FPNaN, FPInfinite, ToPrimitive};
use slice::{SlicePrelude, CloneSliceAllocPrelude};
ExpBin,
}
+impl Copy for ExponentFormat {}
+
/// The number of digits used for emitting the fractional part of a number, if
/// any.
pub enum SignificantDigits {
DigExact(uint)
}
+impl Copy for SignificantDigits {}
+
/// How to emit the sign of a number.
pub enum SignFormat {
/// No sign will be printed. The exponent sign will also be emitted.
SignAll,
}
-/// Converts an integral number to its string representation as a byte vector.
-/// This is meant to be a common base implementation for all integral string
-/// conversion functions like `to_string()` or `to_str_radix()`.
-///
-/// # Arguments
-///
-/// - `num` - The number to convert. Accepts any number that
-/// implements the numeric traits.
-/// - `radix` - Base to use. Accepts only the values 2-36.
-/// - `sign` - How to emit the sign. Options are:
-/// - `SignNone`: No sign at all. Basically emits `abs(num)`.
-/// - `SignNeg`: Only `-` on negative values.
-/// - `SignAll`: Both `+` on positive, and `-` on negative numbers.
-/// - `f` - a callback which will be invoked for each ascii character
-/// which composes the string representation of this integer
-///
-/// # Panics
-///
-/// - Panics if `radix` < 2 or `radix` > 36.
+impl Copy for SignFormat {}
+
+/**
+ * Converts an integral number to its string representation as a byte vector.
+ * This is meant to be a common base implementation for all integral string
+ * conversion functions like `to_string()` or `to_str_radix()`.
+ *
+ * # Arguments
+ * - `num` - The number to convert. Accepts any number that
+ * implements the numeric traits.
+ * - `radix` - Base to use. Accepts only the values 2-36.
+ * - `sign` - How to emit the sign. Options are:
+ * - `SignNone`: No sign at all. Basically emits `abs(num)`.
+ * - `SignNeg`: Only `-` on negative values.
+ * - `SignAll`: Both `+` on positive, and `-` on negative numbers.
+ * - `f` - a callback which will be invoked for each ascii character
+ * which composes the string representation of this integer
+ *
+ * # Return value
+ * A tuple containing the byte vector, and a boolean flag indicating
+ * whether it represents a special value like `inf`, `-inf`, `NaN` or not.
+ * It returns a tuple because there can be ambiguity between a special value
+ * and a number representation at higher bases.
+ *
+ * # Failure
+ * - Fails if `radix` < 2 or `radix` > 36.
+ */
fn int_to_str_bytes_common<T: Int>(num: T, radix: uint, sign: SignFormat, f: |u8|) {
assert!(2 <= radix && radix <= 36);
use fmt;
use io::{IoResult, IoError};
use iter::{Iterator, IteratorExt};
+use kinds::Copy;
use libc::{c_void, c_int};
use libc;
use boxed::Box;
}
#[cfg(windows)]
-pub mod windows {
+pub mod windoze {
use libc::types::os::arch::extra::DWORD;
use libc;
use option::Option;
pub fn getenv(n: &str) -> Option<String> {
unsafe {
with_env_lock(|| {
- use os::windows::{fill_utf16_buf_and_decode};
+ use os::windoze::{fill_utf16_buf_and_decode};
let mut n: Vec<u16> = n.utf16_units().collect();
n.push(0);
fill_utf16_buf_and_decode(|buf, sz| {
pub writer: c_int,
}
+impl Copy for Pipe {}
+
/// Creates a new low-level OS in-memory pipe.
///
/// This function can fail to succeed if there are no more resources available
#[cfg(windows)]
fn load_self() -> Option<Vec<u8>> {
unsafe {
- use os::windows::fill_utf16_buf_and_decode;
+ use os::windoze::fill_utf16_buf_and_decode;
fill_utf16_buf_and_decode(|buf, sz| {
libc::GetModuleFileNameW(0u as libc::DWORD, buf, sz)
}).map(|s| s.into_string().into_bytes())
kind: MemoryMapKind,
}
+#[cfg(not(stage0))]
+impl Copy for MemoryMap {}
+
/// Type of memory map
pub enum MemoryMapKind {
/// Virtual memory map. Usually used to change the permissions of a given
MapVirtual
}
+impl Copy for MemoryMapKind {}
+
/// Options the memory map is created with
pub enum MapOption {
/// The memory should be readable
/// Create a map for a specific address range. Corresponds to `MAP_FIXED` on
/// POSIX.
MapAddr(*const u8),
+ /// Create a memory mapping for a file with a given HANDLE.
+ #[cfg(windows)]
+ MapFd(libc::HANDLE),
/// Create a memory mapping for a file with a given fd.
+ #[cfg(not(windows))]
MapFd(c_int),
/// When using `MapFd`, the start of the map is `uint` bytes from the start
/// of the file.
MapNonStandardFlags(c_int),
}
+impl Copy for MapOption {}
+
/// Possible errors when creating a map.
pub enum MapError {
/// ## The following are POSIX-specific
ErrMapViewOfFile(uint)
}
+impl Copy for MapError {}
+
impl fmt::Show for MapError {
fn fmt(&self, out: &mut fmt::Formatter) -> fmt::Result {
let str = match *self {
let mut readable = false;
let mut writable = false;
let mut executable = false;
- let mut fd: c_int = -1;
+ let mut handle: HANDLE = libc::INVALID_HANDLE_VALUE;
let mut offset: uint = 0;
let len = round_up(min_len, page_size());
MapWritable => { writable = true; },
MapExecutable => { executable = true; }
MapAddr(addr_) => { lpAddress = addr_ as LPVOID; },
- MapFd(fd_) => { fd = fd_; },
+ MapFd(handle_) => { handle = handle_; },
MapOffset(offset_) => { offset = offset_; },
MapNonStandardFlags(..) => {}
}
}
let flProtect = match (executable, readable, writable) {
- (false, false, false) if fd == -1 => libc::PAGE_NOACCESS,
+ (false, false, false) if handle == libc::INVALID_HANDLE_VALUE => libc::PAGE_NOACCESS,
(false, true, false) => libc::PAGE_READONLY,
(false, true, true) => libc::PAGE_READWRITE,
- (true, false, false) if fd == -1 => libc::PAGE_EXECUTE,
+ (true, false, false) if handle == libc::INVALID_HANDLE_VALUE => libc::PAGE_EXECUTE,
(true, true, false) => libc::PAGE_EXECUTE_READ,
(true, true, true) => libc::PAGE_EXECUTE_READWRITE,
_ => return Err(ErrUnsupProt)
};
- if fd == -1 {
+ if handle == libc::INVALID_HANDLE_VALUE {
if offset != 0 {
return Err(ErrUnsupOffset);
}
// we should never get here.
};
unsafe {
- let hFile = libc::get_osfhandle(fd) as HANDLE;
+ let hFile = handle;
let mapping = libc::CreateFileMappingW(hFile,
ptr::null_mut(),
flProtect,
#[test]
fn memory_map_file() {
- use result::Result::{Ok, Err};
+ use libc;
use os::*;
- use libc::*;
- use io::fs;
-
- #[cfg(unix)]
- fn lseek_(fd: c_int, size: uint) {
- unsafe {
- assert!(lseek(fd, size as off_t, SEEK_SET) == size as off_t);
- }
+ use io::fs::{File, unlink};
+ use io::SeekStyle::SeekSet;
+ use io::FileMode::Open;
+ use io::FileAccess::ReadWrite;
+
+ #[cfg(not(windows))]
+ fn get_fd(file: &File) -> libc::c_int {
+ use os::unix::AsRawFd;
+ file.as_raw_fd()
}
+
#[cfg(windows)]
- fn lseek_(fd: c_int, size: uint) {
- unsafe {
- assert!(lseek(fd, size as c_long, SEEK_SET) == size as c_long);
- }
+ fn get_fd(file: &File) -> libc::HANDLE {
+ use os::windows::AsRawHandle;
+ file.as_raw_handle()
}
let mut path = tmpdir();
path.push("mmap_file.tmp");
let size = MemoryMap::granularity() * 2;
+ let mut file = File::open_mode(&path, Open, ReadWrite).unwrap();
+ file.seek(size as i64, SeekSet);
+ file.write_u8(0);
- let fd = unsafe {
- let fd = path.with_c_str(|path| {
- open(path, O_CREAT | O_RDWR | O_TRUNC, S_IRUSR | S_IWUSR)
- });
- lseek_(fd, size);
- "x".with_c_str(|x| assert!(write(fd, x as *const c_void, 1) == 1));
- fd
- };
- let chunk = match MemoryMap::new(size / 2, &[
+ let chunk = MemoryMap::new(size / 2, &[
MapReadable,
MapWritable,
- MapFd(fd),
+ MapFd(get_fd(&file)),
MapOffset(size / 2)
- ]) {
- Ok(chunk) => chunk,
- Err(msg) => panic!("{}", msg)
- };
+ ]).unwrap();
assert!(chunk.len > 0);
unsafe {
*chunk.data = 0xbe;
assert!(*chunk.data == 0xbe);
- close(fd);
}
drop(chunk);
- fs::unlink(&path).unwrap();
+ unlink(&path).unwrap();
}
#[test]
use io::Writer;
use iter::{AdditiveIterator, DoubleEndedIteratorExt, Extend};
use iter::{Iterator, IteratorExt, Map};
+use kinds::Copy;
use mem;
use option::Option;
use option::Option::{Some, None};
DiskPrefix
}
+impl Copy for PathPrefix {}
+
fn parse_prefix<'a>(mut path: &'a str) -> Option<PathPrefix> {
if path.starts_with("\\\\") {
// \\
//! circle, both centered at the origin. Since the area of a unit circle is π,
//! we have:
//!
-//! ```notrust
+//! ```text
//! (area of unit circle) / (area of square) = π / 4
//! ```
//!
use clone::Clone;
use io::IoResult;
use iter::{Iterator, IteratorExt};
+use kinds::Copy;
use mem;
use rc::Rc;
use result::Result::{Ok, Err};
/// The standard RNG. This is designed to be efficient on the current
/// platform.
-pub struct StdRng { rng: IsaacWordRng }
+pub struct StdRng {
+ rng: IsaacWordRng,
+}
+
+impl Copy for StdRng {}
impl StdRng {
/// Create a randomly seeded instance of `StdRng`.
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-use option::None;
+use option::Option::None;
use rustrt::task::Task;
use rustrt::local::Local;
}
unsafe fn lazy_init(&self) -> uint {
- let key = imp::create(self.dtor);
+ // POSIX allows the key created here to be 0, but the compare_and_swap
+ // below relies on using 0 as a sentinel value to check who won the
+ // race to set the shared TLS key. As far as I know, there is no
+ // guaranteed value that cannot be returned as a posix_key_create key,
+ // so there is no value we can initialize the inner key with to
+ // prove that it has not yet been set. As such, we'll continue using a
+ // value of 0, but with some gyrations to make sure we have a non-0
+ // value returned from the creation routine.
+ // FIXME: this is clearly a hack, and should be cleaned up.
+ let key1 = imp::create(self.dtor);
+ let key = if key1 != 0 {
+ key1
+ } else {
+ let key2 = imp::create(self.dtor);
+ imp::destroy(key1);
+ key2
+ };
assert!(key != 0);
match self.inner.key.compare_and_swap(0, key as uint, atomic::SeqCst) {
// The CAS succeeded, so we've created the actual key
use c_str::CString;
use mem;
-use os::windows::fill_utf16_buf_and_decode;
+use os::windoze::fill_utf16_buf_and_decode;
use path;
use ptr;
use str;
#![experimental]
use {fmt, i64};
+use kinds::Copy;
use ops::{Add, Sub, Mul, Div, Neg};
use option::Option;
use option::Option::{Some, None};
nanos: (i64::MAX % MILLIS_PER_SEC) as i32 * NANOS_PER_MILLI
};
+impl Copy for Duration {}
+
impl Duration {
/// Makes a new `Duration` with given number of weeks.
/// Equivalent to `Duration::seconds(weeks * 7 * 24 * 60 * 60), with overflow checks.
use std::fmt;
#[deriving(PartialEq)]
-pub enum Os { OsWindows, OsMacos, OsLinux, OsAndroid, OsFreebsd, OsiOS,
- OsDragonfly }
+pub enum Os {
+ OsWindows,
+ OsMacos,
+ OsLinux,
+ OsAndroid,
+ OsFreebsd,
+ OsiOS,
+ OsDragonfly,
+}
+
+impl Copy for Os {}
#[deriving(PartialEq, Eq, Hash, Encodable, Decodable, Clone)]
pub enum Abi {
RustCall,
}
+impl Copy for Abi {}
+
#[allow(non_camel_case_types)]
#[deriving(PartialEq)]
pub enum Architecture {
Mipsel
}
+impl Copy for Architecture {}
+
pub struct AbiData {
abi: Abi,
name: &'static str,
}
+impl Copy for AbiData {}
+
pub enum AbiArchitecture {
/// Not a real ABI (e.g., intrinsic)
RustArch,
Archs(u32)
}
+#[allow(non_upper_case_globals)]
+impl Copy for AbiArchitecture {}
+
#[allow(non_upper_case_globals)]
static AbiDatas: &'static [AbiData] = &[
// Platform-specific ABIs
pub ctxt: SyntaxContext
}
+impl Copy for Ident {}
+
impl Ident {
/// Construct an identifier with the given name and an empty context:
pub fn new(name: Name) -> Ident { Ident {name: name, ctxt: EMPTY_CTXT}}
#[deriving(Eq, Ord, PartialEq, PartialOrd, Hash, Encodable, Decodable, Clone)]
pub struct Name(pub u32);
+impl Copy for Name {}
+
impl Name {
pub fn as_str<'a>(&'a self) -> &'a str {
unsafe {
pub name: Name
}
+impl Copy for Lifetime {}
+
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
pub struct LifetimeDef {
pub lifetime: Lifetime,
pub node: NodeId,
}
+impl Copy for DefId {}
+
/// Item definitions in the currently-compiled crate would have the CrateNum
/// LOCAL_CRATE in their DefId.
pub const LOCAL_CRATE: CrateNum = 0;
BindByValue(Mutability),
}
+impl Copy for BindingMode {}
+
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
pub enum PatWildKind {
/// Represents the wildcard pattern `_`
PatWildMulti,
}
+impl Copy for PatWildKind {}
+
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
pub enum Pat_ {
/// Represents a wildcard pattern (either `_` or `..`)
MutImmutable,
}
+impl Copy for Mutability {}
+
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
pub enum BinOp {
BiAdd,
BiGt,
}
+#[cfg(not(stage0))]
+impl Copy for BinOp {}
+
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
pub enum UnOp {
UnUniq,
UnNeg
}
+impl Copy for UnOp {}
+
pub type Stmt = Spanned<Stmt_>;
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
LocalFor,
}
+impl Copy for LocalSource {}
+
// FIXME (pending discussion of #1697, #2178...): local should really be
// a refinement on pat.
/// Local represents a `let` statement, e.g., `let <pat>:<ty> = <expr>;`
UnsafeBlock(UnsafeSource),
}
+impl Copy for BlockCheckMode {}
+
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
pub enum UnsafeSource {
CompilerGenerated,
UserProvided,
}
+impl Copy for UnsafeSource {}
+
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
pub struct Expr {
pub id: NodeId,
MatchWhileLetDesugar,
}
+impl Copy for MatchSource {}
+
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
pub enum CaptureClause {
CaptureByValue,
CaptureByRef,
}
+impl Copy for CaptureClause {}
+
/// A delimited sequence of token trees
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
pub struct Delimited {
OneOrMore,
}
+impl Copy for KleeneOp {}
+
/// When the main rust parser encounters a syntax-extension invocation, it
/// parses the arguments to the invocation as a token-tree. This is a very
/// loose structure, such that all sorts of different AST-fragments can
RawStr(uint)
}
+impl Copy for StrStyle {}
+
pub type Lit = Spanned<Lit_>;
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
Plus
}
-impl<T: Int> Sign {
+impl Copy for Sign {}
+
+impl<T> Sign where T: Int {
pub fn new(n: T) -> Sign {
if n < Int::zero() {
Minus
UnsuffixedIntLit(Sign)
}
+impl Copy for LitIntType {}
+
impl LitIntType {
pub fn suffix_len(&self) -> uint {
match *self {
TyI64,
}
+impl Copy for IntTy {}
+
impl fmt::Show for IntTy {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", ast_util::int_ty_to_string(*self, None))
TyU64,
}
+impl Copy for UintTy {}
+
impl UintTy {
pub fn suffix_len(&self) -> uint {
match *self {
TyF64,
}
+impl Copy for FloatTy {}
+
impl fmt::Show for FloatTy {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", ast_util::float_ty_to_string(*self))
TyChar
}
+impl Copy for PrimTy {}
+
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
pub enum Onceness {
Once,
Many
}
+impl Copy for Onceness {}
+
impl fmt::Show for Onceness {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
AsmIntel
}
+impl Copy for AsmDialect {}
+
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
pub struct InlineAsm {
pub asm: InternedString,
NormalFn,
}
+impl Copy for FnStyle {}
+
impl fmt::Show for FnStyle {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
PathListMod { id: NodeId }
}
+impl Copy for PathListItem_ {}
+
impl PathListItem_ {
pub fn id(&self) -> NodeId {
match *self {
AttrInner,
}
+impl Copy for AttrStyle {}
+
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
pub struct AttrId(pub uint);
+impl Copy for AttrId {}
+
/// Doc-comments are promoted to attributes that have is_sugared_doc = true
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
pub struct Attribute_ {
Inherited,
}
+impl Copy for Visibility {}
+
impl Visibility {
pub fn inherit_from(&self, parent_visibility: Visibility) -> Visibility {
match self {
UnnamedField(Visibility),
}
+impl Copy for StructFieldKind {}
+
impl StructFieldKind {
pub fn is_unnamed(&self) -> bool {
match *self {
FnOnceUnboxedClosureKind,
}
+impl Copy for UnboxedClosureKind {}
+
/// The data we save and restore about an inlined item or method. This is not
/// part of the AST that we parse from a file, but it becomes part of the tree
/// that we trans.
/// To construct one, use the `Code::from_node` function.
pub struct FnLikeNode<'a> { node: ast_map::Node<'a> }
+impl<'a> Copy for FnLikeNode<'a> {}
+
/// MaybeFnLike wraps a method that indicates if an object
/// corresponds to some FnLikeNode.
pub trait MaybeFnLike { fn is_fn_like(&self) -> bool; }
BlockCode(&'a Block),
}
+impl<'a> Copy for Code<'a> {}
+
impl<'a> Code<'a> {
pub fn id(&self) -> ast::NodeId {
match *self {
PathName(Name)
}
+impl Copy for PathElem {}
+
impl PathElem {
pub fn name(&self) -> Name {
match *self {
NodeLifetime(&'ast Lifetime),
}
+impl<'ast> Copy for Node<'ast> {}
+
/// Represents an entry and its parent Node ID
/// The odd layout is to bring down the total size.
#[deriving(Show)]
RootInlinedParent(&'ast InlinedParent)
}
+impl<'ast> Copy for MapEntry<'ast> {}
+
impl<'ast> Clone for MapEntry<'ast> {
fn clone(&self) -> MapEntry<'ast> {
*self
pub max: NodeId,
}
+impl Copy for IdRange {}
+
impl IdRange {
pub fn max() -> IdRange {
IdRange {
InlineNever,
}
+impl Copy for InlineAttr {}
+
/// Determine what `#[inline]` attribute is present in `attrs`, if any.
pub fn find_inline_attr(attrs: &[Attribute]) -> InlineAttr {
// FIXME (#2809)---validate the usage of #[inline] and #[inline]
Locked
}
+impl Copy for StabilityLevel {}
+
pub fn find_stability_generic<'a,
AM: AttrMetaMethods,
I: Iterator<&'a AM>>
ReprPacked,
}
+impl Copy for ReprAttr {}
+
impl ReprAttr {
pub fn is_ffi_safe(&self) -> bool {
match *self {
UnsignedInt(ast::UintTy)
}
+impl Copy for IntType {}
+
impl IntType {
#[inline]
pub fn is_signed(self) -> bool {
#[deriving(Clone, PartialEq, Eq, Hash, PartialOrd, Show)]
pub struct BytePos(pub u32);
+impl Copy for BytePos {}
+
/// A character offset. Because of multibyte utf8 characters, a byte offset
/// is not equivalent to a character offset. The CodeMap will convert BytePos
/// values to CharPos values as necessary.
#[deriving(PartialEq, Hash, PartialOrd, Show)]
pub struct CharPos(pub uint);
+impl Copy for CharPos {}
+
// FIXME: Lots of boilerplate in these impls, but so far my attempts to fix
// have been unsuccessful
pub expn_id: ExpnId
}
+impl Copy for Span {}
+
pub const DUMMY_SP: Span = Span { lo: BytePos(0), hi: BytePos(0), expn_id: NO_EXPANSION };
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
pub span: Span,
}
+impl<T:Copy> Copy for Spanned<T> {}
+
impl PartialEq for Span {
fn eq(&self, other: &Span) -> bool {
return (*self).lo == (*other).lo && (*self).hi == (*other).hi;
MacroBang
}
+impl Copy for MacroFormat {}
+
#[deriving(Clone, Hash, Show)]
pub struct NameAndSpan {
/// The name of the macro that was invoked to create the thing
#[deriving(PartialEq, Eq, Clone, Show, Hash, Encodable, Decodable)]
pub struct ExpnId(u32);
+impl Copy for ExpnId {}
+
pub const NO_EXPANSION: ExpnId = ExpnId(-1);
impl ExpnId {
pub bytes: uint,
}
+impl Copy for MultiByteChar {}
+
/// A single source in the CodeMap
pub struct FileMap {
/// The name of the file that the source came from, source that doesn't
FileLine(Span),
}
+impl Copy for RenderSpan {}
+
impl RenderSpan {
fn span(self) -> Span {
match self {
Never
}
+impl Copy for ColorConfig {}
+
pub trait Emitter {
fn emit(&mut self, cmsp: Option<(&codemap::CodeMap, Span)>,
msg: &str, code: Option<&str>, lvl: Level);
/// how a rustc task died (if so desired).
pub struct FatalError;
+impl Copy for FatalError {}
+
/// Signifies that the compiler died with an explicit call to `.bug`
/// or `.span_bug` rather than a failed assertion, etc.
pub struct ExplicitBug;
+impl Copy for ExplicitBug {}
+
/// A span-handler is like a handler but also
/// accepts span information for source-location
/// reporting.
Help,
}
+impl Copy for Level {}
+
impl fmt::Show for Level {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use std::fmt::Show;
meta_item: &ast::MetaItem,
item: &ast::Item,
push: |P<ast::Item>|) {
- (*self)(ecx, sp, meta_item, item, push)
+ self.clone()(ecx, sp, meta_item, item, push)
}
}
meta_item: &ast::MetaItem,
item: P<ast::Item>)
-> P<ast::Item> {
- (*self)(ecx, span, meta_item, item)
+ self.clone()(ecx, span, meta_item, item)
}
}
span: Span,
token_tree: &[ast::TokenTree])
-> Box<MacResult+'cx> {
- (*self)(ecx, span, token_tree)
+ self.clone()(ecx, span, token_tree)
}
}
ident: ast::Ident,
token_tree: Vec<ast::TokenTree> )
-> Box<MacResult+'cx> {
- (*self)(cx, sp, ident, token_tree)
+ self.clone()(cx, sp, ident, token_tree)
}
}
span: Span
}
+impl Copy for DummyResult {}
+
impl DummyResult {
/// Create a default MacResult that can be anything.
///
PartialCmpOp, LtOp, LeOp, GtOp, GeOp,
}
+impl Copy for OrderingOp {}
+
pub fn some_ordering_collapsed(cx: &mut ExtCtxt,
span: Span,
op: OrderingOp,
cx.ident_of("cmp"),
cx.ident_of("Equal")));
+ let cmp_path = vec![
+ cx.ident_of("std"),
+ cx.ident_of("cmp"),
+ cx.ident_of("Ord"),
+ cx.ident_of("cmp"),
+ ];
+
/*
Builds:
- let __test = self_field1.cmp(&other_field2);
+ let __test = ::std::cmp::Ord::cmp(&self_field1, &other_field1);
if other == ::std::cmp::Ordering::Equal {
- let __test = self_field2.cmp(&other_field2);
+ let __test = ::std::cmp::Ord::cmp(&self_field2, &other_field2);
if __test == ::std::cmp::Ordering::Equal {
...
} else {
FIXME #6449: These `if`s could/should be `match`es.
*/
- cs_same_method_fold(
+ cs_fold(
// foldr nests the if-elses correctly, leaving the first field
// as the outermost one, and the last as the innermost.
false,
- |cx, span, old, new| {
+ |cx, span, old, self_f, other_fs| {
// let __test = new;
// if __test == ::std::cmp::Ordering::Equal {
// old
// __test
// }
+ let new = {
+ let other_f = match other_fs {
+ [ref o_f] => o_f,
+ _ => cx.span_bug(span, "not exactly 2 arguments in `deriving(PartialOrd)`"),
+ };
+
+ let args = vec![
+ cx.expr_addr_of(span, self_f),
+ cx.expr_addr_of(span, other_f.clone()),
+ ];
+
+ cx.expr_call_global(span, cmp_path.clone(), args)
+ };
+
let assign = cx.stmt_let(span, false, test_id, new);
let cond = cx.expr_binary(span, ast::BiEq,
IllegalCtxt
}
+impl Copy for SyntaxContext_ {}
+
/// A list of ident->name renamings
pub type RenameList = Vec<(Ident, Name)>;
// to bootstrap fix for #5723.
("issue_5723_bootstrap", Accepted),
+ // A way to temporary opt out of opt in copy. This will *never* be accepted.
+ ("opt_out_copy", Active),
+
// These are used to test this portion of the compiler, they don't actually
// mean anything
("test_accepted_feature", Accepted),
pub import_shadowing: bool,
pub visible_private_types: bool,
pub quote: bool,
+ pub opt_out_copy: bool,
}
+impl Copy for Features {}
+
impl Features {
pub fn new() -> Features {
Features {
import_shadowing: false,
visible_private_types: false,
quote: false,
+ opt_out_copy: false,
}
}
}
import_shadowing: cx.has_feature("import_shadowing"),
visible_private_types: cx.has_feature("visible_private_types"),
quote: cx.has_feature("quote"),
+ opt_out_copy: cx.has_feature("opt_out_copy"),
},
unknown_features)
}
BlankLine,
}
+impl Copy for CommentStyle {}
+
#[deriving(Clone)]
pub struct Comment {
pub style: CommentStyle,
}
}
- // SNAP 361baab
+ // SNAP c9f6d69
#[allow(unused)]
fn old_escape_warning(&mut self, sp: Span) {
self.span_diagnostic
self.scan_unicode_escape(delim)
} else {
let res = self.scan_hex_digits(4u, delim, false);
- // SNAP 361baab
+ // SNAP c9f6d69
//let sp = codemap::mk_sp(escaped_pos, self.last_pos);
//self.old_escape_warning(sp);
res
}
'U' if !ascii_only => {
let res = self.scan_hex_digits(8u, delim, false);
- // SNAP 361baab
+ // SNAP c9f6d69
//let sp = codemap::mk_sp(escaped_pos, self.last_pos);
//self.old_escape_warning(sp);
res
ObsoleteExternCrateRenaming,
}
+impl Copy for ObsoleteSyntax {}
+
pub trait ParserObsoleteMethods {
/// Reports an obsolete syntax non-fatal error.
fn obsolete(&mut self, sp: Span, kind: ObsoleteSyntax);
}
}
+impl Copy for Restrictions {}
+
type ItemInfo = (Ident, Item_, Option<Vec<Attribute> >);
/// How to parse a path. There are four different kinds of paths, all of which
LifetimeAndTypesWithColons,
}
+impl Copy for PathParsingMode {}
+
enum ItemOrViewItem {
/// Indicates a failure to parse any kind of item. The attributes are
/// returned.
Shr,
}
+impl Copy for BinOpToken {}
+
/// A delimeter token
#[deriving(Clone, Encodable, Decodable, PartialEq, Eq, Hash, Show)]
pub enum DelimToken {
Brace,
}
+impl Copy for DelimToken {}
+
#[deriving(Clone, Encodable, Decodable, PartialEq, Eq, Hash, Show)]
pub enum IdentStyle {
/// `::` follows the identifier with no whitespace in-between.
}
}
+#[cfg(not(stage0))]
+impl Copy for Lit {}
+
+#[cfg(not(stage0))]
+impl Copy for IdentStyle {}
+
#[allow(non_camel_case_types)]
#[deriving(Clone, Encodable, Decodable, PartialEq, Eq, Hash, Show)]
pub enum Token {
$( $rk_variant, )*
}
+ impl Copy for Keyword {}
+
impl Keyword {
pub fn to_name(&self) -> ast::Name {
match *self {
Inconsistent,
}
+impl Copy for Breaks {}
+
#[deriving(Clone)]
pub struct BreakToken {
offset: int,
blank_space: int
}
+impl Copy for BreakToken {}
+
#[deriving(Clone)]
pub struct BeginToken {
offset: int,
breaks: Breaks
}
+impl Copy for BeginToken {}
+
#[deriving(Clone)]
pub enum Token {
String(string::String, int),
Broken(Breaks),
}
+impl Copy for PrintStackBreak {}
+
pub struct PrintStackElem {
offset: int,
pbreak: PrintStackBreak
}
+impl Copy for PrintStackElem {}
+
static SIZE_INFINITY: int = 0xffff;
pub fn mk_printer(out: Box<io::Writer+'static>, linewidth: uint) -> Printer {
pub struct NoAnn;
+impl Copy for NoAnn {}
+
impl PpAnn for NoAnn {}
pub struct CurrentCommentAndLiteral {
cur_lit: uint,
}
+impl Copy for CurrentCommentAndLiteral {}
+
pub struct State<'a> {
pub s: pp::Printer,
cm: Option<&'a CodeMap>,
FkFnBlock,
}
+impl<'a> Copy for FnKind<'a> {}
+
/// Each method of the Visitor trait is a hook to be potentially
/// overridden. Each method's default implementation recursively visits
/// the substructure of the input via the corresponding `walk` method;
/// Terminal attributes
pub mod attr {
pub use self::Attr::*;
+ use std::kinds::Copy;
/// Terminal attributes for use with term.attr().
///
/// Convenience attribute to set the background color
BackgroundColor(super::color::Color)
}
+
+ impl Copy for Attr {}
}
/// A terminal with similar capabilities to an ANSI Terminal
SeekIfEndPercent(int)
}
+impl Copy for States {}
+
#[deriving(PartialEq)]
enum FormatState {
FormatStateFlags,
FormatStatePrecision
}
+impl Copy for FormatState {}
+
/// Types of parameters a capability can use
#[allow(missing_docs)]
#[deriving(Clone)]
space: bool
}
+impl Copy for Flags {}
+
impl Flags {
fn new() -> Flags {
Flags{ width: 0, precision: 0, alternate: false,
FormatString
}
+impl Copy for FormatOp {}
+
impl FormatOp {
fn from_char(c: char) -> FormatOp {
match c {
}
#[deriving(Clone)]
-enum NamePadding { PadNone, PadOnLeft, PadOnRight }
+enum NamePadding {
+ PadNone,
+ PadOnLeft,
+ PadOnRight,
+}
+
+impl Copy for NamePadding {}
impl TestDesc {
fn padded_name(&self, column_count: uint, align: NamePadding) -> String {
/// This is feed into functions marked with `#[bench]` to allow for
/// set-up & tear-down before running a piece of code repeatedly via a
/// call to `iter`.
+#[deriving(Copy)]
pub struct Bencher {
iterations: u64,
dur: Duration,
pub bytes: u64,
}
-#[deriving(Clone, Show, PartialEq, Eq, Hash)]
+#[deriving(Copy, Clone, Show, PartialEq, Eq, Hash)]
pub enum ShouldFail {
No,
Yes(Option<&'static str>)
noise: f64
}
+impl Copy for Metric {}
+
impl Metric {
pub fn new(value: f64, noise: f64) -> Metric {
Metric {value: value, noise: noise}
Regression(f64)
}
+impl Copy for MetricChange {}
+
pub type MetricDiff = TreeMap<String,MetricChange>;
// The default console test runner. It accepts the command line
NeverColor,
}
+impl Copy for ColorConfig {}
+
pub struct TestOpts {
pub filter: Option<Regex>,
pub run_ignored: bool,
return;
}
StaticBenchFn(benchfn) => {
- let bs = ::bench::benchmark(|harness| benchfn(harness));
+ let bs = ::bench::benchmark(|harness| (benchfn.clone())(harness));
monitor_ch.send((desc, TrBench(bs), Vec::new()));
return;
}
/// A record specifying a time value in seconds and nanoseconds.
#[deriving(Clone, PartialEq, Eq, PartialOrd, Ord, Encodable, Decodable, Show)]
-pub struct Timespec { pub sec: i64, pub nsec: i32 }
+pub struct Timespec {
+ pub sec: i64,
+ pub nsec: i32,
+}
+
+impl Copy for Timespec {}
+
/*
* Timespec assumes that pre-epoch Timespecs have negative sec and positive
* nsec fields. Darwin's and Linux's struct timespec functions handle pre-
pub tm_nsec: i32,
}
+impl Copy for Tm {}
+
pub fn empty_tm() -> Tm {
Tm {
tm_sec: 0_i32,
UnexpectedCharacter(char, char),
}
+impl Copy for ParseError {}
+
impl Show for ParseError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
pub mod grapheme {
pub use self::GraphemeCat::*;
use core::slice::SlicePrelude;
+ use core::kinds::Copy;
use core::slice;
#[allow(non_camel_case_types)]
GC_Any,
}
+ impl Copy for GraphemeCat {}
+
fn bsearch_range_value_table(c: char, r: &'static [(char, char, GraphemeCat)]) -> GraphemeCat {
use core::cmp::Ordering::{Equal, Less, Greater};
match r.binary_search(|&(lo, hi, _)| {
-S 2014-12-05 361baab
- freebsd-x86_64 73cbae4168538a07facd81cca45ed672badb7c3a
- linux-i386 211cf0fbdbc7045b765e7b92d92049bbe6788513
- linux-x86_64 f001cec306fc1ac77504884acf5dac2e7b39e164
- macos-i386 751dc02fac96114361c56eb45ce52e7a58d555e0
- macos-x86_64 58cad0275d7b33412501d7dd3386b924d2304e83
- winnt-i386 872c56b88cebd7d590fd00bcbd264f0003b4427b
- winnt-x86_64 2187d8b3187c03f95cd4e56a582f55ec0cfa8df9
-
S 2014-11-21 c9f6d69
freebsd-x86_64 0ef316e7c369177de043e69e964418bd637cbfc0
linux-i386 c8342e762a1720be939ed7c6a39bdaa27892f66f
pub struct A;
+ impl Copy for A {}
+
pub fn make() -> B { A }
impl A {
p: i32,
}
pub const THREE: P = P { p: 3 };
+ impl Copy for P {}
}
pub static A: S = S { p: private::THREE };
+
+impl Copy for S {}
+
#[lang = "eh_personality"]
extern fn eh_personality() {}
+
+#[lang="copy"]
+pub trait Copy {}
+
+
pub struct Foo;
+impl Copy for Foo {}
+
impl Foo {
pub fn foo(self, x: &Foo) {
unsafe { COUNT *= 2; }
pub struct Foo;
+impl Copy for Foo {}
+
impl Foo {
pub fn run_trait(self) {
unsafe { COUNT *= 17; }
pub struct Struct;
+impl Copy for Struct {}
+
pub enum Unit {
UnitVariant,
Argument(Struct)
}
+impl Copy for Unit {}
+
pub struct TupleStruct(pub uint, pub &'static str);
+impl Copy for TupleStruct {}
+
// used by the cfail test
pub struct StructWithFields {
foo: int,
}
+impl Copy for StructWithFields {}
+
pub enum EnumWithVariants {
EnumVariant,
EnumVariantArg(int)
}
+
+impl Copy for EnumWithVariants {}
+
y: f32,
}
+impl Copy for Vec2 {}
+
fn lerp(a: f32, b: f32, v: f32) -> f32 { a * (1.0 - v) + b * v }
fn smooth(v: f32) -> f32 { v * v * (3.0 - 2.0 * v) }
}
}
-enum Color { Red, Yellow, Blue }
+enum Color {
+ Red,
+ Yellow,
+ Blue,
+}
+
+impl Copy for Color {}
+
impl fmt::Show for Color {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let str = match *self {
color: Color
}
+impl Copy for CreatureInfo {}
+
fn show_color_list(set: Vec<Color>) -> String {
let mut out = String::new();
for col in set.iter() {
p: [i32, .. 16],
}
+impl Copy for P {}
+
struct Perm {
cnt: [i32, .. 16],
fact: [u32, .. 16],
perm: P,
}
+impl Copy for Perm {}
+
impl Perm {
fn new(n: u32) -> Perm {
let mut fact = [1, .. 16];
p: f32,
}
+impl Copy for AminoAcid {}
+
struct RepeatFasta<'a, W:'a> {
alu: &'static str,
out: &'a mut W
#[deriving(PartialEq, PartialOrd, Ord, Eq)]
struct Code(u64);
+impl Copy for Code {}
+
impl Code {
fn hash(&self) -> u64 {
let Code(ret) = *self;
mass: f64,
}
+impl Copy for Planet {}
+
fn advance(bodies: &mut [Planet, ..N_BODIES], dt: f64, steps: int) {
for _ in range(0, steps) {
let mut b_slice = bodies.as_mut_slice();
bar2: Bar
}
+impl Copy for Foo {}
+
struct Bar {
int1: int,
int2: int,
}
+impl Copy for Bar {}
+
fn make_foo() -> Box<Foo> { panic!() }
fn borrow_same_field_twice_mut_mut() {
bar2: Bar
}
+impl Copy for Foo {}
+
struct Bar {
int1: int,
int2: int,
}
+impl Copy for Bar {}
+
fn make_foo() -> Foo { panic!() }
fn borrow_same_field_twice_mut_mut() {
+++ /dev/null
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-enum Either<T, U> { Left(T), Right(U) }
-
- fn f(x: &mut Either<int,f64>, y: &Either<int,f64>) -> int {
- match *y {
- Either::Left(ref z) => {
- *x = Either::Right(1.0);
- *z
- }
- _ => panic!()
- }
- }
-
- fn g() {
- let mut x: Either<int,f64> = Either::Left(3);
- println!("{}", f(&mut x, &x)); //~ ERROR cannot borrow
- }
-
- fn h() {
- let mut x: Either<int,f64> = Either::Left(3);
- let y: &Either<int, f64> = &x;
- let z: &mut Either<int, f64> = &mut x; //~ ERROR cannot borrow
- *z = *y;
- }
-
- fn main() {}
// except according to those terms.
struct A { a: int, b: int }
+
+impl Copy for A {}
+
struct B { a: int, b: Box<int> }
fn var_copy_after_var_borrow() {
struct S;
+impl Copy for S {}
+
impl Index<uint, str> for S {
fn index<'a>(&'a self, _: &uint) -> &'a str {
"hello"
struct T;
+impl Copy for T {}
+
impl Index<uint, Show + 'static> for T {
fn index<'a>(&'a self, idx: &uint) -> &'a (Show + 'static) {
static x: uint = 42;
fn main() {
S[0];
- //~^ ERROR E0161
+ //~^ ERROR cannot move out of dereference
+ //~^^ ERROR E0161
T[0];
//~^ ERROR cannot move out of dereference
//~^^ ERROR E0161
pub fn main() {
let _x: Box<str> = box *"hello world";
//~^ ERROR E0161
+ //~^^ ERROR cannot move out of dereference
let array: &[int] = &[1, 2, 3];
let _x: Box<[int]> = box *array;
//~^ ERROR E0161
+ //~^^ ERROR cannot move out of dereference
}
fn main() {
let x = Foo { x: 3 };
- x.drop(); //~ ERROR explicit call to destructor
+ x.drop(); //~ ERROR explicit use of destructor method
}
impl Bar for Foo {
fn blah(&self) {
- self.drop(); //~ ERROR explicit call to destructor
+ self.drop(); //~ ERROR explicit use of destructor method
}
}
--- /dev/null
+// 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.
+
+#![allow(dead_code)]
+
+struct Foo;
+impl Fn<(), ()> for Foo { //~ ERROR manual implementations of `Fn` are experimental
+ extern "rust-call" fn call(&self, args: ()) -> () {}
+}
+struct Bar;
+impl FnMut<(), ()> for Bar { //~ ERROR manual implementations of `FnMut` are experimental
+ extern "rust-call" fn call_mut(&self, args: ()) -> () {}
+}
+struct Baz;
+impl FnOnce<(), ()> for Baz { //~ ERROR manual implementations of `FnOnce` are experimental
+ extern "rust-call" fn call_once(&self, args: ()) -> () {}
+}
+
+fn main() {}
--- /dev/null
+// 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.
+
+#![allow(dead_code)]
+
+fn foo<F: Fn<(), ()>>(mut f: F) {
+ f.call(()); //~ ERROR explicit use of unboxed closure method `call`
+ f.call_mut(()); //~ ERROR explicit use of unboxed closure method `call_mut`
+ f.call_once(()); //~ ERROR explicit use of unboxed closure method `call_once`
+}
+
+fn main() {}
--- /dev/null
+// 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.
+
+#![allow(dead_code)]
+
+fn foo<F: Fn<(), ()>>(mut f: F, mut g: F) {
+ Fn::call(&g, ()); //~ ERROR explicit use of unboxed closure method `call`
+ FnMut::call_mut(&mut g, ()); //~ ERROR explicit use of unboxed closure method `call_mut`
+ FnOnce::call_once(g, ()); //~ ERROR explicit use of unboxed closure method `call_once`
+}
+
+fn main() {}
--- /dev/null
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+
+struct Foo;
+
+impl Drop for Foo {
+ fn drop(&mut self) {}
+}
+
+fn main() {
+ Drop::drop(&mut Foo) //~ ERROR explicit use of destructor method
+}
fn main() {
(|| box *[0u].as_slice())();
- //~^ ERROR cannot move a value of type [uint]
+ //~^ ERROR cannot move out of dereference
+ //~^^ ERROR cannot move a value of type [uint]
}
use std::rc::Rc;
fn assert_copy<T:Copy>() { }
+
trait Dummy { }
struct MyStruct {
y: int,
}
+impl Copy for MyStruct {}
+
struct MyNoncopyStruct {
x: Box<char>,
}
fn i(_x: int) -> &int { //~ ERROR missing lifetime specifier
//~^ HELP this function's return type contains a borrowed value
-//~^^ HELP consider giving it a 'static lifetime
panic!()
}
#![allow(unused_variables)]
#![allow(non_camel_case_types)]
#![allow(non_upper_case_globals)]
+#![allow(missing_copy_implementations)]
#![deny(dead_code)]
#![crate_type="lib"]
#![feature(globs)]
#![deny(missing_docs)]
#![allow(dead_code)]
+#![allow(missing_copy_implementations)]
//! Some garbage docs for the crate here
#![doc="More garbage"]
--- /dev/null
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+struct CantCopyThis;
+
+struct IWantToCopyThis {
+ but_i_cant: CantCopyThis,
+}
+
+impl Copy for IWantToCopyThis {}
+//~^ ERROR the trait `Copy` may not be implemented for this type
+
+enum CantCopyThisEither {
+ A,
+ B,
+}
+
+enum IWantToCopyThisToo {
+ ButICant(CantCopyThisEither),
+}
+
+impl Copy for IWantToCopyThisToo {}
+//~^ ERROR the trait `Copy` may not be implemented for this type
+
+fn main() {}
+
--- /dev/null
+// 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.
+
+// Test that the recursion limit can be changed. In this case, we have
+// deeply nested types that will fail the `Send` check by overflow
+// when the recursion limit is set very low.
+
+#![feature(macro_rules)]
+#![allow(dead_code)]
+#![recursion_limit="10"]
+
+macro_rules! link {
+ ($id:ident, $t:ty) => {
+ enum $id { $id($t) }
+ }
+}
+
+link!(A,B)
+link!(B,C)
+link!(C,D)
+link!(D,E)
+link!(E,F)
+link!(F,G)
+link!(G,H)
+link!(H,I)
+link!(I,J)
+link!(J,K)
+link!(K,L)
+link!(L,M)
+link!(M,N)
+
+enum N { N(uint) }
+
+fn is_send<T:Send>() { }
+
+fn main() {
+ is_send::<A>();
+ //~^ ERROR overflow evaluating
+ //~^^ NOTE consider adding a `#![recursion_limit="20"]` attribute to your crate
+ //~^^^ NOTE must be implemented
+ //~^^^^ ERROR overflow evaluating
+ //~^^^^^ NOTE consider adding a `#![recursion_limit="20"]` attribute to your crate
+ //~^^^^^^ NOTE must be implemented
+}
+++ /dev/null
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// A zero-dependency test that covers some basic traits, default
-// methods, etc. When mucking about with basic type system stuff I
-// often encounter problems in the iterator trait, so it's useful to
-// have hanging around. -nmatsakis
-
-// error-pattern: requires `start` lang_item
-
-#![no_std]
-#![feature(lang_items)]
-
-#[lang = "sized"]
-pub trait Sized for Sized? {
- // Empty.
-}
-
-pub mod std {
- pub mod clone {
- pub trait Clone {
- fn clone(&self) -> Self;
- }
- }
-}
-
-pub struct ContravariantLifetime<'a>;
-
-impl <'a> ::std::clone::Clone for ContravariantLifetime<'a> {
- #[inline]
- fn clone(&self) -> ContravariantLifetime<'a> {
- match *self { ContravariantLifetime => ContravariantLifetime, }
- }
-}
-
-fn main() { }
+++ /dev/null
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-
-// A zero-dependency test that covers some basic traits, default
-// methods, etc. When mucking about with basic type system stuff I
-// often encounter problems in the iterator trait, so it's useful to
-// have hanging around. -nmatsakis
-
-// error-pattern: requires `start` lang_item
-
-#![no_std]
-#![feature(lang_items)]
-
-#[lang = "sized"]
-pub trait Sized for Sized? {
- // Empty.
-}
-
-#[unstable = "Definition may change slightly after trait reform"]
-pub trait PartialEq for Sized? {
- /// This method tests for `self` and `other` values to be equal, and is used by `==`.
- fn eq(&self, other: &Self) -> bool;
-}
-
-#[unstable = "Trait is unstable."]
-impl<'a, Sized? T: PartialEq> PartialEq for &'a T {
- #[inline]
- fn eq(&self, other: & &'a T) -> bool { PartialEq::eq(*self, *other) }
-}
-
-fn main() { }
eq::< for<'a,'b> Foo<(&'a int,&'b uint),uint>,
Foo(&int,&uint) -> uint >();
- // FIXME(#18992) Test lifetime elision in `()` form:
- // eq::< for<'a,'b> Foo<(&'a int,), &'a int>,
- // Foo(&int) -> &int >();
+ // lifetime elision
+ eq::< for<'a,'b> Foo<(&'a int,), &'a int>,
+ Foo(&int) -> &int >();
// Errors expected:
eq::< Foo<(),()>, Foo(char) >();
--- /dev/null
+// 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.
+
+// Test that the unboxed closure sugar can be used with an arbitrary
+// struct type and that it is equivalent to the same syntax using
+// angle brackets. This test covers only simple types and in
+// particular doesn't test bound regions.
+
+#![feature(unboxed_closures)]
+#![allow(dead_code)]
+
+trait Foo<T,U> {
+ fn dummy(&self, t: T, u: U);
+}
+
+trait Eq<Sized? X> for Sized? { }
+impl<Sized? X> Eq<X> for X { }
+fn eq<Sized? A,Sized? B:Eq<A>>() { }
+
+fn main() {
+ eq::< for<'a> Foo<(&'a int,), &'a int>,
+ Foo(&int) -> &int >();
+ eq::< for<'a> Foo<(&'a int,), (&'a int, &'a int)>,
+ Foo(&int) -> (&int, &int) >();
+
+ let _: Foo(&int, &uint) -> &uint; //~ ERROR missing lifetime specifier
+}
pub fn main() {
let mut f = |&mut: x: int, y: int| -> int { x + y };
- let z = f.call_mut((1u, 2)); //~ ERROR not implemented
+ let z = f.call_mut((1u, 2)); //~ ERROR type mismatch
println!("{}", z);
}
pub fn main() {
let f = |&mut: x: uint, y: int| -> int { (x as int) + y };
- let z = call_it(3, f); //~ ERROR not implemented
+ let z = call_it(3, f); //~ ERROR type mismatch
println!("{}", z);
}
use self::ManualDiscriminant::{OneHundred, OneThousand, OneMillion};
use self::SingleVariant::TheOnlyVariant;
+#[deriving(Copy)]
enum AutoDiscriminant {
One,
Two,
Three
}
+#[deriving(Copy)]
enum ManualDiscriminant {
OneHundred = 100,
OneThousand = 1000,
OneMillion = 1000000
}
+#[deriving(Copy)]
enum SingleVariant {
TheOnlyVariant
}
}
fn zzz() {()}
+
+impl<T:Copy> Copy for Struct<T> {}
+
}
fn zzz() {()}
+
+impl Copy for Enum {}
+
}
fn zzz() {()}
+
+impl<T:Copy> Copy for Struct<T> {}
+
}
fn zzz() {()}
+
+impl Copy for Struct {}
+
}
fn zzz() {()}
+
+impl Copy for Struct {}
+
}
fn zzz() {()}
+
+impl Copy for TupleStruct {}
+
}
fn zzz() {()}
+
+impl Copy for Struct {}
+
}
fn zzz() {()}
+
+impl Copy for Struct {}
+
// gdb-command:print *owned
// gdb-check:$5 = 6
+// gdb-command:continue
+
+// gdb-command:print variable
+// gdb-check:$6 = 2
+// gdb-command:print constant
+// gdb-check:$7 = 2
+// gdb-command:print a_struct
+// gdb-check:$8 = {a = -3, b = 4.5, c = 5}
+// gdb-command:print *struct_ref
+// gdb-check:$9 = {a = -3, b = 4.5, c = 5}
+// gdb-command:print *owned
+// gdb-check:$10 = 6
+
// === LLDB TESTS ==================================================================================
// lldb-command:print *owned
// lldb-check:[...]$4 = 6
+// lldb-command:continue
+
+// lldb-command:print variable
+// lldb-check:[...]$5 = 2
+// lldb-command:print constant
+// lldb-check:[...]$6 = 2
+// lldb-command:print a_struct
+// lldb-check:[...]$7 = Struct { a: -3, b: 4.5, c: 5 }
+// lldb-command:print *struct_ref
+// lldb-check:[...]$8 = Struct { a: -3, b: 4.5, c: 5 }
+// lldb-command:print *owned
+// lldb-check:[...]$9 = 6
+
+#![feature(unboxed_closures)]
#![allow(unused_variables)]
struct Struct {
let struct_ref = &a_struct;
let owned = box 6;
- let closure = || {
- zzz(); // #break
- variable = constant + a_struct.a + struct_ref.a + *owned;
- };
-
- closure();
+ {
+ let closure = || {
+ zzz(); // #break
+ variable = constant + a_struct.a + struct_ref.a + *owned;
+ };
+
+ closure();
+ }
+
+ {
+ let mut unboxed_closure = |&mut:| {
+ zzz(); // #break
+ variable = constant + a_struct.a + struct_ref.a + *owned;
+ };
+ unboxed_closure();
+ }
}
fn zzz() {()}
struct S { eax: int }
+impl Copy for S {}
+
fn test3() {
let regs = &Cell::new(S {eax: 0});
match true { true => { } _ => { } }
c: i8
}
+impl Copy for Foo {}
+
#[link(name = "test", kind = "static")]
extern {
fn foo(f: Foo) -> Foo;
#![feature(lang_items)]
#![no_std]
+#[lang="copy"]
+trait Copy { }
+
#[lang="sized"]
trait Sized { }
// aux-build:issue-13560-1.rs
// aux-build:issue-13560-2.rs
// aux-build:issue-13560-3.rs
-// ignore-pretty FIXME #19501
// ignore-stage1
// Regression test for issue #13560, the test itself is all in the dependent
newvar(int)
}
+impl Copy for newtype {}
+
pub fn main() {
// Test that borrowck treats enums with a single variant
struct X<T>(T);
-impl <T:Sync> RequiresShare for X<T> { }
+impl<T:Copy> Copy for X<T> {}
-impl <T:Sync+Send> RequiresRequiresShareAndSend for X<T> { }
+impl<T:Sync> RequiresShare for X<T> { }
-impl <T:Copy> RequiresCopy for X<T> { }
+impl<T:Sync+Send> RequiresRequiresShareAndSend for X<T> { }
+
+impl<T:Copy> RequiresCopy for X<T> { }
pub fn main() { }
}
}
+impl Copy for Foo {}
+
pub fn main() {
let x = Cell::new(Foo { x: 22 });
let _y = x.get();
#[deriving(Show)]
enum cat_type { tuxedo, tabby, tortoiseshell }
+impl Copy for cat_type {}
+
impl cmp::PartialEq for cat_type {
fn eq(&self, other: &cat_type) -> bool {
((*self) as uint) == ((*other) as uint)
pub fn main() {
enum x { foo }
+ impl Copy for x {}
impl ::std::cmp::PartialEq for x {
fn eq(&self, other: &x) -> bool {
(*self) as int == (*other) as int
dummy: uint
}
+impl Copy for MyType {}
+
impl MyTrait for MyType {
fn get(&self) -> MyType { (*self).clone() }
}
Bar = 0xDEADBEE
}
+impl Copy for Foo {}
+
static X: Foo = Foo::Bar;
pub fn main() {
#[deriving(PartialEq,Eq)]
struct Bar;
+impl Copy for Bar {}
+
trait ToBar {
fn to_bar(&self) -> Bar;
}
#[deriving(PartialEq,Eq)]
struct Bar;
+impl Copy for Bar {}
+
trait ToBar {
fn to_bar(&self) -> Bar;
}
#[deriving(PartialEq,Eq)]
struct Bar;
+impl Copy for Bar {}
+
#[deriving(PartialEq,Eq)]
struct Bar1 {
f: int
}
+impl Copy for Bar1 {}
+
trait ToBar {
fn to_bar(&self) -> Bar;
fn to_val(&self) -> int;
#[deriving(Show)]
enum chan { chan_t, }
+impl Copy for chan {}
+
impl PartialEq for chan {
fn eq(&self, other: &chan) -> bool {
((*self) as uint) == ((*other) as uint)
A = 0
}
static C: E = E::V;
+ impl Copy for E {}
pub fn check() {
assert_eq!(size_of::<E>(), size_of::<$t>());
assert_eq!(E::V as $t, $v as $t);
struct LM { resize_at: uint, size: uint }
+impl Copy for LM {}
+
enum HashMap<K,V> {
HashMap_(LM)
}
+impl<K,V> Copy for HashMap<K,V> {}
+
fn linear_map<K,V>() -> HashMap<K,V> {
HashMap::HashMap_(LM{
resize_at: 32,
// not exported
enum t { t1, t2, }
+ impl Copy for t {}
+
impl PartialEq for t {
fn eq(&self, other: &t) -> bool {
((*self) as uint) == ((*other) as uint)
struct A { a: int }
+impl Copy for A {}
+
pub fn main() {
let mut x = A {a: 10};
f(&mut x);
struct I { i: int }
+impl Copy for I {}
+
fn test_rec() {
let rs = if true { I {i: 100} } else { I {i: 101} };
assert_eq!(rs.i, 100);
#[deriving(Show)]
enum mood { happy, sad, }
+impl Copy for mood {}
+
impl PartialEq for mood {
fn eq(&self, other: &mood) -> bool {
((*self) as uint) == ((*other) as uint)
// Tests for match as expressions resulting in struct types
struct R { i: int }
+impl Copy for R {}
+
fn test_rec() {
let rs = match true { true => R {i: 100}, _ => panic!() };
assert_eq!(rs.i, 100);
#[deriving(Show)]
enum mood { happy, sad, }
+impl Copy for mood {}
+
impl PartialEq for mood {
fn eq(&self, other: &mood) -> bool {
((*self) as uint) == ((*other) as uint)
struct Point {x: int, y: int, z: int}
+impl Copy for Point {}
+
fn f(p: &Cell<Point>) {
assert!((p.get().z == 12));
p.set(Point {x: 10, y: 11, z: 13});
one: u16, two: u16
}
+impl Copy for TwoU16s {}
+
#[link(name = "rust_test_helpers")]
extern {
pub fn rust_dbg_extern_identity_TwoU16s(v: TwoU16s) -> TwoU16s;
one: u32, two: u32
}
+impl Copy for TwoU32s {}
+
#[link(name = "rust_test_helpers")]
extern {
pub fn rust_dbg_extern_identity_TwoU32s(v: TwoU32s) -> TwoU32s;
one: u64, two: u64
}
+impl Copy for TwoU64s {}
+
#[link(name = "rust_test_helpers")]
extern {
pub fn rust_dbg_extern_identity_TwoU64s(v: TwoU64s) -> TwoU64s;
one: u8, two: u8
}
+impl Copy for TwoU8s {}
+
#[link(name = "rust_test_helpers")]
extern {
pub fn rust_dbg_extern_identity_TwoU8s(v: TwoU8s) -> TwoU8s;
z: u64,
}
+impl Copy for S {}
+
#[link(name = "rust_test_helpers")]
extern {
pub fn get_x(x: S) -> u64;
struct Triple {x: int, y: int, z: int}
+impl Copy for Triple {}
+
pub fn main() {
let mut x = 62;
let mut y = 63;
enum Q { R(Option<uint>) }
+impl Copy for Q {}
+
fn xyzzy(q: Q) -> uint {
match q {
Q::R(S) if S.is_some() => { 0 }
struct Pair { x: int, y: int }
+impl Copy for Pair {}
+
pub fn main() {
let a: int =
match 10i { x if x < 7 => { 1i } x if x < 11 => { 2i } 10 => { 3i } _ => { 4i } };
z: int
}
+impl Copy for XYZ {}
+
fn main() {
let mut connected = HashSet::new();
let mut border = HashSet::new();
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#[deriving(PartialEq, PartialOrd)]
+#[deriving(Eq, PartialEq, PartialOrd, Ord)]
enum Test<'a> {
Int(&'a int),
Slice(&'a [u8]),
}
-#[deriving(PartialEq, PartialOrd)]
+#[deriving(Eq, PartialEq, PartialOrd, Ord)]
struct Version {
vendor_info: &'static str
}
-#[deriving(PartialEq, PartialOrd)]
+#[deriving(Eq, PartialEq, PartialOrd, Ord)]
struct Foo(&'static str);
fn main() {}
Baz
}
+impl Copy for Foo {}
+
impl Foo {
fn foo(&self) {
match self {
trait clam<A> {
fn chowder(&self, y: A);
}
+
struct foo<A> {
x: A,
}
+impl<A:Copy> Copy for foo<A> {}
+
impl<A> clam<A> for foo<A> {
fn chowder(&self, _y: A) {
}
meow: extern "Rust" fn(),
}
+impl Copy for cat {}
+
fn meow() {
println!("meow")
}
struct KittyInfo {kitty: cat}
+impl Copy for KittyInfo {}
+
// Code compiles and runs successfully if we add a + before the first arg
fn nyan(kitty: cat, _kitty_info: KittyInfo) {
(kitty.meow)();
enum order { hamburger, fries(side), shake }
enum meal { to_go(order), for_here(order) }
+impl Copy for side {}
+impl Copy for order {}
+impl Copy for meal {}
+
fn foo(m: Box<meal>, cond: bool) {
match *m {
meal::to_go(_) => { }
y: int,
}
+impl Copy for Point {}
+
// Represents an offset on a canvas. (This has the same structure as a Point.
// but different semantics).
struct Size {
height: int,
}
+impl Copy for Size {}
+
struct Rect {
top_left: Point,
size: Size,
}
+impl Copy for Rect {}
+
// Contains the information needed to do shape rendering via ASCII art.
struct AsciiArt {
width: uint,
y: f64
}
+impl Copy for Vec2 {}
+
// methods we want to export as methods as well as operators
impl Vec2 {
#[inline(always)]
y: f64
}
+impl Copy for Point {}
+
pub enum Shape {
Circle(Point, f64),
Rectangle(Point, Point)
}
+impl Copy for Shape {}
+
impl Shape {
pub fn area(&self, sh: Shape) -> f64 {
match sh {
*/
struct X { vec: &'static [int] }
+
+impl Copy for X {}
+
static V: &'static [X] = &[X { vec: &[1, 2, 3] }];
+
pub fn main() {
for &v in V.iter() {
println!("{}", v.vec);
// ignore-windows #13361
#![no_std]
+#![feature(lang_items)]
extern crate "lang-item-public" as lang_lib;
pub mod glfw {
pub struct InputState(uint);
+ impl Copy for InputState {}
+
pub const RELEASE : InputState = InputState(0);
pub const PRESS : InputState = InputState(1);
pub const REPEAT : InputState = InputState(2);
struct Foo;
+impl Copy for Foo {}
+
trait Bar {
fn foo1(&self);
fn foo2(self);
struct Foo;
+impl Copy for Foo {}
+
impl Foo {
fn foo(self, x: &Foo) {
unsafe { COUNT *= 2; }
*/
struct S<T> { i:u8, t:T }
-impl<T> S<T> { fn unwrap(self) -> T { self.t } }
+
+impl<T:Copy> Copy for S<T> {}
+
+impl<T> S<T> {
+ fn unwrap(self) -> T {
+ self.t
+ }
+}
+
#[deriving(PartialEq, Show)]
struct A((u32, u32));
+
+impl Copy for A {}
+
#[deriving(PartialEq, Show)]
struct B(u64);
+impl Copy for B {}
+
pub fn main() {
static Ca: S<A> = S { i: 0, t: A((13, 104)) };
static Cb: S<B> = S { i: 0, t: B(31337) };
dummy: uint
}
+impl Copy for MyType {}
+
impl MyTrait<uint> for MyType {
fn get(&self) -> uint { self.dummy }
}
dummy: uint
}
+impl Copy for MyType {}
+
impl MyTrait<uint> for MyType {
fn get(&self) -> uint { self.dummy }
}
struct mytype(Mytype);
-struct Mytype {compute: fn(mytype) -> int, val: int}
+impl Copy for mytype {}
+
+struct Mytype {
+ compute: fn(mytype) -> int,
+ val: int,
+}
+
+impl Copy for Mytype {}
fn compute(i: mytype) -> int {
let mytype(m) = i;
--- /dev/null
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(opt_out_copy)]
+
+// Test the opt-out-copy feature guard. This is the same as the
+// "opt-in-copy.rs" test from compile-fail, except that it is using
+// the feature guard, and hence the structureds in this file are
+// implicitly copyable, and hence we get no errors. This test can be
+// safely removed once the opt-out-copy "feature" is rejected.
+
+struct CantCopyThis;
+
+struct IWantToCopyThis {
+ but_i_cant: CantCopyThis,
+}
+
+impl Copy for IWantToCopyThis {}
+
+enum CantCopyThisEither {
+ A,
+ B,
+}
+
+enum IWantToCopyThisToo {
+ ButICant(CantCopyThisEither),
+}
+
+impl Copy for IWantToCopyThisToo {}
+
+fn is_copy<T:Copy>() { }
+
+fn main() {
+ is_copy::<CantCopyThis>();
+ is_copy::<CantCopyThisEither>();
+ is_copy::<IWantToCopyThis>();
+ is_copy::<IWantToCopyThisToo>();
+}
+
_f2: int,
}
+impl Copy for Foo {}
+
#[inline(never)]
pub fn foo(f: &mut Foo) -> Foo {
let ret = *f;
y: Y
}
+impl<X:Copy,Y:Copy> Copy for DerefWrapper<X,Y> {}
+
impl<X, Y> DerefWrapper<X, Y> {
fn get_x(self) -> X {
self.x
pub y: Y
}
+ impl<X:Copy,Y:Copy> Copy for DerefWrapperHideX<X,Y> {}
+
impl<X, Y> DerefWrapperHideX<X, Y> {
pub fn new(x: X, y: Y) -> DerefWrapperHideX<X, Y> {
DerefWrapperHideX {
baz: u64
}
+impl Copy for Foo {}
+
pub fn main() {
let foos = [Foo { bar: 1, baz: 2 }, .. 10];
struct Point {x: int, y: int}
+impl Copy for Point {}
+
type rect = (Point, Point);
fn fst(r: rect) -> Point { let (fst, _) = r; return fst; }
struct Rect {x: int, y: int, w: int, h: int}
+impl Copy for Rect {}
+
fn f(r: Rect, x: int, y: int, w: int, h: int) {
assert_eq!(r.x, x);
assert_eq!(r.y, y);
f: int
}
+impl Copy for C {}
+
fn get_v1(a: &A) -> &int {
// Region inferencer must deduce that &v < L2 < L1
let foo = &a.value; // L1
t: &'a int
}
+impl<'a> Copy for Box<'a> {}
+
impl<'a> GetRef<'a> for Box<'a> {
fn get(&self) -> &'a int {
self.t
t: &'a T
}
+impl<'a,T:'a> Copy for Box<'a,T> {}
+
impl<'a,T:Clone> GetRef<'a,T> for Box<'a,T> {
fn get(&self) -> &'a T {
self.t
t: T
}
+impl<T:Copy> Copy for Box<T> {}
+
impl<T:Clone> Get<T> for Box<T> {
fn get(&self) -> T {
self.t.clone()
--- /dev/null
+// 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.
+
+// Test that region inference correctly links up the regions when a
+// `ref` borrow occurs inside a fn argument.
+
+#![allow(dead_code)]
+
+fn with<'a>(_: |&'a Vec<int>| -> &'a Vec<int>) { }
+
+fn foo() {
+ with(|&ref ints| ints);
+}
+
+fn main() { }
TypeInt,
TypeFunction(Type<'tcx>, Type<'tcx>),
}
+
+impl<'tcx> Copy for TypeStructure<'tcx> {}
+
impl<'tcx> PartialEq for TypeStructure<'tcx> {
fn eq(&self, other: &TypeStructure<'tcx>) -> bool {
match (*self, *other) {
id: uint
}
+impl Copy for NodeId {}
+
type Ast<'ast> = &'ast AstStructure<'ast>;
struct AstStructure<'ast> {
kind: AstKind<'ast>
}
+impl<'ast> Copy for AstStructure<'ast> {}
+
enum AstKind<'ast> {
ExprInt,
ExprVar(uint),
ExprLambda(Ast<'ast>),
}
+impl<'ast> Copy for AstKind<'ast> {}
+
fn compute_types<'tcx,'ast>(tcx: &mut TypeContext<'tcx,'ast>,
ast: Ast<'ast>) -> Type<'tcx>
{
n: int
}
+impl Copy for Value {}
+
impl Value {
fn squared(mut self) -> Value {
self.n *= self.n;
+++ /dev/null
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-
-// Exercises a bug in the shape code that was exposed
-// on x86_64: when there is an enum embedded in an
-// interior record which is then itself interior to
-// something else, shape calculations were off.
-
-#[deriving(Clone, Show)]
-enum opt_span {
- //hack (as opposed to option), to make `span` compile
- os_none,
- os_some(Box<Span>),
-}
-
-#[deriving(Clone, Show)]
-struct Span {
- lo: uint,
- hi: uint,
- expanded_from: opt_span,
-}
-
-#[deriving(Clone, Show)]
-struct Spanned<T> {
- data: T,
- span: Span,
-}
-
-type ty_ = uint;
-
-#[deriving(Clone, Show)]
-struct Path_ {
- global: bool,
- idents: Vec<String> ,
- types: Vec<Box<ty>>,
-}
-
-type path = Spanned<Path_>;
-type ty = Spanned<ty_>;
-
-#[deriving(Clone, Show)]
-struct X {
- sp: Span,
- path: path,
-}
-
-pub fn main() {
- let sp: Span = Span {lo: 57451u, hi: 57542u, expanded_from: opt_span::os_none};
- let t: Box<ty> = box Spanned { data: 3u, span: sp.clone() };
- let p_: Path_ = Path_ {
- global: true,
- idents: vec!("hi".to_string()),
- types: vec!(t),
- };
- let p: path = Spanned { data: p_, span: sp.clone() };
- let x = X { sp: sp, path: p };
- println!("{}", x.path.clone());
- println!("{}", x.clone());
-}
#[simd] struct f32x4(f32, f32, f32, f32);
+impl Copy for f32x4 {}
+
fn add<T: ops::Add<T, T>>(lhs: T, rhs: T) -> T {
lhs + rhs
}
#[repr(u8)]
enum Eu { Lu = 0, Hu = 255 }
+
+impl Copy for Eu {}
+
static CLu: Eu = Eu::Lu;
static CHu: Eu = Eu::Hu;
#[repr(i8)]
enum Es { Ls = -128, Hs = 127 }
+
+impl Copy for Es {}
+
static CLs: Es = Es::Ls;
static CHs: Es = Es::Hs;
// ignore-lexer-test FIXME #15883
pub struct Quad { a: u64, b: u64, c: u64, d: u64 }
+
+impl Copy for Quad {}
+
pub struct Floats { a: f64, b: u8, c: f64 }
+impl Copy for Floats {}
+
mod rustrt {
use super::{Floats, Quad};
#[deriving(Show)]
enum foo { large, small, }
+impl Copy for foo {}
+
impl PartialEq for foo {
fn eq(&self, other: &foo) -> bool {
((*self) as uint) == ((*other) as uint)
orange = 8 >> 1
}
+impl Copy for color {}
+
impl PartialEq for color {
fn eq(&self, other: &color) -> bool {
((*self) as uint) == ((*other) as uint)
y: int,
}
+impl Copy for Struct {}
+
impl Trait<&'static str> for Struct {
fn f(&self, x: &'static str) {
println!("Hi, {}!", x);
y: int,
}
+impl Copy for Struct {}
+
impl Trait for Struct {
fn f(&self) {
println!("Hi!");
fn isEq(a: &Self, b: &Self) -> bool;
}
+#[deriving(Clone)]
enum Color { cyan, magenta, yellow, black }
+impl Copy for Color {}
+
impl Equal for Color {
fn isEq(a: &Color, b: &Color) -> bool {
match (*a, *b) {
}
}
+#[deriving(Clone)]
enum ColorTree {
leaf(Color),
branch(Box<ColorTree>, Box<ColorTree>)
impl Equal for ColorTree {
fn isEq(a: &ColorTree, b: &ColorTree) -> bool {
match (a, b) {
- (&leaf(x), &leaf(y)) => { Equal::isEq(&x, &y) }
+ (&leaf(ref x), &leaf(ref y)) => {
+ Equal::isEq(&(*x).clone(), &(*y).clone())
+ }
(&branch(ref l1, ref r1), &branch(ref l2, ref r2)) => {
- Equal::isEq(&**l1, &**l2) && Equal::isEq(&**r1, &**r2)
+ Equal::isEq(&(**l1).clone(), &(**l2).clone()) &&
+ Equal::isEq(&(**r1).clone(), &(**r2).clone())
}
_ => { false }
}
fn isEq(&self, a: &Self) -> bool;
}
+#[deriving(Clone)]
enum Color { cyan, magenta, yellow, black }
+impl Copy for Color {}
+
impl Equal for Color {
fn isEq(&self, a: &Color) -> bool {
match (*self, *a) {
}
}
+#[deriving(Clone)]
enum ColorTree {
leaf(Color),
branch(Box<ColorTree>, Box<ColorTree>)
impl Equal for ColorTree {
fn isEq(&self, a: &ColorTree) -> bool {
match (self, a) {
- (&leaf(x), &leaf(y)) => { x.isEq(&y) }
+ (&leaf(ref x), &leaf(ref y)) => { x.isEq(&(*y).clone()) }
(&branch(ref l1, ref r1), &branch(ref l2, ref r2)) => {
- (&**l1).isEq(&**l2) && (&**r1).isEq(&**r2)
+ (*l1).isEq(&(**l2).clone()) && (*r1).isEq(&(**r2).clone())
}
_ => { false }
}
f: int,
}
+impl Copy for Foo {}
+
impl Foo {
fn foo(self: Foo, x: int) -> int {
self.f + x
f: T,
}
+impl<T:Copy> Copy for Bar<T> {}
+
impl<T> Bar<T> {
fn foo(self: Bar<T>, x: int) -> int {
x
--- /dev/null
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+trait Foo<T> {
+ fn get(&self) -> T;
+}
+
+impl Foo<i32> for i32 {
+ fn get(&self) -> i32 { *self }
+}
+
+fn main() {
+ let x: i32 = 1;
+ Foo::<i32>::get(&x);
+}
#[deriving(Show, PartialEq)]
struct Foo(uint, &'static str);
+
+ impl Copy for Foo {}
+
let x = Foo(42, "forty-two");
let f = bar(x);
assert_eq!(f.call_once(()), x);
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-// ignore-test
-
extern crate libc;
use std::io::process::Command;
use libc::funcs::posix88::unistd;
-// "ps -A -o pid,sid,command" with GNU ps should output something like this:
-// PID SID COMMAND
-// 1 1 /sbin/init
+// The output from "ps -A -o pid,ppid,args" should look like this:
+// PID PPID COMMAND
+// 1 0 /sbin/init
// 2 0 [kthreadd]
-// 3 0 [ksoftirqd/0]
// ...
-// 12562 9237 ./spawn-failure
-// 12563 9237 [spawn-failure] <defunct>
-// 12564 9237 [spawn-failure] <defunct>
+// 6076 9064 /bin/zsh
+// ...
+// 7164 6076 ./spawn-failure
+// 7165 7164 [spawn-failure] <defunct>
+// 7166 7164 [spawn-failure] <defunct>
// ...
-// 12592 9237 [spawn-failure] <defunct>
-// 12593 9237 ps -A -o pid,sid,command
-// 12884 12884 /bin/zsh
-// 12922 12922 /bin/zsh
+// 7197 7164 [spawn-failure] <defunct>
+// 7198 7164 ps -A -o pid,ppid,command
// ...
#[cfg(unix)]
fn find_zombies() {
- // http://man.freebsd.org/ps(1)
- // http://man7.org/linux/man-pages/man1/ps.1.html
- #[cfg(not(target_os = "macos"))]
- const FIELDS: &'static str = "pid,sid,command";
-
- // https://developer.apple.com/library/mac/documentation/Darwin/
- // Reference/ManPages/man1/ps.1.html
- #[cfg(target_os = "macos")]
- const FIELDS: &'static str = "pid,sess,command";
-
- let my_sid = unsafe { unistd::getsid(0) };
+ let my_pid = unsafe { unistd::getpid() };
- let ps_cmd_output = Command::new("ps").args(&["-A", "-o", FIELDS]).output().unwrap();
+ // http://pubs.opengroup.org/onlinepubs/9699919799/utilities/ps.html
+ let ps_cmd_output = Command::new("ps").args(&["-A", "-o", "pid,ppid,args"]).output().unwrap();
let ps_output = String::from_utf8_lossy(ps_cmd_output.output.as_slice());
- let found = ps_output.split('\n').enumerate().any(|(line_no, line)|
- 0 < line_no && 0 < line.len() &&
- my_sid == from_str(line.split(' ').filter(|w| 0 < w.len()).nth(1)
- .expect("1st column should be Session ID")
- ).expect("Session ID string into integer") &&
- line.contains("defunct") && {
- println!("Zombie child {}", line);
- true
+ for (line_no, line) in ps_output.split('\n').enumerate() {
+ if 0 < line_no && 0 < line.len() &&
+ my_pid == from_str(line.split(' ').filter(|w| 0 < w.len()).nth(1)
+ .expect("1st column should be PPID")
+ ).expect("PPID string into integer") &&
+ line.contains("defunct") {
+ panic!("Zombie child {}", line);
}
- );
-
- assert!( ! found, "Found at least one zombie child");
+ }
}
#[cfg(windows)]
fn main() {
let too_long = format!("/NoSuchCommand{:0300}", 0u8);
- for _ in range(0u32, 100) {
- let invalid = Command::new(too_long.as_slice()).spawn();
- assert!(invalid.is_err());
- }
+ let _failures = Vec::from_fn(100, |_i| {
+ let cmd = Command::new(too_long.as_slice());
+ let failed = cmd.spawn();
+ assert!(failed.is_err(), "Make sure the command fails to spawn(): {}", cmd);
+ failed
+ });
find_zombies();
+ // then _failures goes out of scope
}