Merge remote-tracking branch 'remotes/origin/incoming' into incoming
This commit is contained in:
commit
7d0ec86c4a
@ -93,6 +93,7 @@ Josh Matthews <josh@joshmatthews.net>
|
||||
Joshua Clark <joshua.clark@txstate.edu>
|
||||
Joshua Wise <joshua@joshuawise.com>
|
||||
Jyun-Yan You <jyyou@cs.nctu.edu.tw>
|
||||
Kang Seonghoon <kang.seonghoon@mearie.org>
|
||||
Kelly Wilson <wilsonk@cpsc.ucalgary.ca>
|
||||
Kevin Atkinson <kevina@cs.utah.edu>
|
||||
Kevin Cantu <me@kevincantu.org>
|
||||
|
2
configure
vendored
2
configure
vendored
@ -678,7 +678,7 @@ do
|
||||
LLVM_BUILD_DIR=${CFG_BUILD_DIR}llvm/$t
|
||||
if [ ! -z "$CFG_DISABLE_OPTIMIZE_LLVM" ]
|
||||
then
|
||||
LLVM_DBG_OPTS=""
|
||||
LLVM_DBG_OPTS="--enable-debug-symbols --disable-optimized"
|
||||
# Just use LLVM straight from its build directory to
|
||||
# avoid 'make install' time
|
||||
LLVM_INST_DIR=$LLVM_BUILD_DIR/Debug+Asserts
|
||||
|
@ -1610,11 +1610,10 @@ The following are examples of structure expressions:
|
||||
~~~~
|
||||
# struct Point { x: float, y: float }
|
||||
# struct TuplePoint(float, float);
|
||||
# mod game { pub struct User { name: &str, age: uint, mut score: uint } }
|
||||
# use game;
|
||||
# mod game { pub struct User { name: &str, age: uint, score: uint } }
|
||||
Point {x: 10f, y: 20f};
|
||||
TuplePoint(10f, 20f);
|
||||
let u = game::User {name: "Joe", age: 35u, mut score: 100_000};
|
||||
let u = game::User {name: "Joe", age: 35u, score: 100_000};
|
||||
~~~~
|
||||
|
||||
A structure expression forms a new value of the named structure type.
|
||||
|
@ -348,12 +348,12 @@ mutations:
|
||||
~~~ {.xfail-test}
|
||||
fn example3() -> int {
|
||||
struct R { g: int }
|
||||
struct S { mut f: ~R }
|
||||
struct S { f: ~R }
|
||||
|
||||
let mut x = ~S {mut f: ~R {g: 3}};
|
||||
let mut x = ~S {f: ~R {g: 3}};
|
||||
let y = &x.f.g;
|
||||
x = ~S {mut f: ~R {g: 4}}; // Error reported here.
|
||||
x.f = ~R {g: 5}; // Error reported here.
|
||||
x = ~S {f: ~R {g: 4}}; // Error reported here.
|
||||
x.f = ~R {g: 5}; // Error reported here.
|
||||
*y
|
||||
}
|
||||
~~~
|
||||
@ -362,91 +362,6 @@ In this case, two errors are reported, one when the variable `x` is
|
||||
modified and another when `x.f` is modified. Either modification would
|
||||
invalidate the pointer `y`.
|
||||
|
||||
Things get trickier when the unique box is not uniquely owned by the
|
||||
stack frame, or when there is no way for the compiler to determine the
|
||||
box's owner. Consider a program like this:
|
||||
|
||||
~~~ {.xfail-test}
|
||||
struct R { g: int }
|
||||
struct S { mut f: ~R }
|
||||
fn example5a(x: @S, callback: @fn()) -> int {
|
||||
let y = &x.f.g; // Error reported here.
|
||||
...
|
||||
callback();
|
||||
...
|
||||
# return 0;
|
||||
}
|
||||
~~~
|
||||
|
||||
Here the heap looks something like:
|
||||
|
||||
~~~ {.notrust}
|
||||
Stack Managed Heap Exchange Heap
|
||||
|
||||
x +------+ +-------------+ +------+
|
||||
| @... | ----> | mut f: ~... | --+-> | g: 3 |
|
||||
y +------+ +-------------+ | +------+
|
||||
| &int | -------------------------+
|
||||
+------+
|
||||
~~~
|
||||
|
||||
In this case, the owning reference to the value being borrowed is
|
||||
`x.f`. Moreover, `x.f` is both mutable and *aliasable*. Aliasable
|
||||
means that there may be other pointers to that same managed box, so
|
||||
even if the compiler were to prove an absence of mutations to `x.f`,
|
||||
code could mutate `x.f` indirectly by changing an alias of
|
||||
`x`. Therefore, to be safe, the compiler only accepts *pure* actions
|
||||
during the lifetime of `y`. We define what "pure" means in the section
|
||||
on [purity](#purity).
|
||||
|
||||
Besides ensuring purity, the only way to borrow the interior of a
|
||||
unique found in aliasable memory is to ensure that the borrowed field
|
||||
itself is also unique, as in the following example:
|
||||
|
||||
~~~
|
||||
struct R { g: int }
|
||||
struct S { f: ~R }
|
||||
fn example5b(x: @S) -> int {
|
||||
let y = &x.f.g;
|
||||
...
|
||||
# return 0;
|
||||
}
|
||||
~~~
|
||||
|
||||
Here, the field `f` is not declared as mutable. But that is enough for
|
||||
the compiler to know that, even if aliases to `x` exist, the field `f`
|
||||
cannot be changed and hence the unique box `g` will remain valid.
|
||||
|
||||
If you do have a unique box in a mutable field, and you wish to borrow
|
||||
it, one option is to use the swap operator to move that unique box
|
||||
onto your stack:
|
||||
|
||||
~~~
|
||||
struct R { g: int }
|
||||
struct S { mut f: ~R }
|
||||
fn example5c(x: @S) -> int {
|
||||
let mut v = ~R {g: 0};
|
||||
v <-> x.f; // Swap v and x.f
|
||||
{ // Block constrains the scope of `y`:
|
||||
let y = &v.g;
|
||||
...
|
||||
}
|
||||
x.f = v; // Replace x.f
|
||||
...
|
||||
# return 0;
|
||||
}
|
||||
~~~
|
||||
|
||||
Of course, this has the side effect of modifying your managed box for
|
||||
the duration of the borrow, so it only works when you know that you
|
||||
won't be accessing that same box for the duration of the loan. Also,
|
||||
it is sometimes necessary to introduce additional blocks to constrain
|
||||
the scope of the loan. In this example, the borrowed pointer `y`
|
||||
would still be in scope when you moved the value `v` back into `x.f`,
|
||||
and hence moving `v` would be considered illegal. You cannot move
|
||||
values if they are the targets of valid outstanding loans. Introducing
|
||||
the block restricts the scope of `y`, making the move legal.
|
||||
|
||||
# Borrowing and enums
|
||||
|
||||
The previous example showed that the type system forbids any borrowing
|
||||
@ -558,11 +473,6 @@ permit `ref` bindings into data owned by the stack frame even if the
|
||||
data are mutable, but otherwise it requires that the data reside in
|
||||
immutable memory.
|
||||
|
||||
> ***Note:*** Right now, pattern bindings not explicitly annotated
|
||||
> with `ref` or `copy` use a special mode of "implicit by reference".
|
||||
> This is changing as soon as we finish updating all the existing code
|
||||
> in the compiler that relies on the current settings.
|
||||
|
||||
# Returning borrowed pointers
|
||||
|
||||
So far, all of the examples we've looked at use borrowed pointers in a
|
||||
@ -745,69 +655,6 @@ fn select<T>(shape: &Shape, threshold: float,
|
||||
|
||||
This is equivalent to the previous definition.
|
||||
|
||||
# Purity
|
||||
|
||||
As mentioned before, the Rust compiler offers a kind of escape hatch
|
||||
that permits borrowing of any data, as long as the actions that occur
|
||||
during the lifetime of the borrow are pure. Pure actions are those
|
||||
that only modify data owned by the current stack frame. The compiler
|
||||
can therefore permit arbitrary pointers into the heap, secure in the
|
||||
knowledge that no pure action will ever cause them to become
|
||||
invalidated (the compiler must still track data on the stack which is
|
||||
borrowed and enforce those rules normally, of course). A pure function
|
||||
in Rust is referentially transparent: it returns the same results
|
||||
given the same (observably equivalent) inputs. That is because while
|
||||
pure functions are allowed to modify data, they may only modify
|
||||
*stack-local* data, which cannot be observed outside the scope of the
|
||||
function itself. (Using an `unsafe` block invalidates this guarantee.)
|
||||
|
||||
Let’s revisit a previous example and show how purity can affect
|
||||
typechecking. Here is `example5a()`, which borrows the interior of a
|
||||
unique box found in an aliasable, mutable location, only now we’ve
|
||||
replaced the `...` with some specific code:
|
||||
|
||||
~~~
|
||||
struct R { g: int }
|
||||
struct S { mut f: ~R }
|
||||
fn example5a(x: @S ...) -> int {
|
||||
let y = &x.f.g; // Unsafe
|
||||
*y + 1
|
||||
}
|
||||
~~~
|
||||
|
||||
The new code simply returns an incremented version of `y`. This code
|
||||
clearly doesn't mutate the heap, so the compiler is satisfied.
|
||||
|
||||
But suppose we wanted to pull the increment code into a helper, like
|
||||
this:
|
||||
|
||||
~~~
|
||||
fn add_one(x: &int) -> int { *x + 1 }
|
||||
~~~
|
||||
|
||||
We can now update `example5a()` to use `add_one()`:
|
||||
|
||||
~~~
|
||||
# struct R { g: int }
|
||||
# struct S { mut f: ~R }
|
||||
# pure fn add_one(x: &int) -> int { *x + 1 }
|
||||
fn example5a(x: @S ...) -> int {
|
||||
let y = &x.f.g;
|
||||
add_one(y) // Error reported here
|
||||
}
|
||||
~~~
|
||||
|
||||
But now the compiler will report an error again. The reason is that it
|
||||
only considers one function at a time (like most typecheckers), and
|
||||
so it does not know that `add_one()` consists of pure code. We can
|
||||
help the compiler by labeling `add_one()` as pure:
|
||||
|
||||
~~~
|
||||
pure fn add_one(x: &int) -> int { *x + 1 }
|
||||
~~~
|
||||
|
||||
With this change, the modified version of `example5a()` will again compile.
|
||||
|
||||
# Conclusion
|
||||
|
||||
So there you have it: a (relatively) brief tour of the borrowed pointer
|
||||
|
@ -220,21 +220,21 @@ extern mod std;
|
||||
use libc::c_ulonglong;
|
||||
|
||||
struct timeval {
|
||||
mut tv_sec: c_ulonglong,
|
||||
mut tv_usec: c_ulonglong
|
||||
tv_sec: c_ulonglong,
|
||||
tv_usec: c_ulonglong
|
||||
}
|
||||
|
||||
#[nolink]
|
||||
extern mod lib_c {
|
||||
fn gettimeofday(tv: *timeval, tz: *()) -> i32;
|
||||
fn gettimeofday(tv: *mut timeval, tz: *()) -> i32;
|
||||
}
|
||||
fn unix_time_in_microseconds() -> u64 {
|
||||
unsafe {
|
||||
let x = timeval {
|
||||
mut tv_sec: 0 as c_ulonglong,
|
||||
mut tv_usec: 0 as c_ulonglong
|
||||
let mut x = timeval {
|
||||
tv_sec: 0 as c_ulonglong,
|
||||
tv_usec: 0 as c_ulonglong
|
||||
};
|
||||
lib_c::gettimeofday(ptr::addr_of(&x), ptr::null());
|
||||
lib_c::gettimeofday(&mut x, ptr::null());
|
||||
return (x.tv_sec as u64) * 1000_000_u64 + (x.tv_usec as u64);
|
||||
}
|
||||
}
|
||||
|
@ -468,7 +468,6 @@ Here is the function that implements the child task:
|
||||
|
||||
~~~~
|
||||
# use std::comm::DuplexStream;
|
||||
# use comm::{Port, Chan};
|
||||
fn stringifier(channel: &DuplexStream<~str, uint>) {
|
||||
let mut value: uint;
|
||||
loop {
|
||||
@ -491,7 +490,6 @@ Here is the code for the parent task:
|
||||
|
||||
~~~~
|
||||
# use std::comm::DuplexStream;
|
||||
# use comm::{Port, Chan};
|
||||
# use task::spawn;
|
||||
# fn stringifier(channel: &DuplexStream<~str, uint>) {
|
||||
# let mut value: uint;
|
||||
|
@ -556,7 +556,7 @@ let mut x = 5;
|
||||
loop {
|
||||
x += x - 3;
|
||||
if x % 5 == 0 { break; }
|
||||
io::println(int::str(x));
|
||||
io::println(int::to_str(x));
|
||||
}
|
||||
~~~~
|
||||
|
||||
@ -583,19 +583,16 @@ Inherited mutability means that any field of a struct may be mutable, if the
|
||||
struct is in a mutable slot (or a field of a struct in a mutable slot, and
|
||||
so forth).
|
||||
|
||||
A struct that is not mutable due to inherited mutability may declare some
|
||||
of its fields nevertheless mutable, using the `mut` keyword.
|
||||
|
||||
~~~~
|
||||
struct Stack {
|
||||
content: ~[int],
|
||||
mut head: uint
|
||||
head: uint
|
||||
}
|
||||
~~~~
|
||||
|
||||
With a value of such a type, you can do `mystack.head += 1`. If `mut` were
|
||||
omitted from the type, such an assignment to a struct without inherited
|
||||
mutability would result in a type error.
|
||||
With a value (say, `mystack`) of such a type in a mutable location, you can do
|
||||
`mystack.head += 1`. But in an immutable location, such an assignment to a
|
||||
struct without inherited mutability would result in a type error.
|
||||
|
||||
`match` patterns destructure structs. The basic syntax is
|
||||
`Name { fieldname: pattern, ... }`:
|
||||
@ -938,19 +935,19 @@ type that contains managed boxes or other managed types.
|
||||
~~~
|
||||
// A linked list node
|
||||
struct Node {
|
||||
mut next: MaybeNode,
|
||||
mut prev: MaybeNode,
|
||||
next: MaybeNode,
|
||||
prev: MaybeNode,
|
||||
payload: int
|
||||
}
|
||||
|
||||
enum MaybeNode {
|
||||
SomeNode(@Node),
|
||||
SomeNode(@mut Node),
|
||||
NoNode
|
||||
}
|
||||
|
||||
let node1 = @Node { next: NoNode, prev: NoNode, payload: 1 };
|
||||
let node2 = @Node { next: NoNode, prev: NoNode, payload: 2 };
|
||||
let node3 = @Node { next: NoNode, prev: NoNode, payload: 3 };
|
||||
let node1 = @mut Node { next: NoNode, prev: NoNode, payload: 1 };
|
||||
let node2 = @mut Node { next: NoNode, prev: NoNode, payload: 2 };
|
||||
let node3 = @mut Node { next: NoNode, prev: NoNode, payload: 3 };
|
||||
|
||||
// Link the three list nodes together
|
||||
node1.next = SomeNode(node2);
|
||||
@ -1129,7 +1126,7 @@ points to.
|
||||
|
||||
~~~
|
||||
let managed = @mut 10;
|
||||
let owned = ~mut 20;
|
||||
let mut owned = ~20;
|
||||
|
||||
let mut value = 30;
|
||||
let borrowed = &mut value;
|
||||
@ -2273,7 +2270,9 @@ fn chicken_farmer() {
|
||||
// The same, but name it `my_chicken`
|
||||
use my_chicken = farm::chicken;
|
||||
...
|
||||
# my_chicken();
|
||||
}
|
||||
# chicken();
|
||||
# }
|
||||
~~~
|
||||
|
||||
@ -2300,8 +2299,8 @@ mod farm {
|
||||
# impl Human { fn rest(&self) { } }
|
||||
# pub fn make_me_a_farm() -> farm::Farm { farm::Farm { chickens: ~[], cows: ~[], farmer: Human(0) } }
|
||||
pub struct Farm {
|
||||
priv mut chickens: ~[Chicken],
|
||||
priv mut cows: ~[Cow],
|
||||
priv chickens: ~[Chicken],
|
||||
priv cows: ~[Cow],
|
||||
farmer: Human
|
||||
}
|
||||
|
||||
|
@ -66,22 +66,17 @@
|
||||
"trait" "struct" "fn" "enum"
|
||||
"impl"))
|
||||
(puthash word 'def table))
|
||||
(dolist (word '("again" "assert"
|
||||
"break"
|
||||
"copy"
|
||||
"do" "drop"
|
||||
"else" "export" "extern"
|
||||
"fail" "for"
|
||||
"if" "use"
|
||||
"let" "log" "loop"
|
||||
"move" "new"
|
||||
"pure" "pub" "priv"
|
||||
"ref" "return" "static"
|
||||
"unchecked" "unsafe"
|
||||
"while"))
|
||||
(dolist (word '("as" "break"
|
||||
"copy" "do" "drop" "else"
|
||||
"extern" "for" "if" "let" "log"
|
||||
"loop" "once" "priv" "pub" "pure"
|
||||
"ref" "return" "static" "unsafe" "use"
|
||||
"while" "while"
|
||||
"assert"
|
||||
"mut"))
|
||||
(puthash word t table))
|
||||
(puthash "match" 'alt table)
|
||||
(dolist (word '("true" "false")) (puthash word 'atom table))
|
||||
(dolist (word '("self" "true" "false")) (puthash word 'atom table))
|
||||
table))
|
||||
;; FIXME type-context keywords
|
||||
|
||||
|
@ -422,6 +422,13 @@
|
||||
...
|
||||
}
|
||||
|
||||
{
|
||||
enum-instruction-scheduling-9
|
||||
Memcheck:Cond
|
||||
fun:*get_authority*
|
||||
...
|
||||
}
|
||||
|
||||
{
|
||||
llvm-user-new-leak
|
||||
Memcheck:Leak
|
||||
|
@ -168,7 +168,7 @@ pub mod traits {
|
||||
use kinds::Copy;
|
||||
use ops::Add;
|
||||
|
||||
pub impl<T:Copy> Add<&[const T],@[T]> for @[T] {
|
||||
impl<T:Copy> Add<&[const T],@[T]> for @[T] {
|
||||
#[inline(always)]
|
||||
pure fn add(&self, rhs: & &self/[const T]) -> @[T] {
|
||||
append(*self, (*rhs))
|
||||
|
@ -8,8 +8,8 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use core::option;
|
||||
use core::prelude::*;
|
||||
use option;
|
||||
use prelude::*;
|
||||
|
||||
/// A dynamic, mutable location.
|
||||
///
|
@ -51,6 +51,7 @@ Implicitly, all crates behave as if they included the following prologue:
|
||||
#[warn(vecs_implicitly_copyable)];
|
||||
#[deny(non_camel_case_types)];
|
||||
#[allow(deprecated_self)];
|
||||
#[allow(deprecated_mutable_fields)];
|
||||
|
||||
/* The Prelude. */
|
||||
|
||||
@ -142,6 +143,7 @@ pub mod dlist;
|
||||
#[path="iter-trait.rs"] #[merge = "iter-trait/dlist.rs"]
|
||||
pub mod dlist_iter;
|
||||
pub mod hashmap;
|
||||
pub mod cell;
|
||||
|
||||
|
||||
/* Tasks and communication */
|
||||
|
@ -133,18 +133,6 @@ impl<A> DVec<A> {
|
||||
self.check_out(|v| self.give_back(f(v)))
|
||||
}
|
||||
|
||||
/**
|
||||
* Swaps out the current vector and hands it off to a user-provided
|
||||
* function `f`. The function should transform it however is desired
|
||||
* and return a new vector to replace it with.
|
||||
*/
|
||||
#[inline(always)]
|
||||
fn swap_mut(f: &fn(v: ~[mut A]) -> ~[mut A]) {
|
||||
do self.swap |v| {
|
||||
vec::cast_from_mut(f(vec::cast_to_mut(v)))
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the number of elements currently in the dvec
|
||||
#[inline(always)]
|
||||
pure fn len() -> uint {
|
||||
@ -217,7 +205,7 @@ impl<A> DVec<A> {
|
||||
}
|
||||
|
||||
/// Gives access to the vector as a slice with mutable contents
|
||||
fn borrow_mut<R>(op: fn(x: &[mut A]) -> R) -> R {
|
||||
fn borrow_mut<R>(op: &fn(x: &mut [A]) -> R) -> R {
|
||||
do self.check_out |v| {
|
||||
let mut v = v;
|
||||
let result = op(v);
|
||||
|
@ -186,6 +186,39 @@ fn SipState(key0: u64, key1: u64) -> SipState {
|
||||
state
|
||||
}
|
||||
|
||||
// sadly, these macro definitions can't appear later,
|
||||
// because they're needed in the following defs;
|
||||
// this design could be improved.
|
||||
|
||||
macro_rules! u8to64_le (
|
||||
($buf:expr, $i:expr) =>
|
||||
($buf[0+$i] as u64 |
|
||||
$buf[1+$i] as u64 << 8 |
|
||||
$buf[2+$i] as u64 << 16 |
|
||||
$buf[3+$i] as u64 << 24 |
|
||||
$buf[4+$i] as u64 << 32 |
|
||||
$buf[5+$i] as u64 << 40 |
|
||||
$buf[6+$i] as u64 << 48 |
|
||||
$buf[7+$i] as u64 << 56)
|
||||
)
|
||||
|
||||
macro_rules! rotl (
|
||||
($x:expr, $b:expr) =>
|
||||
(($x << $b) | ($x >> (64 - $b)))
|
||||
)
|
||||
|
||||
macro_rules! compress (
|
||||
($v0:expr, $v1:expr, $v2:expr, $v3:expr) =>
|
||||
({
|
||||
$v0 += $v1; $v1 = rotl!($v1, 13); $v1 ^= $v0;
|
||||
$v0 = rotl!($v0, 32);
|
||||
$v2 += $v3; $v3 = rotl!($v3, 16); $v3 ^= $v2;
|
||||
$v0 += $v3; $v3 = rotl!($v3, 21); $v3 ^= $v0;
|
||||
$v2 += $v1; $v1 = rotl!($v1, 17); $v1 ^= $v2;
|
||||
$v2 = rotl!($v2, 32);
|
||||
})
|
||||
)
|
||||
|
||||
|
||||
impl io::Writer for SipState {
|
||||
|
||||
@ -193,35 +226,6 @@ impl io::Writer for SipState {
|
||||
#[inline(always)]
|
||||
fn write(&self, msg: &[const u8]) {
|
||||
|
||||
macro_rules! u8to64_le (
|
||||
($buf:expr, $i:expr) =>
|
||||
($buf[0+$i] as u64 |
|
||||
$buf[1+$i] as u64 << 8 |
|
||||
$buf[2+$i] as u64 << 16 |
|
||||
$buf[3+$i] as u64 << 24 |
|
||||
$buf[4+$i] as u64 << 32 |
|
||||
$buf[5+$i] as u64 << 40 |
|
||||
$buf[6+$i] as u64 << 48 |
|
||||
$buf[7+$i] as u64 << 56)
|
||||
);
|
||||
|
||||
macro_rules! rotl (
|
||||
($x:expr, $b:expr) =>
|
||||
(($x << $b) | ($x >> (64 - $b)))
|
||||
);
|
||||
|
||||
macro_rules! compress (
|
||||
($v0:expr, $v1:expr, $v2:expr, $v3:expr) =>
|
||||
({
|
||||
$v0 += $v1; $v1 = rotl!($v1, 13); $v1 ^= $v0;
|
||||
$v0 = rotl!($v0, 32);
|
||||
$v2 += $v3; $v3 = rotl!($v3, 16); $v3 ^= $v2;
|
||||
$v0 += $v3; $v3 = rotl!($v3, 21); $v3 ^= $v0;
|
||||
$v2 += $v1; $v1 = rotl!($v1, 17); $v1 ^= $v2;
|
||||
$v2 = rotl!($v2, 32);
|
||||
})
|
||||
);
|
||||
|
||||
let length = msg.len();
|
||||
self.length += length;
|
||||
|
||||
|
@ -284,7 +284,7 @@ impl num::One for f32 {
|
||||
static pure fn one() -> f32 { 1.0 }
|
||||
}
|
||||
|
||||
pub impl NumCast for f32 {
|
||||
impl NumCast for f32 {
|
||||
/**
|
||||
* Cast `n` to an `f32`
|
||||
*/
|
||||
|
@ -299,7 +299,7 @@ impl cmp::Ord for f64 {
|
||||
pure fn gt(&self, other: &f64) -> bool { (*self) > (*other) }
|
||||
}
|
||||
|
||||
pub impl NumCast for f64 {
|
||||
impl NumCast for f64 {
|
||||
/**
|
||||
* Cast `n` to an `f64`
|
||||
*/
|
||||
|
@ -420,7 +420,7 @@ impl num::One for float {
|
||||
static pure fn one() -> float { 1.0 }
|
||||
}
|
||||
|
||||
pub impl NumCast for float {
|
||||
impl NumCast for float {
|
||||
/**
|
||||
* Cast `n` to a `float`
|
||||
*/
|
||||
|
@ -265,11 +265,6 @@ pub pure fn to_str_radix(num: T, radix: uint) -> ~str {
|
||||
buf
|
||||
}
|
||||
|
||||
/// Convert to a string.
|
||||
/// *Deprecated*, use to_str() instead.
|
||||
#[inline(always)]
|
||||
pub pure fn str(i: T) -> ~str { to_str(i) }
|
||||
|
||||
impl ToStr for T {
|
||||
#[inline(always)]
|
||||
pure fn to_str(&self) -> ~str {
|
||||
|
@ -17,7 +17,7 @@ mod inst {
|
||||
pub const bits: uint = ::u16::bits;
|
||||
}
|
||||
|
||||
pub impl NumCast for i16 {
|
||||
impl NumCast for i16 {
|
||||
/**
|
||||
* Cast `n` to a `i16`
|
||||
*/
|
||||
|
@ -17,7 +17,7 @@ mod inst {
|
||||
pub const bits: uint = ::u32::bits;
|
||||
}
|
||||
|
||||
pub impl NumCast for i32 {
|
||||
impl NumCast for i32 {
|
||||
/**
|
||||
* Cast `n` to a `i32`
|
||||
*/
|
||||
|
@ -17,7 +17,7 @@ mod inst {
|
||||
pub const bits: uint = ::u64::bits;
|
||||
}
|
||||
|
||||
pub impl NumCast for i64 {
|
||||
impl NumCast for i64 {
|
||||
/**
|
||||
* Cast `n` to a `i64`
|
||||
*/
|
||||
|
@ -17,7 +17,7 @@ mod inst {
|
||||
pub const bits: uint = ::u8::bits;
|
||||
}
|
||||
|
||||
pub impl NumCast for i8 {
|
||||
impl NumCast for i8 {
|
||||
/**
|
||||
* Cast `n` to a `i8`
|
||||
*/
|
||||
|
@ -58,7 +58,7 @@ mod inst {
|
||||
}
|
||||
}
|
||||
|
||||
pub impl NumCast for int {
|
||||
impl NumCast for int {
|
||||
/**
|
||||
* Cast `n` to a `int`
|
||||
*/
|
||||
|
@ -229,11 +229,6 @@ pub pure fn to_str_radix(num: T, radix: uint) -> ~str {
|
||||
buf
|
||||
}
|
||||
|
||||
/// Convert to a string.
|
||||
/// *Deprecated*, use to_str() instead.
|
||||
#[inline(always)]
|
||||
pub pure fn str(i: T) -> ~str { to_str(i) }
|
||||
|
||||
impl ToStr for T {
|
||||
#[inline(always)]
|
||||
pure fn to_str(&self) -> ~str {
|
||||
|
@ -19,7 +19,7 @@ mod inst {
|
||||
pub const bits: uint = 16;
|
||||
}
|
||||
|
||||
pub impl NumCast for u16 {
|
||||
impl NumCast for u16 {
|
||||
/**
|
||||
* Cast `n` to a `u16`
|
||||
*/
|
||||
|
@ -19,7 +19,7 @@ mod inst {
|
||||
pub const bits: uint = 32;
|
||||
}
|
||||
|
||||
pub impl NumCast for u32 {
|
||||
impl NumCast for u32 {
|
||||
/**
|
||||
* Cast `n` to a `u32`
|
||||
*/
|
||||
|
@ -19,7 +19,7 @@ mod inst {
|
||||
pub const bits: uint = 64;
|
||||
}
|
||||
|
||||
pub impl NumCast for u64 {
|
||||
impl NumCast for u64 {
|
||||
/**
|
||||
* Cast `n` to a `u64`
|
||||
*/
|
||||
|
@ -26,7 +26,7 @@ mod inst {
|
||||
pub pure fn is_ascii(x: T) -> bool { return 0 as T == x & 128 as T; }
|
||||
}
|
||||
|
||||
pub impl NumCast for u8 {
|
||||
impl NumCast for u8 {
|
||||
/**
|
||||
* Cast `n` to a `u8`
|
||||
*/
|
||||
|
@ -110,7 +110,7 @@ pub mod inst {
|
||||
return true;
|
||||
}
|
||||
|
||||
pub impl iter::Times for uint {
|
||||
impl iter::Times for uint {
|
||||
#[inline(always)]
|
||||
/**
|
||||
* A convenience form for basic iteration. Given a uint `x`,
|
||||
@ -209,7 +209,7 @@ pub mod inst {
|
||||
}
|
||||
}
|
||||
|
||||
pub impl NumCast for uint {
|
||||
impl NumCast for uint {
|
||||
/**
|
||||
* Cast `n` to a `uint`
|
||||
*/
|
||||
|
@ -56,7 +56,7 @@ pub enum Option<T> {
|
||||
Some(T),
|
||||
}
|
||||
|
||||
pub impl<T:Ord> Ord for Option<T> {
|
||||
impl<T:Ord> Ord for Option<T> {
|
||||
pure fn lt(&self, other: &Option<T>) -> bool {
|
||||
match (self, other) {
|
||||
(&None, &None) => false,
|
||||
|
@ -109,7 +109,7 @@ pub mod win32 {
|
||||
let mut done = false;
|
||||
while !done {
|
||||
let mut k: DWORD = 0;
|
||||
let buf = vec::cast_to_mut(vec::from_elem(n as uint, 0u16));
|
||||
let mut buf = vec::from_elem(n as uint, 0u16);
|
||||
do vec::as_mut_buf(buf) |b, _sz| {
|
||||
k = f(b, TMPBUF_SZ as DWORD);
|
||||
if k == (0 as DWORD) {
|
||||
@ -566,17 +566,13 @@ pub fn path_exists(p: &Path) -> bool {
|
||||
*
|
||||
* If the given path is relative, return it prepended with the current working
|
||||
* directory. If the given path is already an absolute path, return it
|
||||
* as is.
|
||||
* as is. This is a shortcut for calling os::getcwd().unsafe_join(p)
|
||||
*/
|
||||
// NB: this is here rather than in path because it is a form of environment
|
||||
// querying; what it does depends on the process working directory, not just
|
||||
// the input paths.
|
||||
pub fn make_absolute(p: &Path) -> Path {
|
||||
if p.is_absolute {
|
||||
copy *p
|
||||
} else {
|
||||
getcwd().push_many(p.components)
|
||||
}
|
||||
getcwd().unsafe_join(p)
|
||||
}
|
||||
|
||||
|
||||
|
@ -13,22 +13,22 @@
|
||||
use cmp::{Eq, Ord};
|
||||
|
||||
#[cfg(notest)]
|
||||
impl<T:Eq> Eq for ~const T {
|
||||
impl<T:Eq> Eq for ~T {
|
||||
#[inline(always)]
|
||||
pure fn eq(&self, other: &~const T) -> bool { *(*self) == *(*other) }
|
||||
pure fn eq(&self, other: &~T) -> bool { *(*self) == *(*other) }
|
||||
#[inline(always)]
|
||||
pure fn ne(&self, other: &~const T) -> bool { *(*self) != *(*other) }
|
||||
pure fn ne(&self, other: &~T) -> bool { *(*self) != *(*other) }
|
||||
}
|
||||
|
||||
#[cfg(notest)]
|
||||
impl<T:Ord> Ord for ~const T {
|
||||
impl<T:Ord> Ord for ~T {
|
||||
#[inline(always)]
|
||||
pure fn lt(&self, other: &~const T) -> bool { *(*self) < *(*other) }
|
||||
pure fn lt(&self, other: &~T) -> bool { *(*self) < *(*other) }
|
||||
#[inline(always)]
|
||||
pure fn le(&self, other: &~const T) -> bool { *(*self) <= *(*other) }
|
||||
pure fn le(&self, other: &~T) -> bool { *(*self) <= *(*other) }
|
||||
#[inline(always)]
|
||||
pure fn ge(&self, other: &~const T) -> bool { *(*self) >= *(*other) }
|
||||
pure fn ge(&self, other: &~T) -> bool { *(*self) >= *(*other) }
|
||||
#[inline(always)]
|
||||
pure fn gt(&self, other: &~const T) -> bool { *(*self) > *(*other) }
|
||||
pure fn gt(&self, other: &~T) -> bool { *(*self) > *(*other) }
|
||||
}
|
||||
|
||||
|
@ -64,6 +64,9 @@ pub trait GenericPath {
|
||||
pure fn push_many((&[~str])) -> Self;
|
||||
pure fn pop() -> Self;
|
||||
|
||||
pure fn unsafe_join((&Self)) -> Self;
|
||||
pure fn is_restricted() -> bool;
|
||||
|
||||
pure fn normalize() -> Self;
|
||||
}
|
||||
|
||||
@ -485,6 +488,19 @@ impl GenericPath for PosixPath {
|
||||
self.push_many(other.components)
|
||||
}
|
||||
|
||||
pure fn unsafe_join(other: &PosixPath) -> PosixPath {
|
||||
if other.is_absolute {
|
||||
PosixPath { is_absolute: true,
|
||||
components: copy other.components }
|
||||
} else {
|
||||
self.push_rel(other)
|
||||
}
|
||||
}
|
||||
|
||||
pure fn is_restricted() -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
pure fn push_many(cs: &[~str]) -> PosixPath {
|
||||
let mut v = copy self.components;
|
||||
for cs.each |e| {
|
||||
@ -685,6 +701,61 @@ impl GenericPath for WindowsPath {
|
||||
self.push_many(other.components)
|
||||
}
|
||||
|
||||
pure fn unsafe_join(other: &WindowsPath) -> WindowsPath {
|
||||
/* rhs not absolute is simple push */
|
||||
if !other.is_absolute {
|
||||
return self.push_many(other.components);
|
||||
}
|
||||
|
||||
/* if rhs has a host set, then the whole thing wins */
|
||||
match other.host {
|
||||
Some(copy host) => {
|
||||
return WindowsPath {
|
||||
host: Some(host),
|
||||
device: copy other.device,
|
||||
is_absolute: true,
|
||||
components: copy other.components
|
||||
};
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
/* if rhs has a device set, then a part wins */
|
||||
match other.device {
|
||||
Some(copy device) => {
|
||||
return WindowsPath {
|
||||
host: None,
|
||||
device: Some(device),
|
||||
is_absolute: true,
|
||||
components: copy other.components
|
||||
};
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
/* fallback: host and device of lhs win, but the
|
||||
whole path of the right */
|
||||
WindowsPath {
|
||||
host: copy self.host,
|
||||
device: copy self.device,
|
||||
is_absolute: self.is_absolute || other.is_absolute,
|
||||
components: copy other.components
|
||||
}
|
||||
}
|
||||
|
||||
pure fn is_restricted() -> bool {
|
||||
match self.filestem() {
|
||||
Some(stem) => {
|
||||
match stem.to_lower() {
|
||||
~"con" | ~"aux" | ~"com1" | ~"com2" | ~"com3" | ~"com4" |
|
||||
~"lpt1" | ~"lpt2" | ~"lpt3" | ~"prn" | ~"nul" => true,
|
||||
_ => false
|
||||
}
|
||||
},
|
||||
None => false
|
||||
}
|
||||
}
|
||||
|
||||
pure fn push_many(cs: &[~str]) -> WindowsPath {
|
||||
let mut v = copy self.components;
|
||||
for cs.each |e| {
|
||||
@ -725,7 +796,10 @@ impl GenericPath for WindowsPath {
|
||||
pure fn normalize() -> WindowsPath {
|
||||
return WindowsPath {
|
||||
host: copy self.host,
|
||||
device: copy self.device,
|
||||
device: match self.device {
|
||||
None => None,
|
||||
Some(ref device) => Some(device.to_upper())
|
||||
},
|
||||
is_absolute: self.is_absolute,
|
||||
components: normalize(self.components)
|
||||
}
|
||||
@ -764,13 +838,13 @@ pub mod windows {
|
||||
|
||||
pub pure fn extract_unc_prefix(s: &str) -> Option<(~str,~str)> {
|
||||
if (s.len() > 1 &&
|
||||
s[0] == '\\' as u8 &&
|
||||
s[1] == '\\' as u8) {
|
||||
(s[0] == '\\' as u8 || s[0] == '/' as u8) &&
|
||||
s[0] == s[1]) {
|
||||
let mut i = 2;
|
||||
while i < s.len() {
|
||||
if s[i] == '\\' as u8 {
|
||||
if is_sep(s[i]) {
|
||||
let pre = s.slice(2, i);
|
||||
let rest = s.slice(i, s.len());
|
||||
let mut rest = s.slice(i, s.len());
|
||||
return Some((pre, rest));
|
||||
}
|
||||
i += 1;
|
||||
@ -916,13 +990,21 @@ mod tests {
|
||||
#[test]
|
||||
fn test_extract_unc_prefixes() {
|
||||
assert windows::extract_unc_prefix("\\\\").is_none();
|
||||
assert windows::extract_unc_prefix("//").is_none();
|
||||
assert windows::extract_unc_prefix("\\\\hi").is_none();
|
||||
assert windows::extract_unc_prefix("//hi").is_none();
|
||||
assert windows::extract_unc_prefix("\\\\hi\\") ==
|
||||
Some((~"hi", ~"\\"));
|
||||
assert windows::extract_unc_prefix("//hi\\") ==
|
||||
Some((~"hi", ~"\\"));
|
||||
assert windows::extract_unc_prefix("\\\\hi\\there") ==
|
||||
Some((~"hi", ~"\\there"));
|
||||
assert windows::extract_unc_prefix("//hi/there") ==
|
||||
Some((~"hi", ~"/there"));
|
||||
assert windows::extract_unc_prefix("\\\\hi\\there\\friends.txt") ==
|
||||
Some((~"hi", ~"\\there\\friends.txt"));
|
||||
assert windows::extract_unc_prefix("//hi\\there\\friends.txt") ==
|
||||
Some((~"hi", ~"\\there\\friends.txt"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -981,5 +1063,61 @@ mod tests {
|
||||
.push_many([~"lib", ~"thingy.dll"])
|
||||
.with_filename("librustc.dll")),
|
||||
"c:\\program files (x86)\\rust\\lib\\librustc.dll");
|
||||
|
||||
t(&(WindowsPath("\\\\computer\\share")
|
||||
.unsafe_join(&WindowsPath("\\a"))),
|
||||
"\\\\computer\\a");
|
||||
|
||||
t(&(WindowsPath("//computer/share")
|
||||
.unsafe_join(&WindowsPath("\\a"))),
|
||||
"\\\\computer\\a");
|
||||
|
||||
t(&(WindowsPath("//computer/share")
|
||||
.unsafe_join(&WindowsPath("\\\\computer\\share"))),
|
||||
"\\\\computer\\share");
|
||||
|
||||
t(&(WindowsPath("C:/whatever")
|
||||
.unsafe_join(&WindowsPath("//computer/share/a/b"))),
|
||||
"\\\\computer\\share\\a\\b");
|
||||
|
||||
t(&(WindowsPath("C:")
|
||||
.unsafe_join(&WindowsPath("D:/foo"))),
|
||||
"D:\\foo");
|
||||
|
||||
t(&(WindowsPath("C:")
|
||||
.unsafe_join(&WindowsPath("B"))),
|
||||
"C:B");
|
||||
|
||||
t(&(WindowsPath("C:")
|
||||
.unsafe_join(&WindowsPath("/foo"))),
|
||||
"C:\\foo");
|
||||
|
||||
t(&(WindowsPath("C:\\")
|
||||
.unsafe_join(&WindowsPath("\\bar"))),
|
||||
"C:\\bar");
|
||||
|
||||
t(&(WindowsPath("")
|
||||
.unsafe_join(&WindowsPath(""))),
|
||||
"");
|
||||
|
||||
t(&(WindowsPath("")
|
||||
.unsafe_join(&WindowsPath("a"))),
|
||||
"a");
|
||||
|
||||
t(&(WindowsPath("")
|
||||
.unsafe_join(&WindowsPath("C:\\a"))),
|
||||
"C:\\a");
|
||||
|
||||
t(&(WindowsPath("c:\\foo")
|
||||
.normalize()),
|
||||
"C:\\foo");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_windows_path_restrictions() {
|
||||
assert WindowsPath("hi").is_restricted() == false;
|
||||
assert WindowsPath("C:\\NUL").is_restricted() == true;
|
||||
assert WindowsPath("C:\\COM1.TXT").is_restricted() == true;
|
||||
assert WindowsPath("c:\\prn.exe").is_restricted() == true;
|
||||
}
|
||||
}
|
||||
|
@ -86,6 +86,7 @@ bounded and unbounded protocols allows for less code duplication.
|
||||
|
||||
use cmp::Eq;
|
||||
use cast::{forget, reinterpret_cast, transmute};
|
||||
use cell::Cell;
|
||||
use either::{Either, Left, Right};
|
||||
use kinds::Owned;
|
||||
use libc;
|
||||
@ -917,11 +918,9 @@ pub fn spawn_service<T:Owned,Tb:Owned>(
|
||||
|
||||
// This is some nasty gymnastics required to safely move the pipe
|
||||
// into a new task.
|
||||
let server = ~mut Some(server);
|
||||
do task::spawn || {
|
||||
let mut server_ = None;
|
||||
server_ <-> *server;
|
||||
service(option::unwrap(server_))
|
||||
let server = Cell(server);
|
||||
do task::spawn {
|
||||
service(server.take());
|
||||
}
|
||||
|
||||
client
|
||||
@ -941,11 +940,9 @@ pub fn spawn_service_recv<T:Owned,Tb:Owned>(
|
||||
|
||||
// This is some nasty gymnastics required to safely move the pipe
|
||||
// into a new task.
|
||||
let server = ~mut Some(server);
|
||||
do task::spawn || {
|
||||
let mut server_ = None;
|
||||
server_ <-> *server;
|
||||
service(option::unwrap(server_))
|
||||
let server = Cell(server);
|
||||
do task::spawn {
|
||||
service(server.take())
|
||||
}
|
||||
|
||||
client
|
||||
|
@ -107,10 +107,14 @@ fn compare_and_swap(address: &mut int, oldval: int, newval: int) -> bool {
|
||||
* Shared state & exclusive ARC
|
||||
****************************************************************************/
|
||||
|
||||
struct UnwrapProtoInner {
|
||||
contents: Option<(comm::ChanOne<()>, comm::PortOne<bool>)>,
|
||||
}
|
||||
|
||||
// An unwrapper uses this protocol to communicate with the "other" task that
|
||||
// drops the last refcount on an arc. Unfortunately this can't be a proper
|
||||
// pipe protocol because the unwrapper has to access both stages at once.
|
||||
type UnwrapProto = ~mut Option<(comm::ChanOne<()>, comm::PortOne<bool>)>;
|
||||
type UnwrapProto = ~UnwrapProtoInner;
|
||||
|
||||
struct ArcData<T> {
|
||||
mut count: libc::intptr_t,
|
||||
@ -139,9 +143,10 @@ struct ArcDestruct<T> {
|
||||
// reference. In effect, being here means we're the only
|
||||
// *awake* task with the data.
|
||||
if data.unwrapper != 0 {
|
||||
let p: UnwrapProto =
|
||||
let mut p: UnwrapProto =
|
||||
cast::reinterpret_cast(&data.unwrapper);
|
||||
let (message, response) = option::swap_unwrap(p);
|
||||
let (message, response) =
|
||||
option::swap_unwrap(&mut p.contents);
|
||||
// Send 'ready' and wait for a response.
|
||||
comm::send_one(message, ());
|
||||
// Unkillable wait. Message guaranteed to come.
|
||||
@ -196,7 +201,9 @@ pub unsafe fn unwrap_shared_mutable_state<T:Owned>(rc: SharedMutableState<T>)
|
||||
let ptr: ~ArcData<T> = cast::reinterpret_cast(&rc.data);
|
||||
let (p1,c1) = comm::oneshot(); // ()
|
||||
let (p2,c2) = comm::oneshot(); // bool
|
||||
let server: UnwrapProto = ~mut Some((c1,p2));
|
||||
let mut server: UnwrapProto = ~UnwrapProtoInner {
|
||||
contents: Some((c1,p2))
|
||||
};
|
||||
let serverp: int = cast::transmute(server);
|
||||
// Try to put our server end in the unwrapper slot.
|
||||
if compare_and_swap(&mut ptr.unwrapper, 0, serverp) {
|
||||
@ -409,8 +416,9 @@ pub fn unwrap_exclusive<T:Owned>(arc: Exclusive<T>) -> T {
|
||||
pub mod tests {
|
||||
use core::option::{None, Some};
|
||||
|
||||
use option;
|
||||
use cell::Cell;
|
||||
use comm;
|
||||
use option;
|
||||
use private::{exclusive, unwrap_exclusive};
|
||||
use result;
|
||||
use task;
|
||||
@ -423,7 +431,7 @@ pub mod tests {
|
||||
let num_tasks = 10;
|
||||
let count = 10;
|
||||
|
||||
let total = exclusive(~mut 0);
|
||||
let total = exclusive(~0);
|
||||
|
||||
for uint::range(0, num_tasks) |_i| {
|
||||
let total = total.clone();
|
||||
@ -472,9 +480,9 @@ pub mod tests {
|
||||
#[test]
|
||||
pub fn exclusive_unwrap_contended() {
|
||||
let x = exclusive(~~"hello");
|
||||
let x2 = ~mut Some(x.clone());
|
||||
do task::spawn || {
|
||||
let x2 = option::swap_unwrap(x2);
|
||||
let x2 = Cell(x.clone());
|
||||
do task::spawn {
|
||||
let x2 = x2.take();
|
||||
do x2.with |_hello| { }
|
||||
task::yield();
|
||||
}
|
||||
@ -482,11 +490,10 @@ pub mod tests {
|
||||
|
||||
// Now try the same thing, but with the child task blocking.
|
||||
let x = exclusive(~~"hello");
|
||||
let x2 = ~mut Some(x.clone());
|
||||
let x2 = Cell(x.clone());
|
||||
let mut res = None;
|
||||
do task::task().future_result(|+r| res = Some(r)).spawn
|
||||
|| {
|
||||
let x2 = option::swap_unwrap(x2);
|
||||
do task::task().future_result(|+r| res = Some(r)).spawn {
|
||||
let x2 = x2.take();
|
||||
assert unwrap_exclusive(x2) == ~~"hello";
|
||||
}
|
||||
// Have to get rid of our reference before blocking.
|
||||
@ -498,11 +505,10 @@ pub mod tests {
|
||||
#[test] #[should_fail] #[ignore(cfg(windows))]
|
||||
pub fn exclusive_unwrap_conflict() {
|
||||
let x = exclusive(~~"hello");
|
||||
let x2 = ~mut Some(x.clone());
|
||||
let x2 = Cell(x.clone());
|
||||
let mut res = None;
|
||||
do task::task().future_result(|+r| res = Some(r)).spawn
|
||||
|| {
|
||||
let x2 = option::swap_unwrap(x2);
|
||||
do task::task().future_result(|+r| res = Some(r)).spawn {
|
||||
let x2 = x2.take();
|
||||
assert unwrap_exclusive(x2) == ~~"hello";
|
||||
}
|
||||
assert unwrap_exclusive(x) == ~~"hello";
|
||||
|
@ -18,16 +18,17 @@ it is running, sending a notification to the task that the runtime
|
||||
is trying to shut down.
|
||||
*/
|
||||
|
||||
use option::{Some, None, swap_unwrap};
|
||||
use private::at_exit::at_exit;
|
||||
use private::global::global_data_clone_create;
|
||||
use private::finally::Finally;
|
||||
use comm::{Port, Chan, SharedChan, GenericChan,
|
||||
GenericPort, GenericSmartChan, stream};
|
||||
use task::{Task, task, spawn};
|
||||
use task::rt::{task_id, get_task_id};
|
||||
use cell::Cell;
|
||||
use comm::{GenericSmartChan, stream};
|
||||
use comm::{Port, Chan, SharedChan, GenericChan, GenericPort};
|
||||
use hashmap::linear::LinearMap;
|
||||
use ops::Drop;
|
||||
use option::{Some, None, swap_unwrap};
|
||||
use private::at_exit::at_exit;
|
||||
use private::finally::Finally;
|
||||
use private::global::global_data_clone_create;
|
||||
use task::rt::{task_id, get_task_id};
|
||||
use task::{Task, task, spawn};
|
||||
|
||||
type ShutdownMsg = ();
|
||||
|
||||
@ -37,14 +38,13 @@ pub unsafe fn weaken_task(f: &fn(Port<ShutdownMsg>)) {
|
||||
let service = global_data_clone_create(global_data_key,
|
||||
create_global_service);
|
||||
let (shutdown_port, shutdown_chan) = stream::<ShutdownMsg>();
|
||||
let shutdown_port = ~mut Some(shutdown_port);
|
||||
let shutdown_port = Cell(shutdown_port);
|
||||
let task = get_task_id();
|
||||
// Expect the weak task service to be alive
|
||||
assert service.try_send(RegisterWeakTask(task, shutdown_chan));
|
||||
unsafe { rust_dec_kernel_live_count(); }
|
||||
do fn&() {
|
||||
let shutdown_port = swap_unwrap(&mut *shutdown_port);
|
||||
f(shutdown_port)
|
||||
f(shutdown_port.take())
|
||||
}.finally || {
|
||||
unsafe { rust_inc_kernel_live_count(); }
|
||||
// Service my have already exited
|
||||
@ -67,16 +67,15 @@ fn create_global_service() -> ~WeakTaskService {
|
||||
|
||||
debug!("creating global weak task service");
|
||||
let (port, chan) = stream::<ServiceMsg>();
|
||||
let port = ~mut Some(port);
|
||||
let port = Cell(port);
|
||||
let chan = SharedChan(chan);
|
||||
let chan_clone = chan.clone();
|
||||
|
||||
do task().unlinked().spawn {
|
||||
debug!("running global weak task service");
|
||||
let port = swap_unwrap(&mut *port);
|
||||
let port = ~mut Some(port);
|
||||
let port = Cell(port.take());
|
||||
do fn&() {
|
||||
let port = swap_unwrap(&mut *port);
|
||||
let port = port.take();
|
||||
// The weak task service is itself a weak task
|
||||
debug!("weakening the weak service task");
|
||||
unsafe { rust_dec_kernel_live_count(); }
|
||||
|
@ -602,7 +602,6 @@ fn test_repr() {
|
||||
exact_test(&(@10), "@10");
|
||||
exact_test(&(@mut 10), "@10");
|
||||
exact_test(&(~10), "~10");
|
||||
exact_test(&(~mut 10), "~mut 10");
|
||||
exact_test(&(&10), "&10");
|
||||
let mut x = 10;
|
||||
exact_test(&(&mut x), "&mut 10");
|
||||
|
@ -11,7 +11,7 @@
|
||||
//! Runtime calls emitted by the compiler.
|
||||
|
||||
use cast::transmute;
|
||||
use libc::{c_char, c_uchar, c_void, size_t, uintptr_t};
|
||||
use libc::{c_char, c_uchar, c_void, size_t, uintptr_t, c_int};
|
||||
use managed::raw::BoxRepr;
|
||||
use str;
|
||||
use sys;
|
||||
@ -121,6 +121,21 @@ pub unsafe fn strdup_uniq(ptr: *c_uchar, len: uint) -> ~str {
|
||||
str::raw::from_buf_len(ptr, len)
|
||||
}
|
||||
|
||||
#[lang="start"]
|
||||
pub fn start(main: *u8, argc: int, argv: *c_char,
|
||||
crate_map: *u8) -> int {
|
||||
|
||||
extern {
|
||||
fn rust_start(main: *c_void, argc: c_int, argv: *c_char,
|
||||
crate_map: *c_void) -> c_int;
|
||||
}
|
||||
|
||||
unsafe {
|
||||
return rust_start(main as *c_void, argc as c_int, argv,
|
||||
crate_map as *c_void) as int;
|
||||
}
|
||||
}
|
||||
|
||||
// Local Variables:
|
||||
// mode: rust;
|
||||
// fill-column: 78;
|
||||
|
@ -590,6 +590,40 @@ pub pure fn split_str_nonempty(s: &a/str, sep: &b/str) -> ~[~str] {
|
||||
result
|
||||
}
|
||||
|
||||
/// Levenshtein Distance between two strings
|
||||
pub fn levdistance(s: &str, t: &str) -> uint {
|
||||
|
||||
let slen = str::len(s);
|
||||
let tlen = str::len(t);
|
||||
|
||||
if slen == 0 { return tlen; }
|
||||
if tlen == 0 { return slen; }
|
||||
|
||||
let mut dcol = vec::from_fn(tlen + 1, |x| x);
|
||||
|
||||
for str::each_chari(s) |i, sc| {
|
||||
|
||||
let mut current = i;
|
||||
dcol[0] = current + 1;
|
||||
|
||||
for str::each_chari(t) |j, tc| {
|
||||
|
||||
let mut next = dcol[j + 1];
|
||||
|
||||
if sc == tc {
|
||||
dcol[j + 1] = current;
|
||||
} else {
|
||||
dcol[j + 1] = ::cmp::min(current, next);
|
||||
dcol[j + 1] = ::cmp::min(dcol[j + 1], dcol[j]) + 1;
|
||||
}
|
||||
|
||||
current = next;
|
||||
}
|
||||
}
|
||||
|
||||
return dcol[tlen];
|
||||
}
|
||||
|
||||
/**
|
||||
* Splits a string into a vector of the substrings separated by LF ('\n')
|
||||
*/
|
||||
@ -2328,7 +2362,7 @@ pub trait OwnedStr {
|
||||
fn push_char(&mut self, c: char);
|
||||
}
|
||||
|
||||
pub impl OwnedStr for ~str {
|
||||
impl OwnedStr for ~str {
|
||||
fn push_str(&mut self, v: &str) {
|
||||
push_str(self, v);
|
||||
}
|
||||
|
@ -34,6 +34,7 @@
|
||||
*/
|
||||
|
||||
use cast;
|
||||
use cell::Cell;
|
||||
use cmp;
|
||||
use cmp::Eq;
|
||||
use iter;
|
||||
@ -397,9 +398,9 @@ impl TaskBuilder {
|
||||
}
|
||||
/// Runs a task, while transfering ownership of one argument to the child.
|
||||
fn spawn_with<A:Owned>(arg: A, f: fn~(v: A)) {
|
||||
let arg = ~mut Some(arg);
|
||||
do self.spawn || {
|
||||
f(option::swap_unwrap(arg))
|
||||
let arg = Cell(arg);
|
||||
do self.spawn {
|
||||
f(arg.take());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -73,6 +73,7 @@
|
||||
#[doc(hidden)]; // FIXME #3538
|
||||
|
||||
use cast;
|
||||
use cell::Cell;
|
||||
use container::Map;
|
||||
use option;
|
||||
use comm::{Chan, GenericChan, GenericPort, Port, stream};
|
||||
@ -530,11 +531,11 @@ pub fn spawn_raw(opts: TaskOpts, f: fn~()) {
|
||||
gen_child_taskgroup(opts.linked, opts.supervised);
|
||||
|
||||
unsafe {
|
||||
let child_data = ~mut Some((child_tg, ancestors, f));
|
||||
let child_data = Cell((child_tg, ancestors, f));
|
||||
// Being killed with the unsafe task/closure pointers would leak them.
|
||||
do unkillable {
|
||||
// Agh. Get move-mode items into the closure. FIXME (#2829)
|
||||
let (child_tg, ancestors, f) = option::swap_unwrap(child_data);
|
||||
let (child_tg, ancestors, f) = child_data.take();
|
||||
// Create child task.
|
||||
let new_task = match opts.sched.mode {
|
||||
DefaultScheduler => rt::new_task(),
|
||||
@ -571,10 +572,10 @@ pub fn spawn_raw(opts: TaskOpts, f: fn~()) {
|
||||
ancestors: AncestorList, is_main: bool,
|
||||
notify_chan: Option<Chan<TaskResult>>,
|
||||
f: fn~()) -> fn~() {
|
||||
let child_data = ~mut Some((child_arc, ancestors));
|
||||
let child_data = Cell((child_arc, ancestors));
|
||||
return fn~() {
|
||||
// Agh. Get move-mode items into the closure. FIXME (#2829)
|
||||
let mut (child_arc, ancestors) = option::swap_unwrap(child_data);
|
||||
let mut (child_arc, ancestors) = child_data.take();
|
||||
// Child task runs this code.
|
||||
|
||||
// Even if the below code fails to kick the child off, we must
|
||||
|
@ -170,7 +170,7 @@ impl IterBytes for char {
|
||||
pub mod x32 {
|
||||
use to_bytes::{Cb, IterBytes};
|
||||
|
||||
pub impl IterBytes for uint {
|
||||
impl IterBytes for uint {
|
||||
#[inline(always)]
|
||||
pure fn iter_bytes(&self, lsb0: bool, f: Cb) {
|
||||
(*self as u32).iter_bytes(lsb0, f)
|
||||
@ -182,7 +182,7 @@ pub mod x32 {
|
||||
pub mod x64 {
|
||||
use to_bytes::{Cb, IterBytes};
|
||||
|
||||
pub impl IterBytes for uint {
|
||||
impl IterBytes for uint {
|
||||
#[inline(always)]
|
||||
pure fn iter_bytes(&self, lsb0: bool, f: Cb) {
|
||||
(*self as u64).iter_bytes(lsb0, f)
|
||||
|
@ -209,16 +209,6 @@ pub pure fn build_sized_opt<A>(size: Option<uint>,
|
||||
build_sized(size.get_or_default(4), builder)
|
||||
}
|
||||
|
||||
/// Produces a mut vector from an immutable vector.
|
||||
pub pure fn cast_to_mut<T>(v: ~[T]) -> ~[mut T] {
|
||||
unsafe { ::cast::transmute(v) }
|
||||
}
|
||||
|
||||
/// Produces an immutable vector from a mut vector.
|
||||
pub pure fn cast_from_mut<T>(v: ~[mut T]) -> ~[T] {
|
||||
unsafe { ::cast::transmute(v) }
|
||||
}
|
||||
|
||||
// Accessors
|
||||
|
||||
/// Returns the first element of a vector
|
||||
@ -274,9 +264,10 @@ pub pure fn slice<T>(v: &r/[T], start: uint, end: uint) -> &r/[T] {
|
||||
|
||||
/// Return a slice that points into another slice.
|
||||
#[inline(always)]
|
||||
pub pure fn mut_slice<T>(v: &r/[mut T], start: uint,
|
||||
end: uint) -> &r/[mut T] {
|
||||
|
||||
pub pure fn mut_slice<T>(v: &r/mut [T],
|
||||
start: uint,
|
||||
end: uint)
|
||||
-> &r/mut [T] {
|
||||
assert (start <= end);
|
||||
assert (end <= len(v));
|
||||
do as_mut_buf(v) |p, _len| {
|
||||
@ -290,8 +281,10 @@ pub pure fn mut_slice<T>(v: &r/[mut T], start: uint,
|
||||
|
||||
/// Return a slice that points into another slice.
|
||||
#[inline(always)]
|
||||
pub pure fn const_slice<T>(v: &r/[const T], start: uint,
|
||||
end: uint) -> &r/[const T] {
|
||||
pub pure fn const_slice<T>(v: &r/[const T],
|
||||
start: uint,
|
||||
end: uint)
|
||||
-> &r/[const T] {
|
||||
assert (start <= end);
|
||||
assert (end <= len(v));
|
||||
do as_const_buf(v) |p, _len| {
|
||||
@ -3337,28 +3330,6 @@ mod tests {
|
||||
let _x = windowed (0u, ~[1u,2u,3u,4u,5u,6u]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cast_to_mut_no_copy() {
|
||||
unsafe {
|
||||
let x = ~[1, 2, 3];
|
||||
let addr = raw::to_ptr(x);
|
||||
let x_mut = cast_to_mut(x);
|
||||
let addr_mut = raw::to_ptr(x_mut);
|
||||
assert addr == addr_mut;
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cast_from_mut_no_copy() {
|
||||
unsafe {
|
||||
let x = ~[mut 1, 2, 3];
|
||||
let addr = raw::to_ptr(x);
|
||||
let x_imm = cast_from_mut(x);
|
||||
let addr_imm = raw::to_ptr(x_imm);
|
||||
assert addr == addr_imm;
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_unshift() {
|
||||
let mut x = ~[1, 2, 3];
|
||||
|
@ -290,7 +290,7 @@ pub fn check_variants_T<T: Copy>(
|
||||
|
||||
if L < 100 {
|
||||
do under(uint::min(L, 20)) |i| {
|
||||
log(error, ~"Replacing... #" + uint::str(i));
|
||||
log(error, ~"Replacing... #" + uint::to_str(i));
|
||||
let fname = str::from_slice(filename.to_str());
|
||||
do under(uint::min(L, 30)) |j| {
|
||||
log(error, ~"With... " + stringifier(@things[j], intr));
|
||||
@ -415,7 +415,7 @@ pub fn check_running(exe_filename: &Path) -> happiness {
|
||||
}
|
||||
rc => {
|
||||
failed(~"Rust program ran but exited with status " +
|
||||
int::str(rc))
|
||||
int::to_str(rc))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -838,9 +838,6 @@ pub fn link_binary(sess: Session,
|
||||
}
|
||||
}
|
||||
|
||||
// Always want the runtime linked in
|
||||
cc_args.push(~"-lrustrt");
|
||||
|
||||
// On linux librt and libdl are an indirect dependencies via rustrt,
|
||||
// and binutils 2.22+ won't add them automatically
|
||||
if sess.targ_cfg.os == session::os_linux {
|
||||
@ -880,6 +877,9 @@ pub fn link_binary(sess: Session,
|
||||
cc_args.push(~"-lmorestack");
|
||||
}
|
||||
|
||||
// Always want the runtime linked in
|
||||
cc_args.push(~"-lrustrt");
|
||||
|
||||
// FIXME (#2397): At some point we want to rpath our guesses as to where
|
||||
// extern libraries might live, based on the addl_lib_search_paths
|
||||
cc_args.push_all(rpath::get_rpath_flags(sess, &output));
|
||||
|
@ -1379,12 +1379,7 @@ pub fn type_to_str_inner(names: @TypeNames, +outer0: &[TypeRef], ty: TypeRef)
|
||||
type_to_str_inner(names, outer, out_ty)).to_managed();
|
||||
}
|
||||
Struct => {
|
||||
let n_elts = llvm::LLVMCountStructElementTypes(ty) as uint;
|
||||
let mut elts = vec::from_elem(n_elts, 0 as TypeRef);
|
||||
if !elts.is_empty() {
|
||||
llvm::LLVMGetStructElementTypes(
|
||||
ty, ptr::to_mut_unsafe_ptr(&mut elts[0]));
|
||||
}
|
||||
let elts = struct_tys(ty);
|
||||
// See [Note at-str]
|
||||
return fmt!("{%s}", tys_str(names, outer, elts)).to_managed();
|
||||
}
|
||||
@ -1445,17 +1440,16 @@ pub fn fn_ty_param_tys(fn_ty: TypeRef) -> ~[TypeRef] {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn struct_element_types(struct_ty: TypeRef) -> ~[TypeRef] {
|
||||
pub fn struct_tys(struct_ty: TypeRef) -> ~[TypeRef] {
|
||||
unsafe {
|
||||
let count = llvm::LLVMCountStructElementTypes(struct_ty);
|
||||
let mut buf: ~[TypeRef] =
|
||||
vec::from_elem(count as uint,
|
||||
cast::transmute::<uint,TypeRef>(0));
|
||||
if buf.len() > 0 {
|
||||
llvm::LLVMGetStructElementTypes(
|
||||
struct_ty, ptr::to_mut_unsafe_ptr(&mut buf[0]));
|
||||
let n_elts = llvm::LLVMCountStructElementTypes(struct_ty) as uint;
|
||||
if n_elts == 0 {
|
||||
return ~[];
|
||||
}
|
||||
return buf;
|
||||
let mut elts = vec::from_elem(n_elts, ptr::null());
|
||||
llvm::LLVMGetStructElementTypes(
|
||||
struct_ty, ptr::to_mut_unsafe_ptr(&mut elts[0]));
|
||||
return elts;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -307,7 +307,7 @@ fn enc_sty(w: io::Writer, cx: @ctxt, +st: ty::sty) {
|
||||
w.write_char('p');
|
||||
w.write_str((cx.ds)(did));
|
||||
w.write_char('|');
|
||||
w.write_str(uint::str(id));
|
||||
w.write_str(uint::to_str(id));
|
||||
}
|
||||
ty::ty_self => {
|
||||
w.write_char('s');
|
||||
|
@ -860,7 +860,7 @@ fn encode_side_tables_for_id(ecx: @e::EncodeContext,
|
||||
}
|
||||
}
|
||||
}
|
||||
do option::iter(&(*tcx.node_types).find(id as uint)) |ty| {
|
||||
do option::iter(&tcx.node_types.find(&(id as uint))) |&ty| {
|
||||
do ebml_w.tag(c::tag_table_node_type) {
|
||||
ebml_w.id(id);
|
||||
do ebml_w.tag(c::tag_table_val) {
|
||||
@ -1135,7 +1135,7 @@ fn decode_side_tables(xcx: @ExtendedDecodeContext,
|
||||
let ty = val_dsr.read_ty(xcx);
|
||||
debug!("inserting ty for node %?: %s",
|
||||
id, ty_to_str(dcx.tcx, ty));
|
||||
(*dcx.tcx.node_types).insert(id as uint, ty);
|
||||
dcx.tcx.node_types.insert(id as uint, ty);
|
||||
} else if tag == (c::tag_table_node_type_subst as uint) {
|
||||
let tys = val_dsr.read_tys(xcx);
|
||||
dcx.tcx.node_type_substs.insert(id, tys);
|
||||
|
@ -451,7 +451,7 @@ impl LoanKind {
|
||||
|
||||
/// Creates and returns a new root_map
|
||||
|
||||
pub impl to_bytes::IterBytes for root_map_key {
|
||||
impl to_bytes::IterBytes for root_map_key {
|
||||
pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) {
|
||||
to_bytes::iter_bytes_2(&self.id, &self.derefs, lsb0, f);
|
||||
}
|
||||
|
@ -101,7 +101,11 @@ pub fn check_expr(cx: @MatchCheckCtxt, ex: @expr, &&s: (), v: visit::vt<()>) {
|
||||
_ => { /* We assume only enum types can be uninhabited */ }
|
||||
}
|
||||
let arms = vec::concat(arms.filter_mapped(unguarded_pat));
|
||||
check_exhaustive(cx, ex.span, arms);
|
||||
if arms.is_empty() {
|
||||
cx.tcx.sess.span_err(ex.span, ~"non-exhaustive patterns");
|
||||
} else {
|
||||
check_exhaustive(cx, ex.span, arms);
|
||||
}
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
|
@ -117,7 +117,7 @@ pub fn annotate_freevars(def_map: resolve::DefMap, crate: @ast::crate) ->
|
||||
|
||||
pub fn get_freevars(tcx: ty::ctxt, fid: ast::node_id) -> freevar_info {
|
||||
match tcx.freevars.find(&fid) {
|
||||
None => fail!(~"get_freevars: " + int::str(fid) + ~" has no freevars"),
|
||||
None => fail!(~"get_freevars: "+int::to_str(fid)+~" has no freevars"),
|
||||
Some(d) => return d
|
||||
}
|
||||
}
|
||||
|
@ -75,16 +75,18 @@ pub enum LangItem {
|
||||
ReturnToMutFnLangItem, // 31
|
||||
CheckNotBorrowedFnLangItem, // 32
|
||||
StrDupUniqFnLangItem, // 33
|
||||
|
||||
StartFnLangItem, // 34
|
||||
}
|
||||
|
||||
pub struct LanguageItems {
|
||||
items: [ Option<def_id> * 34 ]
|
||||
items: [ Option<def_id> * 35 ]
|
||||
}
|
||||
|
||||
pub impl LanguageItems {
|
||||
static pub fn new(&self) -> LanguageItems {
|
||||
LanguageItems {
|
||||
items: [ None, ..34 ]
|
||||
items: [ None, ..35 ]
|
||||
}
|
||||
}
|
||||
|
||||
@ -136,6 +138,8 @@ pub impl LanguageItems {
|
||||
32 => "check_not_borrowed",
|
||||
33 => "strdup_uniq",
|
||||
|
||||
34 => "start",
|
||||
|
||||
_ => "???"
|
||||
}
|
||||
}
|
||||
@ -248,6 +252,9 @@ pub impl LanguageItems {
|
||||
pub fn strdup_uniq_fn(&const self) -> def_id {
|
||||
self.items[StrDupUniqFnLangItem as uint].get()
|
||||
}
|
||||
pub fn start_fn(&const self) -> def_id {
|
||||
self.items[StartFnLangItem as uint].get()
|
||||
}
|
||||
}
|
||||
|
||||
fn LanguageItemCollector(crate: @crate,
|
||||
@ -296,6 +303,7 @@ fn LanguageItemCollector(crate: @crate,
|
||||
item_refs.insert(@~"check_not_borrowed",
|
||||
CheckNotBorrowedFnLangItem as uint);
|
||||
item_refs.insert(@~"strdup_uniq", StrDupUniqFnLangItem as uint);
|
||||
item_refs.insert(@~"start", StartFnLangItem as uint);
|
||||
|
||||
LanguageItemCollector {
|
||||
crate: crate,
|
||||
|
@ -34,8 +34,7 @@ use core::uint;
|
||||
use core::vec;
|
||||
use std::oldmap::{Map, HashMap};
|
||||
use std::oldmap;
|
||||
use std::oldsmallintmap::{Map, SmallIntMap};
|
||||
use std::oldsmallintmap;
|
||||
use std::smallintmap::SmallIntMap;
|
||||
use syntax::ast_util::{path_to_ident};
|
||||
use syntax::attr;
|
||||
use syntax::codemap::span;
|
||||
@ -81,6 +80,7 @@ pub enum lint {
|
||||
type_limits,
|
||||
default_methods,
|
||||
deprecated_self,
|
||||
deprecated_mutable_fields,
|
||||
|
||||
managed_heap_memory,
|
||||
owned_heap_memory,
|
||||
@ -255,6 +255,13 @@ pub fn get_lint_dict() -> LintDict {
|
||||
default: warn
|
||||
}),
|
||||
|
||||
(@~"deprecated_mutable_fields",
|
||||
@LintSpec {
|
||||
lint: deprecated_mutable_fields,
|
||||
desc: "deprecated mutable fields in structures",
|
||||
default: deny
|
||||
}),
|
||||
|
||||
/* FIXME(#3266)--make liveness warnings lintable
|
||||
(@~"unused_variable",
|
||||
@LintSpec {
|
||||
@ -275,7 +282,7 @@ pub fn get_lint_dict() -> LintDict {
|
||||
}
|
||||
|
||||
// This is a highly not-optimal set of data structure decisions.
|
||||
type LintModes = SmallIntMap<level>;
|
||||
type LintModes = @mut SmallIntMap<level>;
|
||||
type LintModeMap = HashMap<ast::node_id, LintModes>;
|
||||
|
||||
// settings_map maps node ids of items with non-default lint settings
|
||||
@ -288,14 +295,14 @@ pub struct LintSettings {
|
||||
|
||||
pub fn mk_lint_settings() -> LintSettings {
|
||||
LintSettings {
|
||||
default_settings: oldsmallintmap::mk(),
|
||||
default_settings: @mut SmallIntMap::new(),
|
||||
settings_map: HashMap()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_lint_level(modes: LintModes, lint: lint) -> level {
|
||||
match modes.find(lint as uint) {
|
||||
Some(c) => c,
|
||||
match modes.find(&(lint as uint)) {
|
||||
Some(&c) => c,
|
||||
None => allow
|
||||
}
|
||||
}
|
||||
@ -314,8 +321,7 @@ pub fn get_lint_settings_level(settings: LintSettings,
|
||||
// This is kind of unfortunate. It should be somewhere else, or we should use
|
||||
// a persistent data structure...
|
||||
fn clone_lint_modes(modes: LintModes) -> LintModes {
|
||||
oldsmallintmap::SmallIntMap_(@oldsmallintmap::SmallIntMap_
|
||||
{v: copy modes.v})
|
||||
@mut (copy *modes)
|
||||
}
|
||||
|
||||
struct Context {
|
||||
@ -332,7 +338,7 @@ impl Context {
|
||||
|
||||
fn set_level(&self, lint: lint, level: level) {
|
||||
if level == allow {
|
||||
self.curr.remove(lint as uint);
|
||||
self.curr.remove(&(lint as uint));
|
||||
} else {
|
||||
self.curr.insert(lint as uint, level);
|
||||
}
|
||||
@ -440,7 +446,7 @@ fn build_settings_item(i: @ast::item, &&cx: Context, v: visit::vt<Context>) {
|
||||
pub fn build_settings_crate(sess: session::Session, crate: @ast::crate) {
|
||||
let cx = Context {
|
||||
dict: get_lint_dict(),
|
||||
curr: oldsmallintmap::mk(),
|
||||
curr: @mut SmallIntMap::new(),
|
||||
is_default: true,
|
||||
sess: sess
|
||||
};
|
||||
@ -458,7 +464,7 @@ pub fn build_settings_crate(sess: session::Session, crate: @ast::crate) {
|
||||
|
||||
do cx.with_lint_attrs(/*bad*/copy crate.node.attrs) |cx| {
|
||||
// Copy out the default settings
|
||||
for cx.curr.each |k, v| {
|
||||
for cx.curr.each |&(k, &v)| {
|
||||
sess.lint_settings.default_settings.insert(k, v);
|
||||
}
|
||||
|
||||
@ -488,6 +494,7 @@ fn check_item(i: @ast::item, cx: ty::ctxt) {
|
||||
check_item_type_limits(cx, i);
|
||||
check_item_default_methods(cx, i);
|
||||
check_item_deprecated_self(cx, i);
|
||||
check_item_deprecated_mutable_fields(cx, i);
|
||||
}
|
||||
|
||||
// Take a visitor, and modify it so that it will not proceed past subitems.
|
||||
@ -705,6 +712,26 @@ fn check_item_deprecated_self(cx: ty::ctxt, item: @ast::item) {
|
||||
}
|
||||
}
|
||||
|
||||
fn check_item_deprecated_mutable_fields(cx: ty::ctxt, item: @ast::item) {
|
||||
match item.node {
|
||||
ast::item_struct(struct_def, _) => {
|
||||
for struct_def.fields.each |field| {
|
||||
match field.node.kind {
|
||||
ast::named_field(_, ast::struct_mutable, _) => {
|
||||
cx.sess.span_lint(deprecated_mutable_fields,
|
||||
item.id,
|
||||
item.id,
|
||||
field.span,
|
||||
~"mutable fields are deprecated");
|
||||
}
|
||||
ast::named_field(*) | ast::unnamed_field => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn check_item_structural_records(cx: ty::ctxt, it: @ast::item) {
|
||||
let visit = item_stopping_visitor(
|
||||
visit::mk_simple_visitor(@visit::SimpleVisitor {
|
||||
|
@ -667,8 +667,8 @@ struct Liveness {
|
||||
tcx: ty::ctxt,
|
||||
ir: @mut IrMaps,
|
||||
s: Specials,
|
||||
successors: ~[mut LiveNode],
|
||||
users: ~[mut Users],
|
||||
successors: @mut ~[LiveNode],
|
||||
users: @mut ~[Users],
|
||||
// The list of node IDs for the nested loop scopes
|
||||
// we're in.
|
||||
loop_scope: DVec<node_id>,
|
||||
@ -684,14 +684,9 @@ fn Liveness(ir: @mut IrMaps, specials: Specials) -> Liveness {
|
||||
ir: ir,
|
||||
tcx: ir.tcx,
|
||||
s: specials,
|
||||
successors:
|
||||
vec::cast_to_mut(
|
||||
vec::from_elem(ir.num_live_nodes,
|
||||
invalid_node())),
|
||||
users:
|
||||
vec::cast_to_mut(
|
||||
vec::from_elem(ir.num_live_nodes * ir.num_vars,
|
||||
invalid_users())),
|
||||
successors: @mut vec::from_elem(ir.num_live_nodes, invalid_node()),
|
||||
users: @mut vec::from_elem(ir.num_live_nodes * ir.num_vars,
|
||||
invalid_users()),
|
||||
loop_scope: DVec(),
|
||||
break_ln: HashMap(),
|
||||
cont_ln: HashMap()
|
||||
@ -916,12 +911,13 @@ impl Liveness {
|
||||
|
||||
let mut changed = false;
|
||||
do self.indices2(ln, succ_ln) |idx, succ_idx| {
|
||||
changed |= copy_if_invalid(copy self.users[succ_idx].reader,
|
||||
&mut self.users[idx].reader);
|
||||
changed |= copy_if_invalid(copy self.users[succ_idx].writer,
|
||||
&mut self.users[idx].writer);
|
||||
if self.users[succ_idx].used && !self.users[idx].used {
|
||||
self.users[idx].used = true;
|
||||
let users = &mut *self.users;
|
||||
changed |= copy_if_invalid(copy users[succ_idx].reader,
|
||||
&mut users[idx].reader);
|
||||
changed |= copy_if_invalid(copy users[succ_idx].writer,
|
||||
&mut users[idx].writer);
|
||||
if users[succ_idx].used && !users[idx].used {
|
||||
users[idx].used = true;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
@ -956,7 +952,8 @@ impl Liveness {
|
||||
// Either read, write, or both depending on the acc bitset
|
||||
fn acc(&self, ln: LiveNode, var: Variable, acc: uint) {
|
||||
let idx = self.idx(ln, var);
|
||||
let user = &mut self.users[idx];
|
||||
let users = &mut *self.users;
|
||||
let user = &mut users[idx];
|
||||
|
||||
if (acc & ACC_WRITE) != 0 {
|
||||
user.reader = invalid_node();
|
||||
@ -970,7 +967,7 @@ impl Liveness {
|
||||
}
|
||||
|
||||
if (acc & ACC_USE) != 0 {
|
||||
self.users[idx].used = true;
|
||||
user.used = true;
|
||||
}
|
||||
|
||||
debug!("%s accesses[%x] %s: %s",
|
||||
|
@ -281,12 +281,12 @@ pub trait ast_node {
|
||||
fn span(&self) -> span;
|
||||
}
|
||||
|
||||
pub impl ast_node for @ast::expr {
|
||||
impl ast_node for @ast::expr {
|
||||
fn id(&self) -> ast::node_id { self.id }
|
||||
fn span(&self) -> span { self.span }
|
||||
}
|
||||
|
||||
pub impl ast_node for @ast::pat {
|
||||
impl ast_node for @ast::pat {
|
||||
fn id(&self) -> ast::node_id { self.id }
|
||||
fn span(&self) -> span { self.span }
|
||||
}
|
||||
@ -295,7 +295,7 @@ pub trait get_type_for_node {
|
||||
fn ty<N:ast_node>(&self, node: N) -> ty::t;
|
||||
}
|
||||
|
||||
pub impl get_type_for_node for ty::ctxt {
|
||||
impl get_type_for_node for ty::ctxt {
|
||||
fn ty<N:ast_node>(&self, node: N) -> ty::t {
|
||||
ty::node_id_to_type(*self, node.id())
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ use metadata::cstore::find_extern_mod_stmt_cnum;
|
||||
use metadata::decoder::{def_like, dl_def, dl_field, dl_impl};
|
||||
use middle::lang_items::LanguageItems;
|
||||
use middle::lint::{deny, allow, forbid, level, unused_imports, warn};
|
||||
use middle::lint::{get_lint_level, get_lint_settings_level};
|
||||
use middle::pat_util::{pat_bindings};
|
||||
|
||||
use core::cmp;
|
||||
@ -508,16 +509,6 @@ pub impl Module {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn unused_import_lint_level(session: Session) -> level {
|
||||
for session.opts.lint_opts.each |lint_option_pair| {
|
||||
let (lint_type, lint_level) = *lint_option_pair;
|
||||
if lint_type == unused_imports {
|
||||
return lint_level;
|
||||
}
|
||||
}
|
||||
return allow;
|
||||
}
|
||||
|
||||
// Records a possibly-private type definition.
|
||||
pub struct TypeNsDef {
|
||||
privacy: Privacy,
|
||||
@ -770,8 +761,6 @@ pub fn Resolver(session: Session,
|
||||
|
||||
graph_root: graph_root,
|
||||
|
||||
unused_import_lint_level: unused_import_lint_level(session),
|
||||
|
||||
trait_info: @HashMap(),
|
||||
structs: @HashMap(),
|
||||
|
||||
@ -816,8 +805,6 @@ pub struct Resolver {
|
||||
|
||||
graph_root: @mut NameBindings,
|
||||
|
||||
unused_import_lint_level: level,
|
||||
|
||||
trait_info: @HashMap<def_id,@HashMap<ident,()>>,
|
||||
structs: @HashMap<def_id,()>,
|
||||
|
||||
@ -4829,6 +4816,42 @@ pub impl Resolver {
|
||||
}
|
||||
}
|
||||
|
||||
fn find_best_match_for_name(@mut self, name: &str) -> Option<~str> {
|
||||
let mut maybes: ~[~str] = ~[];
|
||||
let mut values: ~[uint] = ~[];
|
||||
|
||||
let mut j = self.value_ribs.len();
|
||||
while j != 0 {
|
||||
j -= 1;
|
||||
let rib = self.value_ribs.get_elt(j);
|
||||
for rib.bindings.each_entry |e| {
|
||||
vec::push(&mut maybes, copy *self.session.str_of(e.key));
|
||||
vec::push(&mut values, uint::max_value);
|
||||
}
|
||||
}
|
||||
|
||||
let mut smallest = 0;
|
||||
for vec::eachi(maybes) |i, &other| {
|
||||
|
||||
values[i] = str::levdistance(name, other);
|
||||
|
||||
if values[i] <= values[smallest] {
|
||||
smallest = i;
|
||||
}
|
||||
}
|
||||
|
||||
if vec::len(values) > 0 &&
|
||||
values[smallest] != uint::max_value &&
|
||||
values[smallest] < str::len(name) + 2 &&
|
||||
maybes[smallest] != name.to_owned() {
|
||||
|
||||
Some(vec::swap_remove(&mut maybes, smallest))
|
||||
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn name_exists_in_scope_struct(@mut self, name: &str) -> bool {
|
||||
let mut i = self.type_ribs.len();
|
||||
while i != 0 {
|
||||
@ -4895,9 +4918,20 @@ pub impl Resolver {
|
||||
wrong_name));
|
||||
}
|
||||
else {
|
||||
self.session.span_err(expr.span,
|
||||
fmt!("unresolved name: %s",
|
||||
match self.find_best_match_for_name(wrong_name) {
|
||||
|
||||
Some(m) => {
|
||||
self.session.span_err(expr.span,
|
||||
fmt!("unresolved name: `%s`. \
|
||||
Did you mean: `%s`?",
|
||||
wrong_name, m));
|
||||
}
|
||||
None => {
|
||||
self.session.span_err(expr.span,
|
||||
fmt!("unresolved name: `%s`.",
|
||||
wrong_name));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -5232,8 +5266,17 @@ pub impl Resolver {
|
||||
// resolve data structures.
|
||||
//
|
||||
|
||||
fn unused_import_lint_level(@mut self, m: @mut Module) -> level {
|
||||
let settings = self.session.lint_settings;
|
||||
match m.def_id {
|
||||
Some(def) => get_lint_settings_level(settings, unused_imports,
|
||||
def.node, def.node),
|
||||
None => get_lint_level(settings.default_settings, unused_imports)
|
||||
}
|
||||
}
|
||||
|
||||
fn check_for_unused_imports_if_necessary(@mut self) {
|
||||
if self.unused_import_lint_level == allow {
|
||||
if self.unused_import_lint_level(self.current_module) == allow {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -5285,12 +5328,15 @@ pub impl Resolver {
|
||||
for module_.import_resolutions.each_value |&import_resolution| {
|
||||
// Ignore dummy spans for things like automatically injected
|
||||
// imports for the prelude, and also don't warn about the same
|
||||
// import statement being unused more than once.
|
||||
// import statement being unused more than once. Furthermore, if
|
||||
// the import is public, then we can't be sure whether it's unused
|
||||
// or not so don't warn about it.
|
||||
if !import_resolution.state.used &&
|
||||
!import_resolution.state.warned &&
|
||||
import_resolution.span != dummy_sp() {
|
||||
import_resolution.span != dummy_sp() &&
|
||||
import_resolution.privacy != Public {
|
||||
import_resolution.state.warned = true;
|
||||
match self.unused_import_lint_level {
|
||||
match self.unused_import_lint_level(module_) {
|
||||
warn => {
|
||||
self.session.span_warn(copy import_resolution.span,
|
||||
~"unused import");
|
||||
@ -5299,11 +5345,7 @@ pub impl Resolver {
|
||||
self.session.span_err(copy import_resolution.span,
|
||||
~"unused import");
|
||||
}
|
||||
allow => {
|
||||
self.session.span_bug(copy import_resolution.span,
|
||||
~"shouldn't be here if lint \
|
||||
is allowed");
|
||||
}
|
||||
allow => ()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -172,11 +172,6 @@ use syntax::ast_util;
|
||||
use syntax::codemap::span;
|
||||
use syntax::print::pprust::pat_to_str;
|
||||
|
||||
pub fn macros() {
|
||||
// FIXME(#3114): Macro import/export.
|
||||
include!("macros.rs");
|
||||
}
|
||||
|
||||
// An option identifying a literal: either a unit-like struct or an
|
||||
// expression.
|
||||
pub enum Lit {
|
||||
|
@ -76,7 +76,6 @@ use core::option::{is_none, is_some};
|
||||
use core::option;
|
||||
use core::uint;
|
||||
use std::oldmap::HashMap;
|
||||
use std::oldsmallintmap;
|
||||
use std::{oldmap, time, list};
|
||||
use syntax::ast_map::{path, path_elt_to_str, path_mod, path_name};
|
||||
use syntax::ast_util::{def_id_of_def, local_def, path_to_ident};
|
||||
@ -108,7 +107,7 @@ pub trait get_insn_ctxt {
|
||||
fn insn_ctxt(&self, s: &str) -> icx_popper;
|
||||
}
|
||||
|
||||
pub impl get_insn_ctxt for @CrateContext {
|
||||
impl get_insn_ctxt for @CrateContext {
|
||||
fn insn_ctxt(&self, s: &str) -> icx_popper {
|
||||
debug!("new insn_ctxt: %s", s);
|
||||
if self.sess.count_llvm_insns() {
|
||||
@ -118,13 +117,13 @@ pub impl get_insn_ctxt for @CrateContext {
|
||||
}
|
||||
}
|
||||
|
||||
pub impl get_insn_ctxt for block {
|
||||
impl get_insn_ctxt for block {
|
||||
fn insn_ctxt(&self, s: &str) -> icx_popper {
|
||||
self.ccx().insn_ctxt(s)
|
||||
}
|
||||
}
|
||||
|
||||
pub impl get_insn_ctxt for fn_ctxt {
|
||||
impl get_insn_ctxt for fn_ctxt {
|
||||
fn insn_ctxt(&self, s: &str) -> icx_popper {
|
||||
self.ccx.insn_ctxt(s)
|
||||
}
|
||||
@ -2171,11 +2170,6 @@ pub fn trans_mod(ccx: @CrateContext, m: &ast::_mod) {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_pair_fn_ty(llpairty: TypeRef) -> TypeRef {
|
||||
// Bit of a kludge: pick the fn typeref out of the pair.
|
||||
return struct_elt(llpairty, 0u);
|
||||
}
|
||||
|
||||
pub fn register_fn(ccx: @CrateContext,
|
||||
sp: span,
|
||||
+path: path,
|
||||
@ -2272,7 +2266,7 @@ pub fn create_main_wrapper(ccx: @CrateContext,
|
||||
fn main_name() -> ~str { return ~"WinMain@16"; }
|
||||
#[cfg(unix)]
|
||||
fn main_name() -> ~str { return ~"main"; }
|
||||
let llfty = T_fn(~[ccx.int_type, ccx.int_type], ccx.int_type);
|
||||
let llfty = T_fn(~[ccx.int_type, T_ptr(T_i8())], ccx.int_type);
|
||||
|
||||
// FIXME #4404 android JNI hacks
|
||||
let llfn = if *ccx.sess.building_library {
|
||||
@ -2290,33 +2284,50 @@ pub fn create_main_wrapper(ccx: @CrateContext,
|
||||
llvm::LLVMPositionBuilderAtEnd(bld, llbb);
|
||||
}
|
||||
let crate_map = ccx.crate_map;
|
||||
let start_ty = T_fn(~[val_ty(rust_main), ccx.int_type, ccx.int_type,
|
||||
val_ty(crate_map)], ccx.int_type);
|
||||
let start = decl_cdecl_fn(ccx.llmod, ~"rust_start", start_ty);
|
||||
let start_def_id = ccx.tcx.lang_items.start_fn();
|
||||
let start_fn = if start_def_id.crate == ast::local_crate {
|
||||
ccx.sess.bug(~"start lang item is never in the local crate")
|
||||
} else {
|
||||
let start_fn_type = csearch::get_type(ccx.tcx,
|
||||
start_def_id).ty;
|
||||
trans_external_path(ccx, start_def_id, start_fn_type)
|
||||
};
|
||||
|
||||
let retptr = unsafe {
|
||||
llvm::LLVMBuildAlloca(bld, ccx.int_type, noname())
|
||||
};
|
||||
|
||||
let args = unsafe {
|
||||
let opaque_rust_main = llvm::LLVMBuildPointerCast(
|
||||
bld, rust_main, T_ptr(T_i8()), noname());
|
||||
let opaque_crate_map = llvm::LLVMBuildPointerCast(
|
||||
bld, crate_map, T_ptr(T_i8()), noname());
|
||||
|
||||
if *ccx.sess.building_library {
|
||||
~[
|
||||
rust_main,
|
||||
retptr,
|
||||
C_null(T_opaque_box_ptr(ccx)),
|
||||
opaque_rust_main,
|
||||
llvm::LLVMConstInt(T_i32(), 0u as c_ulonglong, False),
|
||||
llvm::LLVMConstInt(T_i32(), 0u as c_ulonglong, False),
|
||||
crate_map
|
||||
opaque_crate_map
|
||||
]
|
||||
} else {
|
||||
~[
|
||||
rust_main,
|
||||
retptr,
|
||||
C_null(T_opaque_box_ptr(ccx)),
|
||||
opaque_rust_main,
|
||||
llvm::LLVMGetParam(llfn, 0 as c_uint),
|
||||
llvm::LLVMGetParam(llfn, 1 as c_uint),
|
||||
crate_map
|
||||
opaque_crate_map
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
let result = unsafe {
|
||||
llvm::LLVMBuildCall(bld, start, vec::raw::to_ptr(args),
|
||||
args.len() as c_uint, noname())
|
||||
};
|
||||
unsafe {
|
||||
llvm::LLVMBuildCall(bld, start_fn, vec::raw::to_ptr(args),
|
||||
args.len() as c_uint, noname());
|
||||
let result = llvm::LLVMBuildLoad(bld, retptr, noname());
|
||||
llvm::LLVMBuildRet(bld, result);
|
||||
}
|
||||
}
|
||||
|
164
src/librustc/middle/trans/cabi_arm.rs
Normal file
164
src/librustc/middle/trans/cabi_arm.rs
Normal file
@ -0,0 +1,164 @@
|
||||
// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use lib::llvm::{llvm, Integer, Pointer, Float, Double, Struct, Array};
|
||||
use lib::llvm::struct_tys;
|
||||
use lib::llvm::TypeRef;
|
||||
use lib::llvm::{Attribute, StructRetAttribute};
|
||||
use middle::trans::cabi::{ABIInfo, FnType, LLVMType};
|
||||
use middle::trans::common::{T_i8, T_i16, T_i32, T_i64};
|
||||
use middle::trans::common::{T_array, T_ptr, T_void};
|
||||
|
||||
use core::option::{Option, None, Some};
|
||||
use core::uint;
|
||||
use core::vec;
|
||||
|
||||
fn align_up_to(off: uint, a: uint) -> uint {
|
||||
return (off + a - 1u) / a * a;
|
||||
}
|
||||
|
||||
fn align(off: uint, ty: TypeRef) -> uint {
|
||||
let a = ty_align(ty);
|
||||
return align_up_to(off, a);
|
||||
}
|
||||
|
||||
fn ty_align(ty: TypeRef) -> uint {
|
||||
unsafe {
|
||||
return match llvm::LLVMGetTypeKind(ty) {
|
||||
Integer => {
|
||||
((llvm::LLVMGetIntTypeWidth(ty) as uint) + 7) / 8
|
||||
}
|
||||
Pointer => 4,
|
||||
Float => 4,
|
||||
Double => 8,
|
||||
Struct => {
|
||||
do vec::foldl(1, struct_tys(ty)) |a, t| {
|
||||
uint::max(a, ty_align(*t))
|
||||
}
|
||||
}
|
||||
Array => {
|
||||
let elt = llvm::LLVMGetElementType(ty);
|
||||
ty_align(elt)
|
||||
}
|
||||
_ => fail!(~"ty_align: unhandled type")
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
fn ty_size(ty: TypeRef) -> uint {
|
||||
unsafe {
|
||||
return match llvm::LLVMGetTypeKind(ty) {
|
||||
Integer => {
|
||||
((llvm::LLVMGetIntTypeWidth(ty) as uint) + 7) / 8
|
||||
}
|
||||
Pointer => 4,
|
||||
Float => 4,
|
||||
Double => 8,
|
||||
Struct => {
|
||||
let size = do vec::foldl(0, struct_tys(ty)) |s, t| {
|
||||
align(s, *t) + ty_size(*t)
|
||||
};
|
||||
align(size, ty)
|
||||
}
|
||||
Array => {
|
||||
let len = llvm::LLVMGetArrayLength(ty) as uint;
|
||||
let elt = llvm::LLVMGetElementType(ty);
|
||||
let eltsz = ty_size(elt);
|
||||
len * eltsz
|
||||
}
|
||||
_ => fail!(~"ty_size: unhandled type")
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
fn classify_ret_ty(ty: TypeRef) -> (LLVMType, Option<Attribute>) {
|
||||
if is_reg_ty(ty) {
|
||||
return (LLVMType { cast: false, ty: ty }, None);
|
||||
}
|
||||
let size = ty_size(ty);
|
||||
if size <= 4 {
|
||||
let llty = if size <= 1 {
|
||||
T_i8()
|
||||
} else if size <= 2 {
|
||||
T_i16()
|
||||
} else {
|
||||
T_i32()
|
||||
};
|
||||
return (LLVMType { cast: true, ty: llty }, None);
|
||||
}
|
||||
(LLVMType { cast: false, ty: T_ptr(ty) }, Some(StructRetAttribute))
|
||||
}
|
||||
|
||||
fn classify_arg_ty(ty: TypeRef) -> (LLVMType, Option<Attribute>) {
|
||||
if is_reg_ty(ty) {
|
||||
return (LLVMType { cast: false, ty: ty }, None);
|
||||
}
|
||||
let align = ty_align(ty);
|
||||
let size = ty_size(ty);
|
||||
let llty = if align <= 4 {
|
||||
T_array(T_i32(), (size + 3) / 4)
|
||||
} else {
|
||||
T_array(T_i64(), (size + 7) / 8)
|
||||
};
|
||||
(LLVMType { cast: true, ty: llty }, None)
|
||||
}
|
||||
|
||||
fn is_reg_ty(ty: TypeRef) -> bool {
|
||||
unsafe {
|
||||
return match llvm::LLVMGetTypeKind(ty) {
|
||||
Integer
|
||||
| Pointer
|
||||
| Float
|
||||
| Double => true,
|
||||
_ => false
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
enum ARM_ABIInfo { ARM_ABIInfo }
|
||||
|
||||
impl ABIInfo for ARM_ABIInfo {
|
||||
fn compute_info(&self,
|
||||
atys: &[TypeRef],
|
||||
rty: TypeRef,
|
||||
ret_def: bool) -> FnType {
|
||||
let mut arg_tys = ~[];
|
||||
let mut attrs = ~[];
|
||||
for atys.each |&aty| {
|
||||
let (ty, attr) = classify_arg_ty(aty);
|
||||
arg_tys.push(ty);
|
||||
attrs.push(attr);
|
||||
}
|
||||
|
||||
let mut (ret_ty, ret_attr) = if ret_def {
|
||||
classify_ret_ty(rty)
|
||||
} else {
|
||||
(LLVMType { cast: false, ty: T_void() }, None)
|
||||
};
|
||||
|
||||
let sret = ret_attr.is_some();
|
||||
if sret {
|
||||
arg_tys.unshift(ret_ty);
|
||||
attrs.unshift(ret_attr);
|
||||
ret_ty = LLVMType { cast: false, ty: T_void() };
|
||||
}
|
||||
|
||||
return FnType {
|
||||
arg_tys: arg_tys,
|
||||
ret_ty: ret_ty,
|
||||
attrs: attrs,
|
||||
sret: sret
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
pub fn abi_info() -> ABIInfo {
|
||||
return ARM_ABIInfo as ABIInfo;
|
||||
}
|
@ -14,6 +14,7 @@
|
||||
use lib::llvm::{llvm, TypeRef, ValueRef, Integer, Pointer, Float, Double};
|
||||
use lib::llvm::{Struct, Array, Attribute};
|
||||
use lib::llvm::{StructRetAttribute, ByValAttribute};
|
||||
use lib::llvm::struct_tys;
|
||||
use middle::trans::common::*;
|
||||
use middle::trans::cabi::*;
|
||||
|
||||
@ -65,19 +66,6 @@ fn classify_ty(ty: TypeRef) -> ~[x86_64_reg_class] {
|
||||
return (off + a - 1u) / a * a;
|
||||
}
|
||||
|
||||
fn struct_tys(ty: TypeRef) -> ~[TypeRef] {
|
||||
unsafe {
|
||||
let n = llvm::LLVMCountStructElementTypes(ty);
|
||||
if (n == 0) {
|
||||
return ~[];
|
||||
}
|
||||
let mut elts = vec::from_elem(n as uint, ptr::null());
|
||||
llvm::LLVMGetStructElementTypes(ty,
|
||||
ptr::to_mut_unsafe_ptr(&mut elts[0]));
|
||||
return elts;
|
||||
}
|
||||
}
|
||||
|
||||
fn ty_align(ty: TypeRef) -> uint {
|
||||
unsafe {
|
||||
return match llvm::LLVMGetTypeKind(ty) {
|
||||
|
@ -380,7 +380,7 @@ pub fn trans_rtcall_or_lang_call_with_type_params(bcx: block,
|
||||
fty);
|
||||
let mut llfnty = type_of::type_of(callee.bcx.ccx(),
|
||||
substituted);
|
||||
llfnty = T_ptr(struct_elt(llfnty, 0));
|
||||
llfnty = lib::llvm::struct_tys(llfnty)[0];
|
||||
new_llval = PointerCast(callee.bcx, fn_data.llfn, llfnty);
|
||||
}
|
||||
_ => fail!()
|
||||
|
@ -538,13 +538,13 @@ pub trait get_node_info {
|
||||
fn info(&self) -> Option<NodeInfo>;
|
||||
}
|
||||
|
||||
pub impl get_node_info for @ast::expr {
|
||||
impl get_node_info for @ast::expr {
|
||||
fn info(&self) -> Option<NodeInfo> {
|
||||
Some(NodeInfo { id: self.id, span: self.span })
|
||||
}
|
||||
}
|
||||
|
||||
pub impl get_node_info for ast::blk {
|
||||
impl get_node_info for ast::blk {
|
||||
fn info(&self) -> Option<NodeInfo> {
|
||||
Some(NodeInfo { id: self.node.id, span: self.span })
|
||||
}
|
||||
@ -553,7 +553,7 @@ pub impl get_node_info for ast::blk {
|
||||
// XXX: Work around a trait parsing bug. remove after snapshot
|
||||
pub type optional_boxed_ast_expr = Option<@ast::expr>;
|
||||
|
||||
pub impl get_node_info for optional_boxed_ast_expr {
|
||||
impl get_node_info for optional_boxed_ast_expr {
|
||||
fn info(&self) -> Option<NodeInfo> {
|
||||
self.chain_ref(|s| s.info())
|
||||
}
|
||||
@ -647,19 +647,6 @@ pub fn val_str(tn: @TypeNames, v: ValueRef) -> @str {
|
||||
return ty_str(tn, val_ty(v));
|
||||
}
|
||||
|
||||
// Returns the nth element of the given LLVM structure type.
|
||||
pub fn struct_elt(llstructty: TypeRef, n: uint) -> TypeRef {
|
||||
unsafe {
|
||||
let elt_count = llvm::LLVMCountStructElementTypes(llstructty) as uint;
|
||||
assert (n < elt_count);
|
||||
let mut elt_tys = vec::from_elem(elt_count, T_nil());
|
||||
llvm::LLVMGetStructElementTypes(
|
||||
llstructty,
|
||||
ptr::to_mut_unsafe_ptr(&mut elt_tys[0]));
|
||||
return llvm::LLVMGetElementType(elt_tys[n]);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn in_scope_cx(cx: block, f: &fn(&mut scope_info)) {
|
||||
let mut cur = cx;
|
||||
loop {
|
||||
@ -1288,7 +1275,7 @@ pub struct mono_id_ {
|
||||
|
||||
pub type mono_id = @mono_id_;
|
||||
|
||||
pub impl to_bytes::IterBytes for mono_param_id {
|
||||
impl to_bytes::IterBytes for mono_param_id {
|
||||
pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) {
|
||||
match /*bad*/copy *self {
|
||||
mono_precise(t, mids) =>
|
||||
@ -1302,7 +1289,7 @@ pub impl to_bytes::IterBytes for mono_param_id {
|
||||
}
|
||||
}
|
||||
|
||||
pub impl to_bytes::IterBytes for mono_id_ {
|
||||
impl to_bytes::IterBytes for mono_id_ {
|
||||
pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) {
|
||||
to_bytes::iter_bytes_2(&self.def, &self.params, lsb0, f);
|
||||
}
|
||||
|
@ -18,11 +18,6 @@ use middle::trans::datum::*;
|
||||
|
||||
use core::str;
|
||||
|
||||
pub fn macros() {
|
||||
// FIXME(#3114): Macro import/export.
|
||||
include!("macros.rs");
|
||||
}
|
||||
|
||||
pub fn trans_block(bcx: block, b: &ast::blk, dest: expr::Dest) -> block {
|
||||
let _icx = bcx.insn_ctxt("trans_block");
|
||||
let mut bcx = bcx;
|
||||
|
@ -151,14 +151,14 @@ pub impl DatumMode {
|
||||
}
|
||||
}
|
||||
|
||||
pub impl cmp::Eq for DatumMode {
|
||||
impl cmp::Eq for DatumMode {
|
||||
pure fn eq(&self, other: &DatumMode) -> bool {
|
||||
(*self) as uint == (*other as uint)
|
||||
}
|
||||
pure fn ne(&self, other: &DatumMode) -> bool { !(*self).eq(other) }
|
||||
}
|
||||
|
||||
pub impl to_bytes::IterBytes for DatumMode {
|
||||
impl to_bytes::IterBytes for DatumMode {
|
||||
pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) {
|
||||
(*self as uint).iter_bytes(lsb0, f)
|
||||
}
|
||||
|
@ -149,8 +149,6 @@ use syntax::codemap::spanned;
|
||||
// These are passed around by the code generating functions to track the
|
||||
// destination of a computation's value.
|
||||
|
||||
fn macros() { include!("macros.rs"); } // FIXME(#3114): Macro import/export.
|
||||
|
||||
pub enum Dest {
|
||||
SaveIn(ValueRef),
|
||||
Ignore,
|
||||
|
@ -21,6 +21,7 @@ use lib;
|
||||
use middle::trans::base::*;
|
||||
use middle::trans::cabi;
|
||||
use middle::trans::cabi_x86_64::*;
|
||||
use middle::trans::cabi_arm;
|
||||
use middle::trans::build::*;
|
||||
use middle::trans::callee::*;
|
||||
use middle::trans::common::*;
|
||||
@ -42,7 +43,8 @@ use syntax::parse::token::special_idents;
|
||||
|
||||
fn abi_info(arch: session::arch) -> cabi::ABIInfo {
|
||||
return match arch {
|
||||
arch_x86_64 | arch_arm => x86_64_abi_info(),
|
||||
arch_x86_64 => x86_64_abi_info(),
|
||||
arch_arm => cabi_arm::abi_info(),
|
||||
_ => cabi::llvm_abi_info()
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
{
|
||||
#[macro_escape];
|
||||
|
||||
macro_rules! unpack_datum(
|
||||
($bcx: ident, $inp: expr) => (
|
||||
@ -18,7 +18,7 @@ macro_rules! unpack_datum(
|
||||
db.datum
|
||||
}
|
||||
)
|
||||
);
|
||||
)
|
||||
|
||||
macro_rules! unpack_result(
|
||||
($bcx: ident, $inp: expr) => (
|
||||
@ -28,7 +28,7 @@ macro_rules! unpack_result(
|
||||
db.val
|
||||
}
|
||||
)
|
||||
);
|
||||
)
|
||||
|
||||
macro_rules! trace_span(
|
||||
($bcx: ident, $sp: expr, $str: expr) => (
|
||||
@ -39,7 +39,7 @@ macro_rules! trace_span(
|
||||
}
|
||||
}
|
||||
)
|
||||
);
|
||||
)
|
||||
|
||||
macro_rules! trace(
|
||||
($bcx: ident, $str: expr) => (
|
||||
@ -50,6 +50,5 @@ macro_rules! trace(
|
||||
}
|
||||
}
|
||||
)
|
||||
);
|
||||
)
|
||||
|
||||
}
|
||||
|
@ -39,11 +39,6 @@ use syntax::ast_util::local_def;
|
||||
use syntax::print::pprust::expr_to_str;
|
||||
use syntax::{ast, ast_map};
|
||||
|
||||
pub fn macros() {
|
||||
// FIXME(#3114): Macro import/export.
|
||||
include!("macros.rs");
|
||||
}
|
||||
|
||||
/**
|
||||
The main "translation" pass for methods. Generates code
|
||||
for non-monomorphized methods only. Other methods will
|
||||
|
@ -51,7 +51,7 @@ pub const use_tydesc: uint = 2u; /* Takes the tydesc, or compares */
|
||||
|
||||
pub struct Context {
|
||||
ccx: @CrateContext,
|
||||
uses: ~[mut type_uses]
|
||||
uses: @mut ~[type_uses]
|
||||
}
|
||||
|
||||
pub fn type_uses_for(ccx: @CrateContext, fn_id: def_id, n_tps: uint)
|
||||
@ -72,7 +72,7 @@ pub fn type_uses_for(ccx: @CrateContext, fn_id: def_id, n_tps: uint)
|
||||
|
||||
let cx = Context {
|
||||
ccx: ccx,
|
||||
uses: vec::cast_to_mut(vec::from_elem(n_tps, 0u))
|
||||
uses: @mut vec::from_elem(n_tps, 0u)
|
||||
};
|
||||
match ty::get(ty::lookup_item_type(cx.ccx.tcx, fn_id).ty).sty {
|
||||
ty::ty_bare_fn(ty::BareFnTy {sig: ref sig, _}) |
|
||||
@ -90,7 +90,7 @@ pub fn type_uses_for(ccx: @CrateContext, fn_id: def_id, n_tps: uint)
|
||||
}
|
||||
|
||||
if fn_id_loc.crate != local_crate {
|
||||
let uses = vec::cast_from_mut(copy cx.uses);
|
||||
let uses = copy *cx.uses;
|
||||
ccx.type_use_cache.insert(fn_id, copy uses);
|
||||
return uses;
|
||||
}
|
||||
@ -175,16 +175,16 @@ pub fn type_uses_for(ccx: @CrateContext, fn_id: def_id, n_tps: uint)
|
||||
ccx.tcx.sess.parse_sess.interner)));
|
||||
}
|
||||
}
|
||||
let uses = vec::cast_from_mut(copy cx.uses);
|
||||
// XXX: Bad copy, use @vec instead?
|
||||
// XXX: Bad copies, use @vec instead?
|
||||
let uses = copy *cx.uses;
|
||||
ccx.type_use_cache.insert(fn_id, copy uses);
|
||||
uses
|
||||
}
|
||||
|
||||
pub fn type_needs(cx: Context, use_: uint, ty: ty::t) {
|
||||
// Optimization -- don't descend type if all params already have this use
|
||||
for vec::each_mut(cx.uses) |u| {
|
||||
if *u & use_ != use_ {
|
||||
for uint::range(0, cx.uses.len()) |i| {
|
||||
if cx.uses[i] & use_ != use_ {
|
||||
type_needs_inner(cx, use_, ty, @Nil);
|
||||
return;
|
||||
}
|
||||
|
@ -42,7 +42,8 @@ use core::uint;
|
||||
use core::vec;
|
||||
use core::hashmap::linear::LinearMap;
|
||||
use std::oldmap::HashMap;
|
||||
use std::{oldmap, oldsmallintmap};
|
||||
use std::oldmap;
|
||||
use std::smallintmap::SmallIntMap;
|
||||
use syntax::ast::*;
|
||||
use syntax::ast_util::{is_local, local_def};
|
||||
use syntax::ast_util;
|
||||
@ -258,7 +259,6 @@ struct ctxt_ {
|
||||
rcache: creader_cache,
|
||||
ccache: constness_cache,
|
||||
short_names_cache: HashMap<t, @~str>,
|
||||
needs_drop_cache: HashMap<t, bool>,
|
||||
needs_unwind_cleanup_cache: HashMap<t, bool>,
|
||||
tc_cache: @mut LinearMap<uint, TypeContents>,
|
||||
ast_ty_to_ty_cache: HashMap<node_id, ast_ty_to_ty_cache_entry>,
|
||||
@ -660,46 +660,46 @@ pub trait Vid {
|
||||
pure fn to_uint(&self) -> uint;
|
||||
}
|
||||
|
||||
pub impl Vid for TyVid {
|
||||
impl Vid for TyVid {
|
||||
pure fn to_uint(&self) -> uint { **self }
|
||||
}
|
||||
|
||||
pub impl ToStr for TyVid {
|
||||
impl ToStr for TyVid {
|
||||
pure fn to_str(&self) -> ~str { fmt!("<V%u>", self.to_uint()) }
|
||||
}
|
||||
|
||||
pub impl Vid for IntVid {
|
||||
impl Vid for IntVid {
|
||||
pure fn to_uint(&self) -> uint { **self }
|
||||
}
|
||||
|
||||
pub impl ToStr for IntVid {
|
||||
impl ToStr for IntVid {
|
||||
pure fn to_str(&self) -> ~str { fmt!("<VI%u>", self.to_uint()) }
|
||||
}
|
||||
|
||||
pub impl Vid for FloatVid {
|
||||
impl Vid for FloatVid {
|
||||
pure fn to_uint(&self) -> uint { **self }
|
||||
}
|
||||
|
||||
pub impl ToStr for FloatVid {
|
||||
impl ToStr for FloatVid {
|
||||
pure fn to_str(&self) -> ~str { fmt!("<VF%u>", self.to_uint()) }
|
||||
}
|
||||
|
||||
pub impl Vid for RegionVid {
|
||||
impl Vid for RegionVid {
|
||||
pure fn to_uint(&self) -> uint { **self }
|
||||
}
|
||||
|
||||
pub impl ToStr for RegionVid {
|
||||
impl ToStr for RegionVid {
|
||||
pure fn to_str(&self) -> ~str { fmt!("%?", self) }
|
||||
}
|
||||
|
||||
pub impl ToStr for FnSig {
|
||||
impl ToStr for FnSig {
|
||||
pure fn to_str(&self) -> ~str {
|
||||
// grr, without tcx not much we can do.
|
||||
return ~"(...)";
|
||||
}
|
||||
}
|
||||
|
||||
pub impl ToStr for InferTy {
|
||||
impl ToStr for InferTy {
|
||||
pure fn to_str(&self) -> ~str {
|
||||
match *self {
|
||||
TyVar(ref v) => v.to_str(),
|
||||
@ -709,7 +709,7 @@ pub impl ToStr for InferTy {
|
||||
}
|
||||
}
|
||||
|
||||
pub impl ToStr for IntVarValue {
|
||||
impl ToStr for IntVarValue {
|
||||
pure fn to_str(&self) -> ~str {
|
||||
match *self {
|
||||
IntType(ref v) => v.to_str(),
|
||||
@ -718,25 +718,25 @@ pub impl ToStr for IntVarValue {
|
||||
}
|
||||
}
|
||||
|
||||
pub impl to_bytes::IterBytes for TyVid {
|
||||
impl to_bytes::IterBytes for TyVid {
|
||||
pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) {
|
||||
self.to_uint().iter_bytes(lsb0, f)
|
||||
}
|
||||
}
|
||||
|
||||
pub impl to_bytes::IterBytes for IntVid {
|
||||
impl to_bytes::IterBytes for IntVid {
|
||||
pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) {
|
||||
self.to_uint().iter_bytes(lsb0, f)
|
||||
}
|
||||
}
|
||||
|
||||
pub impl to_bytes::IterBytes for FloatVid {
|
||||
impl to_bytes::IterBytes for FloatVid {
|
||||
pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) {
|
||||
self.to_uint().iter_bytes(lsb0, f)
|
||||
}
|
||||
}
|
||||
|
||||
pub impl to_bytes::IterBytes for RegionVid {
|
||||
impl to_bytes::IterBytes for RegionVid {
|
||||
pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) {
|
||||
self.to_uint().iter_bytes(lsb0, f)
|
||||
}
|
||||
@ -767,7 +767,7 @@ type type_cache = HashMap<ast::def_id, ty_param_bounds_and_ty>;
|
||||
|
||||
type constness_cache = HashMap<ast::def_id, const_eval::constness>;
|
||||
|
||||
pub type node_type_table = @oldsmallintmap::SmallIntMap<t>;
|
||||
pub type node_type_table = @mut SmallIntMap<t>;
|
||||
|
||||
fn mk_rcache() -> creader_cache {
|
||||
type val = {cnum: int, pos: uint, len: uint};
|
||||
@ -812,7 +812,7 @@ pub fn mk_ctxt(s: session::Session,
|
||||
def_map: dm,
|
||||
region_map: region_map,
|
||||
region_paramd_items: region_paramd_items,
|
||||
node_types: @oldsmallintmap::mk(),
|
||||
node_types: @mut SmallIntMap::new(),
|
||||
node_type_substs: oldmap::HashMap(),
|
||||
items: amap,
|
||||
intrinsic_defs: oldmap::HashMap(),
|
||||
@ -821,7 +821,6 @@ pub fn mk_ctxt(s: session::Session,
|
||||
rcache: mk_rcache(),
|
||||
ccache: HashMap(),
|
||||
short_names_cache: new_ty_hash(),
|
||||
needs_drop_cache: new_ty_hash(),
|
||||
needs_unwind_cleanup_cache: new_ty_hash(),
|
||||
tc_cache: @mut LinearMap::new(),
|
||||
ast_ty_to_ty_cache: HashMap(),
|
||||
@ -1599,79 +1598,7 @@ pub fn type_is_immediate(ty: t) -> bool {
|
||||
}
|
||||
|
||||
pub fn type_needs_drop(cx: ctxt, ty: t) -> bool {
|
||||
match cx.needs_drop_cache.find(&ty) {
|
||||
Some(result) => return result,
|
||||
None => {/* fall through */ }
|
||||
}
|
||||
|
||||
let mut accum = false;
|
||||
let result = match /*bad*/copy get(ty).sty {
|
||||
// scalar types
|
||||
ty_nil | ty_bot | ty_bool | ty_int(_) | ty_float(_) | ty_uint(_) |
|
||||
ty_type | ty_ptr(_) | ty_rptr(_, _) |
|
||||
ty_estr(vstore_fixed(_)) |
|
||||
ty_estr(vstore_slice(_)) |
|
||||
ty_evec(_, vstore_slice(_)) |
|
||||
ty_self => false,
|
||||
|
||||
ty_box(_) | ty_uniq(_) |
|
||||
ty_opaque_box | ty_opaque_closure_ptr(*) |
|
||||
ty_estr(vstore_uniq) |
|
||||
ty_estr(vstore_box) |
|
||||
ty_evec(_, vstore_uniq) |
|
||||
ty_evec(_, vstore_box) => true,
|
||||
|
||||
ty_trait(_, _, vstore_box) |
|
||||
ty_trait(_, _, vstore_uniq) => true,
|
||||
ty_trait(_, _, vstore_fixed(_)) |
|
||||
ty_trait(_, _, vstore_slice(_)) => false,
|
||||
|
||||
ty_param(*) | ty_infer(*) | ty_err => true,
|
||||
|
||||
ty_evec(mt, vstore_fixed(_)) => type_needs_drop(cx, mt.ty),
|
||||
ty_unboxed_vec(mt) => type_needs_drop(cx, mt.ty),
|
||||
ty_rec(flds) => {
|
||||
for flds.each |f| {
|
||||
if type_needs_drop(cx, f.mt.ty) { accum = true; }
|
||||
}
|
||||
accum
|
||||
}
|
||||
ty_struct(did, ref substs) => {
|
||||
// Any struct with a dtor needs a drop
|
||||
ty_dtor(cx, did).is_present() || {
|
||||
for vec::each(ty::struct_fields(cx, did, substs)) |f| {
|
||||
if type_needs_drop(cx, f.mt.ty) { accum = true; }
|
||||
}
|
||||
accum
|
||||
}
|
||||
}
|
||||
ty_tup(elts) => {
|
||||
for elts.each |m| { if type_needs_drop(cx, *m) { accum = true; } }
|
||||
accum
|
||||
}
|
||||
ty_enum(did, ref substs) => {
|
||||
let variants = enum_variants(cx, did);
|
||||
for vec::each(*variants) |variant| {
|
||||
for variant.args.each |aty| {
|
||||
// Perform any type parameter substitutions.
|
||||
let arg_ty = subst(cx, substs, *aty);
|
||||
if type_needs_drop(cx, arg_ty) { accum = true; }
|
||||
}
|
||||
if accum { break; }
|
||||
}
|
||||
accum
|
||||
}
|
||||
ty_bare_fn(*) => false,
|
||||
ty_closure(ref fty) => {
|
||||
match fty.sigil {
|
||||
ast::BorrowedSigil => false,
|
||||
ast::ManagedSigil | ast::OwnedSigil => true,
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
cx.needs_drop_cache.insert(ty, result);
|
||||
return result;
|
||||
type_contents(cx, ty).needs_drop(cx)
|
||||
}
|
||||
|
||||
// Some things don't need cleanups during unwinding because the
|
||||
@ -1818,7 +1745,7 @@ pub impl TypeContents {
|
||||
|
||||
static fn nonimplicitly_copyable(cx: ctxt) -> TypeContents {
|
||||
let base = TypeContents::noncopyable(cx) + TC_OWNED_POINTER;
|
||||
if cx.vecs_implicitly_copyable {base} else {base + TC_OWNED_SLICE}
|
||||
if cx.vecs_implicitly_copyable {base} else {base + TC_OWNED_VEC}
|
||||
}
|
||||
|
||||
fn is_safe_for_default_mode(&self, cx: ctxt) -> bool {
|
||||
@ -1827,7 +1754,17 @@ pub impl TypeContents {
|
||||
|
||||
static fn nondefault_mode(cx: ctxt) -> TypeContents {
|
||||
let tc = TypeContents::nonimplicitly_copyable(cx);
|
||||
tc + TC_BIG + TC_OWNED_SLICE // disregard cx.vecs_implicitly_copyable
|
||||
tc + TC_BIG + TC_OWNED_VEC // disregard cx.vecs_implicitly_copyable
|
||||
}
|
||||
|
||||
fn needs_drop(&self, cx: ctxt) -> bool {
|
||||
let tc = TC_MANAGED + TC_DTOR + TypeContents::owned(cx);
|
||||
self.intersects(tc)
|
||||
}
|
||||
|
||||
static fn owned(&self, _cx: ctxt) -> TypeContents {
|
||||
//! Any kind of owned contents.
|
||||
TC_OWNED_CLOSURE + TC_OWNED_POINTER + TC_OWNED_VEC
|
||||
}
|
||||
}
|
||||
|
||||
@ -1858,8 +1795,8 @@ const TC_BORROWED_POINTER: TypeContents = TypeContents{bits:0b0000_00000001};
|
||||
/// Contains an owned pointer (~T) but not slice of some kind
|
||||
const TC_OWNED_POINTER: TypeContents = TypeContents{bits:0b000000000010};
|
||||
|
||||
/// Contains an owned slice
|
||||
const TC_OWNED_SLICE: TypeContents = TypeContents{bits:0b000000000100};
|
||||
/// Contains an owned vector ~[] or owned string ~str
|
||||
const TC_OWNED_VEC: TypeContents = TypeContents{bits:0b000000000100};
|
||||
|
||||
/// Contains a ~fn() or a ~Trait, which is non-copyable.
|
||||
const TC_OWNED_CLOSURE: TypeContents = TypeContents{bits:0b000000001000};
|
||||
@ -1962,7 +1899,7 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
|
||||
}
|
||||
|
||||
ty_estr(vstore_uniq) => {
|
||||
TC_OWNED_SLICE
|
||||
TC_OWNED_VEC
|
||||
}
|
||||
|
||||
ty_closure(ref c) => {
|
||||
@ -1995,7 +1932,7 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
|
||||
}
|
||||
|
||||
ty_evec(mt, vstore_uniq) => {
|
||||
TC_OWNED_SLICE + tc_mt(cx, mt, cache)
|
||||
TC_OWNED_VEC + tc_mt(cx, mt, cache)
|
||||
}
|
||||
|
||||
ty_evec(mt, vstore_box) => {
|
||||
@ -2787,8 +2724,8 @@ pub fn br_hashmap<V:Copy>() -> HashMap<bound_region, V> {
|
||||
|
||||
pub fn node_id_to_type(cx: ctxt, id: ast::node_id) -> t {
|
||||
//io::println(fmt!("%?/%?", id, cx.node_types.len()));
|
||||
match oldsmallintmap::find(*cx.node_types, id as uint) {
|
||||
Some(t) => t,
|
||||
match cx.node_types.find(&(id as uint)) {
|
||||
Some(&t) => t,
|
||||
None => cx.sess.bug(
|
||||
fmt!("node_id_to_type: no type for node `%s`",
|
||||
ast_map::node_id_to_str(cx.items, id,
|
||||
@ -3179,8 +3116,8 @@ pub fn expr_kind(tcx: ctxt,
|
||||
}
|
||||
|
||||
ast::expr_cast(*) => {
|
||||
match oldsmallintmap::find(*tcx.node_types, expr.id as uint) {
|
||||
Some(t) => {
|
||||
match tcx.node_types.find(&(expr.id as uint)) {
|
||||
Some(&t) => {
|
||||
if ty::type_is_immediate(t) {
|
||||
RvalueDatumExpr
|
||||
} else {
|
||||
@ -4289,7 +4226,8 @@ pub fn eval_repeat_count(tcx: ctxt,
|
||||
count_expr: @ast::expr,
|
||||
span: span)
|
||||
-> uint {
|
||||
match const_eval::eval_const_expr(tcx, count_expr) {
|
||||
match const_eval::eval_const_expr_partial(tcx, count_expr) {
|
||||
Ok(ref const_val) => match *const_val {
|
||||
const_eval::const_int(count) => return count as uint,
|
||||
const_eval::const_uint(count) => return count as uint,
|
||||
const_eval::const_float(count) => {
|
||||
@ -4310,7 +4248,13 @@ pub fn eval_repeat_count(tcx: ctxt,
|
||||
repeat count but found boolean");
|
||||
return 0;
|
||||
}
|
||||
|
||||
},
|
||||
Err(*) => {
|
||||
tcx.sess.span_err(span,
|
||||
~"expected constant integer for repeat count \
|
||||
but found variable");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -216,7 +216,8 @@ pub fn ast_ty_to_ty<AC:AstConv,RS:region_scope + Copy + Durable>(
|
||||
match a_seq_ty.ty.node {
|
||||
ast::ty_vec(mt) => {
|
||||
let mut mt = ast_mt_to_mt(self, rscope, mt);
|
||||
if a_seq_ty.mutbl == ast::m_mutbl {
|
||||
if a_seq_ty.mutbl == ast::m_mutbl ||
|
||||
a_seq_ty.mutbl == ast::m_const {
|
||||
mt = ty::mt { ty: mt.ty, mutbl: ast::m_mutbl };
|
||||
}
|
||||
return ty::mk_evec(tcx, mt, vst);
|
||||
|
@ -635,7 +635,7 @@ pub fn check_item(ccx: @mut CrateCtxt, it: @ast::item) {
|
||||
}
|
||||
}
|
||||
|
||||
pub impl AstConv for FnCtxt {
|
||||
impl AstConv for FnCtxt {
|
||||
fn tcx(@mut self) -> ty::ctxt { self.ccx.tcx }
|
||||
fn ccx(@mut self) -> @mut CrateCtxt { self.ccx }
|
||||
|
||||
@ -669,7 +669,7 @@ pub impl FnCtxt {
|
||||
}
|
||||
}
|
||||
|
||||
pub impl region_scope for @mut FnCtxt {
|
||||
impl region_scope for @mut FnCtxt {
|
||||
pure fn anon_region(&self, span: span) -> Result<ty::Region, ~str> {
|
||||
// XXX: Unsafe to work around purity
|
||||
unsafe {
|
||||
|
@ -121,7 +121,7 @@ pub impl @mut CrateCtxt {
|
||||
}
|
||||
}
|
||||
|
||||
pub impl AstConv for CrateCtxt {
|
||||
impl AstConv for CrateCtxt {
|
||||
fn tcx(@mut self) -> ty::ctxt { self.tcx }
|
||||
fn ccx(@mut self) -> @mut CrateCtxt { self }
|
||||
|
||||
|
@ -72,11 +72,6 @@ use syntax::ast::{Onceness, purity, ret_style};
|
||||
use syntax::ast;
|
||||
use syntax::codemap::span;
|
||||
|
||||
pub fn macros() {
|
||||
// FIXME(#3114): Macro import/export.
|
||||
include!("macros.rs");
|
||||
}
|
||||
|
||||
pub trait Combine {
|
||||
fn infcx(&self) -> @mut InferCtxt;
|
||||
fn tag(&self) -> ~str;
|
||||
|
@ -27,7 +27,7 @@ use std::list;
|
||||
|
||||
pub enum Glb = CombineFields; // "greatest lower bound" (common subtype)
|
||||
|
||||
pub impl Combine for Glb {
|
||||
impl Combine for Glb {
|
||||
fn infcx(&self) -> @mut InferCtxt { self.infcx }
|
||||
fn tag(&self) -> ~str { ~"glb" }
|
||||
fn a_is_expected(&self) -> bool { self.a_is_expected }
|
||||
|
@ -59,7 +59,7 @@ pub trait LatticeValue {
|
||||
|
||||
pub type LatticeOp<T> = &fn(cf: &CombineFields, a: &T, b: &T) -> cres<T>;
|
||||
|
||||
pub impl LatticeValue for ty::t {
|
||||
impl LatticeValue for ty::t {
|
||||
static fn sub(&self, cf: &CombineFields, a: &ty::t, b: &ty::t) -> ures {
|
||||
Sub(*cf).tys(*a, *b).to_ures()
|
||||
}
|
||||
@ -305,7 +305,7 @@ pub trait TyLatticeDir {
|
||||
fn ty_bot(&self, t: ty::t) -> cres<ty::t>;
|
||||
}
|
||||
|
||||
pub impl LatticeDir for Lub {
|
||||
impl LatticeDir for Lub {
|
||||
fn combine_fields(&self) -> CombineFields { **self }
|
||||
fn bnd<T:Copy>(&self, b: &Bounds<T>) -> Option<T> { b.ub }
|
||||
fn with_bnd<T:Copy>(&self, b: &Bounds<T>, +t: T) -> Bounds<T> {
|
||||
@ -313,13 +313,13 @@ pub impl LatticeDir for Lub {
|
||||
}
|
||||
}
|
||||
|
||||
pub impl TyLatticeDir for Lub {
|
||||
impl TyLatticeDir for Lub {
|
||||
fn ty_bot(&self, t: ty::t) -> cres<ty::t> {
|
||||
Ok(t)
|
||||
}
|
||||
}
|
||||
|
||||
pub impl LatticeDir for Glb {
|
||||
impl LatticeDir for Glb {
|
||||
fn combine_fields(&self) -> CombineFields { **self }
|
||||
fn bnd<T:Copy>(&self, b: &Bounds<T>) -> Option<T> { b.lb }
|
||||
fn with_bnd<T:Copy>(&self, b: &Bounds<T>, +t: T) -> Bounds<T> {
|
||||
@ -327,7 +327,7 @@ pub impl LatticeDir for Glb {
|
||||
}
|
||||
}
|
||||
|
||||
pub impl TyLatticeDir for Glb {
|
||||
impl TyLatticeDir for Glb {
|
||||
fn ty_bot(&self, _t: ty::t) -> cres<ty::t> {
|
||||
Ok(ty::mk_bot(self.infcx.tcx))
|
||||
}
|
||||
|
@ -24,11 +24,6 @@ use std::list;
|
||||
use syntax::ast::{Many, Once, extern_fn, m_const, impure_fn, noreturn};
|
||||
use syntax::ast::{pure_fn, ret_style, return_val, unsafe_fn};
|
||||
|
||||
pub fn macros() {
|
||||
// FIXME(#3114): Macro import/export.
|
||||
include!("macros.rs");
|
||||
}
|
||||
|
||||
pub enum Lub = CombineFields; // least-upper-bound: common supertype
|
||||
|
||||
pub impl Lub {
|
||||
@ -37,7 +32,7 @@ pub impl Lub {
|
||||
-> cres<ty::t> { self.bot_ty(b) } // commutative
|
||||
}
|
||||
|
||||
pub impl Combine for Lub {
|
||||
impl Combine for Lub {
|
||||
fn infcx(&self) -> @mut InferCtxt { self.infcx }
|
||||
fn tag(&self) -> ~str { ~"lub" }
|
||||
fn a_is_expected(&self) -> bool { self.a_is_expected }
|
||||
|
@ -8,7 +8,7 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
{
|
||||
#[macro_escape];
|
||||
|
||||
macro_rules! if_ok(
|
||||
($inp: expr) => (
|
||||
@ -17,6 +17,5 @@ macro_rules! if_ok(
|
||||
Err(e) => { return Err(e); }
|
||||
}
|
||||
)
|
||||
);
|
||||
)
|
||||
|
||||
}
|
||||
|
@ -277,7 +277,7 @@ use core::result;
|
||||
use core::vec;
|
||||
use std::list::Nil;
|
||||
use std::oldmap::HashMap;
|
||||
use std::oldsmallintmap;
|
||||
use std::smallintmap::SmallIntMap;
|
||||
use syntax::ast::{ret_style, purity};
|
||||
use syntax::ast::{m_const, m_imm, m_mutbl};
|
||||
use syntax::ast::{unsafe_fn, impure_fn, pure_fn, extern_fn};
|
||||
@ -287,6 +287,7 @@ use syntax::codemap;
|
||||
use syntax::ast_util;
|
||||
use syntax::codemap::span;
|
||||
|
||||
pub mod macros;
|
||||
pub mod combine;
|
||||
pub mod glb;
|
||||
pub mod lattice;
|
||||
@ -353,7 +354,7 @@ pub fn fixup_err_to_str(f: fixup_err) -> ~str {
|
||||
|
||||
fn new_ValsAndBindings<V:Copy,T:Copy>() -> ValsAndBindings<V, T> {
|
||||
ValsAndBindings {
|
||||
vals: oldsmallintmap::mk(),
|
||||
vals: @mut SmallIntMap::new(),
|
||||
bindings: ~[]
|
||||
}
|
||||
}
|
||||
@ -734,10 +735,10 @@ impl @mut InferCtxt {
|
||||
|
||||
fn report_mismatched_types(&self, sp: span, e: ty::t, a: ty::t,
|
||||
err: &ty::type_err) {
|
||||
// Don't report an error if expected is ty_err
|
||||
let resolved_expected =
|
||||
self.resolve_type_vars_if_possible(e);
|
||||
let mk_msg = match ty::get(resolved_expected).sty {
|
||||
// Don't report an error if expected is ty_err
|
||||
ty::ty_err => return,
|
||||
_ => {
|
||||
// if I leave out : ~str, it infers &str and complains
|
||||
@ -780,4 +781,3 @@ impl @mut InferCtxt {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -549,6 +549,7 @@ use syntax::codemap;
|
||||
use util::common::indenter;
|
||||
use util::ppaux::note_and_explain_region;
|
||||
|
||||
use core::cell::{Cell, empty_cell};
|
||||
use core::cmp;
|
||||
use core::dvec::DVec;
|
||||
use core::to_bytes;
|
||||
@ -557,7 +558,6 @@ use core::vec;
|
||||
use result::Result;
|
||||
use result::{Ok, Err};
|
||||
use std::oldmap::HashMap;
|
||||
use std::cell::{Cell, empty_cell};
|
||||
use std::list::{List, Nil, Cons};
|
||||
use syntax::codemap::span;
|
||||
use syntax::codemap;
|
||||
|
@ -25,14 +25,10 @@ use std::list::Nil;
|
||||
use std::list;
|
||||
use syntax::ast::{m_const, purity, ret_style};
|
||||
|
||||
pub fn macros() {
|
||||
// FIXME(#3114): Macro import/export.
|
||||
include!("macros.rs");
|
||||
}
|
||||
|
||||
pub enum Sub = CombineFields; // "subtype", "subregion" etc
|
||||
|
||||
pub impl Combine for Sub {
|
||||
impl Combine for Sub {
|
||||
fn infcx(&self) -> @mut InferCtxt { self.infcx }
|
||||
fn tag(&self) -> ~str { ~"sub" }
|
||||
fn a_is_expected(&self) -> bool { self.a_is_expected }
|
||||
|
@ -28,13 +28,13 @@ pub trait InferStr {
|
||||
fn inf_str(&self, cx: &InferCtxt) -> ~str;
|
||||
}
|
||||
|
||||
pub impl InferStr for ty::t {
|
||||
impl InferStr for ty::t {
|
||||
fn inf_str(&self, cx: &InferCtxt) -> ~str {
|
||||
ty_to_str(cx.tcx, *self)
|
||||
}
|
||||
}
|
||||
|
||||
pub impl InferStr for FnSig {
|
||||
impl InferStr for FnSig {
|
||||
fn inf_str(&self, cx: &InferCtxt) -> ~str {
|
||||
fmt!("(%s) -> %s",
|
||||
str::connect(self.inputs.map(|a| a.ty.inf_str(cx)), ", "),
|
||||
@ -42,19 +42,19 @@ pub impl InferStr for FnSig {
|
||||
}
|
||||
}
|
||||
|
||||
pub impl InferStr for ty::mt {
|
||||
impl InferStr for ty::mt {
|
||||
fn inf_str(&self, cx: &InferCtxt) -> ~str {
|
||||
mt_to_str(cx.tcx, *self)
|
||||
}
|
||||
}
|
||||
|
||||
pub impl InferStr for ty::Region {
|
||||
impl InferStr for ty::Region {
|
||||
fn inf_str(&self, _cx: &InferCtxt) -> ~str {
|
||||
fmt!("%?", *self)
|
||||
}
|
||||
}
|
||||
|
||||
pub impl<V:InferStr> InferStr for Bound<V> {
|
||||
impl<V:InferStr> InferStr for Bound<V> {
|
||||
fn inf_str(&self, cx: &InferCtxt) -> ~str {
|
||||
match *self {
|
||||
Some(ref v) => v.inf_str(cx),
|
||||
@ -63,7 +63,7 @@ pub impl<V:InferStr> InferStr for Bound<V> {
|
||||
}
|
||||
}
|
||||
|
||||
pub impl<T:InferStr> InferStr for Bounds<T> {
|
||||
impl<T:InferStr> InferStr for Bounds<T> {
|
||||
fn inf_str(&self, cx: &InferCtxt) -> ~str {
|
||||
fmt!("{%s <: %s}",
|
||||
self.lb.inf_str(cx),
|
||||
@ -71,7 +71,7 @@ pub impl<T:InferStr> InferStr for Bounds<T> {
|
||||
}
|
||||
}
|
||||
|
||||
pub impl<V:Vid + ToStr,T:InferStr> InferStr for VarValue<V, T> {
|
||||
impl<V:Vid + ToStr,T:InferStr> InferStr for VarValue<V, T> {
|
||||
fn inf_str(&self, cx: &InferCtxt) -> ~str {
|
||||
match *self {
|
||||
Redirect(ref vid) => fmt!("Redirect(%s)", vid.to_str()),
|
||||
@ -81,13 +81,13 @@ pub impl<V:Vid + ToStr,T:InferStr> InferStr for VarValue<V, T> {
|
||||
}
|
||||
}
|
||||
|
||||
pub impl InferStr for IntVarValue {
|
||||
impl InferStr for IntVarValue {
|
||||
fn inf_str(&self, _cx: &InferCtxt) -> ~str {
|
||||
self.to_str()
|
||||
}
|
||||
}
|
||||
|
||||
pub impl InferStr for ast::float_ty {
|
||||
impl InferStr for ast::float_ty {
|
||||
fn inf_str(&self, _cx: &InferCtxt) -> ~str {
|
||||
self.to_str()
|
||||
}
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
use core::prelude::*;
|
||||
use core::result;
|
||||
use std::oldsmallintmap::SmallIntMap;
|
||||
use std::smallintmap::SmallIntMap;
|
||||
|
||||
use middle::ty::{Vid, expected_found, IntVarValue};
|
||||
use middle::ty;
|
||||
@ -27,7 +27,7 @@ pub enum VarValue<V, T> {
|
||||
}
|
||||
|
||||
pub struct ValsAndBindings<V, T> {
|
||||
vals: SmallIntMap<VarValue<V, T>>,
|
||||
vals: @mut SmallIntMap<VarValue<V, T>>,
|
||||
bindings: ~[(V, VarValue<V, T>)],
|
||||
}
|
||||
|
||||
@ -64,12 +64,12 @@ pub impl InferCtxt {
|
||||
vid: V) -> Node<V, T>
|
||||
{
|
||||
let vid_u = vid.to_uint();
|
||||
match vb.vals.find(vid_u) {
|
||||
match vb.vals.find(&vid_u) {
|
||||
None => {
|
||||
tcx.sess.bug(fmt!(
|
||||
"failed lookup of vid `%u`", vid_u));
|
||||
}
|
||||
Some(ref var_val) => {
|
||||
Some(var_val) => {
|
||||
match *var_val {
|
||||
Redirect(vid) => {
|
||||
let node: Node<V,T> = helper(tcx, vb, vid);
|
||||
@ -103,8 +103,8 @@ pub impl InferCtxt {
|
||||
|
||||
{ // FIXME(#4903)---borrow checker is not flow sensitive
|
||||
let vb = UnifyVid::appropriate_vals_and_bindings(self);
|
||||
let old_v = vb.vals.get(vid.to_uint());
|
||||
vb.bindings.push((vid, old_v));
|
||||
let old_v = vb.vals.get(&vid.to_uint());
|
||||
vb.bindings.push((vid, *old_v));
|
||||
vb.vals.insert(vid.to_uint(), new_v);
|
||||
}
|
||||
}
|
||||
@ -237,35 +237,35 @@ pub impl InferCtxt {
|
||||
|
||||
// ______________________________________________________________________
|
||||
|
||||
pub impl UnifyVid<Bounds<ty::t>> for ty::TyVid {
|
||||
impl UnifyVid<Bounds<ty::t>> for ty::TyVid {
|
||||
static fn appropriate_vals_and_bindings(&self, infcx: &v/mut InferCtxt)
|
||||
-> &v/mut ValsAndBindings<ty::TyVid, Bounds<ty::t>> {
|
||||
return &mut infcx.ty_var_bindings;
|
||||
}
|
||||
}
|
||||
|
||||
pub impl UnifyVid<Option<IntVarValue>> for ty::IntVid {
|
||||
impl UnifyVid<Option<IntVarValue>> for ty::IntVid {
|
||||
static fn appropriate_vals_and_bindings(&self, infcx: &v/mut InferCtxt)
|
||||
-> &v/mut ValsAndBindings<ty::IntVid, Option<IntVarValue>> {
|
||||
return &mut infcx.int_var_bindings;
|
||||
}
|
||||
}
|
||||
|
||||
pub impl SimplyUnifiable for IntVarValue {
|
||||
impl SimplyUnifiable for IntVarValue {
|
||||
static fn to_type_err(&self, err: expected_found<IntVarValue>)
|
||||
-> ty::type_err {
|
||||
return ty::terr_int_mismatch(err);
|
||||
}
|
||||
}
|
||||
|
||||
pub impl UnifyVid<Option<ast::float_ty>> for ty::FloatVid {
|
||||
impl UnifyVid<Option<ast::float_ty>> for ty::FloatVid {
|
||||
static fn appropriate_vals_and_bindings(&self, infcx: &v/mut InferCtxt)
|
||||
-> &v/mut ValsAndBindings<ty::FloatVid, Option<ast::float_ty>> {
|
||||
return &mut infcx.float_var_bindings;
|
||||
}
|
||||
}
|
||||
|
||||
pub impl SimplyUnifiable for ast::float_ty {
|
||||
impl SimplyUnifiable for ast::float_ty {
|
||||
static fn to_type_err(&self, err: expected_found<ast::float_ty>)
|
||||
-> ty::type_err {
|
||||
return ty::terr_float_mismatch(err);
|
||||
|
@ -69,7 +69,6 @@ use std::list::{List, Nil, Cons};
|
||||
use std::list;
|
||||
use std::oldmap::HashMap;
|
||||
use std::oldmap;
|
||||
use std::oldsmallintmap;
|
||||
use syntax::ast::{provided, required};
|
||||
use syntax::ast_map::node_id_to_str;
|
||||
use syntax::ast_util::{local_def, split_trait_methods};
|
||||
|
@ -26,7 +26,8 @@ pub trait region_scope {
|
||||
}
|
||||
|
||||
pub enum empty_rscope { empty_rscope }
|
||||
pub impl region_scope for empty_rscope {
|
||||
|
||||
impl region_scope for empty_rscope {
|
||||
pure fn anon_region(&self, _span: span) -> Result<ty::Region, ~str> {
|
||||
result::Ok(ty::re_static)
|
||||
}
|
||||
@ -40,7 +41,8 @@ pub impl region_scope for empty_rscope {
|
||||
}
|
||||
|
||||
pub enum type_rscope = Option<ty::region_variance>;
|
||||
pub impl region_scope for type_rscope {
|
||||
|
||||
impl region_scope for type_rscope {
|
||||
pure fn anon_region(&self, _span: span) -> Result<ty::Region, ~str> {
|
||||
match **self {
|
||||
Some(_) => result::Ok(ty::re_bound(ty::br_self)),
|
||||
@ -74,7 +76,8 @@ pub fn in_anon_rscope<RS:region_scope + Copy + Durable>(self: RS,
|
||||
-> @anon_rscope {
|
||||
@anon_rscope {anon: r, base: self as region_scope}
|
||||
}
|
||||
pub impl region_scope for @anon_rscope {
|
||||
|
||||
impl region_scope for @anon_rscope {
|
||||
pure fn anon_region(&self, _span: span) -> Result<ty::Region, ~str> {
|
||||
result::Ok(self.anon)
|
||||
}
|
||||
@ -97,7 +100,8 @@ pub fn in_binding_rscope<RS:region_scope + Copy + Durable>(self: RS)
|
||||
let base = self as region_scope;
|
||||
@mut binding_rscope { base: base, anon_bindings: 0 }
|
||||
}
|
||||
pub impl region_scope for @mut binding_rscope {
|
||||
|
||||
impl region_scope for @mut binding_rscope {
|
||||
pure fn anon_region(&self, _span: span) -> Result<ty::Region, ~str> {
|
||||
// XXX: Unsafe to work around purity
|
||||
unsafe {
|
||||
|
@ -49,6 +49,7 @@ use back_ = back;
|
||||
|
||||
pub mod middle {
|
||||
pub mod trans {
|
||||
pub mod macros;
|
||||
pub mod inline;
|
||||
pub mod monomorphize;
|
||||
pub mod controlflow;
|
||||
@ -68,6 +69,7 @@ pub mod middle {
|
||||
pub mod meth;
|
||||
pub mod cabi;
|
||||
pub mod cabi_x86_64;
|
||||
pub mod cabi_arm;
|
||||
pub mod foreign;
|
||||
pub mod reflect;
|
||||
pub mod shape;
|
||||
@ -314,8 +316,8 @@ fails without recording a fatal error then we've encountered a compiler
|
||||
bug and need to present an error.
|
||||
*/
|
||||
pub fn monitor(+f: fn~(diagnostic::Emitter)) {
|
||||
use core::cell::Cell;
|
||||
use core::comm::*;
|
||||
use std::cell::Cell;
|
||||
let (p, ch) = stream();
|
||||
let ch = SharedChan(ch);
|
||||
let ch_capture = ch.clone();
|
||||
|
@ -238,19 +238,19 @@ pub fn vstore_to_str(cx: ctxt, vs: ty::vstore) -> ~str {
|
||||
ty::vstore_fixed(n) => fmt!("%u", n),
|
||||
ty::vstore_uniq => ~"~",
|
||||
ty::vstore_box => ~"@",
|
||||
ty::vstore_slice(r) => region_to_str(cx, r)
|
||||
ty::vstore_slice(r) => region_to_str_adorned(cx, "&", r, "/")
|
||||
}
|
||||
}
|
||||
|
||||
pub fn vstore_ty_to_str(cx: ctxt, ty: ~str, vs: ty::vstore) -> ~str {
|
||||
match vs {
|
||||
ty::vstore_fixed(_) => {
|
||||
fmt!("%s/%s", ty, vstore_to_str(cx, vs))
|
||||
fmt!("[%s * %s]", ty, vstore_to_str(cx, vs))
|
||||
}
|
||||
ty::vstore_slice(_) => {
|
||||
fmt!("%s/%s", vstore_to_str(cx, vs), ty)
|
||||
}
|
||||
_ => fmt!("%s%s", vstore_to_str(cx, vs), ty)
|
||||
_ => fmt!("%s[%s]", vstore_to_str(cx, vs), ty)
|
||||
}
|
||||
}
|
||||
|
||||
@ -453,13 +453,13 @@ pub fn ty_to_str(cx: ctxt, typ: t) -> ~str {
|
||||
ty_trait(did, ref substs, vs) => {
|
||||
let path = ty::item_path(cx, did);
|
||||
let base = ast_map::path_to_str(path, cx.sess.intr());
|
||||
let result = parameterized(cx, base, substs.self_r, substs.tps);
|
||||
vstore_ty_to_str(cx, result, vs)
|
||||
let ty = parameterized(cx, base, substs.self_r, substs.tps);
|
||||
fmt!("%s%s", vstore_to_str(cx, vs), ty)
|
||||
}
|
||||
ty_evec(mt, vs) => {
|
||||
vstore_ty_to_str(cx, fmt!("[%s]", mt_to_str(cx, mt)), vs)
|
||||
vstore_ty_to_str(cx, fmt!("%s", mt_to_str(cx, mt)), vs)
|
||||
}
|
||||
ty_estr(vs) => vstore_ty_to_str(cx, ~"str", vs),
|
||||
ty_estr(vs) => fmt!("%s%s", vstore_to_str(cx, vs), ~"str"),
|
||||
ty_opaque_box => ~"@?",
|
||||
ty_opaque_closure_ptr(ast::BorrowedSigil) => ~"closure&",
|
||||
ty_opaque_closure_ptr(ast::ManagedSigil) => ~"closure@",
|
||||
|
@ -21,8 +21,8 @@ use core::prelude::*;
|
||||
|
||||
use parse;
|
||||
use util;
|
||||
use std::cell::Cell;
|
||||
|
||||
use core::cell::Cell;
|
||||
use core::comm::{stream, Chan, SharedChan, Port};
|
||||
use core::vec;
|
||||
use core::ops::Drop;
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use core::cell::Cell;
|
||||
use core::cmp;
|
||||
use core::os;
|
||||
use core::result;
|
||||
@ -18,7 +19,6 @@ use core::run::ProgramOutput;
|
||||
use core::vec;
|
||||
use core::result::Result;
|
||||
use std::getopts;
|
||||
use std::cell::Cell;
|
||||
|
||||
/// The type of document to output
|
||||
pub enum OutputFormat {
|
||||
@ -59,7 +59,7 @@ pub struct Config {
|
||||
pandoc_cmd: Option<~str>
|
||||
}
|
||||
|
||||
pub impl Clone for Config {
|
||||
impl Clone for Config {
|
||||
fn clone(&self) -> Config { copy *self }
|
||||
}
|
||||
|
||||
|
@ -161,7 +161,7 @@ fn nmoddoc_from_mod(
|
||||
ast::foreign_item_const(*) => {} // XXX: Not implemented.
|
||||
}
|
||||
}
|
||||
doc:: NmodDoc {
|
||||
doc::NmodDoc {
|
||||
item: itemdoc,
|
||||
fns: fns,
|
||||
index: None
|
||||
|
@ -34,11 +34,11 @@ use sort_pass;
|
||||
use trim_pass;
|
||||
use unindent_pass;
|
||||
|
||||
use core::cell::Cell;
|
||||
use core::iter;
|
||||
use core::str;
|
||||
use core::vec;
|
||||
use std::par;
|
||||
use std::cell::Cell;
|
||||
use syntax;
|
||||
|
||||
pub fn mk_pass(writer_factory: WriterFactory) -> Pass {
|
||||
|
@ -20,8 +20,8 @@ use fold;
|
||||
use pass::Pass;
|
||||
use util::NominalOp;
|
||||
|
||||
use core::cell::Cell;
|
||||
use std::par;
|
||||
use std::cell::Cell;
|
||||
|
||||
pub fn mk_pass(name: ~str, op: @fn(&str) -> ~str) -> Pass {
|
||||
let op = Cell(op);
|
||||
|
@ -17,6 +17,7 @@ use sync;
|
||||
use sync::{Mutex, mutex_with_condvars, RWlock, rwlock_with_condvars};
|
||||
|
||||
use core::cast;
|
||||
use core::cell::Cell;
|
||||
use core::pipes;
|
||||
use core::prelude::*;
|
||||
use core::private::{SharedMutableState, shared_mutable_state};
|
||||
@ -532,17 +533,17 @@ mod tests {
|
||||
let arc = ~MutexARC(false);
|
||||
let arc2 = ~arc.clone();
|
||||
let (p,c) = comm::oneshot();
|
||||
let (c,p) = (~mut Some(c), ~mut Some(p));
|
||||
let (c,p) = (Cell(c), Cell(p));
|
||||
do task::spawn || {
|
||||
// wait until parent gets in
|
||||
comm::recv_one(option::swap_unwrap(p));
|
||||
comm::recv_one(p.take());
|
||||
do arc2.access_cond |state, cond| {
|
||||
*state = true;
|
||||
cond.signal();
|
||||
}
|
||||
}
|
||||
do arc.access_cond |state, cond| {
|
||||
comm::send_one(option::swap_unwrap(c), ());
|
||||
comm::send_one(c.take(), ());
|
||||
assert !*state;
|
||||
while !*state {
|
||||
cond.wait();
|
||||
|
@ -258,7 +258,7 @@ pub trait ByteChan {
|
||||
|
||||
const CONTINUE: [u8 * 4] = [0xAA, 0xBB, 0xCC, 0xDD];
|
||||
|
||||
pub impl<T,U:Unflattener<T>,P:BytePort> GenericPort<T> for FlatPort<T, U, P> {
|
||||
impl<T,U:Unflattener<T>,P:BytePort> GenericPort<T> for FlatPort<T, U, P> {
|
||||
fn recv() -> T {
|
||||
match self.try_recv() {
|
||||
Some(val) => val,
|
||||
@ -358,7 +358,7 @@ pub mod flatteners {
|
||||
bogus: ()
|
||||
}
|
||||
|
||||
pub impl<T:Copy + Owned> Unflattener<T> for PodUnflattener<T> {
|
||||
impl<T:Copy + Owned> Unflattener<T> for PodUnflattener<T> {
|
||||
fn unflatten(&self, buf: ~[u8]) -> T {
|
||||
assert size_of::<T>() != 0;
|
||||
assert size_of::<T>() == buf.len();
|
||||
@ -368,7 +368,7 @@ pub mod flatteners {
|
||||
}
|
||||
}
|
||||
|
||||
pub impl<T:Copy + Owned> Flattener<T> for PodFlattener<T> {
|
||||
impl<T:Copy + Owned> Flattener<T> for PodFlattener<T> {
|
||||
fn flatten(&self, val: T) -> ~[u8] {
|
||||
assert size_of::<T>() != 0;
|
||||
let val: *T = ptr::to_unsafe_ptr(&val);
|
||||
@ -406,14 +406,14 @@ pub mod flatteners {
|
||||
serialize_value: SerializeValue<T>
|
||||
}
|
||||
|
||||
pub impl<D:Decoder,T:Decodable<D>> Unflattener<T>
|
||||
impl<D:Decoder,T:Decodable<D>> Unflattener<T>
|
||||
for DeserializingUnflattener<D, T> {
|
||||
fn unflatten(&self, buf: ~[u8]) -> T {
|
||||
(self.deserialize_buffer)(buf)
|
||||
}
|
||||
}
|
||||
|
||||
pub impl<S:Encoder,T:Encodable<S>> Flattener<T>
|
||||
impl<S:Encoder,T:Encodable<S>> Flattener<T>
|
||||
for SerializingFlattener<S, T> {
|
||||
fn flatten(&self, val: T) -> ~[u8] {
|
||||
(self.serialize_value)(&val)
|
||||
@ -519,7 +519,7 @@ pub mod bytepipes {
|
||||
writer: W
|
||||
}
|
||||
|
||||
pub impl<R:Reader> BytePort for ReaderBytePort<R> {
|
||||
impl<R:Reader> BytePort for ReaderBytePort<R> {
|
||||
fn try_recv(&self, count: uint) -> Option<~[u8]> {
|
||||
let mut left = count;
|
||||
let mut bytes = ~[];
|
||||
@ -541,7 +541,7 @@ pub mod bytepipes {
|
||||
}
|
||||
}
|
||||
|
||||
pub impl<W:Writer> ByteChan for WriterByteChan<W> {
|
||||
impl<W:Writer> ByteChan for WriterByteChan<W> {
|
||||
fn send(&self, val: ~[u8]) {
|
||||
self.writer.write(val);
|
||||
}
|
||||
@ -572,7 +572,7 @@ pub mod bytepipes {
|
||||
chan: comm::Chan<~[u8]>
|
||||
}
|
||||
|
||||
pub impl BytePort for PipeBytePort {
|
||||
impl BytePort for PipeBytePort {
|
||||
fn try_recv(&self, count: uint) -> Option<~[u8]> {
|
||||
if self.buf.len() >= count {
|
||||
let mut bytes = ::core::util::replace(&mut self.buf, ~[]);
|
||||
@ -604,7 +604,7 @@ pub mod bytepipes {
|
||||
}
|
||||
}
|
||||
|
||||
pub impl ByteChan for PipeByteChan {
|
||||
impl ByteChan for PipeByteChan {
|
||||
fn send(&self, val: ~[u8]) {
|
||||
self.chan.send(val)
|
||||
}
|
||||
|
@ -23,6 +23,7 @@
|
||||
|
||||
use core::cast::copy_lifetime;
|
||||
use core::cast;
|
||||
use core::cell::Cell;
|
||||
use core::either::Either;
|
||||
use core::option;
|
||||
use core::comm::{oneshot, ChanOne, PortOne, send_one, recv_one};
|
||||
@ -103,11 +104,9 @@ pub fn from_port<A:Owned>(port: PortOne<A>) ->
|
||||
* waiting for the result to be received on the port.
|
||||
*/
|
||||
|
||||
let port = ~mut Some(port);
|
||||
let port = Cell(port);
|
||||
do from_fn || {
|
||||
let mut port_ = None;
|
||||
port_ <-> *port;
|
||||
let port = option::unwrap(port_);
|
||||
let port = port.take();
|
||||
match recv(port) {
|
||||
oneshot::send(data) => data
|
||||
}
|
||||
@ -136,9 +135,9 @@ pub fn spawn<A:Owned>(blk: fn~() -> A) -> Future<A> {
|
||||
|
||||
let (chan, port) = oneshot::init();
|
||||
|
||||
let chan = ~mut Some(chan);
|
||||
let chan = Cell(chan);
|
||||
do task::spawn || {
|
||||
let chan = option::swap_unwrap(&mut *chan);
|
||||
let chan = chan.take();
|
||||
send_one(chan, blk());
|
||||
}
|
||||
|
||||
|
@ -82,7 +82,7 @@ pub fn Encoder(wr: io::Writer) -> Encoder {
|
||||
Encoder { wr: wr }
|
||||
}
|
||||
|
||||
pub impl serialize::Encoder for Encoder {
|
||||
impl serialize::Encoder for Encoder {
|
||||
fn emit_nil(&self) { self.wr.write_str("null") }
|
||||
|
||||
fn emit_uint(&self, v: uint) { self.emit_float(v as float); }
|
||||
@ -217,7 +217,7 @@ pub fn PrettyEncoder(wr: io::Writer) -> PrettyEncoder {
|
||||
PrettyEncoder { wr: wr, indent: 0 }
|
||||
}
|
||||
|
||||
pub impl serialize::Encoder for PrettyEncoder {
|
||||
impl serialize::Encoder for PrettyEncoder {
|
||||
fn emit_nil(&self) { self.wr.write_str("null") }
|
||||
|
||||
fn emit_uint(&self, v: uint) { self.emit_float(v as float); }
|
||||
@ -323,7 +323,7 @@ pub impl serialize::Encoder for PrettyEncoder {
|
||||
}
|
||||
}
|
||||
|
||||
pub impl<S:serialize::Encoder> serialize::Encodable<S> for Json {
|
||||
impl<S:serialize::Encoder> serialize::Encodable<S> for Json {
|
||||
fn encode(&self, s: &S) {
|
||||
match *self {
|
||||
Number(v) => v.encode(s),
|
||||
@ -768,7 +768,7 @@ priv impl Decoder {
|
||||
}
|
||||
}
|
||||
|
||||
pub impl serialize::Decoder for Decoder {
|
||||
impl serialize::Decoder for Decoder {
|
||||
fn read_nil(&self) -> () {
|
||||
debug!("read_nil");
|
||||
match *self.pop() {
|
||||
|
@ -1,237 +0,0 @@
|
||||
// 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.
|
||||
|
||||
/*!
|
||||
* A simple map based on a vector for small integer keys. Space requirements
|
||||
* are O(highest integer key).
|
||||
*/
|
||||
#[forbid(deprecated_mode)];
|
||||
|
||||
use core::container::{Container, Mutable, Map, Set};
|
||||
use core::dvec::DVec;
|
||||
use core::ops;
|
||||
use core::option::{Some, None};
|
||||
use core::option;
|
||||
use core::prelude::*;
|
||||
|
||||
// FIXME (#2347): Should not be @; there's a bug somewhere in rustc that
|
||||
// requires this to be.
|
||||
struct SmallIntMap_<T> {
|
||||
v: DVec<Option<T>>,
|
||||
}
|
||||
|
||||
pub enum SmallIntMap<T> {
|
||||
SmallIntMap_(@SmallIntMap_<T>)
|
||||
}
|
||||
|
||||
/// Create a smallintmap
|
||||
pub fn mk<T:Copy>() -> SmallIntMap<T> {
|
||||
let v = DVec();
|
||||
SmallIntMap_(@SmallIntMap_ { v: v } )
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a value to the map. If the map already contains a value for
|
||||
* the specified key then the original value is replaced.
|
||||
*/
|
||||
#[inline(always)]
|
||||
pub fn insert<T:Copy>(self: SmallIntMap<T>, key: uint, val: T) {
|
||||
//io::println(fmt!("%?", key));
|
||||
self.v.grow_set_elt(key, &None, Some(val));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value for the specified key. If the key does not exist
|
||||
* in the map then returns none
|
||||
*/
|
||||
pub pure fn find<T:Copy>(self: SmallIntMap<T>, key: uint) -> Option<T> {
|
||||
if key < self.v.len() { return self.v.get_elt(key); }
|
||||
return None::<T>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value for the specified key
|
||||
*
|
||||
* # Failure
|
||||
*
|
||||
* If the key does not exist in the map
|
||||
*/
|
||||
pub pure fn get<T:Copy>(self: SmallIntMap<T>, key: uint) -> T {
|
||||
match find(self, key) {
|
||||
None => {
|
||||
error!("smallintmap::get(): key not present");
|
||||
fail!();
|
||||
}
|
||||
Some(v) => return v
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns true if the map contains a value for the specified key
|
||||
pub pure fn contains_key<T:Copy>(self: SmallIntMap<T>, key: uint) -> bool {
|
||||
return !find(self, key).is_none();
|
||||
}
|
||||
|
||||
impl<V> Container for SmallIntMap<V> {
|
||||
/// Return the number of elements in the map
|
||||
pure fn len(&self) -> uint {
|
||||
let mut sz = 0u;
|
||||
for self.v.each |item| {
|
||||
match *item {
|
||||
Some(_) => sz += 1u,
|
||||
_ => ()
|
||||
}
|
||||
}
|
||||
sz
|
||||
}
|
||||
|
||||
/// Return true if the map contains no elements
|
||||
pure fn is_empty(&self) -> bool { self.len() == 0 }
|
||||
}
|
||||
|
||||
impl<V> Mutable for SmallIntMap<V> {
|
||||
fn clear(&mut self) { self.v.set(~[]) }
|
||||
}
|
||||
|
||||
/// Implements the map::map interface for smallintmap
|
||||
impl<V:Copy> SmallIntMap<V> {
|
||||
#[inline(always)]
|
||||
fn insert(key: uint, value: V) -> bool {
|
||||
let exists = contains_key(self, key);
|
||||
insert(self, key, value);
|
||||
return !exists;
|
||||
}
|
||||
fn remove(key: uint) -> bool {
|
||||
if key >= self.v.len() {
|
||||
return false;
|
||||
}
|
||||
let old = self.v.get_elt(key);
|
||||
self.v.set_elt(key, None);
|
||||
old.is_some()
|
||||
}
|
||||
pure fn contains_key(key: uint) -> bool {
|
||||
contains_key(self, key)
|
||||
}
|
||||
pure fn contains_key_ref(key: &uint) -> bool {
|
||||
contains_key(self, *key)
|
||||
}
|
||||
pure fn get(key: uint) -> V { get(self, key) }
|
||||
pure fn find(key: uint) -> Option<V> { find(self, key) }
|
||||
|
||||
fn update_with_key(key: uint, val: V, ff: fn(uint, V, V) -> V) -> bool {
|
||||
match self.find(key) {
|
||||
None => return self.insert(key, val),
|
||||
Some(copy orig) => return self.insert(key, ff(key, orig, val)),
|
||||
}
|
||||
}
|
||||
|
||||
fn update(key: uint, newval: V, ff: fn(V, V) -> V) -> bool {
|
||||
return self.update_with_key(key, newval, |_k, v, v1| ff(v,v1));
|
||||
}
|
||||
|
||||
pure fn each(it: fn(key: uint, value: V) -> bool) {
|
||||
self.each_ref(|k, v| it(*k, *v))
|
||||
}
|
||||
pure fn each_key(it: fn(key: uint) -> bool) {
|
||||
self.each_ref(|k, _v| it(*k))
|
||||
}
|
||||
pure fn each_value(it: fn(value: V) -> bool) {
|
||||
self.each_ref(|_k, v| it(*v))
|
||||
}
|
||||
pure fn each_ref(it: fn(key: &uint, value: &V) -> bool) {
|
||||
let mut idx = 0u, l = self.v.len();
|
||||
while idx < l {
|
||||
match self.v.get_elt(idx) {
|
||||
Some(ref elt) => if !it(&idx, elt) { break },
|
||||
None => ()
|
||||
}
|
||||
idx += 1u;
|
||||
}
|
||||
}
|
||||
pure fn each_key_ref(blk: fn(key: &uint) -> bool) {
|
||||
self.each_ref(|k, _v| blk(k))
|
||||
}
|
||||
pure fn each_value_ref(blk: fn(value: &V) -> bool) {
|
||||
self.each_ref(|_k, v| blk(v))
|
||||
}
|
||||
}
|
||||
|
||||
impl<V:Copy> ops::Index<uint, V> for SmallIntMap<V> {
|
||||
pure fn index(&self, key: uint) -> V {
|
||||
unsafe {
|
||||
get(*self, key)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{mk, SmallIntMap};
|
||||
|
||||
use core::option::None;
|
||||
|
||||
#[test]
|
||||
fn test_len() {
|
||||
let mut map = mk();
|
||||
assert map.len() == 0;
|
||||
assert map.is_empty();
|
||||
map.insert(5, 20);
|
||||
assert map.len() == 1;
|
||||
assert !map.is_empty();
|
||||
map.insert(11, 12);
|
||||
assert map.len() == 2;
|
||||
assert !map.is_empty();
|
||||
map.insert(14, 22);
|
||||
assert map.len() == 3;
|
||||
assert !map.is_empty();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_clear() {
|
||||
let mut map = mk();
|
||||
map.insert(5, 20);
|
||||
map.insert(11, 12);
|
||||
map.insert(14, 22);
|
||||
map.clear();
|
||||
assert map.is_empty();
|
||||
assert map.find(5).is_none();
|
||||
assert map.find(11).is_none();
|
||||
assert map.find(14).is_none();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_insert_with_key() {
|
||||
let map: SmallIntMap<uint> = mk();
|
||||
|
||||
// given a new key, initialize it with this new count, given
|
||||
// given an existing key, add more to its count
|
||||
fn addMoreToCount(_k: uint, v0: uint, v1: uint) -> uint {
|
||||
v0 + v1
|
||||
}
|
||||
|
||||
fn addMoreToCount_simple(v0: uint, v1: uint) -> uint {
|
||||
v0 + v1
|
||||
}
|
||||
|
||||
// count integers
|
||||
map.update(3, 1, addMoreToCount_simple);
|
||||
map.update_with_key(9, 1, addMoreToCount);
|
||||
map.update(3, 7, addMoreToCount_simple);
|
||||
map.update_with_key(5, 3, addMoreToCount);
|
||||
map.update_with_key(3, 2, addMoreToCount);
|
||||
|
||||
// check the total counts
|
||||
assert map.find(3).get() == 10;
|
||||
assert map.find(5).get() == 3;
|
||||
assert map.find(9).get() == 1;
|
||||
|
||||
// sadly, no sevens were counted
|
||||
assert None == map.find(7);
|
||||
}
|
||||
}
|
@ -22,7 +22,7 @@ pub fn Serializer(wr: io::Writer) -> Serializer {
|
||||
Serializer { wr: wr }
|
||||
}
|
||||
|
||||
pub impl serialize::Encoder for Serializer {
|
||||
impl serialize::Encoder for Serializer {
|
||||
fn emit_nil(&self) {
|
||||
self.wr.write_str(~"()")
|
||||
}
|
||||
|
@ -113,210 +113,210 @@ pub trait Decodable<D:Decoder> {
|
||||
static fn decode(&self, d: &D) -> Self;
|
||||
}
|
||||
|
||||
pub impl<S:Encoder> Encodable<S> for uint {
|
||||
impl<S:Encoder> Encodable<S> for uint {
|
||||
fn encode(&self, s: &S) { s.emit_uint(*self) }
|
||||
}
|
||||
|
||||
pub impl<D:Decoder> Decodable<D> for uint {
|
||||
impl<D:Decoder> Decodable<D> for uint {
|
||||
static fn decode(&self, d: &D) -> uint {
|
||||
d.read_uint()
|
||||
}
|
||||
}
|
||||
|
||||
pub impl<S:Encoder> Encodable<S> for u8 {
|
||||
impl<S:Encoder> Encodable<S> for u8 {
|
||||
fn encode(&self, s: &S) { s.emit_u8(*self) }
|
||||
}
|
||||
|
||||
pub impl<D:Decoder> Decodable<D> for u8 {
|
||||
impl<D:Decoder> Decodable<D> for u8 {
|
||||
static fn decode(&self, d: &D) -> u8 {
|
||||
d.read_u8()
|
||||
}
|
||||
}
|
||||
|
||||
pub impl<S:Encoder> Encodable<S> for u16 {
|
||||
impl<S:Encoder> Encodable<S> for u16 {
|
||||
fn encode(&self, s: &S) { s.emit_u16(*self) }
|
||||
}
|
||||
|
||||
pub impl<D:Decoder> Decodable<D> for u16 {
|
||||
impl<D:Decoder> Decodable<D> for u16 {
|
||||
static fn decode(&self, d: &D) -> u16 {
|
||||
d.read_u16()
|
||||
}
|
||||
}
|
||||
|
||||
pub impl<S:Encoder> Encodable<S> for u32 {
|
||||
impl<S:Encoder> Encodable<S> for u32 {
|
||||
fn encode(&self, s: &S) { s.emit_u32(*self) }
|
||||
}
|
||||
|
||||
pub impl<D:Decoder> Decodable<D> for u32 {
|
||||
impl<D:Decoder> Decodable<D> for u32 {
|
||||
static fn decode(&self, d: &D) -> u32 {
|
||||
d.read_u32()
|
||||
}
|
||||
}
|
||||
|
||||
pub impl<S:Encoder> Encodable<S> for u64 {
|
||||
impl<S:Encoder> Encodable<S> for u64 {
|
||||
fn encode(&self, s: &S) { s.emit_u64(*self) }
|
||||
}
|
||||
|
||||
pub impl<D:Decoder> Decodable<D> for u64 {
|
||||
impl<D:Decoder> Decodable<D> for u64 {
|
||||
static fn decode(&self, d: &D) -> u64 {
|
||||
d.read_u64()
|
||||
}
|
||||
}
|
||||
|
||||
pub impl<S:Encoder> Encodable<S> for int {
|
||||
impl<S:Encoder> Encodable<S> for int {
|
||||
fn encode(&self, s: &S) { s.emit_int(*self) }
|
||||
}
|
||||
|
||||
pub impl<D:Decoder> Decodable<D> for int {
|
||||
impl<D:Decoder> Decodable<D> for int {
|
||||
static fn decode(&self, d: &D) -> int {
|
||||
d.read_int()
|
||||
}
|
||||
}
|
||||
|
||||
pub impl<S:Encoder> Encodable<S> for i8 {
|
||||
impl<S:Encoder> Encodable<S> for i8 {
|
||||
fn encode(&self, s: &S) { s.emit_i8(*self) }
|
||||
}
|
||||
|
||||
pub impl<D:Decoder> Decodable<D> for i8 {
|
||||
impl<D:Decoder> Decodable<D> for i8 {
|
||||
static fn decode(&self, d: &D) -> i8 {
|
||||
d.read_i8()
|
||||
}
|
||||
}
|
||||
|
||||
pub impl<S:Encoder> Encodable<S> for i16 {
|
||||
impl<S:Encoder> Encodable<S> for i16 {
|
||||
fn encode(&self, s: &S) { s.emit_i16(*self) }
|
||||
}
|
||||
|
||||
pub impl<D:Decoder> Decodable<D> for i16 {
|
||||
impl<D:Decoder> Decodable<D> for i16 {
|
||||
static fn decode(&self, d: &D) -> i16 {
|
||||
d.read_i16()
|
||||
}
|
||||
}
|
||||
|
||||
pub impl<S:Encoder> Encodable<S> for i32 {
|
||||
impl<S:Encoder> Encodable<S> for i32 {
|
||||
fn encode(&self, s: &S) { s.emit_i32(*self) }
|
||||
}
|
||||
|
||||
pub impl<D:Decoder> Decodable<D> for i32 {
|
||||
impl<D:Decoder> Decodable<D> for i32 {
|
||||
static fn decode(&self, d: &D) -> i32 {
|
||||
d.read_i32()
|
||||
}
|
||||
}
|
||||
|
||||
pub impl<S:Encoder> Encodable<S> for i64 {
|
||||
impl<S:Encoder> Encodable<S> for i64 {
|
||||
fn encode(&self, s: &S) { s.emit_i64(*self) }
|
||||
}
|
||||
|
||||
pub impl<D:Decoder> Decodable<D> for i64 {
|
||||
impl<D:Decoder> Decodable<D> for i64 {
|
||||
static fn decode(&self, d: &D) -> i64 {
|
||||
d.read_i64()
|
||||
}
|
||||
}
|
||||
|
||||
pub impl<S:Encoder> Encodable<S> for &str {
|
||||
impl<S:Encoder> Encodable<S> for &str {
|
||||
fn encode(&self, s: &S) { s.emit_borrowed_str(*self) }
|
||||
}
|
||||
|
||||
pub impl<S:Encoder> Encodable<S> for ~str {
|
||||
impl<S:Encoder> Encodable<S> for ~str {
|
||||
fn encode(&self, s: &S) { s.emit_owned_str(*self) }
|
||||
}
|
||||
|
||||
pub impl<D:Decoder> Decodable<D> for ~str {
|
||||
impl<D:Decoder> Decodable<D> for ~str {
|
||||
static fn decode(&self, d: &D) -> ~str {
|
||||
d.read_owned_str()
|
||||
}
|
||||
}
|
||||
|
||||
pub impl<S:Encoder> Encodable<S> for @str {
|
||||
impl<S:Encoder> Encodable<S> for @str {
|
||||
fn encode(&self, s: &S) { s.emit_managed_str(*self) }
|
||||
}
|
||||
|
||||
pub impl<D:Decoder> Decodable<D> for @str {
|
||||
impl<D:Decoder> Decodable<D> for @str {
|
||||
static fn decode(&self, d: &D) -> @str {
|
||||
d.read_managed_str()
|
||||
}
|
||||
}
|
||||
|
||||
pub impl<S:Encoder> Encodable<S> for float {
|
||||
impl<S:Encoder> Encodable<S> for float {
|
||||
fn encode(&self, s: &S) { s.emit_float(*self) }
|
||||
}
|
||||
|
||||
pub impl<D:Decoder> Decodable<D> for float {
|
||||
impl<D:Decoder> Decodable<D> for float {
|
||||
static fn decode(&self, d: &D) -> float {
|
||||
d.read_float()
|
||||
}
|
||||
}
|
||||
|
||||
pub impl<S:Encoder> Encodable<S> for f32 {
|
||||
impl<S:Encoder> Encodable<S> for f32 {
|
||||
fn encode(&self, s: &S) { s.emit_f32(*self) }
|
||||
}
|
||||
|
||||
pub impl<D:Decoder> Decodable<D> for f32 {
|
||||
impl<D:Decoder> Decodable<D> for f32 {
|
||||
static fn decode(&self, d: &D) -> f32 {
|
||||
d.read_f32() }
|
||||
}
|
||||
|
||||
pub impl<S:Encoder> Encodable<S> for f64 {
|
||||
impl<S:Encoder> Encodable<S> for f64 {
|
||||
fn encode(&self, s: &S) { s.emit_f64(*self) }
|
||||
}
|
||||
|
||||
pub impl<D:Decoder> Decodable<D> for f64 {
|
||||
impl<D:Decoder> Decodable<D> for f64 {
|
||||
static fn decode(&self, d: &D) -> f64 {
|
||||
d.read_f64()
|
||||
}
|
||||
}
|
||||
|
||||
pub impl<S:Encoder> Encodable<S> for bool {
|
||||
impl<S:Encoder> Encodable<S> for bool {
|
||||
fn encode(&self, s: &S) { s.emit_bool(*self) }
|
||||
}
|
||||
|
||||
pub impl<D:Decoder> Decodable<D> for bool {
|
||||
impl<D:Decoder> Decodable<D> for bool {
|
||||
static fn decode(&self, d: &D) -> bool {
|
||||
d.read_bool()
|
||||
}
|
||||
}
|
||||
|
||||
pub impl<S:Encoder> Encodable<S> for () {
|
||||
impl<S:Encoder> Encodable<S> for () {
|
||||
fn encode(&self, s: &S) { s.emit_nil() }
|
||||
}
|
||||
|
||||
pub impl<D:Decoder> Decodable<D> for () {
|
||||
impl<D:Decoder> Decodable<D> for () {
|
||||
static fn decode(&self, d: &D) -> () {
|
||||
d.read_nil()
|
||||
}
|
||||
}
|
||||
|
||||
pub impl<S:Encoder,T:Encodable<S>> Encodable<S> for &T {
|
||||
impl<S:Encoder,T:Encodable<S>> Encodable<S> for &T {
|
||||
fn encode(&self, s: &S) {
|
||||
s.emit_borrowed(|| (**self).encode(s))
|
||||
}
|
||||
}
|
||||
|
||||
pub impl<S:Encoder,T:Encodable<S>> Encodable<S> for ~T {
|
||||
impl<S:Encoder,T:Encodable<S>> Encodable<S> for ~T {
|
||||
fn encode(&self, s: &S) {
|
||||
s.emit_owned(|| (**self).encode(s))
|
||||
}
|
||||
}
|
||||
|
||||
pub impl<D:Decoder,T:Decodable<D>> Decodable<D> for ~T {
|
||||
impl<D:Decoder,T:Decodable<D>> Decodable<D> for ~T {
|
||||
static fn decode(&self, d: &D) -> ~T {
|
||||
d.read_owned(|| ~Decodable::decode(d))
|
||||
}
|
||||
}
|
||||
|
||||
pub impl<S:Encoder,T:Encodable<S>> Encodable<S> for @T {
|
||||
impl<S:Encoder,T:Encodable<S>> Encodable<S> for @T {
|
||||
fn encode(&self, s: &S) {
|
||||
s.emit_managed(|| (**self).encode(s))
|
||||
}
|
||||
}
|
||||
|
||||
pub impl<D:Decoder,T:Decodable<D>> Decodable<D> for @T {
|
||||
impl<D:Decoder,T:Decodable<D>> Decodable<D> for @T {
|
||||
static fn decode(&self, d: &D) -> @T {
|
||||
d.read_managed(|| @Decodable::decode(d))
|
||||
}
|
||||
}
|
||||
|
||||
pub impl<S:Encoder,T:Encodable<S>> Encodable<S> for &[T] {
|
||||
impl<S:Encoder,T:Encodable<S>> Encodable<S> for &[T] {
|
||||
fn encode(&self, s: &S) {
|
||||
do s.emit_borrowed_vec(self.len()) {
|
||||
for self.eachi |i, e| {
|
||||
@ -326,7 +326,7 @@ pub impl<S:Encoder,T:Encodable<S>> Encodable<S> for &[T] {
|
||||
}
|
||||
}
|
||||
|
||||
pub impl<S:Encoder,T:Encodable<S>> Encodable<S> for ~[T] {
|
||||
impl<S:Encoder,T:Encodable<S>> Encodable<S> for ~[T] {
|
||||
fn encode(&self, s: &S) {
|
||||
do s.emit_owned_vec(self.len()) {
|
||||
for self.eachi |i, e| {
|
||||
@ -336,7 +336,7 @@ pub impl<S:Encoder,T:Encodable<S>> Encodable<S> for ~[T] {
|
||||
}
|
||||
}
|
||||
|
||||
pub impl<D:Decoder,T:Decodable<D>> Decodable<D> for ~[T] {
|
||||
impl<D:Decoder,T:Decodable<D>> Decodable<D> for ~[T] {
|
||||
static fn decode(&self, d: &D) -> ~[T] {
|
||||
do d.read_owned_vec |len| {
|
||||
do vec::from_fn(len) |i| {
|
||||
@ -346,7 +346,7 @@ pub impl<D:Decoder,T:Decodable<D>> Decodable<D> for ~[T] {
|
||||
}
|
||||
}
|
||||
|
||||
pub impl<S:Encoder,T:Encodable<S>> Encodable<S> for @[T] {
|
||||
impl<S:Encoder,T:Encodable<S>> Encodable<S> for @[T] {
|
||||
fn encode(&self, s: &S) {
|
||||
do s.emit_managed_vec(self.len()) {
|
||||
for self.eachi |i, e| {
|
||||
@ -356,7 +356,7 @@ pub impl<S:Encoder,T:Encodable<S>> Encodable<S> for @[T] {
|
||||
}
|
||||
}
|
||||
|
||||
pub impl<D:Decoder,T:Decodable<D>> Decodable<D> for @[T] {
|
||||
impl<D:Decoder,T:Decodable<D>> Decodable<D> for @[T] {
|
||||
static fn decode(&self, d: &D) -> @[T] {
|
||||
do d.read_managed_vec |len| {
|
||||
do at_vec::from_fn(len) |i| {
|
||||
@ -366,7 +366,7 @@ pub impl<D:Decoder,T:Decodable<D>> Decodable<D> for @[T] {
|
||||
}
|
||||
}
|
||||
|
||||
pub impl<S:Encoder,T:Encodable<S>> Encodable<S> for Option<T> {
|
||||
impl<S:Encoder,T:Encodable<S>> Encodable<S> for Option<T> {
|
||||
fn encode(&self, s: &S) {
|
||||
do s.emit_enum(~"option") {
|
||||
match *self {
|
||||
@ -381,7 +381,7 @@ pub impl<S:Encoder,T:Encodable<S>> Encodable<S> for Option<T> {
|
||||
}
|
||||
}
|
||||
|
||||
pub impl<D:Decoder,T:Decodable<D>> Decodable<D> for Option<T> {
|
||||
impl<D:Decoder,T:Decodable<D>> Decodable<D> for Option<T> {
|
||||
static fn decode(&self, d: &D) -> Option<T> {
|
||||
do d.read_enum(~"option") {
|
||||
do d.read_enum_variant |i| {
|
||||
@ -396,8 +396,7 @@ pub impl<D:Decoder,T:Decodable<D>> Decodable<D> for Option<T> {
|
||||
}
|
||||
}
|
||||
|
||||
pub impl<S:Encoder,T0:Encodable<S>,T1:Encodable<S>> Encodable<S>
|
||||
for (T0, T1) {
|
||||
impl<S:Encoder,T0:Encodable<S>,T1:Encodable<S>> Encodable<S> for (T0, T1) {
|
||||
fn encode(&self, s: &S) {
|
||||
match *self {
|
||||
(ref t0, ref t1) => {
|
||||
@ -410,8 +409,7 @@ pub impl<S:Encoder,T0:Encodable<S>,T1:Encodable<S>> Encodable<S>
|
||||
}
|
||||
}
|
||||
|
||||
pub impl<D:Decoder,T0:Decodable<D>,T1:Decodable<D>> Decodable<D>
|
||||
for (T0, T1) {
|
||||
impl<D:Decoder,T0:Decodable<D>,T1:Decodable<D>> Decodable<D> for (T0, T1) {
|
||||
static fn decode(&self, d: &D) -> (T0, T1) {
|
||||
do d.read_tup(2) {
|
||||
(
|
||||
@ -422,7 +420,7 @@ pub impl<D:Decoder,T0:Decodable<D>,T1:Decodable<D>> Decodable<D>
|
||||
}
|
||||
}
|
||||
|
||||
pub impl<
|
||||
impl<
|
||||
S: Encoder,
|
||||
T0: Encodable<S>,
|
||||
T1: Encodable<S>,
|
||||
@ -441,7 +439,7 @@ pub impl<
|
||||
}
|
||||
}
|
||||
|
||||
pub impl<
|
||||
impl<
|
||||
D: Decoder,
|
||||
T0: Decodable<D>,
|
||||
T1: Decodable<D>,
|
||||
@ -458,7 +456,7 @@ pub impl<
|
||||
}
|
||||
}
|
||||
|
||||
pub impl<
|
||||
impl<
|
||||
S: Encoder,
|
||||
T0: Encodable<S>,
|
||||
T1: Encodable<S>,
|
||||
@ -479,7 +477,7 @@ pub impl<
|
||||
}
|
||||
}
|
||||
|
||||
pub impl<
|
||||
impl<
|
||||
D: Decoder,
|
||||
T0: Decodable<D>,
|
||||
T1: Decodable<D>,
|
||||
@ -498,7 +496,7 @@ pub impl<
|
||||
}
|
||||
}
|
||||
|
||||
pub impl<
|
||||
impl<
|
||||
S: Encoder,
|
||||
T0: Encodable<S>,
|
||||
T1: Encodable<S>,
|
||||
@ -521,7 +519,7 @@ pub impl<
|
||||
}
|
||||
}
|
||||
|
||||
pub impl<
|
||||
impl<
|
||||
D: Decoder,
|
||||
T0: Decodable<D>,
|
||||
T1: Decodable<D>,
|
||||
@ -552,7 +550,7 @@ pub trait EncoderHelpers {
|
||||
fn emit_from_vec<T>(&self, v: &[T], f: fn(v: &T));
|
||||
}
|
||||
|
||||
pub impl<S:Encoder> EncoderHelpers for S {
|
||||
impl<S:Encoder> EncoderHelpers for S {
|
||||
fn emit_from_vec<T>(&self, v: &[T], f: fn(v: &T)) {
|
||||
do self.emit_owned_vec(v.len()) {
|
||||
for v.eachi |i, e| {
|
||||
@ -568,7 +566,7 @@ pub trait DecoderHelpers {
|
||||
fn read_to_vec<T>(&self, f: fn() -> T) -> ~[T];
|
||||
}
|
||||
|
||||
pub impl<D:Decoder> DecoderHelpers for D {
|
||||
impl<D:Decoder> DecoderHelpers for D {
|
||||
fn read_to_vec<T>(&self, f: fn() -> T) -> ~[T] {
|
||||
do self.read_owned_vec |len| {
|
||||
do vec::from_fn(len) |i| {
|
||||
|
@ -455,8 +455,7 @@ impl<T:Copy + Ord> MergeState<T> {
|
||||
base2: uint, len2: uint) {
|
||||
assert len1 != 0 && len2 != 0 && base1+len1 == base2;
|
||||
|
||||
let tmp = vec::cast_to_mut(
|
||||
vec::slice(array, base1, base1+len1).to_vec());
|
||||
let mut tmp = vec::slice(array, base1, base1+len1).to_vec();
|
||||
|
||||
let mut c1 = 0;
|
||||
let mut c2 = base2;
|
||||
@ -559,8 +558,7 @@ impl<T:Copy + Ord> MergeState<T> {
|
||||
base2: uint, len2: uint) {
|
||||
assert len1 != 1 && len2 != 0 && base1 + len1 == base2;
|
||||
|
||||
let tmp = vec::cast_to_mut(
|
||||
vec::slice(array, base2, base2+len2).to_vec());
|
||||
let mut tmp = vec::slice(array, base2, base2+len2).to_vec();
|
||||
|
||||
let mut c1 = base1 + len1 - 1;
|
||||
let mut c2 = len2 - 1;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user