rustc: Make shape-based compare glue never called for comparison operators.
Only called for string patterns.
This commit is contained in:
parent
9a15c50f6c
commit
22b8757705
22 changed files with 322 additions and 82 deletions
|
@ -179,7 +179,7 @@ pure fn min<A:Copy Ord,IA:BaseIter<A>>(self: IA) -> A {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pure fn max<A:Copy,IA:BaseIter<A>>(self: IA) -> A {
|
pure fn max<A:Copy Ord,IA:BaseIter<A>>(self: IA) -> A {
|
||||||
match do foldl::<A,Option<A>,IA>(self, None) |a, b| {
|
match do foldl::<A,Option<A>,IA>(self, None) |a, b| {
|
||||||
match a {
|
match a {
|
||||||
Some(a_) if a_ > b => {
|
Some(a_) if a_ > b => {
|
||||||
|
|
|
@ -769,28 +769,17 @@ pure fn lt(a: &str, b: &str) -> bool {
|
||||||
|
|
||||||
/// Bytewise less than or equal
|
/// Bytewise less than or equal
|
||||||
pure fn le(a: &str, b: &str) -> bool {
|
pure fn le(a: &str, b: &str) -> bool {
|
||||||
let (a_len, b_len) = (a.len(), b.len());
|
!lt(b, a)
|
||||||
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 greater than or equal
|
/// Bytewise greater than or equal
|
||||||
pure fn ge(a: &str, b: &str) -> bool {
|
pure fn ge(a: &str, b: &str) -> bool {
|
||||||
!lt(b, a)
|
!lt(a, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Bytewise greater than
|
/// Bytewise greater than
|
||||||
pure fn gt(a: &str, b: &str) -> bool {
|
pure fn gt(a: &str, b: &str) -> bool {
|
||||||
!le(b, a)
|
!le(a, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl &str: Eq {
|
impl &str: Eq {
|
||||||
|
|
|
@ -158,6 +158,46 @@ enum SchedMode {
|
||||||
PlatformThread
|
PlatformThread
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl SchedMode : cmp::Eq {
|
||||||
|
pure fn eq(&&other: SchedMode) -> bool {
|
||||||
|
match self {
|
||||||
|
SingleThreaded => {
|
||||||
|
match other {
|
||||||
|
SingleThreaded => true,
|
||||||
|
_ => false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ThreadPerCore => {
|
||||||
|
match other {
|
||||||
|
ThreadPerCore => true,
|
||||||
|
_ => false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ThreadPerTask => {
|
||||||
|
match other {
|
||||||
|
ThreadPerTask => true,
|
||||||
|
_ => false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ManualThreads(e0a) => {
|
||||||
|
match other {
|
||||||
|
ManualThreads(e0b) => e0a == e0b,
|
||||||
|
_ => false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PlatformThread => {
|
||||||
|
match other {
|
||||||
|
PlatformThread => true,
|
||||||
|
_ => false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pure fn ne(&&other: SchedMode) -> bool {
|
||||||
|
!self.eq(other)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Scheduler configuration options
|
* Scheduler configuration options
|
||||||
*
|
*
|
||||||
|
|
|
@ -3,11 +3,12 @@
|
||||||
|
|
||||||
//! json serialization
|
//! json serialization
|
||||||
|
|
||||||
use core::cmp::Eq;
|
use core::cmp::{Eq, Ord};
|
||||||
use result::{Result, Ok, Err};
|
use result::{Result, Ok, Err};
|
||||||
use io::WriterUtil;
|
use io::WriterUtil;
|
||||||
use map::hashmap;
|
use map::hashmap;
|
||||||
use map::map;
|
use map::map;
|
||||||
|
use sort::Sort;
|
||||||
|
|
||||||
export Json;
|
export Json;
|
||||||
export Error;
|
export Error;
|
||||||
|
@ -603,6 +604,75 @@ pure fn eq(value0: Json, value1: Json) -> bool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Test if two json values are less than one another
|
||||||
|
pure fn lt(value0: Json, value1: Json) -> bool {
|
||||||
|
match value0 {
|
||||||
|
Num(f0) => {
|
||||||
|
match value1 {
|
||||||
|
Num(f1) => f0 < f1,
|
||||||
|
String(_) | Boolean(_) | List(_) | Dict(_) | Null => true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String(s0) => {
|
||||||
|
match value1 {
|
||||||
|
Num(_) => false,
|
||||||
|
String(s1) => s0 < s1,
|
||||||
|
Boolean(_) | List(_) | Dict(_) | Null => true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Boolean(b0) => {
|
||||||
|
match value1 {
|
||||||
|
Num(_) | String(_) => false,
|
||||||
|
Boolean(b1) => b0 < b1,
|
||||||
|
List(_) | Dict(_) | Null => true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List(l0) => {
|
||||||
|
match value1 {
|
||||||
|
Num(_) | String(_) | Boolean(_) => false,
|
||||||
|
List(l1) => l0 < l1,
|
||||||
|
Dict(_) | Null => true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Dict(d0) => {
|
||||||
|
match value1 {
|
||||||
|
Num(_) | String(_) | Boolean(_) | List(_) => false,
|
||||||
|
Dict(d1) => {
|
||||||
|
unchecked {
|
||||||
|
let (d0_flat, d1_flat) = {
|
||||||
|
let d0_flat = dvec::DVec();
|
||||||
|
for d0.each |k, v| { d0_flat.push((k, v)); }
|
||||||
|
let d0_flat = dvec::unwrap(d0_flat);
|
||||||
|
d0_flat.qsort();
|
||||||
|
|
||||||
|
let mut d1_flat = dvec::DVec();
|
||||||
|
for d1.each |k, v| { d1_flat.push((k, v)); }
|
||||||
|
let d1_flat = dvec::unwrap(d1_flat);
|
||||||
|
d1_flat.qsort();
|
||||||
|
|
||||||
|
(d0_flat, d1_flat)
|
||||||
|
};
|
||||||
|
|
||||||
|
d0_flat < d1_flat
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Null => true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Null => {
|
||||||
|
match value1 {
|
||||||
|
Num(_) | String(_) | Boolean(_) | List(_) | Dict(_) => false,
|
||||||
|
Null => true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Error : Eq {
|
impl Error : Eq {
|
||||||
pure fn eq(&&other: Error) -> bool {
|
pure fn eq(&&other: Error) -> bool {
|
||||||
self.line == other.line &&
|
self.line == other.line &&
|
||||||
|
@ -617,6 +687,13 @@ impl Json : Eq {
|
||||||
pure fn ne(&&other: Json) -> bool { !self.eq(other) }
|
pure fn ne(&&other: Json) -> bool { !self.eq(other) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Json : Ord {
|
||||||
|
pure fn lt(&&other: Json) -> bool { lt(self, other) }
|
||||||
|
pure fn le(&&other: Json) -> bool { !other.lt(self) }
|
||||||
|
pure fn ge(&&other: Json) -> bool { !self.lt(other) }
|
||||||
|
pure fn gt(&&other: Json) -> bool { other.lt(self) }
|
||||||
|
}
|
||||||
|
|
||||||
trait ToJson { fn to_json() -> Json; }
|
trait ToJson { fn to_json() -> Json; }
|
||||||
|
|
||||||
impl Json: ToJson {
|
impl Json: ToJson {
|
||||||
|
|
|
@ -405,6 +405,13 @@ enum proto {
|
||||||
proto_block, // fn&
|
proto_block, // fn&
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl proto : cmp::Eq {
|
||||||
|
pure fn eq(&&other: proto) -> bool {
|
||||||
|
(self as uint) == (other as uint)
|
||||||
|
}
|
||||||
|
pure fn ne(&&other: proto) -> bool { !self.eq(other) }
|
||||||
|
}
|
||||||
|
|
||||||
#[auto_serialize]
|
#[auto_serialize]
|
||||||
enum vstore {
|
enum vstore {
|
||||||
// FIXME (#2112): Change uint to @expr (actually only constant exprs)
|
// FIXME (#2112): Change uint to @expr (actually only constant exprs)
|
||||||
|
@ -454,7 +461,49 @@ impl binop : cmp::Eq {
|
||||||
enum unop {
|
enum unop {
|
||||||
box(mutability),
|
box(mutability),
|
||||||
uniq(mutability),
|
uniq(mutability),
|
||||||
deref, not, neg
|
deref,
|
||||||
|
not,
|
||||||
|
neg
|
||||||
|
}
|
||||||
|
|
||||||
|
impl unop : cmp::Eq {
|
||||||
|
pure fn eq(&&other: unop) -> bool {
|
||||||
|
match self {
|
||||||
|
box(e0a) => {
|
||||||
|
match other {
|
||||||
|
box(e0b) => e0a == e0b,
|
||||||
|
_ => false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
uniq(e0a) => {
|
||||||
|
match other {
|
||||||
|
uniq(e0b) => e0a == e0b,
|
||||||
|
_ => false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
deref => {
|
||||||
|
match other {
|
||||||
|
deref => true,
|
||||||
|
_ => false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
not => {
|
||||||
|
match other {
|
||||||
|
not => true,
|
||||||
|
_ => false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
neg => {
|
||||||
|
match other {
|
||||||
|
neg => true,
|
||||||
|
_ => false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pure fn ne(&&other: unop) -> bool {
|
||||||
|
!self.eq(other)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generally, after typeck you can get the inferred value
|
// Generally, after typeck you can get the inferred value
|
||||||
|
|
|
@ -337,6 +337,13 @@ enum inline_attr {
|
||||||
ia_never,
|
ia_never,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl inline_attr : cmp::Eq {
|
||||||
|
pure fn eq(&&other: inline_attr) -> bool {
|
||||||
|
(self as uint) == (other as uint)
|
||||||
|
}
|
||||||
|
pure fn ne(&&other: inline_attr) -> bool { !self.eq(other) }
|
||||||
|
}
|
||||||
|
|
||||||
/// True if something like #[inline] is found in the list of attrs.
|
/// True if something like #[inline] is found in the list of attrs.
|
||||||
fn find_inline_attr(attrs: ~[ast::attribute]) -> inline_attr {
|
fn find_inline_attr(attrs: ~[ast::attribute]) -> inline_attr {
|
||||||
// FIXME (#2809)---validate the usage of #[inline] and #[inline(always)]
|
// FIXME (#2809)---validate the usage of #[inline] and #[inline(always)]
|
||||||
|
|
|
@ -143,7 +143,7 @@ struct protocol_ {
|
||||||
fn get_state_by_id(id: uint) -> state { self.states[id] }
|
fn get_state_by_id(id: uint) -> state { self.states[id] }
|
||||||
|
|
||||||
fn has_state(name: ~str) -> bool {
|
fn has_state(name: ~str) -> bool {
|
||||||
self.states.find(|i| i.name == name) != None
|
self.states.find(|i| i.name == name).is_some()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn filename() -> ~str {
|
fn filename() -> ~str {
|
||||||
|
|
|
@ -68,7 +68,7 @@ fn elts_to_ell(cx: ext_ctxt, elts: ~[@expr]) ->
|
||||||
match elt.node {
|
match elt.node {
|
||||||
expr_mac(m) => match m.node {
|
expr_mac(m) => match m.node {
|
||||||
ast::mac_ellipsis => {
|
ast::mac_ellipsis => {
|
||||||
if res != None {
|
if res.is_some() {
|
||||||
cx.span_fatal(m.span, ~"only one ellipsis allowed");
|
cx.span_fatal(m.span, ~"only one ellipsis allowed");
|
||||||
}
|
}
|
||||||
res =
|
res =
|
||||||
|
@ -449,7 +449,7 @@ fn p_t_s_rec(cx: ext_ctxt, m: matchable, s: selector, b: binders) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{pre: pre, rep: None, post: post} => {
|
{pre: pre, rep: None, post: post} => {
|
||||||
if post != ~[] {
|
if post.len() > 0 {
|
||||||
cx.bug(~"elts_to_ell provided an invalid result");
|
cx.bug(~"elts_to_ell provided an invalid result");
|
||||||
}
|
}
|
||||||
p_t_s_r_length(cx, vec::len(pre), false, s, b);
|
p_t_s_r_length(cx, vec::len(pre), false, s, b);
|
||||||
|
|
|
@ -17,6 +17,15 @@ enum cmnt_style {
|
||||||
blank_line, // Just a manual blank line "\n\n", for layout
|
blank_line, // Just a manual blank line "\n\n", for layout
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl cmnt_style : cmp::Eq {
|
||||||
|
pure fn eq(&&other: cmnt_style) -> bool {
|
||||||
|
(self as uint) == (other as uint)
|
||||||
|
}
|
||||||
|
pure fn ne(&&other: cmnt_style) -> bool {
|
||||||
|
(self as uint) != (other as uint)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type cmnt = {style: cmnt_style, lines: ~[~str], pos: uint};
|
type cmnt = {style: cmnt_style, lines: ~[~str], pos: uint};
|
||||||
|
|
||||||
fn is_doc_comment(s: ~str) -> bool {
|
fn is_doc_comment(s: ~str) -> bool {
|
||||||
|
|
|
@ -1616,10 +1616,13 @@ fn print_fn_args_and_ret(s: ps, decl: ast::fn_decl,
|
||||||
pclose(s);
|
pclose(s);
|
||||||
|
|
||||||
maybe_print_comment(s, decl.output.span.lo);
|
maybe_print_comment(s, decl.output.span.lo);
|
||||||
if decl.output.node != ast::ty_nil {
|
match decl.output.node {
|
||||||
space_if_not_bol(s);
|
ast::ty_nil => {}
|
||||||
word_space(s, ~"->");
|
_ => {
|
||||||
print_type(s, decl.output);
|
space_if_not_bol(s);
|
||||||
|
word_space(s, ~"->");
|
||||||
|
print_type(s, decl.output);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1628,11 +1631,16 @@ fn print_fn_block_args(s: ps, decl: ast::fn_decl,
|
||||||
word(s.s, ~"|");
|
word(s.s, ~"|");
|
||||||
print_fn_args(s, decl, cap_items, None);
|
print_fn_args(s, decl, cap_items, None);
|
||||||
word(s.s, ~"|");
|
word(s.s, ~"|");
|
||||||
if decl.output.node != ast::ty_infer {
|
|
||||||
space_if_not_bol(s);
|
match decl.output.node {
|
||||||
word_space(s, ~"->");
|
ast::ty_infer => {}
|
||||||
print_type(s, decl.output);
|
_ => {
|
||||||
|
space_if_not_bol(s);
|
||||||
|
word_space(s, ~"->");
|
||||||
|
print_type(s, decl.output);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
maybe_print_comment(s, decl.output.span.lo);
|
maybe_print_comment(s, decl.output.span.lo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1829,14 +1837,19 @@ fn print_ty_fn(s: ps, opt_proto: Option<ast::proto>, purity: ast::purity,
|
||||||
pclose(s);
|
pclose(s);
|
||||||
|
|
||||||
maybe_print_comment(s, decl.output.span.lo);
|
maybe_print_comment(s, decl.output.span.lo);
|
||||||
if decl.output.node != ast::ty_nil {
|
|
||||||
space_if_not_bol(s);
|
match decl.output.node {
|
||||||
ibox(s, indent_unit);
|
ast::ty_nil => {}
|
||||||
word_space(s, ~"->");
|
_ => {
|
||||||
if decl.cf == ast::noreturn { word_nbsp(s, ~"!"); }
|
space_if_not_bol(s);
|
||||||
else { print_type(s, decl.output); }
|
ibox(s, indent_unit);
|
||||||
end(s);
|
word_space(s, ~"->");
|
||||||
|
if decl.cf == ast::noreturn { word_nbsp(s, ~"!"); }
|
||||||
|
else { print_type(s, decl.output); }
|
||||||
|
end(s);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
end(s);
|
end(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -79,6 +79,13 @@ enum assignment_type {
|
||||||
at_mutbl_ref,
|
at_mutbl_ref,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl assignment_type : cmp::Eq {
|
||||||
|
pure fn eq(&&other: assignment_type) -> bool {
|
||||||
|
(self as uint) == (other as uint)
|
||||||
|
}
|
||||||
|
pure fn ne(&&other: assignment_type) -> bool { !self.eq(other) }
|
||||||
|
}
|
||||||
|
|
||||||
impl assignment_type {
|
impl assignment_type {
|
||||||
fn checked_by_liveness() -> bool {
|
fn checked_by_liveness() -> bool {
|
||||||
// the liveness pass guarantees that immutable local variables
|
// the liveness pass guarantees that immutable local variables
|
||||||
|
|
|
@ -210,6 +210,15 @@ enum ResolveResult<T> {
|
||||||
Success(T) // Successfully resolved the import.
|
Success(T) // Successfully resolved the import.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T> ResolveResult<T> {
|
||||||
|
fn failed() -> bool {
|
||||||
|
match self { Failed => true, _ => false }
|
||||||
|
}
|
||||||
|
fn indeterminate() -> bool {
|
||||||
|
match self { Indeterminate => true, _ => false }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
enum TypeParameters/& {
|
enum TypeParameters/& {
|
||||||
NoTypeParameters, //< No type parameters.
|
NoTypeParameters, //< No type parameters.
|
||||||
HasTypeParameters(&~[ty_param], //< Type parameters.
|
HasTypeParameters(&~[ty_param], //< Type parameters.
|
||||||
|
@ -558,9 +567,14 @@ struct NameBindings {
|
||||||
|
|
||||||
fn defined_in_namespace(namespace: Namespace) -> bool {
|
fn defined_in_namespace(namespace: Namespace) -> bool {
|
||||||
match namespace {
|
match namespace {
|
||||||
ModuleNS => return self.module_def != NoModuleDef,
|
ModuleNS => {
|
||||||
TypeNS => return self.type_def != None,
|
match self.module_def {
|
||||||
ValueNS => return self.value_def != None
|
NoModuleDef => false,
|
||||||
|
_ => true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TypeNS => return self.type_def.is_some(),
|
||||||
|
ValueNS => return self.value_def.is_some()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1788,7 +1802,7 @@ struct Resolver {
|
||||||
// processing imports here. (See the loop in
|
// processing imports here. (See the loop in
|
||||||
// resolve_imports_for_module.)
|
// resolve_imports_for_module.)
|
||||||
|
|
||||||
if resolution_result != Indeterminate {
|
if !resolution_result.indeterminate() {
|
||||||
match *import_directive.subclass {
|
match *import_directive.subclass {
|
||||||
GlobImport => {
|
GlobImport => {
|
||||||
assert module_.glob_count >= 1u;
|
assert module_.glob_count >= 1u;
|
||||||
|
|
|
@ -1117,12 +1117,21 @@ fn trans_eager_binop(bcx: block,
|
||||||
AShr(bcx, lhs, rhs)
|
AShr(bcx, lhs, rhs)
|
||||||
} else { LShr(bcx, lhs, rhs) }
|
} else { LShr(bcx, lhs, rhs) }
|
||||||
}
|
}
|
||||||
|
ast::eq | ast::ne | ast::lt | ast::ge | ast::le | ast::gt => {
|
||||||
|
if ty::type_is_bot(rhs_t) {
|
||||||
|
C_bool(false)
|
||||||
|
} else {
|
||||||
|
if !ty::type_is_scalar(rhs_t) {
|
||||||
|
bcx.tcx().sess.span_bug(binop_expr.span,
|
||||||
|
~"non-scalar comparison");
|
||||||
|
}
|
||||||
|
let cmpr = base::compare_scalar_types(bcx, lhs, rhs, rhs_t, op);
|
||||||
|
bcx = cmpr.bcx;
|
||||||
|
cmpr.val
|
||||||
|
}
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
let cmpr = base::trans_compare(bcx, op,
|
bcx.tcx().sess.span_bug(binop_expr.span, ~"unexpected binop");
|
||||||
lhs, lhs_t,
|
|
||||||
rhs, rhs_t);
|
|
||||||
bcx = cmpr.bcx;
|
|
||||||
cmpr.val
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -516,12 +516,14 @@ fn gen_enum_shapes(ccx: @crate_ctxt) -> ValueRef {
|
||||||
ranges[i].align.bounded &&
|
ranges[i].align.bounded &&
|
||||||
ranges[j].size.bounded &&
|
ranges[j].size.bounded &&
|
||||||
ranges[j].align.bounded {
|
ranges[j].align.bounded {
|
||||||
if ranges[i].size >= ranges[j].size &&
|
if ranges[i].size.min >= ranges[j].size.min &&
|
||||||
ranges[i].align >= ranges[j].align {
|
ranges[i].align.min >= ranges[j].align.min {
|
||||||
// Throw out j.
|
// Throw out j.
|
||||||
candidates[j] = false;
|
candidates[j] = false;
|
||||||
} else if ranges[j].size >= ranges[i].size &&
|
} else if ranges[j].size.min >=
|
||||||
ranges[j].align >= ranges[j].align {
|
ranges[i].size.min &&
|
||||||
|
ranges[j].align.min >=
|
||||||
|
ranges[j].align.min {
|
||||||
// Throw out i.
|
// Throw out i.
|
||||||
candidates[i] = false;
|
candidates[i] = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3081,8 +3081,8 @@ fn occurs_check(tcx: ctxt, sp: span, vid: TyVid, rt: t) {
|
||||||
|
|
||||||
// Maintains a little union-set tree for inferred modes. `canon()` returns
|
// Maintains a little union-set tree for inferred modes. `canon()` returns
|
||||||
// the current head value for `m0`.
|
// the current head value for `m0`.
|
||||||
fn canon<T:Copy>(tbl: hashmap<ast::node_id, ast::inferable<T>>,
|
fn canon<T:Copy cmp::Eq>(tbl: hashmap<ast::node_id, ast::inferable<T>>,
|
||||||
+m0: ast::inferable<T>) -> ast::inferable<T> {
|
+m0: ast::inferable<T>) -> ast::inferable<T> {
|
||||||
match m0 {
|
match m0 {
|
||||||
ast::infer(id) => match tbl.find(id) {
|
ast::infer(id) => match tbl.find(id) {
|
||||||
None => m0,
|
None => m0,
|
||||||
|
|
|
@ -1132,7 +1132,13 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
|
||||||
let rhs_bot = check_expr_with(fcx, rhs, tvar);
|
let rhs_bot = check_expr_with(fcx, rhs, tvar);
|
||||||
let result_t = match op {
|
let result_t = match op {
|
||||||
ast::eq | ast::lt | ast::le | ast::ne | ast::ge |
|
ast::eq | ast::lt | ast::le | ast::ne | ast::ge |
|
||||||
ast::gt => ty::mk_bool(fcx.ccx.tcx),
|
ast::gt => {
|
||||||
|
if !ty::type_is_scalar(lhs_t) {
|
||||||
|
fcx.ccx.tcx.sess.span_bug(expr.span,
|
||||||
|
~"non-scalar compare");
|
||||||
|
}
|
||||||
|
ty::mk_bool(fcx.ccx.tcx)
|
||||||
|
}
|
||||||
_ => lhs_t
|
_ => lhs_t
|
||||||
};
|
};
|
||||||
fcx.write_ty(expr.id, result_t);
|
fcx.write_ty(expr.id, result_t);
|
||||||
|
@ -1410,23 +1416,6 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
|
||||||
let typ = check_lit(fcx, lit);
|
let typ = check_lit(fcx, lit);
|
||||||
fcx.write_ty(id, typ);
|
fcx.write_ty(id, typ);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Something of a hack: special rules for comparison operators that
|
|
||||||
// simply unify LHS and RHS. This helps with inference as LHS and RHS
|
|
||||||
// do not need to be "resolvable". Some tests, particularly those with
|
|
||||||
// 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::ne, lhs, rhs) |
|
|
||||||
ast::expr_binary(ast::le, lhs, rhs) |
|
|
||||||
ast::expr_binary(ast::gt, lhs, rhs) |
|
|
||||||
ast::expr_binary(ast::ge, lhs, rhs) => {
|
|
||||||
let tcx = fcx.ccx.tcx;
|
|
||||||
let tvar = fcx.infcx().next_ty_var();
|
|
||||||
bot |= check_expr_with(fcx, lhs, tvar);
|
|
||||||
bot |= check_expr_with(fcx, rhs, tvar);
|
|
||||||
fcx.write_ty(id, ty::mk_bool(tcx));
|
|
||||||
}
|
|
||||||
ast::expr_binary(op, lhs, rhs) => {
|
ast::expr_binary(op, lhs, rhs) => {
|
||||||
bot |= check_binop(fcx, expr, op, lhs, rhs);
|
bot |= check_binop(fcx, expr, op, lhs, rhs);
|
||||||
}
|
}
|
||||||
|
@ -1806,7 +1795,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
|
||||||
}
|
}
|
||||||
ast::expr_rec(fields, base) => {
|
ast::expr_rec(fields, base) => {
|
||||||
option::iter(base, |b| { check_expr(fcx, b, expected); });
|
option::iter(base, |b| { check_expr(fcx, b, expected); });
|
||||||
let expected = if expected == None && base != None {
|
let expected = if expected.is_none() && base.is_some() {
|
||||||
Some(fcx.expr_ty(base.get()))
|
Some(fcx.expr_ty(base.get()))
|
||||||
} else { expected };
|
} else { expected };
|
||||||
let flds = unpack_expected(fcx, expected, |sty|
|
let flds = unpack_expected(fcx, expected, |sty|
|
||||||
|
|
|
@ -20,7 +20,7 @@ struct node<V:Copy, T:Copy> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl infer_ctxt {
|
impl infer_ctxt {
|
||||||
fn get<V:Copy vid, T:Copy>(
|
fn get<V:Copy vid Eq, T:Copy>(
|
||||||
vb: &vals_and_bindings<V, T>, vid: V) -> node<V, T> {
|
vb: &vals_and_bindings<V, T>, vid: V) -> node<V, T> {
|
||||||
|
|
||||||
let vid_u = vid.to_uint();
|
let vid_u = vid.to_uint();
|
||||||
|
@ -377,4 +377,4 @@ impl infer_ctxt {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,22 +14,22 @@ fn sort_and_fmt(mm: hashmap<~[u8], uint>, total: uint) -> ~str {
|
||||||
return (xx as float) * 100f / (yy as float);
|
return (xx as float) * 100f / (yy as float);
|
||||||
}
|
}
|
||||||
|
|
||||||
pure fn le_by_val<TT: Copy, UU: Copy>(kv0: &(TT,UU),
|
pure fn le_by_val<TT: Copy Ord, UU: Copy Ord>(kv0: &(TT,UU),
|
||||||
kv1: &(TT,UU)) -> bool {
|
kv1: &(TT,UU)) -> bool {
|
||||||
let (_, v0) = *kv0;
|
let (_, v0) = *kv0;
|
||||||
let (_, v1) = *kv1;
|
let (_, v1) = *kv1;
|
||||||
return v0 >= v1;
|
return v0 >= v1;
|
||||||
}
|
}
|
||||||
|
|
||||||
pure fn le_by_key<TT: Copy, UU: Copy>(kv0: &(TT,UU),
|
pure fn le_by_key<TT: Copy Ord, UU: Copy Ord>(kv0: &(TT,UU),
|
||||||
kv1: &(TT,UU)) -> bool {
|
kv1: &(TT,UU)) -> bool {
|
||||||
let (k0, _) = *kv0;
|
let (k0, _) = *kv0;
|
||||||
let (k1, _) = *kv1;
|
let (k1, _) = *kv1;
|
||||||
return k0 <= k1;
|
return k0 <= k1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// sort by key, then by value
|
// sort by key, then by value
|
||||||
fn sortKV<TT: Copy, UU: Copy>(orig: ~[(TT,UU)]) -> ~[(TT,UU)] {
|
fn sortKV<TT: Copy Ord, UU: Copy Ord>(orig: ~[(TT,UU)]) -> ~[(TT,UU)] {
|
||||||
return sort::merge_sort(le_by_val, sort::merge_sort(le_by_key, orig));
|
return sort::merge_sort(le_by_val, sort::merge_sort(le_by_key, orig));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ fn main() {
|
||||||
error!("selecting");
|
error!("selecting");
|
||||||
let (i, m, _) = select(~[left, right]);
|
let (i, m, _) = select(~[left, right]);
|
||||||
error!("selected %?", i);
|
error!("selected %?", i);
|
||||||
if m != None {
|
if m.is_some() {
|
||||||
assert i == 1;
|
assert i == 1;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
|
|
||||||
|
|
||||||
enum taggy { foo(@taggy), bar, }
|
|
||||||
|
|
||||||
fn main() { assert (bar <= bar); }
|
|
|
@ -4,6 +4,26 @@
|
||||||
// -*- rust -*-
|
// -*- rust -*-
|
||||||
enum colour { red(int, int), green, }
|
enum colour { red(int, int), green, }
|
||||||
|
|
||||||
|
impl colour : cmp::Eq {
|
||||||
|
pure fn eq(&&other: colour) -> bool {
|
||||||
|
match self {
|
||||||
|
red(a0, b0) => {
|
||||||
|
match other {
|
||||||
|
red(a1, b1) => a0 == a1 && b0 == b1,
|
||||||
|
green => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
green => {
|
||||||
|
match other {
|
||||||
|
red(*) => false,
|
||||||
|
green => true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pure fn ne(&&other: colour) -> bool { !self.eq(other) }
|
||||||
|
}
|
||||||
|
|
||||||
fn f() { let x = red(1, 2); let y = green; assert (x != y); }
|
fn f() { let x = red(1, 2); let y = green; assert (x != y); }
|
||||||
|
|
||||||
fn main() { f(); }
|
fn main() { f(); }
|
||||||
|
|
|
@ -1,6 +1,26 @@
|
||||||
|
|
||||||
enum t { a, b(~str), }
|
enum t { a, b(~str), }
|
||||||
|
|
||||||
|
impl t : cmp::Eq {
|
||||||
|
pure fn eq(&&other: t) -> bool {
|
||||||
|
match self {
|
||||||
|
a => {
|
||||||
|
match other {
|
||||||
|
a => true,
|
||||||
|
b(_) => false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
b(s0) => {
|
||||||
|
match other {
|
||||||
|
a => false,
|
||||||
|
b(s1) => s0 == s1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pure fn ne(&&other: t) -> bool { !self.eq(other) }
|
||||||
|
}
|
||||||
|
|
||||||
fn make(i: int) -> t {
|
fn make(i: int) -> t {
|
||||||
if i > 10 { return a; }
|
if i > 10 { return a; }
|
||||||
let mut s = ~"hello";
|
let mut s = ~"hello";
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue