Merge remote-tracking branch 'remotes/origin/incoming' into incoming

This commit is contained in:
Erick Tryzelaar 2013-02-27 11:03:21 -08:00
commit 7d0ec86c4a
224 changed files with 2220 additions and 2144 deletions

View File

@ -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
View File

@ -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

View File

@ -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.

View File

@ -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.)
Lets 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 weve
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

View File

@ -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);
}
}

View File

@ -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;

View File

@ -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
}

View File

@ -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

View File

@ -422,6 +422,13 @@
...
}
{
enum-instruction-scheduling-9
Memcheck:Cond
fun:*get_authority*
...
}
{
llvm-user-new-leak
Memcheck:Leak

View File

@ -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))

View File

@ -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.
///

View File

@ -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 */

View File

@ -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);

View File

@ -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;

View File

@ -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`
*/

View File

@ -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`
*/

View File

@ -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`
*/

View File

@ -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 {

View File

@ -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`
*/

View File

@ -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`
*/

View File

@ -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`
*/

View File

@ -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`
*/

View File

@ -58,7 +58,7 @@ mod inst {
}
}
pub impl NumCast for int {
impl NumCast for int {
/**
* Cast `n` to a `int`
*/

View File

@ -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 {

View File

@ -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`
*/

View File

@ -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`
*/

View File

@ -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`
*/

View File

@ -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`
*/

View File

@ -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`
*/

View File

@ -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,

View File

@ -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)
}

View File

@ -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) }
}

View File

@ -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;
}
}

View File

@ -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

View File

@ -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";

View File

@ -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(); }

View File

@ -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");

View File

@ -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;

View File

@ -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);
}

View File

@ -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());
}
}

View File

@ -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

View File

@ -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)

View File

@ -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];

View File

@ -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))
}
}
}

View File

@ -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));

View File

@ -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;
}
}

View File

@ -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');

View File

@ -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);

View File

@ -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);
}

View File

@ -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);
}
}
_ => ()
}

View File

@ -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
}
}

View File

@ -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,

View File

@ -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 {

View File

@ -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",

View File

@ -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())
}

View File

@ -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 => ()
}
}
}

View File

@ -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 {

View File

@ -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);
}
}

View 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;
}

View File

@ -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) {

View File

@ -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!()

View File

@ -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);
}

View File

@ -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;

View File

@ -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)
}

View File

@ -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,

View File

@ -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()
}
}

View File

@ -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(
}
}
)
);
)
}

View File

@ -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

View File

@ -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;
}

View File

@ -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;
}
}
}

View File

@ -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);

View File

@ -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 {

View File

@ -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 }

View File

@ -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;

View File

@ -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 }

View File

@ -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))
}

View File

@ -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 }

View File

@ -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); }
}
)
);
)
}

View File

@ -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 {
}
}

View File

@ -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;

View File

@ -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 }

View File

@ -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()
}

View File

@ -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);

View File

@ -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};

View File

@ -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 {

View File

@ -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();

View File

@ -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@",

View File

@ -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;

View File

@ -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 }
}

View File

@ -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

View File

@ -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 {

View File

@ -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);

View File

@ -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();

View File

@ -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)
}

View File

@ -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());
}

View File

@ -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() {

View File

@ -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);
}
}

View File

@ -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(~"()")
}

View File

@ -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| {

View File

@ -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