rustc: Make `<` and `=` into traits

This commit is contained in:
Patrick Walton 2012-08-27 16:26:35 -07:00
parent 94720fcea7
commit 96534365c2
103 changed files with 2985 additions and 328 deletions

View File

@ -25,6 +25,25 @@ type package = {
versions: ~[(~str, ~str)]
};
impl package : cmp::Ord {
pure fn lt(&&other: package) -> bool {
if self.name.lt(other.name) { return true; }
if other.name.lt(self.name) { return false; }
if self.uuid.lt(other.uuid) { return true; }
if other.uuid.lt(self.uuid) { return false; }
if self.url.lt(other.url) { return true; }
if other.url.lt(self.url) { return false; }
if self.method.lt(other.method) { return true; }
if other.method.lt(self.method) { return false; }
if self.description.lt(other.description) { return true; }
if other.description.lt(self.description) { return false; }
if self.tags.lt(other.tags) { return true; }
if other.tags.lt(self.tags) { return false; }
if self.versions.lt(other.versions) { return true; }
return false;
}
}
type local_package = {
name: ~str,
metaname: ~str,
@ -74,6 +93,12 @@ type options = {
enum mode { system_mode, user_mode, local_mode }
impl mode : cmp::Eq {
pure fn eq(&&other: mode) -> bool {
(self as uint) == (other as uint)
}
}
fn opts() -> ~[getopts::Opt] {
~[optflag(~"g"), optflag(~"G"), optflag(~"test"),
optflag(~"h"), optflag(~"help")]

View File

@ -8,6 +8,12 @@ import syntax::diagnostic;
enum test_mode { tm_converge, tm_run, }
type context = { mode: test_mode }; // + rng
impl test_mode : cmp::Eq {
pure fn eq(&&other: test_mode) -> bool {
(self as uint) == (other as uint)
}
}
fn write_file(filename: &Path, content: ~str) {
result::get(
io::file_writer(filename, ~[io::Create, io::Truncate]))

View File

@ -6,6 +6,8 @@
//! Boolean logic
import cmp::Eq;
export not, and, or, xor, implies;
export eq, ne, is_true, is_false;
export from_str, to_str, all_values, to_bit;
@ -67,6 +69,12 @@ fn all_values(blk: fn(v: bool)) {
/// converts truth value to an 8 bit byte
pure fn to_bit(v: bool) -> u8 { if v { 1u8 } else { 0u8 } }
impl bool : cmp::Eq {
pure fn eq(&&other: bool) -> bool {
self == other
}
}
#[test]
fn test_bool_from_str() {
do all_values |v| {

View File

@ -4,6 +4,8 @@
#[forbid(deprecated_mode)];
#[forbid(deprecated_pattern)];
import cmp::{Eq, Ord};
export ptr_eq;
pure fn ptr_eq<T>(a: @T, b: @T) -> bool {
@ -11,6 +13,14 @@ pure fn ptr_eq<T>(a: @T, b: @T) -> bool {
unsafe { ptr::addr_of(*a) == ptr::addr_of(*b) }
}
impl<T:Eq> @const T : Eq {
pure fn eq(&&other: @const T) -> bool { *self == *other }
}
impl<T:Ord> @const T : Ord {
pure fn lt(&&other: @const T) -> bool { *self < *other }
}
#[test]
fn test() {
let x = @3;

View File

@ -4,6 +4,8 @@
#[forbid(deprecated_mode)];
#[forbid(deprecated_pattern)];
import cmp::Eq;
/*
Lu Uppercase_Letter an uppercase letter
Ll Lowercase_Letter a lowercase letter
@ -187,6 +189,10 @@ pure fn cmp(a: char, b: char) -> int {
else { 0 }
}
impl char: Eq {
pure fn eq(&&other: char) -> bool { self == other }
}
#[test]
fn test_is_lowercase() {
assert is_lowercase('a');

View File

@ -28,13 +28,13 @@ trait Eq {
}
pure fn lt<T: Ord>(v1: &T, v2: &T) -> bool {
v1.lt(*v2)
v1.lt(v2)
}
pure fn le<T: Ord Eq>(v1: &T, v2: &T) -> bool {
v1.lt(*v2) || v1.eq(*v2)
v1.lt(v2) || v1.eq(v2)
}
pure fn eq<T: Eq>(v1: &T, v2: &T) -> bool {
v1.eq(*v2)
v1.eq(v2)
}

View File

@ -57,6 +57,8 @@ export num;
export path;
export managed;
export flate;
export unit;
export uniq;
// NDM seems to be necessary for resolve to work
export option_iter;
@ -183,6 +185,10 @@ mod at_vec;
mod bool;
#[warn(non_camel_case_types)]
mod tuple;
#[warn(non_camel_case_types)]
mod unit;
#[warn(non_camel_case_types)]
mod uniq;
// Ubiquitous-utility-type modules

View File

@ -18,8 +18,9 @@ import PosixPath = path::PosixPath;
import tuple::{TupleOps, ExtendedTupleOps};
import str::{StrSlice, UniqueStr};
import vec::{ConstVector, CopyableVector, ImmutableVector};
import vec::{ImmutableCopyableVector};
import iter::{BaseIter, ExtendedIter, CopyableIter, Times, TimesIx};
import vec::{ImmutableEqVector, ImmutableCopyableVector};
import iter::{BaseIter, ExtendedIter, EqIter, CopyableIter};
import iter::{CopyableOrderedIter, Times, TimesIx};
import num::Num;
import ptr::Ptr;
import to_str::ToStr;
@ -33,8 +34,8 @@ export Num, Times, TimesIx;
// The following exports are the common traits
export StrSlice, UniqueStr;
export ConstVector, CopyableVector, ImmutableVector;
export ImmutableCopyableVector, IterTraitExtensions;
export BaseIter, CopyableIter, ExtendedIter;
export ImmutableEqVector, ImmutableCopyableVector, IterTraitExtensions;
export BaseIter, CopyableIter, CopyableOrderedIter, ExtendedIter, EqIter;
export TupleOps, ExtendedTupleOps;
export Ptr;
export ToStr;

View File

@ -4,6 +4,7 @@
//! A type that represents one of two alternatives
import cmp::Eq;
import result::Result;
/// The either type
@ -125,6 +126,25 @@ pure fn unwrap_right<T,U>(+eith: Either<T,U>) -> U {
}
}
impl<T:Eq,U:Eq> Either<T,U> : Eq {
pure fn eq(&&other: Either<T,U>) -> bool {
match self {
Left(a) => {
match other {
Left(b) => a.eq(b),
Right(_) => false
}
}
Right(a) => {
match other {
Left(_) => false,
Right(b) => a.eq(b)
}
}
}
}
}
#[test]
fn test_either_left() {
let val = Left(10);

View File

@ -25,6 +25,7 @@ debug!("hello, %s!", "world");
*/
import cmp::Eq;
import option::{Some, None};
@ -383,7 +384,24 @@ mod rt {
count_implied => 1u
};
}
enum pad_mode { pad_signed, pad_unsigned, pad_nozero, pad_float }
impl pad_mode: Eq {
pure fn eq(&&other: pad_mode) -> bool {
match (self, other) {
(pad_signed, pad_signed) => true,
(pad_unsigned, pad_unsigned) => true,
(pad_nozero, pad_nozero) => true,
(pad_float, pad_float) => true,
(pad_signed, _) => false,
(pad_unsigned, _) => false,
(pad_nozero, _) => false,
(pad_float, _) => false
}
}
}
fn pad(cv: conv, &s: ~str, mode: pad_mode) -> ~str {
let uwidth : uint = match cv.width {
count_implied => return s,

View File

@ -41,6 +41,7 @@ import f64::{lgamma, ln, log_radix, ln1p, log10, log2, ilog_radix};
import f64::{modf, pow, round, sinh, tanh, tgamma, trunc};
import f64::signbit;
import f64::{j0, j1, jn, y0, y1, yn};
import cmp::{Eq, Ord};
import num::from_int;
const NaN: float = 0.0/0.0;
@ -311,7 +312,7 @@ fn from_str(num: &str) -> Option<float> {
}
}
if (c == 'e') | (c == 'E') {//Examine exponent
if (c == 'e') || (c == 'E') { //Examine exponent
let mut exponent = 0u;
let mut neg_exponent = false;
if(pos < len) {
@ -414,6 +415,14 @@ pure fn sin(x: float) -> float { f64::sin(x as f64) as float }
pure fn cos(x: float) -> float { f64::cos(x as f64) as float }
pure fn tan(x: float) -> float { f64::tan(x as f64) as float }
impl float: Eq {
pure fn eq(&&other: float) -> bool { self == other }
}
impl float: Ord {
pure fn lt(&&other: float) -> bool { self < other }
}
impl float: num::Num {
pure fn add(&&other: float) -> float { return self + other; }
pure fn sub(&&other: float) -> float { return self - other; }
@ -521,7 +530,7 @@ fn test_to_str_inf() {
#[test]
fn test_traits() {
fn test<U:num::Num>(ten: &U) {
fn test<U:num::Num cmp::Eq>(ten: &U) {
assert (ten.to_int() == 10);
let two: U = from_int(2);

View File

@ -239,7 +239,7 @@ fn test_to_str() {
#[test]
fn test_interfaces() {
fn test<U:num::Num>(+ten: U) {
fn test<U:num::Num cmp::Eq>(+ten: U) {
assert (ten.to_int() == 10);
let two: U = from_int(2);

View File

@ -6,6 +6,7 @@ Basic input/output
import result::Result;
import cmp::Eq;
import dvec::DVec;
import libc::{c_int, c_long, c_uint, c_void, size_t, ssize_t};
import libc::consts::os::posix88::*;
@ -324,6 +325,15 @@ enum FileFlag { Append, Create, Truncate, NoFlag, }
// What type of writer are we?
enum WriterType { Screen, File }
impl WriterType: Eq {
pure fn eq(&&other: WriterType) -> bool {
match (self, other) {
(Screen, Screen) | (File, File) => true,
(Screen, _) | (File, _) => false
}
}
}
// FIXME (#2004): Seekable really should be orthogonal.
// FIXME (#2004): eventually u64
trait Writer {

View File

@ -2,6 +2,7 @@
// workaround our lack of traits and lack of macros. See core.{rc,rs} for
// how this file is used.
import cmp::{Eq, Ord};
import inst::{IMPL_T, EACH, SIZE_HINT};
export extensions;
@ -17,6 +18,9 @@ impl<A> IMPL_T<A>: iter::ExtendedIter<A> {
pure fn foldl<B>(+b0: B, blk: fn(B, A) -> B) -> B {
iter::foldl(self, b0, blk)
}
}
impl<A: Eq> IMPL_T<A>: iter::EqIter<A> {
pure fn contains(x: A) -> bool { iter::contains(self, x) }
pure fn count(x: A) -> uint { iter::count(self, x) }
pure fn position(f: fn(A) -> bool) -> Option<uint> {
@ -38,7 +42,11 @@ impl<A: copy> IMPL_T<A>: iter::CopyableIter<A> {
// iter::flat_map_to_vec(self, op)
// }
pure fn min() -> A { iter::min(self) }
pure fn max() -> A { iter::max(self) }
pure fn find(p: fn(A) -> bool) -> Option<A> { iter::find(self, p) }
}
impl<A: copy Ord> IMPL_T<A>: iter::CopyableOrderedIter<A> {
pure fn min() -> A { iter::min(self) }
pure fn max() -> A { iter::max(self) }
}

View File

@ -1,3 +1,5 @@
use cmp::{Eq, Ord};
/// A function used to initialize the elements of a sequence
type InitOp<T> = fn(uint) -> T;
@ -11,6 +13,9 @@ trait ExtendedIter<A> {
pure fn all(blk: fn(A) -> bool) -> bool;
pure fn any(blk: fn(A) -> bool) -> bool;
pure fn foldl<B>(+b0: B, blk: fn(B, A) -> B) -> B;
}
trait EqIter<A:Eq> {
pure fn contains(x: A) -> bool;
pure fn count(x: A) -> uint;
pure fn position(f: fn(A) -> bool) -> Option<uint>;
@ -27,9 +32,12 @@ trait CopyableIter<A:copy> {
pure fn filter_to_vec(pred: fn(A) -> bool) -> ~[A];
pure fn map_to_vec<B>(op: fn(A) -> B) -> ~[B];
pure fn to_vec() -> ~[A];
pure fn find(p: fn(A) -> bool) -> Option<A>;
}
trait CopyableOrderedIter<A:copy Ord> {
pure fn min() -> A;
pure fn max() -> A;
pure fn find(p: fn(A) -> bool) -> Option<A>;
}
// A trait for sequences that can be by imperatively pushing elements
@ -116,14 +124,14 @@ pure fn to_vec<A:copy,IA:BaseIter<A>>(self: IA) -> ~[A] {
foldl::<A,~[A],IA>(self, ~[], |r, a| vec::append(r, ~[a]))
}
pure fn contains<A,IA:BaseIter<A>>(self: IA, x: A) -> bool {
pure fn contains<A:Eq,IA:BaseIter<A>>(self: IA, x: A) -> bool {
for self.each |a| {
if a == x { return true; }
}
return false;
}
pure fn count<A,IA:BaseIter<A>>(self: IA, x: A) -> uint {
pure fn count<A:Eq,IA:BaseIter<A>>(self: IA, x: A) -> uint {
do foldl(self, 0u) |count, value| {
if value == x {
count + 1u
@ -155,7 +163,7 @@ pure fn repeat(times: uint, blk: fn() -> bool) {
}
}
pure fn min<A:copy,IA:BaseIter<A>>(self: IA) -> A {
pure fn min<A:copy Ord,IA:BaseIter<A>>(self: IA) -> A {
match do foldl::<A,Option<A>,IA>(self, None) |a, b| {
match a {
Some(a_) if a_ < b => {

View File

@ -222,7 +222,7 @@ mod global_env {
fn getenv(n: &str) -> Option<~str> {
unsafe {
let s = str::as_c_str(n, libc::getenv);
return if unsafe::reinterpret_cast(s) == 0 {
return if ptr::null::<u8>() == unsafe::reinterpret_cast(s) {
option::None::<~str>
} else {
let s = unsafe::reinterpret_cast(s);

View File

@ -2,6 +2,8 @@
#[forbid(deprecated_mode)];
#[forbid(deprecated_pattern)];
use cmp::Eq;
struct WindowsPath {
host: Option<~str>;
device: Option<~str>;
@ -62,6 +64,13 @@ impl PosixPath : ToStr {
}
}
impl PosixPath : Eq {
pure fn eq(&&other: PosixPath) -> bool {
return self.is_absolute == other.is_absolute &&
self.components == other.components;
}
}
// FIXME (#3227): when default methods in traits are working, de-duplicate
// PosixPath and WindowsPath, most of their methods are common.
impl PosixPath : GenericPath {

View File

@ -76,6 +76,7 @@ bounded and unbounded protocols allows for less code duplication.
#[forbid(deprecated_mode)];
#[forbid(deprecated_pattern)];
import cmp::Eq;
import unsafe::{forget, reinterpret_cast, transmute};
import either::{Either, Left, Right};
import option::unwrap;
@ -123,6 +124,12 @@ enum State {
Terminated
}
impl State: Eq {
pure fn eq(&&other: State) -> bool {
(self as uint) == (other as uint)
}
}
struct BufferHeader {
// Tracks whether this buffer needs to be freed. We can probably
// get away with restricting it to 0 or 1, if we're careful.

View File

@ -18,7 +18,7 @@ export buf_len;
export position;
export Ptr;
import cmp::Eq;
import cmp::{Eq, Ord};
import libc::{c_void, size_t};
#[nolink]
@ -174,7 +174,34 @@ impl<T> *T: Ptr {
// Equality for pointers
impl<T> *const T : Eq {
pure fn eq(&&other: *const T) -> bool { self == other }
pure fn eq(&&other: *const T) -> bool unsafe {
let a: uint = unsafe::reinterpret_cast(self);
let b: uint = unsafe::reinterpret_cast(other);
return a == b;
}
}
// Comparison for pointers
impl<T> *const T : Ord {
pure fn lt(&&other: *const T) -> bool unsafe {
let a: uint = unsafe::reinterpret_cast(self);
let b: uint = unsafe::reinterpret_cast(other);
return a < b;
}
}
// Equality for region pointers
impl<T:Eq> &const T : Eq {
pure fn eq(&&other: &const T) -> bool {
return *self == *other;
}
}
// Comparison for region pointers
impl<T:Ord> &const T : Ord {
pure fn lt(&&other: &const T) -> bool {
return *self < *other;
}
}
#[test]

View File

@ -408,7 +408,8 @@ mod tests {
#[test]
fn choose_option() {
let r = rand::Rng();
assert r.choose_option::<int>([]).is_none();
let x: Option<int> = r.choose_option([]);
assert x.is_none();
assert r.choose_option([1, 1, 1]) == Some(1);
}
@ -431,7 +432,8 @@ mod tests {
{weight: 0u, item: 42},
{weight: 1u, item: 43}
]) == Some(43);
assert r.choose_weighted_option::<int>([]).is_none();
let v: Option<int> = r.choose_weighted_option([]);
assert v.is_none();
}
#[test]

View File

@ -1,5 +1,6 @@
//! A type representing either success or failure
import cmp::Eq;
import either::Either;
/// The result type
@ -352,6 +353,25 @@ fn unwrap<T, U>(-res: Result<T, U>) -> T {
}
}
impl<T:Eq,U:Eq> Result<T,U> : Eq {
pure fn eq(&&other: Result<T,U>) -> bool {
match self {
Ok(e0a) => {
match other {
Ok(e0b) => e0a == e0b,
_ => false
}
}
Err(e0a) => {
match other {
Err(e0b) => e0a == e0b,
_ => false
}
}
}
}
}
#[cfg(test)]
mod tests {
fn op1() -> result::Result<int, ~str> { result::Ok(666) }

View File

@ -7,7 +7,7 @@
* some heavy-duty uses, try std::rope.
*/
import cmp::Eq;
import cmp::{Eq, Ord};
import libc::size_t;
import io::WriterUtil;
@ -671,8 +671,6 @@ Section: Comparing strings
/// Bytewise slice equality
pure fn eq_slice(a: &str, b: &str) -> bool {
// FIXME (#2627): This should just be "a == b" but that calls into the
// shape code.
let a_len = a.len();
let b_len = b.len();
if a_len != b_len { return false; }
@ -692,10 +690,25 @@ pure fn eq(a: &~str, b: &~str) -> bool {
eq_slice(*a, *b)
}
/// Bytewise slice less than
pure fn lt(a: &str, b: &str) -> bool {
let (a_len, b_len) = (a.len(), b.len());
let mut end = uint::min(a_len, b_len);
let mut i = 0;
while i < end {
let (c_a, c_b) = (a[i], b[i]);
if c_a < c_b { return true; }
if c_a > c_b { return false; }
i += 1;
}
return a_len < b_len;
}
/// Bytewise less than or equal
pure fn le(a: &~str, b: &~str) -> bool { *a <= *b }
#[cfg(notest)]
impl &str: Eq {
#[inline(always)]
pure fn eq(&&other: &str) -> bool {
@ -703,7 +716,6 @@ impl &str: Eq {
}
}
#[cfg(notest)]
impl ~str: Eq {
#[inline(always)]
pure fn eq(&&other: ~str) -> bool {
@ -711,7 +723,6 @@ impl ~str: Eq {
}
}
#[cfg(notest)]
impl @str: Eq {
#[inline(always)]
pure fn eq(&&other: @str) -> bool {
@ -719,6 +730,21 @@ impl @str: Eq {
}
}
impl ~str : Ord {
#[inline(always)]
pure fn lt(&&other: ~str) -> bool { lt(self, other) }
}
impl &str : Ord {
#[inline(always)]
pure fn lt(&&other: &str) -> bool { lt(self, other) }
}
impl @str : Ord {
#[inline(always)]
pure fn lt(&&other: @str) -> bool { lt(self, other) }
}
/// String hash function
pure fn hash(s: &~str) -> uint {
hash::hash_str(*s) as uint

View File

@ -1,5 +1,7 @@
//! Misc low level stuff
use cmp::{Eq, Ord};
export TypeDesc;
export Closure;
export get_type_desc;
@ -38,16 +40,16 @@ extern mod rusti {
/// Compares contents of two pointers using the default method.
/// Equivalent to `*x1 == *x2`. Useful for hashtables.
pure fn shape_eq<T>(x1: &T, x2: &T) -> bool {
pure fn shape_eq<T:Eq>(x1: &T, x2: &T) -> bool {
*x1 == *x2
}
pure fn shape_lt<T>(x1: &T, x2: &T) -> bool {
pure fn shape_lt<T:Ord>(x1: &T, x2: &T) -> bool {
*x1 < *x2
}
pure fn shape_le<T>(x1: &T, x2: &T) -> bool {
*x1 < *x2
pure fn shape_le<T:Ord>(x1: &T, x2: &T) -> bool {
*x1 <= *x2
}
/**

View File

@ -27,6 +27,7 @@
* ~~~
*/
import cmp::Eq;
import result::Result;
export Task;
@ -79,7 +80,15 @@ export PlatformThread;
/* Data types */
/// A handle to a task
enum Task { TaskHandle(task_id) }
enum Task {
TaskHandle(task_id)
}
impl Task : cmp::Eq {
pure fn eq(&&other: Task) -> bool {
*self == *other
}
}
/**
* Indicates the manner in which a task exited.
@ -97,12 +106,33 @@ enum TaskResult {
Failure,
}
impl TaskResult: Eq {
pure fn eq(&&other: TaskResult) -> bool {
match (self, other) {
(Success, Success) | (Failure, Failure) => true,
(Success, _) | (Failure, _) => false
}
}
}
/// A message type for notifying of task lifecycle events
enum Notification {
/// Sent when a task exits with the task handle and result
Exit(Task, TaskResult)
}
impl Notification : cmp::Eq {
pure fn eq(&&other: Notification) -> bool {
match self {
Exit(e0a, e1a) => {
match other {
Exit(e0b, e1b) => e0a == e0b && e1a == e1b
}
}
}
}
}
/// Scheduler modes
enum SchedMode {
/// All tasks run in the same OS thread
@ -1273,6 +1303,14 @@ type LocalDataKey<T: owned> = &fn(+@T);
trait LocalData { }
impl<T: owned> @T: LocalData { }
impl LocalData: Eq {
pure fn eq(&&other: LocalData) -> bool unsafe {
let ptr_a: (uint, uint) = unsafe::reinterpret_cast(self);
let ptr_b: (uint, uint) = unsafe::reinterpret_cast(other);
return ptr_a == ptr_b;
}
}
// We use dvec because it's the best data structure in core. If TLS is used
// heavily in future, this could be made more efficient with a proper map.
type TaskLocalElement = (*libc::c_void, *libc::c_void, LocalData);
@ -1743,13 +1781,13 @@ fn test_spawn_listiner_bidi() {
let ch = do spawn_listener |po| {
// Now the child has a port called 'po' to read from and
// an environment-captured channel called 'ch'.
let res = comm::recv(po);
let res: ~str = comm::recv(po);
assert res == ~"ping";
comm::send(ch, ~"pong");
};
// Likewise, the parent has both a 'po' and 'ch'
comm::send(ch, ~"ping");
let res = comm::recv(po);
let res: ~str = comm::recv(po);
assert res == ~"pong";
}

View File

@ -4,6 +4,8 @@
//! Operations on tuples
use cmp::{Eq, Ord};
trait TupleOps<T,U> {
pure fn first() -> T;
pure fn second() -> U;
@ -63,6 +65,76 @@ impl<A: copy, B: copy> (~[A], ~[B]): ExtendedTupleOps<A,B> {
}
}
impl<A: Eq, B: Eq> (A, B): Eq {
pure fn eq(&&other: (A, B)) -> bool {
// XXX: This would be a lot less wordy with ref bindings, but I don't
// trust that they work yet.
match self {
(self_a, self_b) => {
match other {
(other_a, other_b) => {
self_a.eq(other_a) && self_b.eq(other_b)
}
}
}
}
}
}
impl<A: Ord, B: Ord> (A, B): Ord {
pure fn lt(&&other: (A, B)) -> bool {
match self {
(self_a, self_b) => {
match other {
(other_a, other_b) => {
if self_a.lt(other_a) { return true; }
if other_a.lt(self_a) { return false; }
if self_b.lt(other_b) { return true; }
return false;
}
}
}
}
}
}
impl<A: Eq, B: Eq, C: Eq> (A, B, C): Eq {
pure fn eq(&&other: (A, B, C)) -> bool {
// XXX: This would be a lot less wordy with ref bindings, but I don't
// trust that they work yet.
match self {
(self_a, self_b, self_c) => {
match other {
(other_a, other_b, other_c) => {
self_a.eq(other_a) &&
self_b.eq(other_b) &&
self_c.eq(other_c)
}
}
}
}
}
}
impl<A: Ord, B: Ord, C: Ord> (A, B, C): Ord {
pure fn lt(&&other: (A, B, C)) -> bool {
match self {
(self_a, self_b, self_c) => {
match other {
(other_a, other_b, other_c) => {
if self_a.lt(other_a) { return true; }
if other_a.lt(self_a) { return false; }
if self_b.lt(other_b) { return true; }
if other_b.lt(self_b) { return false; }
if self_c.lt(other_c) { return true; }
return false;
}
}
}
}
}
}
#[test]
fn test_tuple() {
assert (948, 4039.48).first() == 948;

12
src/libcore/uniq.rs Normal file
View File

@ -0,0 +1,12 @@
//! Operations on unique pointer types
import cmp::{Eq, Ord};
impl<T:Eq> ~const T : Eq {
pure fn eq(&&other: ~const T) -> bool { *self == *other }
}
impl<T:Ord> ~const T : Ord {
pure fn lt(&&other: ~const T) -> bool { *self < *other }
}

View File

@ -61,7 +61,7 @@ mod tests {
#[test]
fn identity_crisis() {
// Writing a test for the identity function. How did it come to this?
let x = ~[{mut a: 5, b: false}];
let x = ~[(5, false)];
assert x == id(copy x);
}
#[test]

View File

@ -68,7 +68,6 @@ export rfind_between;
export position_elem;
export position;
export position_between;
export position_elem;
export rposition;
export rposition_between;
export unzip;
@ -93,6 +92,7 @@ export extensions;
export ConstVector;
export CopyableVector;
export ImmutableVector;
export ImmutableEqVector;
export ImmutableCopyableVector;
export IterTraitExtensions;
export vec_concat;
@ -896,13 +896,13 @@ pure fn all2<T, U>(v0: &[T], v1: &[U],
}
/// Return true if a vector contains an element with the given value
pure fn contains<T>(v: &[T], x: T) -> bool {
pure fn contains<T: Eq>(v: &[T], x: T) -> bool {
for each(v) |elt| { if x == elt { return true; } }
return false;
}
/// Returns the number of elements that are equal to a given value
pure fn count<T>(v: &[T], x: T) -> uint {
pure fn count<T: Eq>(v: &[T], x: T) -> uint {
let mut cnt = 0u;
for each(v) |elt| { if x == elt { cnt += 1u; } }
return cnt;
@ -955,7 +955,7 @@ pure fn rfind_between<T: copy>(v: &[T], start: uint, end: uint,
}
/// Find the first index containing a matching value
pure fn position_elem<T>(v: &[T], x: T) -> Option<uint> {
pure fn position_elem<T: Eq>(v: &[T], x: T) -> Option<uint> {
position(v, |y| x == y)
}
@ -987,7 +987,7 @@ pure fn position_between<T>(v: &[T], start: uint, end: uint,
}
/// Find the last index containing a matching value
pure fn rposition_elem<T>(v: &[T], x: T) -> Option<uint> {
pure fn rposition_elem<T: Eq>(v: &[T], x: T) -> Option<uint> {
rposition(v, |y| x == y)
}
@ -1529,12 +1529,8 @@ trait ImmutableVector<T> {
pure fn foldr<U: copy>(z: U, p: fn(T, U) -> U) -> U;
pure fn iter(f: fn(T));
pure fn iteri(f: fn(uint, T));
pure fn position(f: fn(T) -> bool) -> Option<uint>;
pure fn position_elem(x: T) -> Option<uint>;
pure fn riter(f: fn(T));
pure fn riteri(f: fn(uint, T));
pure fn rposition(f: fn(T) -> bool) -> Option<uint>;
pure fn rposition_elem(x: T) -> Option<uint>;
pure fn map<U>(f: fn(T) -> U) -> ~[U];
pure fn mapi<U>(f: fn(uint, T) -> U) -> ~[U];
fn map_r<U>(f: fn(x: &T) -> U) -> ~[U];
@ -1543,6 +1539,13 @@ trait ImmutableVector<T> {
pure fn filter_map<U: copy>(f: fn(T) -> Option<U>) -> ~[U];
}
trait ImmutableEqVector<T: Eq> {
pure fn position(f: fn(T) -> bool) -> Option<uint>;
pure fn position_elem(x: T) -> Option<uint>;
pure fn rposition(f: fn(T) -> bool) -> Option<uint>;
pure fn rposition_elem(x: T) -> Option<uint>;
}
/// Extension methods for vectors
impl<T> &[T]: ImmutableVector<T> {
/// Reduce a vector from right to left
@ -1564,18 +1567,6 @@ impl<T> &[T]: ImmutableVector<T> {
*/
#[inline]
pure fn iteri(f: fn(uint, T)) { iteri(self, f) }
/**
* Find the first index matching some predicate
*
* Apply function `f` to each element of `v`. When function `f` returns
* true then an option containing the index is returned. If `f` matches no
* elements then none is returned.
*/
#[inline]
pure fn position(f: fn(T) -> bool) -> Option<uint> { position(self, f) }
/// Find the first index containing a matching value
#[inline]
pure fn position_elem(x: T) -> Option<uint> { position_elem(self, x) }
/**
* Iterates over a vector in reverse
*
@ -1592,18 +1583,6 @@ impl<T> &[T]: ImmutableVector<T> {
*/
#[inline]
pure fn riteri(f: fn(uint, T)) { riteri(self, f) }
/**
* Find the last index matching some predicate
*
* Apply function `f` to each element of `v` in reverse order. When
* function `f` returns true then an option containing the index is
* returned. If `f` matches no elements then none is returned.
*/
#[inline]
pure fn rposition(f: fn(T) -> bool) -> Option<uint> { rposition(self, f) }
/// Find the last index containing a matching value
#[inline]
pure fn rposition_elem(x: T) -> Option<uint> { rposition_elem(self, x) }
/// Apply a function to each element of a vector and return the results
#[inline]
pure fn map<U>(f: fn(T) -> U) -> ~[U] { map(self, f) }
@ -1652,6 +1631,33 @@ impl<T> &[T]: ImmutableVector<T> {
}
}
impl<T: Eq> &[T]: ImmutableEqVector<T> {
/**
* Find the first index matching some predicate
*
* Apply function `f` to each element of `v`. When function `f` returns
* true then an option containing the index is returned. If `f` matches no
* elements then none is returned.
*/
#[inline]
pure fn position(f: fn(T) -> bool) -> Option<uint> { position(self, f) }
/// Find the first index containing a matching value
#[inline]
pure fn position_elem(x: T) -> Option<uint> { position_elem(self, x) }
/**
* Find the last index matching some predicate
*
* Apply function `f` to each element of `v` in reverse order. When
* function `f` returns true then an option containing the index is
* returned. If `f` matches no elements then none is returned.
*/
#[inline]
pure fn rposition(f: fn(T) -> bool) -> Option<uint> { rposition(self, f) }
/// Find the last index containing a matching value
#[inline]
pure fn rposition_elem(x: T) -> Option<uint> { rposition_elem(self, x) }
}
trait ImmutableCopyableVector<T> {
pure fn filter(f: fn(T) -> bool) -> ~[T];
pure fn rfind(f: fn(T) -> bool) -> Option<T>;
@ -1906,6 +1912,9 @@ impl<A> &[A]: iter::ExtendedIter<A> {
pure fn foldl<B>(+b0: B, blk: fn(B, A) -> B) -> B {
iter::foldl(self, b0, blk)
}
}
impl<A: Eq> &[A]: iter::EqIter<A> {
pure fn contains(x: A) -> bool { iter::contains(self, x) }
pure fn count(x: A) -> uint { iter::count(self, x) }
pure fn position(f: fn(A) -> bool) -> Option<uint> {
@ -1927,9 +1936,12 @@ impl<A: copy> &[A]: iter::CopyableIter<A> {
// iter::flat_map_to_vec(self, op)
// }
pure fn find(p: fn(A) -> bool) -> Option<A> { iter::find(self, p) }
}
impl<A: copy Ord> &[A]: iter::CopyableOrderedIter<A> {
pure fn min() -> A { iter::min(self) }
pure fn max() -> A { iter::max(self) }
pure fn find(p: fn(A) -> bool) -> Option<A> { iter::find(self, p) }
}
// ___________________________________________________________________________

View File

@ -11,6 +11,7 @@
* of features.
*/
import core::cmp::{Eq, Ord};
import option::{Some, None};
import option = option;
@ -31,7 +32,8 @@ enum TreeNode<K, V> {
fn init<K, V>() -> Treemap<K, V> { @Empty }
/// Insert a value into the map
fn insert<K: copy, V: copy>(m: Treemap<K, V>, k: K, v: V) -> Treemap<K, V> {
fn insert<K: copy Eq Ord, V: copy>(m: Treemap<K, V>, k: K, v: V)
-> Treemap<K, V> {
@match m {
@Empty => Node(@k, @v, @Empty, @Empty),
@Node(@kk, vv, left, right) => {
@ -45,7 +47,7 @@ fn insert<K: copy, V: copy>(m: Treemap<K, V>, k: K, v: V) -> Treemap<K, V> {
}
/// Find a value based on the key
fn find<K, V: copy>(m: Treemap<K, V>, k: K) -> Option<V> {
fn find<K: Eq Ord, V: copy>(m: Treemap<K, V>, k: K) -> Option<V> {
match *m {
Empty => None,
Node(@kk, @v, left, right) => {

View File

@ -67,6 +67,7 @@
#[forbid(deprecated_mode)];
#[forbid(deprecated_pattern)];
import core::cmp::Eq;
import core::result::{Err, Ok};
import core::option;
import core::option::{Some, None};
@ -89,7 +90,10 @@ export opt_maybe_str;
export opt_default;
export Result; //NDM
enum Name { Long(~str), Short(char), }
enum Name {
Long(~str),
Short(char),
}
enum HasArg { Yes, No, Maybe, }
@ -105,6 +109,31 @@ fn mkname(nm: &str) -> Name {
} else { Long(unm) };
}
impl Name : Eq {
pure fn eq(&&other: Name) -> bool {
match self {
Long(e0a) => {
match other {
Long(e0b) => e0a == e0b,
_ => false
}
}
Short(e0a) => {
match other {
Short(e0b) => e0a == e0b,
_ => false
}
}
}
}
}
impl Occur : Eq {
pure fn eq(&&other: Occur) -> bool {
(self as uint) == (other as uint)
}
}
/// Create an option that is required and takes an argument
fn reqopt(name: &str) -> Opt {
return {name: mkname(name), hasarg: Yes, occur: Req};
@ -410,19 +439,25 @@ fn opt_default(+mm: Matches, nm: &str, def: &str) -> Option<~str> {
_ => Some::<~str>(str::from_slice(def)) }
}
enum FailType {
ArgumentMissing_,
UnrecognizedOption_,
OptionMissing_,
OptionDuplicated_,
UnexpectedArgument_,
}
impl FailType : Eq {
pure fn eq(&&other: FailType) -> bool {
(self as uint) == (other as uint)
}
}
#[cfg(test)]
mod tests {
import opt = getopts;
import result::{Err, Ok};
enum FailType {
ArgumentMissing_,
UnrecognizedOption_,
OptionMissing_,
OptionDuplicated_,
UnexpectedArgument_,
}
fn check_fail_type(+f: Fail_, ft: FailType) {
match f {
ArgumentMissing(_) => assert ft == ArgumentMissing_,

View File

@ -5,6 +5,7 @@
//! json serialization
import core::cmp::Eq;
import result::{Result, Ok, Err};
import io;
import io::WriterUtil;
@ -477,7 +478,7 @@ fn from_str(s: ~str) -> Result<Json, Error> {
}
/// Test if two json values are equal
fn eq(value0: Json, value1: Json) -> bool {
pure fn eq(value0: Json, value1: Json) -> bool {
match (value0, value1) {
(Num(f0), Num(f1)) => f0 == f1,
(String(s0), String(s1)) => s0 == s1,
@ -502,6 +503,20 @@ fn eq(value0: Json, value1: Json) -> bool {
}
}
impl Error : Eq {
pure fn eq(&&other: Error) -> bool {
self.line == other.line &&
self.col == other.col &&
self.msg == other.msg
}
}
impl Json : Eq {
pure fn eq(&&other: Json) -> bool {
eq(self, other)
}
}
trait ToJson { fn to_json() -> Json; }
impl Json: ToJson {

View File

@ -1,5 +1,6 @@
//! A standard linked list
import core::cmp::Eq;
import core::option;
import option::*;
import option::{Some, None};
@ -54,7 +55,7 @@ fn find<T: copy>(ls: @list<T>, f: fn(T) -> bool) -> Option<T> {
}
/// Returns true if a list contains an element with the given value
fn has<T: copy>(ls: @list<T>, elt: T) -> bool {
fn has<T: copy Eq>(ls: @list<T>, elt: T) -> bool {
for each(ls) |e| {
if e == elt { return true; }
}
@ -142,6 +143,25 @@ fn each<T>(l: @list<T>, f: fn(T) -> bool) {
}
}
impl<T:Eq> list<T> : Eq {
pure fn eq(&&other: list<T>) -> bool {
match self {
cons(e0a, e1a) => {
match other {
cons(e0b, e1b) => e0a == e0b && e1a == e1b,
_ => false
}
}
nil => {
match other {
nil => true,
_ => false
}
}
}
}
}
#[cfg(test)]
mod tests {

View File

@ -30,7 +30,7 @@ type hashmap<K, V> = chained::t<K, V>;
trait map<K: copy, V: copy> {
/// Return the number of elements in the map
fn size() -> uint;
pure fn size() -> uint;
/**
* Add a value to the map.
@ -59,7 +59,7 @@ trait map<K: copy, V: copy> {
* Get the value for the specified key. If the key does not exist in
* the map then returns none.
*/
fn find(+key: K) -> Option<V>;
pure fn find(+key: K) -> Option<V>;
/**
* Remove and return a value from the map. Returns true if the
@ -71,22 +71,22 @@ trait map<K: copy, V: copy> {
fn clear();
/// Iterate over all the key/value pairs in the map by value
fn each(fn(+key: K, +value: V) -> bool);
pure fn each(fn(+key: K, +value: V) -> bool);
/// Iterate over all the keys in the map by value
fn each_key(fn(+key: K) -> bool);
pure fn each_key(fn(+key: K) -> bool);
/// Iterate over all the values in the map by value
fn each_value(fn(+value: V) -> bool);
pure fn each_value(fn(+value: V) -> bool);
/// Iterate over all the key/value pairs in the map by reference
fn each_ref(fn(key: &K, value: &V) -> bool);
pure fn each_ref(fn(key: &K, value: &V) -> bool);
/// Iterate over all the keys in the map by reference
fn each_key_ref(fn(key: &K) -> bool);
pure fn each_key_ref(fn(key: &K) -> bool);
/// Iterate over all the values in the map by reference
fn each_value_ref(fn(value: &V) -> bool);
pure fn each_value_ref(fn(value: &V) -> bool);
}
mod util {
@ -130,8 +130,8 @@ mod chained {
}
priv impl<K, V: copy> t<K, V> {
fn search_rem(k: &K, h: uint, idx: uint,
e_root: @entry<K,V>) -> search_result<K,V> {
pure fn search_rem(k: &K, h: uint, idx: uint,
e_root: @entry<K,V>) -> search_result<K,V> {
let mut e0 = e_root;
let mut comp = 1u; // for logging
loop {
@ -143,20 +143,22 @@ mod chained {
}
Some(e1) => {
comp += 1u;
if e1.hash == h && self.eqer(&e1.key, k) {
debug!("search_tbl: present, comp %u, \
hash %u, idx %u",
comp, h, idx);
return found_after(e0, e1);
} else {
e0 = e1;
unchecked {
if e1.hash == h && self.eqer(&e1.key, k) {
debug!("search_tbl: present, comp %u, \
hash %u, idx %u",
comp, h, idx);
return found_after(e0, e1);
} else {
e0 = e1;
}
}
}
}
};
}
fn search_tbl(k: &K, h: uint) -> search_result<K,V> {
pure fn search_tbl(k: &K, h: uint) -> search_result<K,V> {
let idx = h % vec::len(self.chains);
match copy self.chains[idx] {
None => {
@ -165,12 +167,14 @@ mod chained {
return not_found;
}
Some(e) => {
if e.hash == h && self.eqer(&e.key, k) {
debug!("search_tbl: present, comp %u, hash %u, idx %u",
1u, h, idx);
return found_first(idx, e);
} else {
return self.search_rem(k, h, idx, e);
unchecked {
if e.hash == h && self.eqer(&e.key, k) {
debug!("search_tbl: present, comp %u, hash %u, \
idx %u", 1u, h, idx);
return found_first(idx, e);
} else {
return self.search_rem(k, h, idx, e);
}
}
}
}
@ -188,7 +192,7 @@ mod chained {
self.chains = new_chains;
}
fn each_entry(blk: fn(@entry<K,V>) -> bool) {
pure fn each_entry(blk: fn(@entry<K,V>) -> bool) {
// n.b. we can't use vec::iter() here because self.chains
// is stored in a mutable location.
let mut i = 0u, n = self.chains.len();
@ -210,7 +214,7 @@ mod chained {
}
impl<K: copy, V: copy> t<K, V>: map<K, V> {
fn size() -> uint { self.count }
pure fn size() -> uint { self.count }
fn contains_key(+k: K) -> bool {
self.contains_key_ref(&k)
@ -266,11 +270,13 @@ mod chained {
}
}
fn find(+k: K) -> Option<V> {
match self.search_tbl(&k, self.hasher(&k)) {
not_found => None,
found_first(_, entry) => Some(entry.value),
found_after(_, entry) => Some(entry.value)
pure fn find(+k: K) -> Option<V> {
unchecked {
match self.search_tbl(&k, self.hasher(&k)) {
not_found => None,
found_first(_, entry) => Some(entry.value),
found_after(_, entry) => Some(entry.value)
}
}
}
@ -303,29 +309,29 @@ mod chained {
self.chains = chains(initial_capacity);
}
fn each(blk: fn(+key: K, +value: V) -> bool) {
pure fn each(blk: fn(+key: K, +value: V) -> bool) {
self.each_ref(|k, v| blk(*k, *v))
}
fn each_key(blk: fn(+key: K) -> bool) {
pure fn each_key(blk: fn(+key: K) -> bool) {
self.each_key_ref(|p| blk(*p))
}
fn each_value(blk: fn(+value: V) -> bool) {
pure fn each_value(blk: fn(+value: V) -> bool) {
self.each_value_ref(|p| blk(*p))
}
fn each_ref(blk: fn(key: &K, value: &V) -> bool) {
pure fn each_ref(blk: fn(key: &K, value: &V) -> bool) {
for self.each_entry |entry| {
if !blk(&entry.key, &entry.value) { break; }
}
}
fn each_key_ref(blk: fn(key: &K) -> bool) {
pure fn each_key_ref(blk: fn(key: &K) -> bool) {
self.each_ref(|k, _v| blk(k))
}
fn each_value_ref(blk: fn(value: &V) -> bool) {
pure fn each_value_ref(blk: fn(value: &V) -> bool) {
self.each_ref(|_k, v| blk(v))
}
}
@ -473,9 +479,11 @@ fn hash_from_uints<V: copy>(items: &[(uint, V)]) -> hashmap<uint, V> {
// XXX Transitionary
impl<K: copy, V: copy> Managed<LinearMap<K, V>>: map<K, V> {
fn size() -> uint {
do self.borrow_const |p| {
p.len()
pure fn size() -> uint {
unchecked {
do self.borrow_const |p| {
p.len()
}
}
}
@ -503,9 +511,11 @@ impl<K: copy, V: copy> Managed<LinearMap<K, V>>: map<K, V> {
}
}
fn find(+key: K) -> Option<V> {
do self.borrow_const |p| {
p.find(&key)
pure fn find(+key: K) -> Option<V> {
unchecked {
do self.borrow_const |p| {
p.find(&key)
}
}
}
@ -521,39 +531,51 @@ impl<K: copy, V: copy> Managed<LinearMap<K, V>>: map<K, V> {
}
}
fn each(op: fn(+key: K, +value: V) -> bool) {
do self.borrow_imm |p| {
p.each(op)
pure fn each(op: fn(+key: K, +value: V) -> bool) {
unchecked {
do self.borrow_imm |p| {
p.each(op)
}
}
}
fn each_key(op: fn(+key: K) -> bool) {
do self.borrow_imm |p| {
p.each_key(op)
pure fn each_key(op: fn(+key: K) -> bool) {
unchecked {
do self.borrow_imm |p| {
p.each_key(op)
}
}
}
fn each_value(op: fn(+value: V) -> bool) {
do self.borrow_imm |p| {
p.each_value(op)
pure fn each_value(op: fn(+value: V) -> bool) {
unchecked {
do self.borrow_imm |p| {
p.each_value(op)
}
}
}
fn each_ref(op: fn(key: &K, value: &V) -> bool) {
do self.borrow_imm |p| {
p.each_ref(op)
pure fn each_ref(op: fn(key: &K, value: &V) -> bool) {
unchecked {
do self.borrow_imm |p| {
p.each_ref(op)
}
}
}
fn each_key_ref(op: fn(key: &K) -> bool) {
do self.borrow_imm |p| {
p.each_key_ref(op)
pure fn each_key_ref(op: fn(key: &K) -> bool) {
unchecked {
do self.borrow_imm |p| {
p.each_key_ref(op)
}
}
}
fn each_value_ref(op: fn(value: &V) -> bool) {
do self.borrow_imm |p| {
p.each_value_ref(op)
pure fn each_value_ref(op: fn(value: &V) -> bool) {
unchecked {
do self.borrow_imm |p| {
p.each_value_ref(op)
}
}
}
}

View File

@ -1,5 +1,6 @@
//! Types/fns concerning URLs (see RFC 3986)
import core::cmp::Eq;
import map;
import map::{hashmap, str_hash};
import io::{Reader, ReaderUtil};
@ -309,6 +310,12 @@ fn userinfo_to_str(-userinfo: userinfo) -> ~str {
}
}
impl userinfo : Eq {
pure fn eq(&&other: userinfo) -> bool {
self.user == other.user && self.pass == other.pass
}
}
fn query_from_str(rawquery: ~str) -> query {
let mut query: query = ~[];
if str::len(rawquery) != 0 {
@ -356,6 +363,25 @@ fn get_scheme(rawurl: ~str) -> result::Result<(~str, ~str), @~str> {
return result::Err(@~"url: Scheme must be terminated with a colon.");
}
enum input {
digit, // all digits
hex, // digits and letters a-f
unreserved // all other legal characters
}
impl input: Eq {
pure fn eq(&&other: input) -> bool {
match (self, other) {
(digit, digit) => true,
(hex, hex) => true,
(unreserved, unreserved) => true,
(digit, _) => false,
(hex, _) => false,
(unreserved, _) => false
}
}
}
// returns userinfo, host, port, and unparsed part, or an error
fn get_authority(rawurl: ~str) ->
result::Result<(Option<userinfo>, ~str, Option<~str>, ~str), @~str> {
@ -372,11 +398,7 @@ fn get_authority(rawurl: ~str) ->
in_host, // are in a host - may be ipv6, but don't know yet
in_port // are in port
}
enum input {
digit, // all digits
hex, // digits and letters a-f
unreserved // all other legal characters
}
let len = str::len(rawurl);
let mut st : state = start;
let mut in : input = digit; // most restricted, start here.
@ -1027,13 +1049,10 @@ mod tests {
fn test_decode_form_urlencoded() {
import map::hash_from_strs;
assert decode_form_urlencoded(~[]) == str_hash();
assert decode_form_urlencoded(~[]).size() == 0;
let s = str::to_bytes(~"a=1&foo+bar=abc&foo+bar=12+%3D+34");
assert decode_form_urlencoded(s) == hash_from_strs(~[
(~"a", @dvec::from_elem(@~"1")),
(~"foo bar", @dvec::from_vec(~[mut @~"abc", @~"12 = 34"]))
]);
assert decode_form_urlencoded(s).size() == 2;
}
}

View File

@ -64,7 +64,7 @@ fn contains_key<T: copy>(self: smallintmap<T>, key: uint) -> bool {
/// Implements the map::map interface for smallintmap
impl<V: copy> smallintmap<V>: map::map<uint, V> {
fn size() -> uint {
pure fn size() -> uint {
let mut sz = 0u;
for self.v.each |item| {
match item {
@ -98,9 +98,9 @@ impl<V: copy> smallintmap<V>: map::map<uint, V> {
contains_key(self, *key)
}
fn get(+key: uint) -> V { get(self, key) }
fn find(+key: uint) -> Option<V> { find(self, key) }
pure fn find(+key: uint) -> Option<V> { find(self, key) }
fn rehash() { fail }
fn each(it: fn(+key: uint, +value: V) -> bool) {
pure fn each(it: fn(+key: uint, +value: V) -> bool) {
let mut idx = 0u, l = self.v.len();
while idx < l {
match self.v.get_elt(idx) {
@ -110,13 +110,13 @@ impl<V: copy> smallintmap<V>: map::map<uint, V> {
idx += 1u;
}
}
fn each_key(it: fn(+key: uint) -> bool) {
pure fn each_key(it: fn(+key: uint) -> bool) {
self.each(|k, _v| it(k))
}
fn each_value(it: fn(+value: V) -> bool) {
pure fn each_value(it: fn(+value: V) -> bool) {
self.each(|_k, v| it(v))
}
fn each_ref(it: fn(key: &uint, value: &V) -> bool) {
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) {
@ -126,10 +126,10 @@ impl<V: copy> smallintmap<V>: map::map<uint, V> {
idx += 1u;
}
}
fn each_key_ref(blk: fn(key: &uint) -> bool) {
pure fn each_key_ref(blk: fn(key: &uint) -> bool) {
self.each_ref(|k, _v| blk(k))
}
fn each_value_ref(blk: fn(value: &V) -> bool) {
pure fn each_value_ref(blk: fn(value: &V) -> bool) {
self.each_ref(|_k, v| blk(v))
}
}

View File

@ -1,6 +1,7 @@
#[forbid(deprecated_mode)];
#[forbid(deprecated_pattern)];
import core::cmp::Eq;
import libc::{c_char, c_int, c_long, size_t, time_t};
import io::Reader;
import result::{Result, Ok, Err};
@ -35,6 +36,12 @@ extern mod rustrt {
/// A record specifying a time value in seconds and nanoseconds.
type Timespec = {sec: i64, nsec: i32};
impl timespec : Eq {
pure fn eq(&&other: timespec) -> bool {
self.sec == other.sec && self.nsec == other.nsec
}
}
/**
* Returns the current time as a `timespec` containing the seconds and
* nanoseconds since 1970-01-01T00:00:00Z.

View File

@ -6,6 +6,7 @@
* red-black tree or something else.
*/
import core::cmp::{Eq, Ord};
import core::option::{Some, None};
import Option = core::Option;
@ -29,7 +30,7 @@ enum tree_node<K, V> = {
fn treemap<K, V>() -> treemap<K, V> { @mut None }
/// Insert a value into the map
fn insert<K: copy, V: copy>(m: &mut tree_edge<K, V>, k: K, v: V) {
fn insert<K: copy Eq Ord, V: copy>(m: &mut tree_edge<K, V>, k: K, v: V) {
match copy *m {
None => {
*m = Some(@tree_node({key: k,
@ -51,7 +52,8 @@ fn insert<K: copy, V: copy>(m: &mut tree_edge<K, V>, k: K, v: V) {
}
/// Find a value based on the key
fn find<K: copy, V: copy>(m: &const tree_edge<K, V>, k: K) -> Option<V> {
fn find<K: copy Eq Ord, V: copy>(m: &const tree_edge<K, V>, k: K)
-> Option<V> {
match copy *m {
None => None,

View File

@ -77,6 +77,12 @@ type node_id = int;
#[auto_serialize]
type def_id = {crate: crate_num, node: node_id};
impl def_id: cmp::Eq {
pure fn eq(&&other: def_id) -> bool {
self.crate == other.crate && self.node == other.node
}
}
const local_crate: crate_num = 0;
const crate_node_id: node_id = 0;
@ -108,16 +114,138 @@ enum def {
def_ty_param(def_id, uint),
def_binding(node_id, binding_mode),
def_use(def_id),
def_upvar(node_id /* id of closed over var */,
@def /* closed over def */,
node_id /* expr node that creates the closure */,
node_id /* id for the block/body of the closure expr */),
def_upvar(node_id, // id of closed over var
@def, // closed over def
node_id, // expr node that creates the closure
node_id), // id for the block/body of the closure expr
def_class(def_id, bool /* has constructor */),
def_typaram_binder(node_id), /* class, impl or trait that has ty params */
def_region(node_id),
def_label(node_id)
}
impl def : cmp::Eq {
pure fn eq(&&other: def) -> bool {
match self {
def_fn(e0a, e1a) => {
match other {
def_fn(e0b, e1b) => e0a == e0b && e1a == e1b,
_ => false
}
}
def_static_method(e0a, e1a) => {
match other {
def_static_method(e0b, e1b) => e0a == e0b && e1a == e1b,
_ => false
}
}
def_self(e0a) => {
match other {
def_self(e0b) => e0a == e0b,
_ => false
}
}
def_mod(e0a) => {
match other {
def_mod(e0b) => e0a == e0b,
_ => false
}
}
def_foreign_mod(e0a) => {
match other {
def_foreign_mod(e0b) => e0a == e0b,
_ => false
}
}
def_const(e0a) => {
match other {
def_const(e0b) => e0a == e0b,
_ => false
}
}
def_arg(e0a, e1a) => {
match other {
def_arg(e0b, e1b) => e0a == e0b && e1a == e1b,
_ => false
}
}
def_local(e0a, e1a) => {
match other {
def_local(e0b, e1b) => e0a == e0b && e1a == e1b,
_ => false
}
}
def_variant(e0a, e1a) => {
match other {
def_variant(e0b, e1b) => e0a == e0b && e1a == e1b,
_ => false
}
}
def_ty(e0a) => {
match other {
def_ty(e0b) => e0a == e0b,
_ => false
}
}
def_prim_ty(e0a) => {
match other {
def_prim_ty(e0b) => e0a == e0b,
_ => false
}
}
def_ty_param(e0a, e1a) => {
match other {
def_ty_param(e0b, e1b) => e0a == e0b && e1a == e1b,
_ => false
}
}
def_binding(e0a, e1a) => {
match other {
def_binding(e0b, e1b) => e0a == e0b && e1a == e1b,
_ => false
}
}
def_use(e0a) => {
match other {
def_use(e0b) => e0a == e0b,
_ => false
}
}
def_upvar(e0a, e1a, e2a, e3a) => {
match other {
def_upvar(e0b, e1b, e2b, e3b) =>
e0a == e0b && e1a == e1b && e2a == e2b && e3a == e3b,
_ => false
}
}
def_class(e0a, e1a) => {
match other {
def_class(e0b, e1b) => e0a == e0b && e1a == e1b,
_ => false
}
}
def_typaram_binder(e0a) => {
match other {
def_typaram_binder(e1a) => e0a == e1a,
_ => false
}
}
def_region(e0a) => {
match other {
def_region(e0b) => e0a == e0b,
_ => false
}
}
def_label(e0a) => {
match other {
def_label(e0b) => e0a == e0b,
_ => false
}
}
}
}
}
// The set of meta_items that define the compilation environment of the crate,
// used to drive conditional compilation
type crate_cfg = ~[@meta_item];
@ -180,6 +308,37 @@ enum binding_mode {
bind_by_implicit_ref
}
impl binding_mode : cmp::Eq {
pure fn eq(&&other: binding_mode) -> bool {
match self {
bind_by_value => {
match other {
bind_by_value => true,
_ => false
}
}
bind_by_move => {
match other {
bind_by_move => true,
_ => false
}
}
bind_by_ref(e0a) => {
match other {
bind_by_ref(e0b) => e0a == e0b,
_ => false
}
}
bind_by_implicit_ref => {
match other {
bind_by_implicit_ref => true,
_ => false
}
}
}
}
}
#[auto_serialize]
enum pat_ {
pat_wild,
@ -205,6 +364,12 @@ enum pat_ {
#[auto_serialize]
enum mutability { m_mutbl, m_imm, m_const, }
impl mutability: cmp::Eq {
pure fn eq(&&other: mutability) -> bool {
(self as uint) == (other as uint)
}
}
#[auto_serialize]
enum proto {
proto_bare, // foreign fn
@ -251,6 +416,12 @@ enum binop {
gt,
}
impl binop : cmp::Eq {
pure fn eq(&&other: binop) -> bool {
(self as uint) == (other as uint)
}
}
#[auto_serialize]
enum unop {
box(mutability),
@ -262,13 +433,39 @@ enum unop {
// using ty::resolved_T(...).
#[auto_serialize]
enum inferable<T> {
expl(T), infer(node_id)
expl(T),
infer(node_id)
}
impl<T:cmp::Eq> inferable<T> : cmp::Eq {
pure fn eq(&&other: inferable<T>) -> bool {
match self {
expl(e0a) => {
match other {
expl(e0b) => e0a == e0b,
_ => false
}
}
infer(e0a) => {
match other {
infer(e0b) => e0a == e0b,
_ => false
}
}
}
}
}
// "resolved" mode: the real modes.
#[auto_serialize]
enum rmode { by_ref, by_val, by_mutbl_ref, by_move, by_copy }
impl rmode : cmp::Eq {
pure fn eq(&&other: rmode) -> bool {
(self as uint) == (other as uint)
}
}
// inferable mode.
#[auto_serialize]
type mode = inferable<rmode>;
@ -290,6 +487,25 @@ enum stmt_ {
#[auto_serialize]
enum init_op { init_assign, init_move, }
impl init_op : cmp::Eq {
pure fn eq(&&other: init_op) -> bool {
match self {
init_assign => {
match other {
init_assign => true,
_ => false
}
}
init_move => {
match other {
init_move => true,
_ => false
}
}
}
}
}
#[auto_serialize]
type initializer = {op: init_op, expr: @expr};
@ -320,6 +536,19 @@ type field = spanned<field_>;
#[auto_serialize]
enum blk_check_mode { default_blk, unchecked_blk, unsafe_blk, }
impl blk_check_mode : cmp::Eq {
pure fn eq(&&other: blk_check_mode) -> bool {
match (self, other) {
(default_blk, default_blk) => true,
(unchecked_blk, unchecked_blk) => true,
(unsafe_blk, unsafe_blk) => true,
(default_blk, _) => false,
(unchecked_blk, _) => false,
(unsafe_blk, _) => false,
}
}
}
#[auto_serialize]
type expr = {id: node_id, callee_id: node_id, node: expr_, span: span};
// Extra node ID is only used for index, assign_op, unary, binary
@ -527,6 +756,33 @@ enum lit_ {
lit_bool(bool),
}
impl ast::lit_: cmp::Eq {
pure fn eq(&&other: ast::lit_) -> bool {
match (self, other) {
(lit_str(a), lit_str(b)) => a == b,
(lit_int(val_a, ty_a), lit_int(val_b, ty_b)) => {
val_a == val_b && ty_a == ty_b
}
(lit_uint(val_a, ty_a), lit_uint(val_b, ty_b)) => {
val_a == val_b && ty_a == ty_b
}
(lit_int_unsuffixed(a), lit_int_unsuffixed(b)) => a == b,
(lit_float(val_a, ty_a), lit_float(val_b, ty_b)) => {
val_a == val_b && ty_a == ty_b
}
(lit_nil, lit_nil) => true,
(lit_bool(a), lit_bool(b)) => a == b,
(lit_str(_), _) => false,
(lit_int(*), _) => false,
(lit_uint(*), _) => false,
(lit_int_unsuffixed(*), _) => false,
(lit_float(*), _) => false,
(lit_nil, _) => false,
(lit_bool(_), _) => false
}
}
}
// NB: If you change this, you'll probably want to change the corresponding
// type structure in middle/ty.rs as well.
#[auto_serialize]
@ -555,12 +811,57 @@ enum trait_method {
#[auto_serialize]
enum int_ty { ty_i, ty_char, ty_i8, ty_i16, ty_i32, ty_i64, }
impl int_ty: cmp::Eq {
pure fn eq(&&other: int_ty) -> bool {
match (self, other) {
(ty_i, ty_i) => true,
(ty_char, ty_char) => true,
(ty_i8, ty_i8) => true,
(ty_i16, ty_i16) => true,
(ty_i32, ty_i32) => true,
(ty_i64, ty_i64) => true,
(ty_i, _) => false,
(ty_char, _) => false,
(ty_i8, _) => false,
(ty_i16, _) => false,
(ty_i32, _) => false,
(ty_i64, _) => false,
}
}
}
#[auto_serialize]
enum uint_ty { ty_u, ty_u8, ty_u16, ty_u32, ty_u64, }
impl uint_ty: cmp::Eq {
pure fn eq(&&other: uint_ty) -> bool {
match (self, other) {
(ty_u, ty_u) => true,
(ty_u8, ty_u8) => true,
(ty_u16, ty_u16) => true,
(ty_u32, ty_u32) => true,
(ty_u64, ty_u64) => true,
(ty_u, _) => false,
(ty_u8, _) => false,
(ty_u16, _) => false,
(ty_u32, _) => false,
(ty_u64, _) => false
}
}
}
#[auto_serialize]
enum float_ty { ty_f, ty_f32, ty_f64, }
impl float_ty: cmp::Eq {
pure fn eq(&&other: float_ty) -> bool {
match (self, other) {
(ty_f, ty_f) | (ty_f32, ty_f32) | (ty_f64, ty_f64) => true,
(ty_f, _) | (ty_f32, _) | (ty_f64, _) => false
}
}
}
#[auto_serialize]
type ty = {id: node_id, node: ty_, span: span};
@ -574,6 +875,43 @@ enum prim_ty {
ty_bool,
}
impl prim_ty : cmp::Eq {
pure fn eq(&&other: prim_ty) -> bool {
match self {
ty_int(e0a) => {
match other {
ty_int(e0b) => e0a == e0b,
_ => false
}
}
ty_uint(e0a) => {
match other {
ty_uint(e0b) => e0a == e0b,
_ => false
}
}
ty_float(e0a) => {
match other {
ty_float(e0b) => e0a == e0b,
_ => false
}
}
ty_str => {
match other {
ty_str => true,
_ => false
}
}
ty_bool => {
match other {
ty_bool => true,
_ => false
}
}
}
}
}
#[auto_serialize]
type region = {id: node_id, node: region_};
@ -618,6 +956,12 @@ enum purity {
extern_fn, // declared with "extern fn"
}
impl purity : cmp::Eq {
pure fn eq(&&other: purity) -> bool {
(self as uint) == (other as uint)
}
}
#[auto_serialize]
enum ret_style {
noreturn, // functions with return type _|_ that always
@ -625,6 +969,17 @@ enum ret_style {
return_val, // everything else
}
impl ret_style : cmp::Eq {
pure fn eq(&&other: ret_style) -> bool {
match (self, other) {
(noreturn, noreturn) => true,
(return_val, return_val) => true,
(noreturn, _) => false,
(return_val, _) => false,
}
}
}
#[auto_serialize]
enum self_ty_ {
sty_static, // no self: static method
@ -635,6 +990,49 @@ enum self_ty_ {
sty_uniq(mutability) // by-unique-pointer self: `~self`
}
impl self_ty_ : cmp::Eq {
pure fn eq(&&other: self_ty_) -> bool {
match self {
sty_static => {
match other {
sty_static => true,
_ => false
}
}
sty_by_ref => {
match other {
sty_by_ref => true,
_ => false
}
}
sty_value => {
match other {
sty_value => true,
_ => false
}
}
sty_region(e0a) => {
match other {
sty_region(e0b) => e0a == e0b,
_ => false
}
}
sty_box(e0a) => {
match other {
sty_box(e0b) => e0a == e0b,
_ => false
}
}
sty_uniq(e0a) => {
match other {
sty_uniq(e0b) => e0a == e0b,
_ => false
}
}
}
}
}
#[auto_serialize]
type self_ty = spanned<self_ty_>;
@ -660,6 +1058,25 @@ enum foreign_abi {
#[auto_serialize]
enum foreign_mod_sort { named, anonymous }
impl foreign_mod_sort : cmp::Eq {
pure fn eq(&&other: foreign_mod_sort) -> bool {
(self as uint) == (other as uint)
}
}
impl foreign_abi : cmp::Eq {
pure fn eq(&&other: foreign_abi) -> bool {
match (self, other) {
(foreign_abi_rust_intrinsic, foreign_abi_rust_intrinsic) => true,
(foreign_abi_cdecl, foreign_abi_cdecl) => true,
(foreign_abi_stdcall, foreign_abi_stdcall) => true,
(foreign_abi_rust_intrinsic, _) => false,
(foreign_abi_cdecl, _) => false,
(foreign_abi_stdcall, _) => false,
}
}
}
#[auto_serialize]
type foreign_mod =
{sort: foreign_mod_sort,
@ -733,6 +1150,17 @@ type attribute = spanned<attribute_>;
#[auto_serialize]
enum attr_style { attr_outer, attr_inner, }
impl attr_style : cmp::Eq {
pure fn eq(&&other: attr_style) -> bool {
match (self, other) {
(attr_outer, attr_outer) => true,
(attr_inner, attr_inner) => true,
(attr_outer, _) => false,
(attr_inner, _) => false,
}
}
}
// doc-comments are promoted to attributes that have is_sugared_doc = true
#[auto_serialize]
type attribute_ = {style: attr_style, value: meta_item, is_sugared_doc: bool};
@ -752,6 +1180,19 @@ type trait_ref = {path: @path, ref_id: node_id, impl_id: node_id};
#[auto_serialize]
enum visibility { public, private, inherited }
impl visibility : cmp::Eq {
pure fn eq(&&other: visibility) -> bool {
match (self, other) {
(public, public) => true,
(private, private) => true,
(inherited, inherited) => true,
(public, _) => false,
(private, _) => false,
(inherited, _) => false,
}
}
}
#[auto_serialize]
type struct_field_ = {
kind: struct_field_kind,
@ -809,6 +1250,17 @@ enum item_ {
#[auto_serialize]
enum class_mutability { class_mutable, class_immutable }
impl class_mutability : cmp::Eq {
pure fn eq(&&other: class_mutability) -> bool {
match (self, other) {
(class_mutable, class_mutable) => true,
(class_immutable, class_immutable) => true,
(class_mutable, _) => false,
(class_immutable, _) => false,
}
}
}
#[auto_serialize]
type class_ctor = spanned<class_ctor_>;

View File

@ -6,7 +6,30 @@ import ast_util::{path_to_ident, stmt_id};
import diagnostic::span_handler;
import parse::token::ident_interner;
enum path_elt { path_mod(ident), path_name(ident) }
enum path_elt {
path_mod(ident),
path_name(ident)
}
impl path_elt : cmp::Eq {
pure fn eq(&&other: path_elt) -> bool {
match self {
path_mod(e0a) => {
match other {
path_mod(e0b) => e0a == e0b,
_ => false
}
}
path_name(e0a) => {
match other {
path_name(e0b) => e0a == e0b,
_ => false
}
}
}
}
}
type path = ~[path_elt];
/* FIXMEs that say "bad" are as per #2543 */

View File

@ -105,7 +105,9 @@ pure fn binop_to_method_name(op: binop) -> Option<~str> {
bitor => return Some(~"bitor"),
shl => return Some(~"shl"),
shr => return Some(~"shr"),
and | or | eq | lt | le | ne | ge | gt => return None
lt => return Some(~"lt"),
eq => return Some(~"eq"),
and | or | le | ne | ge | gt => return None
}
}

View File

@ -32,6 +32,12 @@ type filename = ~str;
type file_pos = {ch: uint, byte: uint};
impl file_pos: cmp::Eq {
pure fn eq(&&other: file_pos) -> bool {
self.ch == other.ch && self.byte == other.byte
}
}
/* A codemap is a thing that maps uints to file/line/column positions
* in a crate. This to make it possible to represent the positions
* with single-word things, rather than passing records all over the
@ -161,8 +167,15 @@ enum expn_info_ {
callie: {name: ~str, span: Option<span>}})
}
type expn_info = Option<@expn_info_>;
type span = {lo: uint, hi: uint, expn_info: expn_info};
impl span : cmp::Eq {
pure fn eq(&&other: span) -> bool {
return self.lo == other.lo && self.hi == other.hi;
}
}
fn span_to_str_no_adj(sp: span, cm: codemap) -> ~str {
let lo = lookup_char_pos(cm, sp.lo);
let hi = lookup_char_pos(cm, sp.hi);
@ -216,7 +229,7 @@ fn lookup_byte_offset(cm: codemap::codemap, chpos: uint)
fn span_to_snippet(sp: span, cm: codemap::codemap) -> ~str {
let begin = lookup_byte_offset(cm, sp.lo);
let end = lookup_byte_offset(cm, sp.hi);
assert begin.fm == end.fm;
assert begin.fm.start_pos == end.fm.start_pos;
return str::slice(*begin.fm.src, begin.pos, end.pos);
}

View File

@ -146,6 +146,12 @@ enum level {
note,
}
impl level : cmp::Eq {
pure fn eq(&&other: level) -> bool {
(self as uint) == (other as uint)
}
}
fn diagnosticstr(lvl: level) -> ~str {
match lvl {
fatal => ~"error",

View File

@ -3,8 +3,17 @@ import dvec::DVec;
import ast_builder::{path, append_types};
enum direction {
send, recv
enum direction { send, recv }
impl direction : cmp::Eq {
pure fn eq(&&other: direction) -> bool {
match (self, other) {
(send, send) => true,
(recv, recv) => true,
(send, _) => false,
(recv, _) => false,
}
}
}
impl direction: ToStr {

View File

@ -466,7 +466,12 @@ fn p_t_s_rec(cx: ext_ctxt, m: matchable, s: selector, b: binders) {
match_result {
return match m {
match_expr(e) => {
if e == pat { Some(leaf(match_exact)) } else { None }
if box::ptr_eq(e, pat) {
// XXX: Is this right?
Some(leaf(match_exact))
} else {
None
}
}
_ => cx.bug(~"broken traversal in p_t_s_r")
}

View File

@ -3563,6 +3563,13 @@ struct parser {
return cdirs;
}
}
impl restriction : cmp::Eq {
pure fn eq(&&other: restriction) -> bool {
(self as uint) == (other as uint)
}
}
//
// Local Variables:
// mode: rust

View File

@ -349,7 +349,7 @@ fn mk_ident_interner() -> ident_interner {
|x,y| str::eq(*x, *y), init_vec);
/* having multiple interners will just confuse the serializer */
unsafe{ assert task::local_data_get(interner_key!()) == None };
unsafe{ assert task::local_data_get(interner_key!()).is_none() };
unsafe{ task::local_data_set(interner_key!(), @rv) };
rv
}
@ -440,6 +440,277 @@ fn restricted_keyword_table() -> hashmap<~str, ()> {
words
}
impl binop : cmp::Eq {
pure fn eq(&&other: binop) -> bool {
(self as uint) == (other as uint)
}
}
impl token : cmp::Eq {
pure fn eq(&&other: token) -> bool {
match self {
EQ => {
match other {
EQ => true,
_ => false
}
}
LT => {
match other {
LT => true,
_ => false
}
}
LE => {
match other {
LE => true,
_ => false
}
}
EQEQ => {
match other {
EQEQ => true,
_ => false
}
}
NE => {
match other {
NE => true,
_ => false
}
}
GE => {
match other {
GE => true,
_ => false
}
}
GT => {
match other {
GT => true,
_ => false
}
}
ANDAND => {
match other {
ANDAND => true,
_ => false
}
}
OROR => {
match other {
OROR => true,
_ => false
}
}
NOT => {
match other {
NOT => true,
_ => false
}
}
TILDE => {
match other {
TILDE => true,
_ => false
}
}
BINOP(e0a) => {
match other {
BINOP(e0b) => e0a == e0b,
_ => false
}
}
BINOPEQ(e0a) => {
match other {
BINOPEQ(e0b) => e0a == e0b,
_ => false
}
}
AT => {
match other {
AT => true,
_ => false
}
}
DOT => {
match other {
DOT => true,
_ => false
}
}
DOTDOT => {
match other {
DOTDOT => true,
_ => false
}
}
ELLIPSIS => {
match other {
ELLIPSIS => true,
_ => false
}
}
COMMA => {
match other {
COMMA => true,
_ => false
}
}
SEMI => {
match other {
SEMI => true,
_ => false
}
}
COLON => {
match other {
COLON => true,
_ => false
}
}
MOD_SEP => {
match other {
MOD_SEP => true,
_ => false
}
}
RARROW => {
match other {
RARROW => true,
_ => false
}
}
LARROW => {
match other {
LARROW => true,
_ => false
}
}
DARROW => {
match other {
DARROW => true,
_ => false
}
}
FAT_ARROW => {
match other {
FAT_ARROW => true,
_ => false
}
}
LPAREN => {
match other {
LPAREN => true,
_ => false
}
}
RPAREN => {
match other {
RPAREN => true,
_ => false
}
}
LBRACKET => {
match other {
LBRACKET => true,
_ => false
}
}
RBRACKET => {
match other {
RBRACKET => true,
_ => false
}
}
LBRACE => {
match other {
LBRACE => true,
_ => false
}
}
RBRACE => {
match other {
RBRACE => true,
_ => false
}
}
POUND => {
match other {
POUND => true,
_ => false
}
}
DOLLAR => {
match other {
DOLLAR => true,
_ => false
}
}
LIT_INT(e0a, e1a) => {
match other {
LIT_INT(e0b, e1b) => e0a == e0b && e1a == e1b,
_ => false
}
}
LIT_UINT(e0a, e1a) => {
match other {
LIT_UINT(e0b, e1b) => e0a == e0b && e1a == e1b,
_ => false
}
}
LIT_INT_UNSUFFIXED(e0a) => {
match other {
LIT_INT_UNSUFFIXED(e0b) => e0a == e0b,
_ => false
}
}
LIT_FLOAT(e0a, e1a) => {
match other {
LIT_FLOAT(e0b, e1b) => e0a == e0b && e1a == e1b,
_ => false
}
}
LIT_STR(e0a) => {
match other {
LIT_STR(e0b) => e0a == e0b,
_ => false
}
}
IDENT(e0a, e1a) => {
match other {
IDENT(e0b, e1b) => e0a == e0b && e1a == e1b,
_ => false
}
}
UNDERSCORE => {
match other {
UNDERSCORE => true,
_ => false
}
}
INTERPOLATED(_) => {
match other {
INTERPOLATED(_) => true,
_ => false
}
}
DOC_COMMENT(e0a) => {
match other {
DOC_COMMENT(e0b) => e0a == e0b,
_ => false
}
}
EOF => {
match other {
EOF => true,
_ => false
}
}
}
}
}
// Local Variables:
// fill-column: 78;
// indent-tabs-mode: nil

View File

@ -55,12 +55,37 @@ import dvec::DVec;
*/
enum breaks { consistent, inconsistent, }
impl breaks : cmp::Eq {
pure fn eq(&&other: breaks) -> bool {
match (self, other) {
(consistent, consistent) => true,
(inconsistent, inconsistent) => true,
(consistent, _) => false,
(inconsistent, _) => false,
}
}
}
type break_t = {offset: int, blank_space: int};
type begin_t = {offset: int, breaks: breaks};
enum token { STRING(@~str, int), BREAK(break_t), BEGIN(begin_t), END, EOF, }
impl token {
fn is_eof() -> bool {
match self { EOF => true, _ => false }
}
fn is_hardbreak_tok() -> bool {
match self {
BREAK({offset: 0, blank_space: bs }) if bs == size_infinity =>
true,
_ =>
false
}
}
}
fn tok_str(++t: token) -> ~str {
match t {
STRING(s, len) => return fmt!("STR(%s,%d)", *s, len),

View File

@ -244,8 +244,7 @@ fn is_end(s: ps) -> bool {
}
fn is_bol(s: ps) -> bool {
return s.s.last_token() == pp::EOF ||
s.s.last_token() == pp::hardbreak_tok();
return s.s.last_token().is_eof() || s.s.last_token().is_hardbreak_tok();
}
fn in_cbox(s: ps) -> bool {
@ -260,7 +259,7 @@ fn break_offset_if_not_bol(s: ps, n: uint, off: int) {
if !is_bol(s) {
break_offset(s.s, n, off);
} else {
if off != 0 && s.s.last_token() == pp::hardbreak_tok() {
if off != 0 && s.s.last_token().is_hardbreak_tok() {
// We do something pretty sketchy here: tuck the nonzero
// offset-adjustment we were going to deposit along with the
// break into the previous hardbreak.

View File

@ -614,11 +614,7 @@ fn mk_simple_visitor(v: simple_visitor) -> vt<()> {
f(fk, decl, body, sp, id);
visit_fn(fk, decl, body, sp, id, e, v);
}
let visit_ty = if v.visit_ty == simple_ignore_ty {
|a,b,c| skip_ty(a, b, c)
} else {
|a,b,c| v_ty(v.visit_ty, a, b, c)
};
let visit_ty = |a,b,c| v_ty(v.visit_ty, a, b, c);
fn v_struct_field(f: fn@(@struct_field), sf: @struct_field, &&e: (),
v: vt<()>) {
f(sf);

View File

@ -26,6 +26,12 @@ enum output_type {
output_type_exe,
}
impl output_type : cmp::Eq {
pure fn eq(&&other: output_type) -> bool {
(self as uint) == (other as uint)
}
}
fn llvm_err(sess: session, msg: ~str) -> ! unsafe {
let cstr = llvm::LLVMRustGetLastError();
if cstr == ptr::null() {

View File

@ -136,6 +136,12 @@ enum compile_upto {
cu_everything,
}
impl compile_upto : cmp::Eq {
pure fn eq(&&other: compile_upto) -> bool {
(self as uint) == (other as uint)
}
}
fn compile_upto(sess: session, cfg: ast::crate_cfg,
input: input, upto: compile_upto,
outputs: Option<output_filenames>)

View File

@ -199,6 +199,17 @@ fn run_compiler(args: ~[~str], demitter: diagnostic::emitter) {
compile_input(sess, cfg, input, &odir, &ofile);
}
enum monitor_msg {
fatal,
done,
}
impl monitor_msg : cmp::Eq {
pure fn eq(&&other: monitor_msg) -> bool {
(self as uint) == (other as uint)
}
}
/*
This is a sanity check that any failure of the compiler is performed
through the diagnostic module and reported properly - we shouldn't be calling
@ -212,11 +223,6 @@ fails without recording a fatal error then we've encountered a compiler
bug and need to present an error.
*/
fn monitor(+f: fn~(diagnostic::emitter)) {
enum monitor_msg {
fatal,
done,
};
let p = comm::Port();
let ch = comm::Chan(p);

View File

@ -12,8 +12,20 @@ import middle::lint;
enum os { os_win32, os_macos, os_linux, os_freebsd, }
impl os : cmp::Eq {
pure fn eq(&&other: os) -> bool {
(self as uint) == (other as uint)
}
}
enum arch { arch_x86, arch_x86_64, arch_arm, }
impl arch: cmp::Eq {
pure fn eq(&&other: arch) -> bool {
(self as uint) == (other as uint)
}
}
enum crate_type { bin_crate, lib_crate, unknown_crate, }
type config =
@ -79,6 +91,12 @@ enum OptLevel {
Aggressive // -O3
}
impl OptLevel : cmp::Eq {
pure fn eq(&&other: OptLevel) -> bool {
(self as uint) == (other as uint)
}
}
type options =
// The crate config requested for the session, which may be combined
// with additional crate configurations during the compile process

View File

@ -134,7 +134,10 @@ fn is_test_fn(i: @ast::item) -> bool {
match i.node {
ast::item_fn(decl, _, tps, _) => {
let input_cnt = vec::len(decl.inputs);
let no_output = decl.output.node == ast::ty_nil;
let no_output = match decl.output.node {
ast::ty_nil => true,
_ => false
};
let tparm_cnt = vec::len(tps);
input_cnt == 0u && no_output && tparm_cnt == 0u
}

View File

@ -128,6 +128,45 @@ enum TypeKind {
X86_MMX = 15
}
impl TypeKind : cmp::Eq {
pure fn eq(&&other: TypeKind) -> bool {
match (self, other) {
(Void, Void) => true,
(Half, Half) => true,
(Float, Float) => true,
(Double, Double) => true,
(X86_FP80, X86_FP80) => true,
(FP128, FP128) => true,
(PPC_FP128, PPC_FP128) => true,
(Label, Label) => true,
(Integer, Integer) => true,
(Function, Function) => true,
(Struct, Struct) => true,
(Array, Array) => true,
(Pointer, Pointer) => true,
(Vector, Vector) => true,
(Metadata, Metadata) => true,
(X86_MMX, X86_MMX) => true,
(Void, _) => false,
(Half, _) => false,
(Float, _) => false,
(Double, _) => false,
(X86_FP80, _) => false,
(FP128, _) => false,
(PPC_FP128, _) => false,
(Label, _) => false,
(Integer, _) => false,
(Function, _) => false,
(Struct, _) => false,
(Array, _) => false,
(Pointer, _) => false,
(Vector, _) => false,
(Metadata, _) => false,
(X86_MMX, _) => false,
}
}
}
enum AtomicBinOp {
Xchg = 0,
Add = 1,

View File

@ -129,6 +129,12 @@ enum Family {
InheritedField // N
}
impl Family : cmp::Eq {
pure fn eq(&&other: Family) -> bool {
(self as uint) == (other as uint)
}
}
fn item_family(item: ebml::Doc) -> Family {
let fam = ebml::get_doc(item, tag_items_data_item_family);
match ebml::doc_as_u8(fam) as char {

View File

@ -322,10 +322,60 @@ enum bckerr_code {
err_out_of_scope(ty::region, ty::region) // superscope, subscope
}
impl bckerr_code : cmp::Eq {
pure fn eq(&&other: bckerr_code) -> bool {
match self {
err_mut_uniq => {
match other {
err_mut_uniq => true,
_ => false
}
}
err_mut_variant => {
match other {
err_mut_variant => true,
_ => false
}
}
err_root_not_permitted => {
match other {
err_root_not_permitted => true,
_ => false
}
}
err_mutbl(e0a, e1a) => {
match other {
err_mutbl(e0b, e1b) => e0a == e0b && e1a == e1b,
_ => false
}
}
err_out_of_root_scope(e0a, e1a) => {
match other {
err_out_of_root_scope(e0b, e1b) =>
e0a == e0b && e1a == e1b,
_ => false
}
}
err_out_of_scope(e0a, e1a) => {
match other {
err_out_of_scope(e0b, e1b) => e0a == e0b && e1a == e1b,
_ => false
}
}
}
}
}
// Combination of an error code and the categorization of the expression
// that caused it
type bckerr = {cmt: cmt, code: bckerr_code};
impl bckerr : cmp::Eq {
pure fn eq(&&other: bckerr) -> bool {
self.cmt == other.cmt && self.code == other.code
}
}
// shorthand for something that fails with `bckerr` or succeeds with `T`
type bckres<T> = Result<T, bckerr>;

View File

@ -36,6 +36,25 @@ enum purity_cause {
pc_cmt(bckerr)
}
impl purity_cause : cmp::Eq {
pure fn eq(&&other: purity_cause) -> bool {
match self {
pc_pure_fn => {
match other {
pc_pure_fn => true,
_ => false
}
}
pc_cmt(e0a) => {
match other {
pc_cmt(e0b) => e0a == e0b,
_ => false
}
}
}
}
}
fn check_loans(bccx: borrowck_ctxt,
req_maps: req_maps,
crate: @ast::crate) {

View File

@ -124,6 +124,22 @@ enum ctor {
range(const_val, const_val),
}
impl ctor: cmp::Eq {
pure fn eq(&&other: ctor) -> bool {
match (self, other) {
(single, single) => true,
(variant(did_self), variant(did_other)) => did_self == did_other,
(val(cv_self), val(cv_other)) => cv_self == cv_other,
(range(cv0_self, cv1_self), range(cv0_other, cv1_other)) => {
cv0_self == cv0_other && cv1_self == cv1_other
}
(single, _) | (variant(_), _) | (val(_), _) | (range(*), _) => {
false
}
}
}
}
// Algorithm from http://moscova.inria.fr/~maranget/papers/warn/index.html
//
// Whether a vector `v` of patterns is 'useful' in relation to a set of such

View File

@ -189,6 +189,20 @@ enum const_val {
const_bool(bool)
}
impl const_val: cmp::Eq {
pure fn eq(&&other: const_val) -> bool {
match (self, other) {
(const_float(a), const_float(b)) => a == b,
(const_int(a), const_int(b)) => a == b,
(const_uint(a), const_uint(b)) => a == b,
(const_str(a), const_str(b)) => a == b,
(const_bool(a), const_bool(b)) => a == b,
(const_float(_), _) | (const_int(_), _) | (const_uint(_), _) |
(const_str(_), _) | (const_bool(_), _) => false
}
}
}
// FIXME: issue #1417
fn eval_const_expr(tcx: middle::ty::ctxt, e: @expr) -> const_val {
import middle::ty;

View File

@ -63,6 +63,12 @@ enum lint {
// dead_assignment
}
impl lint : cmp::Eq {
pure fn eq(&&other: lint) -> bool {
(self as uint) == (other as uint)
}
}
fn level_to_str(lv: level) -> ~str {
match lv {
allow => ~"allow",
@ -76,6 +82,12 @@ enum level {
allow, warn, deny, forbid
}
impl level : cmp::Eq {
pure fn eq(&&other: level) -> bool {
(self as uint) == (other as uint)
}
}
type lint_spec = @{lint: lint,
desc: ~str,
default: level};

View File

@ -127,6 +127,18 @@ type last_use_map = hashmap<node_id, @DVec<node_id>>;
enum Variable = uint;
enum LiveNode = uint;
impl Variable : cmp::Eq {
pure fn eq(&&other: Variable) -> bool {
*self == *other
}
}
impl LiveNode : cmp::Eq {
pure fn eq(&&other: LiveNode) -> bool {
*self == *other
}
}
enum LiveNodeKind {
FreeVarNode(span),
ExprNode(span),
@ -134,6 +146,37 @@ enum LiveNodeKind {
ExitNode
}
impl LiveNodeKind : cmp::Eq {
pure fn eq(&&other: LiveNodeKind) -> bool {
match self {
FreeVarNode(e0a) => {
match other {
FreeVarNode(e0b) => e0a == e0b,
_ => false
}
}
ExprNode(e0a) => {
match other {
ExprNode(e0b) => e0a == e0b,
_ => false
}
}
VarDefNode(e0a) => {
match other {
VarDefNode(e0b) => e0a == e0b,
_ => false
}
}
ExitNode => {
match other {
ExitNode => true,
_ => false
}
}
}
}
}
fn check_crate(tcx: ty::ctxt,
method_map: typeck::method_map,
crate: @crate) -> last_use_map {

View File

@ -55,8 +55,106 @@ enum categorization {
cat_discr(cmt, ast::node_id), // match discriminant (see preserve())
}
impl categorization : cmp::Eq {
pure fn eq(&&other: categorization) -> bool {
match self {
cat_rvalue => {
match other {
cat_rvalue => true,
_ => false
}
}
cat_special(e0a) => {
match other {
cat_special(e0b) => e0a == e0b,
_ => false
}
}
cat_local(e0a) => {
match other {
cat_local(e0b) => e0a == e0b,
_ => false
}
}
cat_binding(e0a) => {
match other {
cat_binding(e0b) => e0a == e0b,
_ => false
}
}
cat_arg(e0a) => {
match other {
cat_arg(e0b) => e0a == e0b,
_ => false
}
}
cat_stack_upvar(e0a) => {
match other {
cat_stack_upvar(e0b) => e0a == e0b,
_ => false
}
}
cat_deref(e0a, e1a, e2a) => {
match other {
cat_deref(e0b, e1b, e2b) =>
e0a == e0b && e1a == e1b && e2a == e2b,
_ => false
}
}
cat_comp(e0a, e1a) => {
match other {
cat_comp(e0b, e1b) => e0a == e0b && e1a == e1b,
_ => false
}
}
cat_discr(e0a, e1a) => {
match other {
cat_discr(e0b, e1b) => e0a == e0b && e1a == e1b,
_ => false
}
}
}
}
}
// different kinds of pointers:
enum ptr_kind {uniq_ptr, gc_ptr, region_ptr(ty::region), unsafe_ptr}
enum ptr_kind {
uniq_ptr,
gc_ptr,
region_ptr(ty::region),
unsafe_ptr
}
impl ptr_kind : cmp::Eq {
pure fn eq(&&other: ptr_kind) -> bool {
match self {
uniq_ptr => {
match other {
uniq_ptr => true,
_ => false
}
}
gc_ptr => {
match other {
gc_ptr => true,
_ => false
}
}
region_ptr(e0a) => {
match other {
region_ptr(e0b) => e0a == e0b,
_ => false
}
}
unsafe_ptr => {
match other {
unsafe_ptr => true,
_ => false
}
}
}
}
}
// I am coining the term "components" to mean "pieces of a data
// structure accessible without a dereference":
@ -69,6 +167,37 @@ enum comp_kind {
ast::mutability) // mutability of vec content
}
impl comp_kind : cmp::Eq {
pure fn eq(&&other: comp_kind) -> bool {
match self {
comp_tuple => {
match other {
comp_tuple => true,
_ => false
}
}
comp_variant(e0a) => {
match other {
comp_variant(e0b) => e0a == e0b,
_ => false
}
}
comp_field(e0a, e1a) => {
match other {
comp_field(e0b, e1b) => e0a == e0b && e1a == e1b,
_ => false
}
}
comp_index(e0a, e1a) => {
match other {
comp_index(e0b, e1b) => e0a == e0b && e1a == e1b,
_ => false
}
}
}
}
}
// different kinds of expressions we might evaluate
enum special_kind {
sk_method,
@ -77,16 +206,35 @@ enum special_kind {
sk_heap_upvar
}
impl special_kind : cmp::Eq {
pure fn eq(&&other: special_kind) -> bool {
(self as uint) == (other as uint)
}
}
// a complete categorization of a value indicating where it originated
// and how it is located, as well as the mutability of the memory in
// which the value is stored.
type cmt = @{id: ast::node_id, // id of expr/pat producing this value
type cmt_ = {id: ast::node_id, // id of expr/pat producing this value
span: span, // span of same expr/pat
cat: categorization, // categorization of expr
lp: Option<@loan_path>, // loan path for expr, if any
mutbl: ast::mutability, // mutability of expr as lvalue
ty: ty::t}; // type of the expr
type cmt = @cmt_;
impl cmt_ : cmp::Eq {
pure fn eq(&&other: cmt_) -> bool {
self.id == other.id &&
self.span == other.span &&
self.cat == other.cat &&
self.lp == other.lp &&
self.mutbl == other.mutbl &&
self.ty == other.ty
}
}
// a loan path is like a category, but it exists only when the data is
// interior to the stack frame. loan paths are used as the key to a
// map indicating what is borrowed at any point in time.
@ -97,6 +245,37 @@ enum loan_path {
lp_comp(@loan_path, comp_kind)
}
impl loan_path : cmp::Eq {
pure fn eq(&&other: loan_path) -> bool {
match self {
lp_local(e0a) => {
match other {
lp_local(e0b) => e0a == e0b,
_ => false
}
}
lp_arg(e0a) => {
match other {
lp_arg(e0b) => e0a == e0b,
_ => false
}
}
lp_deref(e0a, e1a) => {
match other {
lp_deref(e0b, e1b) => e0a == e0b && e1a == e1b,
_ => false
}
}
lp_comp(e0a, e1a) => {
match other {
lp_comp(e0b, e1b) => e0a == e0b && e1a == e1b,
_ => false
}
}
}
}
}
// We pun on *T to mean both actual deref of a ptr as well
// as accessing of components:
enum deref_kind {deref_ptr(ptr_kind), deref_comp(comp_kind)}

View File

@ -370,6 +370,12 @@ type region_paramd_items = hashmap<ast::node_id, region_variance>;
type region_dep = {ambient_variance: region_variance, id: ast::node_id};
type dep_map = hashmap<ast::node_id, @DVec<region_dep>>;
impl region_dep: cmp::Eq {
pure fn eq(&&other: region_dep) -> bool {
self.ambient_variance == other.ambient_variance && self.id == other.id
}
}
type determine_rp_ctxt_ = {
sess: session,
ast_map: ast_map::map,

View File

@ -110,6 +110,13 @@ enum PatternBindingMode {
IrrefutableMode
}
impl PatternBindingMode : cmp::Eq {
pure fn eq(&&other: PatternBindingMode) -> bool {
(self as uint) == (other as uint)
}
}
enum Namespace {
ModuleNS,
TypeNS,
@ -122,6 +129,15 @@ enum NamespaceResult {
BoundResult(@Module, @NameBindings)
}
impl NamespaceResult {
pure fn is_unknown() -> bool {
match self {
UnknownResult => true,
_ => false
}
}
}
enum NameDefinition {
NoNameDefinition, //< The name was unbound.
ChildNameDefinition(def), //< The name identifies an immediate child.
@ -134,6 +150,12 @@ enum Mutability {
Immutable
}
impl Mutability : cmp::Eq {
pure fn eq(&&other: Mutability) -> bool {
(self as uint) == (other as uint)
}
}
enum SelfBinding {
NoSelfBinding,
HasSelfBinding(node_id)
@ -151,6 +173,12 @@ enum ModuleDef {
ModuleDef(@Module), // Defines a module.
}
impl ModuleDef {
pure fn is_none() -> bool {
match self { NoModuleDef => true, _ => false }
}
}
/// Contains data for specific types of import directives.
enum ImportDirectiveSubclass {
SingleImport(Atom /* target */, Atom /* source */),
@ -231,11 +259,23 @@ enum XrayFlag {
Xray //< Private items can be accessed.
}
impl XrayFlag : cmp::Eq {
pure fn eq(&&other: XrayFlag) -> bool {
(self as uint) == (other as uint)
}
}
enum AllowCapturingSelfFlag {
AllowCapturingSelf, //< The "self" definition can be captured.
DontAllowCapturingSelf, //< The "self" definition cannot be captured.
}
impl AllowCapturingSelfFlag : cmp::Eq {
pure fn eq(&&other: AllowCapturingSelfFlag) -> bool {
(self as uint) == (other as uint)
}
}
enum EnumVariantOrConstResolution {
FoundEnumVariant(def),
FoundConst,
@ -425,6 +465,12 @@ enum Privacy {
Public
}
impl Privacy : cmp::Eq {
pure fn eq(&&other: Privacy) -> bool {
(self as uint) == (other as uint)
}
}
// Records a possibly-private definition.
struct Definition {
privacy: Privacy;
@ -456,7 +502,7 @@ struct NameBindings {
/// Creates a new module in this set of name bindings.
fn define_module(parent_link: ParentLink, def_id: Option<def_id>,
sp: span) {
if self.module_def == NoModuleDef {
if self.module_def.is_none() {
let module_ = @Module(parent_link, def_id);
self.module_def = ModuleDef(module_);
self.module_span = Some(sp);
@ -1778,13 +1824,13 @@ struct Resolver {
// therefore accurately report that the names are
// unbound.
if module_result == UnknownResult {
if module_result.is_unknown() {
module_result = UnboundResult;
}
if value_result == UnknownResult {
if value_result.is_unknown() {
value_result = UnboundResult;
}
if type_result == UnknownResult {
if type_result.is_unknown() {
type_result = UnboundResult;
}
}
@ -1812,15 +1858,15 @@ struct Resolver {
// The name is an import which has been fully
// resolved. We can, therefore, just follow it.
if module_result == UnknownResult {
if module_result.is_unknown() {
module_result = get_binding(import_resolution,
ModuleNS);
}
if value_result == UnknownResult {
if value_result.is_unknown() {
value_result = get_binding(import_resolution,
ValueNS);
}
if type_result == UnknownResult {
if type_result.is_unknown() {
type_result = get_binding(import_resolution,
TypeNS);
}
@ -4295,6 +4341,14 @@ struct Resolver {
self.add_fixed_trait_for_expr(expr.id,
self.lang_items.shr_trait);
}
expr_binary(lt, _, _) => {
self.add_fixed_trait_for_expr(expr.id,
self.lang_items.ord_trait);
}
expr_binary(eq, _, _) => {
self.add_fixed_trait_for_expr(expr.id,
self.lang_items.eq_trait);
}
expr_unary(neg, _) => {
self.add_fixed_trait_for_expr(expr.id,
self.lang_items.neg_trait);

View File

@ -443,6 +443,14 @@ fn pick_col(m: match_) -> uint {
return best_col;
}
enum branch_kind { no_branch, single, switch, compare, }
impl branch_kind : cmp::Eq {
pure fn eq(&&other: branch_kind) -> bool {
(self as uint) == (other as uint)
}
}
fn compile_submatch(bcx: block, m: match_, vals: ~[ValueRef],
chk: Option<mk_fail>, &exits: ~[exit_node]) {
/*
@ -612,7 +620,6 @@ fn compile_submatch(bcx: block, m: match_, vals: ~[ValueRef],
// Decide what kind of branch we need
let opts = get_options(ccx, m, col);
enum branch_kind { no_branch, single, switch, compare, }
let mut kind = no_branch;
let mut test_val = val;
if opts.len() > 0u {

View File

@ -65,6 +65,19 @@ enum dest {
ignore,
}
impl dest : cmp::Eq {
pure fn eq(&&other: dest) -> bool {
match (self, other) {
(by_val(e0a), by_val(e0b)) => e0a == e0b,
(save_in(e0a), save_in(e0b)) => e0a == e0b,
(ignore, ignore) => true,
(by_val(*), _) => false,
(save_in(*), _) => false,
(ignore, _) => false,
}
}
}
fn dest_str(ccx: @crate_ctxt, d: dest) -> ~str {
match d {
by_val(v) => fmt!("by_val(%s)", val_str(ccx.tn, *v)),
@ -1448,6 +1461,17 @@ fn memmove_ty(bcx: block, dst: ValueRef, src: ValueRef, t: ty::t) {
enum copy_action { INIT, DROP_EXISTING, }
impl copy_action : cmp::Eq {
pure fn eq(&&other: copy_action) -> bool {
match (self, other) {
(INIT, INIT) => true,
(DROP_EXISTING, DROP_EXISTING) => true,
(INIT, _) => false,
(DROP_EXISTING, _) => false,
}
}
}
// These are the types that are passed by pointer.
fn type_is_structural_or_param(t: ty::t) -> bool {
if ty::type_is_structural(t) { return true; }
@ -2058,6 +2082,20 @@ enum lval_kind {
lv_owned, //< Non-temporary value passed by pointer
lv_owned_imm, //< Non-temporary value passed by value
}
impl lval_kind : cmp::Eq {
pure fn eq(&&other: lval_kind) -> bool {
match (self, other) {
(lv_temporary, lv_temporary) => true,
(lv_owned, lv_owned) => true,
(lv_owned_imm, lv_owned_imm) => true,
(lv_temporary, _) => false,
(lv_owned, _) => false,
(lv_owned_imm, _) => false,
}
}
}
type local_var_result = {val: ValueRef, kind: lval_kind};
type lval_result = {bcx: block, val: ValueRef, kind: lval_kind};
enum callee_env {
@ -2879,8 +2917,31 @@ fn float_cast(bcx: block, lldsttype: TypeRef, llsrctype: TypeRef,
} else { llsrc };
}
enum cast_kind { cast_pointer, cast_integral, cast_float,
cast_enum, cast_other, }
enum cast_kind {
cast_pointer,
cast_integral,
cast_float,
cast_enum,
cast_other,
}
impl cast_kind : cmp::Eq {
pure fn eq(&&other: cast_kind) -> bool {
match (self, other) {
(cast_pointer, cast_pointer) => true,
(cast_integral, cast_integral) => true,
(cast_float, cast_float) => true,
(cast_enum, cast_enum) => true,
(cast_other, cast_other) => true,
(cast_pointer, _) => false,
(cast_integral, _) => false,
(cast_float, _) => false,
(cast_enum, _) => false,
(cast_other, _) => false,
}
}
}
fn cast_type_kind(t: ty::t) -> cast_kind {
match ty::get(t).struct {
ty::ty_float(*) => cast_float,

View File

@ -996,7 +996,34 @@ enum mono_param_id {
mono_any,
mono_repr(uint /* size */, uint /* align */),
}
type mono_id = @{def: ast::def_id, params: ~[mono_param_id]};
type mono_id_ = {def: ast::def_id, params: ~[mono_param_id]};
type mono_id = @mono_id_;
impl mono_param_id: cmp::Eq {
pure fn eq(&&other: mono_param_id) -> bool {
match (self, other) {
(mono_precise(ty_a, ids_a), mono_precise(ty_b, ids_b)) => {
ty_a == ty_b && ids_a == ids_b
}
(mono_any, mono_any) => true,
(mono_repr(size_a, align_a), mono_repr(size_b, align_b)) => {
size_a == size_b && align_a == align_b
}
(mono_precise(*), _) => false,
(mono_any, _) => false,
(mono_repr(*), _) => false
}
}
}
impl mono_id_: cmp::Eq {
pure fn eq(&&other: mono_id_) -> bool {
return self.def == other.def && self.params == other.params;
}
}
pure fn hash_mono_id(mi: &mono_id) -> uint {
let mut h = syntax::ast_util::hash_def(&mi.def);
for vec::each(mi.params) |param| {
@ -1084,6 +1111,25 @@ fn dummy_substs(tps: ~[ty::t]) -> ty::substs {
tps: tps}
}
impl cleantype : cmp::Eq {
pure fn eq(&&other: cleantype) -> bool {
match self {
normal_exit_only => {
match other {
normal_exit_only => true,
_ => false
}
}
normal_exit_and_unwind => {
match other {
normal_exit_and_unwind => true,
_ => false
}
}
}
}
}
//
// Local Variables:
// mode: rust

View File

@ -37,6 +37,12 @@ enum x86_64_reg_class {
memory_class
}
impl x86_64_reg_class: cmp::Eq {
pure fn eq(&&other: x86_64_reg_class) -> bool {
(self as uint) == (other as uint)
}
}
fn is_sse(++c: x86_64_reg_class) -> bool {
return match c {
sse_fs_class | sse_fv_class |

View File

@ -227,6 +227,12 @@ type creader_cache = hashmap<{cnum: int, pos: uint, len: uint}, t>;
type intern_key = {struct: sty, o_def_id: Option<ast::def_id>};
impl intern_key: cmp::Eq {
pure fn eq(&&other: intern_key) -> bool {
self.struct == other.struct && self.o_def_id == other.o_def_id
}
}
enum ast_ty_to_ty_cache_entry {
atttce_unresolved, /* not resolved yet */
atttce_resolved(t) /* resolved to a type, irrespective of region */
@ -238,6 +244,19 @@ type opt_region_variance = Option<region_variance>;
#[auto_serialize]
enum region_variance { rv_covariant, rv_invariant, rv_contravariant }
impl region_variance: cmp::Eq {
pure fn eq(&&other: region_variance) -> bool {
match (self, other) {
(rv_covariant, rv_covariant) => true,
(rv_invariant, rv_invariant) => true,
(rv_contravariant, rv_contravariant) => true,
(rv_covariant, _) => false,
(rv_invariant, _) => false,
(rv_contravariant, _) => false
}
}
}
// N.B.: Borrows from inlined content are not accurately deserialized. This
// is because we don't need the details in trans, we only care if there is an
// entry in the table or not.
@ -246,6 +265,12 @@ type borrow = {
mutbl: ast::mutability
};
impl borrow : cmp::Eq {
pure fn eq(&&other: borrow) -> bool {
self.region == other.region && self.mutbl == other.mutbl
}
}
type ctxt =
@{diag: syntax::diagnostic::span_handler,
interner: hashmap<intern_key, t_box>,
@ -335,11 +360,36 @@ enum closure_kind {
ck_uniq,
}
impl closure_kind : cmp::Eq {
pure fn eq(&&other: closure_kind) -> bool {
(self as uint) == (other as uint)
}
}
enum fn_proto {
proto_bare, // supertype of all other protocols
proto_vstore(vstore)
}
impl fn_proto : cmp::Eq {
pure fn eq(&&other: fn_proto) -> bool {
match self {
proto_bare => {
match other {
proto_bare => true,
_ => false
}
}
proto_vstore(e0a) => {
match other {
proto_vstore(e0b) => e0a == e0b,
_ => false
}
}
}
}
}
/// Innards of a function type:
///
/// - `purity` is the function's effect (pure, impure, unsafe).
@ -357,6 +407,12 @@ type fn_ty = {purity: ast::purity,
type param_ty = {idx: uint, def_id: def_id};
impl param_ty: cmp::Eq {
pure fn eq(&&other: param_ty) -> bool {
self.idx == other.idx && self.def_id == other.def_id
}
}
/// Representation of regions:
enum region {
/// Bound regions are found (primarily) in function types. They indicate
@ -3272,12 +3328,12 @@ fn is_binopable(_cx: ctxt, ty: t, op: ast::binop) -> bool {
/*. add, shift, bit
. sub, rel, logic
. mult, eq, */
/*other*/ ~[f, f, f, f, t, t, f, f],
/*other*/ ~[f, f, f, f, f, f, f, f],
/*bool*/ ~[f, f, f, f, t, t, t, t],
/*int*/ ~[t, t, t, t, t, t, t, f],
/*float*/ ~[t, t, t, f, t, t, f, f],
/*bot*/ ~[f, f, f, f, t, t, f, f],
/*struct*/ ~[t, t, t, t, t, t, t, t]];
/*bot*/ ~[f, f, f, f, f, f, f, f],
/*struct*/ ~[t, t, t, t, f, f, t, t]];
return tbl[tycat(ty)][opcat(op)];
}
@ -3416,6 +3472,367 @@ pure fn determine_inherited_purity(parent_purity: ast::purity,
} else { child_purity }
}
impl mt : cmp::Eq {
pure fn eq(&&other: mt) -> bool {
self.ty == other.ty && self.mutbl == other.mutbl
}
}
impl arg : cmp::Eq {
pure fn eq(&&other: arg) -> bool {
self.mode == other.mode && self.ty == other.ty
}
}
impl field : cmp::Eq {
pure fn eq(&&other: field) -> bool {
self.ident == other.ident && self.mt == other.mt
}
}
impl vstore : cmp::Eq {
pure fn eq(&&other: vstore) -> bool {
match self {
vstore_fixed(e0a) => {
match other {
vstore_fixed(e0b) => e0a == e0b,
_ => false
}
}
vstore_uniq => {
match other {
vstore_uniq => true,
_ => false
}
}
vstore_box => {
match other {
vstore_box => true,
_ => false
}
}
vstore_slice(e0a) => {
match other {
vstore_slice(e0b) => e0a == e0b,
_ => false
}
}
}
}
}
impl fn_ty : cmp::Eq {
pure fn eq(&&other: fn_ty) -> bool {
self.purity == other.purity &&
self.proto == other.proto &&
self.bounds == other.bounds &&
self.inputs == other.inputs &&
self.output == other.output &&
self.ret_style == other.ret_style
}
}
impl tv_vid: cmp::Eq {
pure fn eq(&&other: tv_vid) -> bool {
*self == *other
}
}
impl tvi_vid: cmp::Eq {
pure fn eq(&&other: tvi_vid) -> bool {
*self == *other
}
}
impl region_vid: cmp::Eq {
pure fn eq(&&other: region_vid) -> bool {
*self == *other
}
}
impl region : cmp::Eq {
pure fn eq(&&other: region) -> bool {
match self {
re_bound(e0a) => {
match other {
re_bound(e0b) => e0a == e0b,
_ => false
}
}
re_free(e0a, e1a) => {
match other {
re_free(e0b, e1b) => e0a == e0b && e1a == e1b,
_ => false
}
}
re_scope(e0a) => {
match other {
re_scope(e0b) => e0a == e0b,
_ => false
}
}
re_static => {
match other {
re_static => true,
_ => false
}
}
re_var(e0a) => {
match other {
re_var(e0b) => e0a == e0b,
_ => false
}
}
}
}
}
impl bound_region : cmp::Eq {
pure fn eq(&&other: bound_region) -> bool {
match self {
br_self => {
match other {
br_self => true,
_ => false
}
}
br_anon(e0a) => {
match other {
br_anon(e0b) => e0a == e0b,
_ => false
}
}
br_named(e0a) => {
match other {
br_named(e0b) => e0a == e0b,
_ => false
}
}
br_cap_avoid(e0a, e1a) => {
match other {
br_cap_avoid(e0b, e1b) => e0a == e0b && e1a == e1b,
_ => false
}
}
}
}
}
impl substs : cmp::Eq {
pure fn eq(&&other: substs) -> bool {
self.self_r == other.self_r &&
self.self_ty == other.self_ty &&
self.tps == other.tps
}
}
impl sty : cmp::Eq {
pure fn eq(&&other: sty) -> bool {
match self {
ty_nil => {
match other {
ty_nil => true,
_ => false
}
}
ty_bot => {
match other {
ty_bot => true,
_ => false
}
}
ty_bool => {
match other {
ty_bool => true,
_ => false
}
}
ty_int(e0a) => {
match other {
ty_int(e0b) => e0a == e0b,
_ => false
}
}
ty_uint(e0a) => {
match other {
ty_uint(e0b) => e0a == e0b,
_ => false
}
}
ty_float(e0a) => {
match other {
ty_float(e0b) => e0a == e0b,
_ => false
}
}
ty_estr(e0a) => {
match other {
ty_estr(e0b) => e0a == e0b,
_ => false
}
}
ty_enum(e0a, e1a) => {
match other {
ty_enum(e0b, e1b) => e0a == e0b && e1a == e1b,
_ => false
}
}
ty_box(e0a) => {
match other {
ty_box(e0b) => e0a == e0b,
_ => false
}
}
ty_uniq(e0a) => {
match other {
ty_uniq(e0b) => e0a == e0b,
_ => false
}
}
ty_evec(e0a, e1a) => {
match other {
ty_evec(e0b, e1b) => e0a == e0b && e1a == e1b,
_ => false
}
}
ty_ptr(e0a) => {
match other {
ty_ptr(e0b) => e0a == e0b,
_ => false
}
}
ty_rptr(e0a, e1a) => {
match other {
ty_rptr(e0b, e1b) => e0a == e0b && e1a == e1b,
_ => false
}
}
ty_rec(e0a) => {
match other {
ty_rec(e0b) => e0a == e0b,
_ => false
}
}
ty_fn(e0a) => {
match other {
ty_fn(e0b) => e0a == e0b,
_ => false
}
}
ty_trait(e0a, e1a, e2a) => {
match other {
ty_trait(e0b, e1b, e2b) =>
e0a == e0b && e1a == e1b && e2a == e2b,
_ => false
}
}
ty_class(e0a, e1a) => {
match other {
ty_class(e0b, e1b) => e0a == e0b && e1a == e1b,
_ => false
}
}
ty_tup(e0a) => {
match other {
ty_tup(e0b) => e0a == e0b,
_ => false
}
}
ty_var(e0a) => {
match other {
ty_var(e0b) => e0a == e0b,
_ => false
}
}
ty_var_integral(e0a) => {
match other {
ty_var_integral(e0b) => e0a == e0b,
_ => false
}
}
ty_param(e0a) => {
match other {
ty_param(e0b) => e0a == e0b,
_ => false
}
}
ty_self => {
match other {
ty_self => true,
_ => false
}
}
ty_type => {
match other {
ty_type => true,
_ => false
}
}
ty_opaque_box => {
match other {
ty_opaque_box => true,
_ => false
}
}
ty_opaque_closure_ptr(e0a) => {
match other {
ty_opaque_closure_ptr(e0b) => e0a == e0b,
_ => false
}
}
ty_unboxed_vec(e0a) => {
match other {
ty_unboxed_vec(e0b) => e0a == e0b,
_ => false
}
}
}
}
}
impl param_bound : cmp::Eq {
pure fn eq(&&other: param_bound) -> bool {
match self {
bound_copy => {
match other {
bound_copy => true,
_ => false
}
}
bound_owned => {
match other {
bound_owned => true,
_ => false
}
}
bound_send => {
match other {
bound_send => true,
_ => false
}
}
bound_const => {
match other {
bound_const => true,
_ => false
}
}
bound_trait(e0a) => {
match other {
bound_trait(e0b) => e0a == e0b,
_ => false
}
}
}
}
}
impl kind : cmp::Eq {
pure fn eq(&&other: kind) -> bool {
*self == *other
}
}
// Local Variables:
// mode: rust

View File

@ -1102,6 +1102,15 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
let tcx = fcx.ccx.tcx;
let lhs_bot = check_expr(fcx, lhs, None);
let lhs_t = fcx.expr_ty(lhs);
// Hack: Unify the two sides if this is a relational operator.
match op {
ast::eq | ast::lt | ast::le | ast::ne | ast::ge | ast::gt => {
check_expr_with(fcx, rhs, lhs_t);
}
_ => {}
}
let lhs_t = structurally_resolved_type(fcx, lhs.span, lhs_t);
return match (op, ty::get(lhs_t).struct) {
(_, _) if ty::type_is_integral(lhs_t) &&
@ -1118,19 +1127,12 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
let tvar = fcx.infcx().next_ty_var();
demand::suptype(fcx, expr.span, tvar, lhs_t);
let rhs_bot = check_expr_with(fcx, rhs, tvar);
let rhs_t = match op {
let result_t = match op {
ast::eq | ast::lt | ast::le | ast::ne | ast::ge |
ast::gt => {
// these comparison operators are handled in a
// separate case below.
tcx.sess.span_bug(
expr.span,
fmt!("comparison operator in expr_binop: %s",
ast_util::binop_to_str(op)));
}
ast::gt => ty::mk_bool(fcx.ccx.tcx),
_ => lhs_t
};
fcx.write_ty(expr.id, rhs_t);
fcx.write_ty(expr.id, result_t);
if !ast_util::lazy_binop(op) { lhs_bot | rhs_bot }
else { lhs_bot }
}
@ -1424,9 +1426,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
// complicated trait requirements, fail without this---I think this code
// can be removed if we improve trait resolution to be more eager when
// possible.
ast::expr_binary(ast::eq, lhs, rhs) |
ast::expr_binary(ast::ne, lhs, rhs) |
ast::expr_binary(ast::lt, lhs, rhs) |
ast::expr_binary(ast::le, lhs, rhs) |
ast::expr_binary(ast::gt, lhs, rhs) |
ast::expr_binary(ast::ge, lhs, rhs) => {

View File

@ -265,6 +265,7 @@ import ast::{m_const, m_imm, m_mutbl};
import dvec::DVec;
import region_var_bindings::{RegionVarBindings};
import ast_util::dummy_sp;
import cmp::Eq;
// From submodules:
import resolve::{resolve_nested_tvar, resolve_rvar, resolve_ivar, resolve_all,
@ -473,7 +474,7 @@ trait cres_helpers<T> {
fn compare(t: T, f: fn() -> ty::type_err) -> cres<T>;
}
impl<T:copy> cres<T>: cres_helpers<T> {
impl<T:copy Eq> cres<T>: cres_helpers<T> {
fn to_ures() -> ures {
match self {
Ok(_v) => Ok(()),

View File

@ -329,11 +329,36 @@ enum Constraint {
ConstrainVarSubReg(region_vid, region)
}
impl Constraint: cmp::Eq {
pure fn eq(&&other: Constraint) -> bool {
match (self, other) {
(ConstrainVarSubVar(v0a, v1a), ConstrainVarSubVar(v0b, v1b)) => {
v0a == v0b && v1a == v1b
}
(ConstrainRegSubVar(ra, va), ConstrainRegSubVar(rb, vb)) => {
ra == rb && va == vb
}
(ConstrainVarSubReg(va, ra), ConstrainVarSubReg(vb, rb)) => {
va == vb && ra == rb
}
(ConstrainVarSubVar(*), _) => false,
(ConstrainRegSubVar(*), _) => false,
(ConstrainVarSubReg(*), _) => false
}
}
}
struct TwoRegions {
a: region;
b: region;
}
impl TwoRegions: cmp::Eq {
pure fn eq(&&other: TwoRegions) -> bool {
self.a == other.a && self.b == other.b
}
}
enum UndoLogEntry {
Snapshot,
AddVar(region_vid),
@ -724,8 +749,20 @@ priv impl RegionVarBindings {
enum Direction { Incoming = 0, Outgoing = 1 }
impl Direction : cmp::Eq {
pure fn eq(&&other: Direction) -> bool {
(self as uint) == (other as uint)
}
}
enum Classification { Expanding, Contracting }
impl Classification : cmp::Eq {
pure fn eq(&&other: Classification) -> bool {
(self as uint) == (other as uint)
}
}
enum GraphNodeValue { NoValue, Value(region), ErrorValue }
struct GraphNode {

View File

@ -18,6 +18,12 @@ enum output_format {
pandoc_html
}
impl output_format : cmp::Eq {
pure fn eq(&&other: output_format) -> bool {
(self as uint) == (other as uint)
}
}
/// How to organize the output
enum output_style {
/// All in a single document
@ -26,6 +32,12 @@ enum output_style {
doc_per_mod
}
impl output_style : cmp::Eq {
pure fn eq(&&other: output_style) -> bool {
(self as uint) == (other as uint)
}
}
/// The configuration for a rustdoc session
type config = {
input_crate: Path,

View File

@ -6,20 +6,58 @@ type doc_ = {
pages: ~[page]
};
impl doc_ : cmp::Eq {
pure fn eq(&&other: doc_) -> bool {
self.pages == other.pages
}
}
enum doc {
doc_(doc_)
}
impl doc : cmp::Eq {
pure fn eq(&&other: doc) -> bool {
*self == *other
}
}
enum page {
cratepage(cratedoc),
itempage(itemtag)
}
impl page : cmp::Eq {
pure fn eq(&&other: page) -> bool {
match self {
cratepage(e0a) => {
match other {
cratepage(e0b) => e0a == e0b,
_ => false
}
}
itempage(e0a) => {
match other {
itempage(e0b) => e0a == e0b,
_ => false
}
}
}
}
}
enum implementation {
required,
provided,
}
impl implementation : cmp::Eq {
pure fn eq(&&other: implementation) -> bool {
(self as uint) == (other as uint)
}
}
/**
* Most rustdocs can be parsed into 'sections' according to their markdown
* headers
@ -29,6 +67,12 @@ type section = {
body: ~str
};
impl section : cmp::Eq {
pure fn eq(&&other: section) -> bool {
self.header == other.header && self.body == other.body
}
}
// FIXME (#2596): We currently give topmod the name of the crate. There
// would probably be fewer special cases if the crate had its own name
// and topmod's name was the empty string.
@ -36,6 +80,12 @@ type cratedoc = {
topmod: moddoc,
};
impl cratedoc : cmp::Eq {
pure fn eq(&&other: cratedoc) -> bool {
self.topmod == other.topmod
}
}
enum itemtag {
modtag(moddoc),
nmodtag(nmoddoc),
@ -47,6 +97,61 @@ enum itemtag {
tytag(tydoc)
}
impl itemtag : cmp::Eq {
pure fn eq(&&other: itemtag) -> bool {
match self {
modtag(e0a) => {
match other {
modtag(e0b) => e0a == e0b,
_ => false
}
}
nmodtag(e0a) => {
match other {
nmodtag(e0b) => e0a == e0b,
_ => false
}
}
consttag(e0a) => {
match other {
consttag(e0b) => e0a == e0b,
_ => false
}
}
fntag(e0a) => {
match other {
fntag(e0b) => e0a == e0b,
_ => false
}
}
enumtag(e0a) => {
match other {
enumtag(e0b) => e0a == e0b,
_ => false
}
}
traittag(e0a) => {
match other {
traittag(e0b) => e0a == e0b,
_ => false
}
}
impltag(e0a) => {
match other {
impltag(e0b) => e0a == e0b,
_ => false
}
}
tytag(e0a) => {
match other {
tytag(e0b) => e0a == e0b,
_ => false
}
}
}
}
}
type itemdoc = {
id: ast_id,
name: ~str,
@ -58,27 +163,67 @@ type itemdoc = {
reexport: bool
};
impl itemdoc : cmp::Eq {
pure fn eq(&&other: itemdoc) -> bool {
self.id == other.id &&
self.name == other.name &&
self.path == other.path &&
self.brief == other.brief &&
self.desc == other.desc &&
self.sections == other.sections &&
self.reexport == other.reexport
}
}
type simpleitemdoc = {
item: itemdoc,
sig: Option<~str>
};
impl simpleitemdoc : cmp::Eq {
pure fn eq(&&other: simpleitemdoc) -> bool {
self.item == other.item && self.sig == other.sig
}
}
type moddoc_ = {
item: itemdoc,
items: ~[itemtag],
index: Option<index>
};
impl moddoc_ : cmp::Eq {
pure fn eq(&&other: moddoc_) -> bool {
self.item == other.item &&
self.items == other.items &&
self.index == other.index
}
}
enum moddoc {
moddoc_(moddoc_)
}
impl moddoc : cmp::Eq {
pure fn eq(&&other: moddoc) -> bool {
*self == *other
}
}
type nmoddoc = {
item: itemdoc,
fns: ~[fndoc],
index: Option<index>
};
impl nmoddoc : cmp::Eq {
pure fn eq(&&other: nmoddoc) -> bool {
self.item == other.item &&
self.fns == other.fns &&
self.index == other.index
}
}
type constdoc = simpleitemdoc;
type fndoc = simpleitemdoc;
@ -88,17 +233,37 @@ type enumdoc = {
variants: ~[variantdoc]
};
impl enumdoc : cmp::Eq {
pure fn eq(&&other: enumdoc) -> bool {
self.item == other.item && self.variants == other.variants
}
}
type variantdoc = {
name: ~str,
desc: Option<~str>,
sig: Option<~str>
};
impl variantdoc : cmp::Eq {
pure fn eq(&&other: variantdoc) -> bool {
self.name == other.name &&
self.desc == other.desc &&
self.sig == other.sig
}
}
type traitdoc = {
item: itemdoc,
methods: ~[methoddoc]
};
impl traitdoc : cmp::Eq {
pure fn eq(&&other: traitdoc) -> bool {
self.item == other.item && self.methods == other.methods
}
}
type methoddoc = {
name: ~str,
brief: Option<~str>,
@ -108,6 +273,17 @@ type methoddoc = {
implementation: implementation,
};
impl methoddoc : cmp::Eq {
pure fn eq(&&other: methoddoc) -> bool {
self.name == other.name &&
self.brief == other.brief &&
self.desc == other.desc &&
self.sections == other.sections &&
self.sig == other.sig &&
self.implementation == other.implementation
}
}
type impldoc = {
item: itemdoc,
trait_types: ~[~str],
@ -115,12 +291,27 @@ type impldoc = {
methods: ~[methoddoc]
};
impl impldoc : cmp::Eq {
pure fn eq(&&other: impldoc) -> bool {
self.item == other.item &&
self.trait_types == other.trait_types &&
self.self_ty == other.self_ty &&
self.methods == other.methods
}
}
type tydoc = simpleitemdoc;
type index = {
entries: ~[index_entry]
};
impl index : cmp::Eq {
pure fn eq(&&other: index) -> bool {
self.entries == other.entries
}
}
/**
* A single entry in an index
*
@ -138,6 +329,15 @@ type index_entry = {
link: ~str
};
impl index_entry : cmp::Eq {
pure fn eq(&&other: index_entry) -> bool {
self.kind == other.kind &&
self.name == other.name &&
self.brief == other.brief &&
self.link == other.link
}
}
impl doc {
fn cratedoc() -> cratedoc {
option::get(vec::foldl(None, self.pages, |_m, page| {

View File

@ -2,5 +2,5 @@ fn main() {
fn f() { }
fn g(i: int) { }
let x = f == g;
//~^ ERROR expected `fn()` but found `fn(int)`
//~^ ERROR binary operation == cannot be applied to type
}

View File

@ -1,7 +1,8 @@
use std;
import option;
import cmp::Eq;
fn f<T>(&o: Option<T>) {
fn f<T:Eq>(&o: Option<T>) {
assert o == option::None;
}
@ -9,4 +10,4 @@ fn main() {
f::<int>(option::None);
//~^ ERROR taking mut reference to static item
//~^^ ERROR illegal borrow: creating mutable alias to aliasable, immutable memory
}
}

View File

@ -1,3 +1,3 @@
// error-pattern:quux
fn my_err(s: ~str) -> ! { log(error, s); fail ~"quux"; }
fn main() { my_err(~"bye") == 3u; }
fn main() { 3u == my_err(~"bye"); }

View File

@ -3,15 +3,16 @@ use std;
// These tests used to be separate files, but I wanted to refactor all
// the common code.
import cmp::Eq;
import std::ebml;
import io::Writer;
import std::serialization::{serialize_uint, deserialize_uint};
fn test_ser_and_deser<A>(a1: A,
expected: ~str,
ebml_ser_fn: fn(ebml::Writer, A),
ebml_deser_fn: fn(ebml::EbmlDeserializer) -> A,
io_ser_fn: fn(io::Writer, A)) {
fn test_ser_and_deser<A:Eq>(a1: A,
expected: ~str,
ebml_ser_fn: fn(ebml::Writer, A),
ebml_deser_fn: fn(ebml::EbmlDeserializer) -> A,
io_ser_fn: fn(io::Writer, A)) {
// check the pretty printer:
io_ser_fn(io::stdout(), a1);
@ -41,10 +42,40 @@ enum expr {
minus(@expr, @expr)
}
impl expr : cmp::Eq {
pure fn eq(&&other: expr) -> bool {
match self {
val(e0a) => {
match other {
val(e0b) => e0a == e0b,
_ => false
}
}
plus(e0a, e1a) => {
match other {
plus(e0b, e1b) => e0a == e0b && e1a == e1b,
_ => false
}
}
minus(e0a, e1a) => {
match other {
minus(e0b, e1b) => e0a == e0b && e1a == e1b,
_ => false
}
}
}
}
}
#[auto_serialize]
type spanned<T> = {lo: uint, hi: uint, node: T};
impl<T:cmp::Eq> spanned<T> : cmp::Eq {
pure fn eq(&&other: spanned<T>) -> bool {
self.lo == other.lo && self.hi == other.hi && self.node.eq(other.node)
}
}
#[auto_serialize]
type spanned_uint = spanned<uint>;

View File

@ -55,26 +55,6 @@ fn test_char() {
fn test_box() {
assert (@10 == @10);
assert (@{a: 1, b: 3} < @{a: 1, b: 4});
assert (@{a: 'x'} != @{a: 'y'});
}
fn test_port() {
let p1 = comm::Port::<int>();
let p2 = comm::Port::<int>();
assert (p1 == p1);
assert (p1 != p2);
}
fn test_chan() {
let p: comm::Port<int> = comm::Port();
let ch1 = comm::Chan(p);
let ch2 = comm::Chan(p);
assert (ch1 == ch1);
// Chans are equal because they are just task:port addresses.
assert (ch1 == ch2);
}
fn test_ptr() unsafe {
@ -92,27 +72,6 @@ fn test_ptr() unsafe {
assert p1 >= p2;
}
fn test_fn() {
fn f() { }
fn g() { }
fn h(_i: int) { }
let f1 = f;
let f2 = f;
let g1 = g;
let h1 = h;
let h2 = h;
assert (f1 == f2);
assert (f1 == f);
assert (f1 != g1);
assert (h1 == h2);
assert (!(f1 != f2));
assert (!(h1 < h2));
assert (h1 <= h2);
assert (!(h1 > h2));
assert (h1 >= h2);
}
#[abi = "cdecl"]
#[nolink]
extern mod test {
@ -120,17 +79,18 @@ extern mod test {
fn get_task_id() -> libc::intptr_t;
}
fn test_foreign_fn() {
assert test::rust_get_sched_id != test::get_task_id;
assert test::rust_get_sched_id == test::rust_get_sched_id;
}
struct p {
let mut x: int;
let mut y: int;
new(x: int, y: int) { self.x = x; self.y = y; }
}
impl p : cmp::Eq {
pure fn eq(&&other: p) -> bool {
self.x == other.x && self.y == other.y
}
}
fn test_class() {
let q = p(1, 2);
let r = p(1, 2);
@ -152,11 +112,6 @@ fn main() {
test_bool();
test_char();
test_box();
// FIXME: test_port causes valgrind errors (#2724)
//test_port();
test_chan();
test_ptr();
test_fn();
test_foreign_fn();
test_class();
}

View File

@ -3,6 +3,12 @@ import std::map::*;
enum cat_type { tuxedo, tabby, tortoiseshell }
impl cat_type : cmp::Eq {
pure fn eq(&&other: cat_type) -> bool {
(self as uint) == (other as uint)
}
}
// Very silly -- this just returns the value of the name field
// for any int value that's less than the meows field
@ -40,7 +46,7 @@ struct cat<T: copy> : map<int, T> {
}
}
fn size() -> uint { self.meows as uint }
pure fn size() -> uint { self.meows as uint }
fn insert(+k: int, +_v: T) -> bool {
self.meows += k;
true
@ -53,7 +59,7 @@ struct cat<T: copy> : map<int, T> {
None => { fail ~"epic fail"; }
}
}
fn find(+k:int) -> Option<T> { if k <= self.meows {
pure fn find(+k:int) -> Option<T> { if k <= self.meows {
Some(self.name)
}
else { None }
@ -68,7 +74,7 @@ struct cat<T: copy> : map<int, T> {
}
}
fn each(f: fn(+int, +T) -> bool) {
pure fn each(f: fn(+int, +T) -> bool) {
let mut n = int::abs(self.meows);
while n > 0 {
if !f(n, self.name) { break; }
@ -76,16 +82,16 @@ struct cat<T: copy> : map<int, T> {
}
}
fn each_key(&&f: fn(+int) -> bool) {
pure fn each_key(&&f: fn(+int) -> bool) {
for self.each |k, _v| { if !f(k) { break; } again;};
}
fn each_value(&&f: fn(+T) -> bool) {
pure fn each_value(&&f: fn(+T) -> bool) {
for self.each |_k, v| { if !f(v) { break; } again;};
}
fn each_ref(f: fn(k: &int, v: &T) -> bool) {}
fn each_key_ref(f: fn(k: &int) -> bool) {}
fn each_value_ref(f: fn(k: &T) -> bool) {}
pure fn each_ref(f: fn(k: &int, v: &T) -> bool) {}
pure fn each_key_ref(f: fn(k: &int) -> bool) {}
pure fn each_value_ref(f: fn(k: &T) -> bool) {}
fn clear() { }
}

View File

@ -1,6 +1,12 @@
struct foo { a: int; b: int; c: int; }
impl foo : cmp::Eq {
pure fn eq(&&other: foo) -> bool {
self.a == other.a && self.b == other.b && self.c == other.c
}
}
const x : foo = foo { a:1, b:2, c: 3 };
const y : foo = foo { b:2, c:3, a: 1 };
const z : &foo = &foo { a: 10, b: 22, c: 12 };

View File

@ -7,7 +7,8 @@ use cr5_2 (name = "crateresolve5", vers = "0.2");
fn main() {
// Structural types can be used between two versions of the same crate
assert cr5_1::structural() == cr5_2::structural();
assert cr5_1::structural().name == cr5_2::structural().name;
assert cr5_1::structural().val == cr5_2::structural().val;
// Make sure these are actually two different crates
assert cr5_1::f() == 10 && cr5_2::f() == 20;
}

View File

@ -23,5 +23,6 @@ fn main() {
assert e == exp[i];
}
assert dvec::unwrap(move d) == exp;
}
let v = vec::from_mut(dvec::unwrap(move d));
assert v == exp;
}

View File

@ -1,2 +0,0 @@
fn wsucc(n: int) -> int { ({ return n + 1 } == 0); }
fn main() { }

View File

@ -1,5 +1,11 @@
enum chan { chan_t, }
impl chan : cmp::Eq {
pure fn eq(&&other: chan) -> bool {
(self as uint) == (other as uint)
}
}
fn wrapper3(i: chan) {
assert i == chan_t;
}

View File

@ -8,6 +8,12 @@ mod foo {
// not exported
enum t { t1, t2, }
impl t : cmp::Eq {
pure fn eq(&&other: t) -> bool {
(self as uint) == (other as uint)
}
}
fn f() -> t { return t1; }
fn g(v: t) { assert (v == t1); }

View File

@ -14,9 +14,14 @@ fn test_bool() {
test_generic::<bool>(true, compare_bool);
}
fn test_rec() {
type t = {a: int, b: int};
type t = {a: int, b: int};
impl t : cmp::Eq {
pure fn eq(&&other: t) -> bool {
self.a == other.a && self.b == other.b
}
}
fn test_rec() {
fn compare_rec(t1: t, t2: t) -> bool { return t1 == t2; }
test_generic::<t>({a: 1, b: 2}, compare_rec);
}

View File

@ -6,11 +6,17 @@
// Tests for match as expressions resulting in structural types
fn test_rec() {
let rs = match true { true => {i: 100}, _ => fail };
assert (rs == {i: 100});
assert (rs.i == 100);
}
enum mood { happy, sad, }
impl mood : cmp::Eq {
pure fn eq(&&other: mood) -> bool {
(self as uint) == (other as uint)
}
}
fn test_tag() {
enum mood { happy, sad, }
let rs = match true { true => { happy } false => { sad } };
assert (rs == happy);
}

View File

@ -16,9 +16,14 @@ fn test_bool() {
test_generic::<bool>(true, compare_bool);
}
fn test_rec() {
type t = {a: int, b: int};
type t = {a: int, b: int};
impl t : cmp::Eq {
pure fn eq(&&other: t) -> bool {
self.a == other.a && self.b == other.b
}
}
fn test_rec() {
fn compare_rec(t1: t, t2: t) -> bool { return t1 == t2; }
test_generic::<t>({a: 1, b: 2}, compare_rec);
}

View File

@ -16,9 +16,14 @@ fn test_bool() {
test_generic::<bool>(true, false, compare_bool);
}
fn test_rec() {
type t = {a: int, b: int};
type t = {a: int, b: int};
impl t : cmp::Eq {
pure fn eq(&&other: t) -> bool {
self.a == other.a && self.b == other.b
}
}
fn test_rec() {
fn compare_rec(t1: t, t2: t) -> bool { return t1 == t2; }
test_generic::<t>({a: 1, b: 2}, {a: 2, b: 3}, compare_rec);
}

View File

@ -6,11 +6,17 @@
// Tests for if as expressions returning structural types
fn test_rec() {
let rs = if true { {i: 100} } else { {i: 101} };
assert (rs == {i: 100});
assert (rs.i == 100);
}
enum mood { happy, sad, }
impl mood : cmp::Eq {
pure fn eq(&&other: mood) -> bool {
(self as uint) == (other as uint)
}
}
fn test_tag() {
enum mood { happy, sad, }
let rs = if true { happy } else { sad };
assert (rs == happy);
}

View File

@ -1,4 +1,4 @@
fn main() {
{|i| if i == 1 { }};
}
{|i| if 1 == i { }};
}

View File

@ -8,6 +8,12 @@ mod pipes {
terminated
}
impl state : cmp::Eq {
pure fn eq(&&other: state) -> bool {
(self as uint) == (other as uint)
}
}
type packet<T: send> = {
mut state: state,
mut blocked_task: Option<task::Task>,
@ -51,7 +57,7 @@ mod pipes {
fn send<T: send>(-p: send_packet<T>, -payload: T) {
let p = p.unwrap();
let p = unsafe { uniquify(p) };
assert (*p).payload == None;
assert (*p).payload.is_none();
(*p).payload <- Some(payload);
let old_state = swap_state_rel(&mut (*p).state, full);
match old_state {
@ -208,7 +214,7 @@ mod pingpong {
fn do_pong(-c: pong) -> (ping, ()) {
let packet = pipes::recv(c);
if packet == None {
if packet.is_none() {
fail ~"sender closed the connection"
}
(liberate_pong(option::unwrap(packet)), ())
@ -221,7 +227,7 @@ mod pingpong {
fn do_ping(-c: ping) -> (pong, ()) {
let packet = pipes::recv(c);
if packet == None {
if packet.is_none() {
fail ~"sender closed the connection"
}
(liberate_ping(option::unwrap(packet)), ())

View File

@ -8,12 +8,12 @@ fn main() {
match None::<int> {
None => {}
Some(_) =>{
if test_comm::recv(p) == 0 {
Some(_) => {
if 0 == test_comm::recv(p) {
error!("floop");
}
else {
error!("bloop");
}
}}
}
}

View File

@ -27,6 +27,12 @@ impl Point : ops::index<bool,int> {
}
}
impl Point : cmp::Eq {
pure fn eq(&&other: Point) -> bool {
self.x == other.x && self.y == other.y
}
}
fn main() {
let mut p = Point {x: 10, y: 20};
p += Point {x: 101, y: 102};

View File

@ -1,3 +1,5 @@
import cmp::Eq;
fn iter<T>(v: ~[T], it: fn(T) -> bool) {
let mut i = 0u, l = v.len();
while i < l {
@ -6,7 +8,7 @@ fn iter<T>(v: ~[T], it: fn(T) -> bool) {
}
}
fn find_pos<T>(n: T, h: ~[T]) -> Option<uint> {
fn find_pos<T:Eq>(n: T, h: ~[T]) -> Option<uint> {
let mut i = 0u;
for iter(h) |e| {
if e == n { return Some(i); }

View File

@ -67,10 +67,13 @@ fn seq_range<BT: buildable<int>>(lo: uint, hi: uint) -> BT {
}
fn main() {
assert seq_range(0, 10) == @[0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
let v: @[int] = seq_range(0, 10);
assert v == @[0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
assert map(&[1,2,3], |x| 1+x) == @[2, 3, 4];
assert map(&[1,2,3], |x| 1+x) == ~[2, 3, 4];
let v: @[int] = map(&[1,2,3], |x| 1+x);
assert v == @[2, 3, 4];
let v: ~[int] = map(&[1,2,3], |x| 1+x);
assert v == ~[2, 3, 4];
assert select(true, 9, 14) == 9;
assert !andand(true, false);

View File

@ -6,7 +6,8 @@ import static_methods_crate::read;
import readMaybeRenamed = static_methods_crate::readMaybe;
fn main() {
assert read(~"5") == 5;
let result: int = read(~"5");
assert result == 5;
assert readMaybeRenamed(~"false") == Some(false);
assert readMaybeRenamed(~"foo") == None::<bool>;
}

View File

@ -2,15 +2,21 @@
enum foo { large, small, }
impl foo : cmp::Eq {
pure fn eq(&&other: foo) -> bool {
(self as uint) == (other as uint)
}
}
fn main() {
let a = {x: 1, y: 2, z: 3};
let b = {x: 1, y: 2, z: 3};
let a = (1, 2, 3);
let b = (1, 2, 3);
assert (a == b);
assert (a != {x: 1, y: 2, z: 4});
assert (a < {x: 1, y: 2, z: 4});
assert (a <= {x: 1, y: 2, z: 4});
assert ({x: 1, y: 2, z: 4} > a);
assert ({x: 1, y: 2, z: 4} >= a);
assert (a != (1, 2, 4));
assert (a < (1, 2, 4));
assert (a <= (1, 2, 4));
assert ((1, 2, 4) > a);
assert ((1, 2, 4) >= a);
let x = large;
let y = small;
assert (x != y);

Some files were not shown because too many files have changed in this diff Show More