rustc: make integral type inference transactional, close #3211, close #4401, close #3398.

This commit is contained in:
Graydon Hoare 2013-01-30 16:21:10 -08:00
parent 592c2e1db4
commit 4030aaff20
13 changed files with 64 additions and 91 deletions

View file

@ -18,7 +18,6 @@ use char;
use cmp::{Eq, Ord};
use cmp;
use from_str::FromStr;
use iter;
use num;
use num::Num::from_int;
use prelude::*;
@ -201,26 +200,6 @@ impl T: num::One {
static pure fn one() -> T { 1 }
}
impl T: iter::Times {
#[inline(always)]
#[doc = "A convenience form for basic iteration. Given a variable `x` \
of any numeric type, the expression `for x.times { /* anything */ }` \
will execute the given function exactly x times. If we assume that \
`x` is an int, this is functionally equivalent to \
`for int::range(0, x) |_i| { /* anything */ }`."]
pure fn times(&self, it: fn() -> bool) {
if is_negative(*self) {
fail fmt!("The .times method expects a nonnegative number, \
but found %?", self);
}
let mut i = *self;
while i > 0 {
if !it() { break }
i -= 1;
}
}
}
/**
* Parse a buffer of bytes
*
@ -357,23 +336,6 @@ fn test_interfaces() {
test(10 as T);
}
#[test]
fn test_times() {
use iter::Times;
let ten = 10 as T;
let mut accum = 0;
for ten.times { accum += 1; }
assert (accum == 10);
}
#[test]
#[should_fail]
#[ignore(cfg(windows))]
fn test_times_negative() {
use iter::Times;
for (-10).times { log(error, ~"nope!"); }
}
#[test]
pub fn test_ranges() {
let mut l = ~[];

View file

@ -146,8 +146,8 @@ impl<A: ToStr> ~A: ToStr {
mod tests {
#[test]
fn test_simple_types() {
assert 1.to_str() == ~"1";
assert (-1).to_str() == ~"-1";
assert 1i.to_str() == ~"1";
assert (-1i).to_str() == ~"-1";
assert 200u.to_str() == ~"200";
assert 2u8.to_str() == ~"2";
assert true.to_str() == ~"true";

View file

@ -18,7 +18,6 @@ use T_SIGNED = self::inst::T_SIGNED;
use char;
use cmp::{Eq, Ord};
use from_str::FromStr;
use iter;
use num;
use option::{None, Option, Some};
use str;
@ -161,22 +160,6 @@ impl T: num::One {
static pure fn one() -> T { 1 }
}
impl T: iter::Times {
#[inline(always)]
#[doc = "A convenience form for basic iteration. Given a variable `x` \
of any numeric type, the expression `for x.times { /* anything */ }` \
will execute the given function exactly x times. If we assume that \
`x` is an int, this is functionally equivalent to \
`for int::range(0, x) |_i| { /* anything */ }`."]
pure fn times(&self, it: fn() -> bool) {
let mut i = *self;
while i > 0 {
if !it() { break }
i -= 1;
}
}
}
/**
* Parse a buffer of bytes
*
@ -349,14 +332,6 @@ pub fn to_str_radix17() {
uint::to_str(100u, 17u);
}
#[test]
pub fn test_times() {
use iter::Times;
let ten = 10 as T;
let mut accum = 0;
for ten.times { accum += 1; }
assert (accum == 10);
}
use io;
#[test]
pub fn test_ranges() {

View file

@ -15,9 +15,10 @@ pub use self::inst::{
next_power_of_two
};
mod inst {
pub mod inst {
use sys;
use uint;
use iter;
pub type T = uint;
#[allow(non_camel_case_types)]
@ -107,6 +108,27 @@ mod inst {
return true;
}
pub impl uint: iter::Times {
#[inline(always)]
/**
* A convenience form for basic iteration. Given a uint `x`,
* `for x.times { ... }` executes the given block x times.
*
* Equivalent to `for uint::range(0, x) |_| { ... }`.
*
* Not defined on all integer types to permit unambiguous
* use with integer literals of inferred integer-type as
* the self-value (eg. `for 100.times { ... }`).
*/
pure fn times(&self, it: fn() -> bool) {
let mut i = *self;
while i > 0 {
if !it() { break }
i -= 1;
}
}
}
/// Returns the smallest power of 2 greater than or equal to `n`
#[inline(always)]
pub pure fn next_power_of_two(n: uint) -> uint {
@ -174,4 +196,13 @@ mod inst {
assert(uint::div_ceil(3u, 4u) == 1u);
assert(uint::div_round(3u, 4u) == 1u);
}
#[test]
pub fn test_times() {
use iter::Times;
let ten = 10 as uint;
let mut accum = 0;
for ten.times { accum += 1; }
assert (accum == 10);
}
}

View file

@ -41,7 +41,7 @@ pub fn check_crate(tcx: ty::ctxt,
let legacy_exports = has_legacy_export_attr(crate.node.attrs);
// Adds structs that are privileged to this scope.
let add_privileged_items: @fn(&[@ast::item]) -> int = |items| {
let add_privileged_items: @fn(&[@ast::item]) -> uint = |items| {
let mut count = 0;
for items.each |item| {
match item.node {

View file

@ -257,7 +257,6 @@ pub impl LookupContext {
match ty::deref(self.tcx(), ty, false) {
None => None,
Some(t) => {
//FIXME(#3211) -- probably want to force ivars
Some(structurally_resolved_type(self.fcx,
self.self_expr.span,
t.ty))
@ -907,8 +906,8 @@ pub impl LookupContext {
let tcx = self.tcx();
match ty::get(self_ty).sty {
ty_box(*) | ty_uniq(*) | ty_rptr(*) |
ty_infer(IntVar(_)) | // FIXME(#3211)---should be resolved
ty_infer(FloatVar(_)) | // FIXME(#3211)---should be resolved
ty_infer(IntVar(_)) |
ty_infer(FloatVar(_)) |
ty_self | ty_param(*) | ty_nil | ty_bot | ty_bool |
ty_int(*) | ty_uint(*) |
ty_float(*) | ty_enum(*) | ty_ptr(*) | ty_rec(*) |

View file

@ -562,11 +562,10 @@ impl @InferCtxt {
debug!("rollback!");
rollback_to(&self.ty_var_bindings, snapshot.ty_var_bindings_len);
// FIXME(#3211) -- int_var and float_var not transactional
//rollback_to(&self.int_var_bindings,
// snapshot.int_var_bindings_len);
//rollback_to(&self.float_var_bindings,
// snapshot.float_var_bindings_len);
rollback_to(&self.int_var_bindings,
snapshot.int_var_bindings_len);
rollback_to(&self.float_var_bindings,
snapshot.float_var_bindings_len);
self.region_vars.rollback_to(snapshot.region_vars_snapshot);
}

View file

@ -54,13 +54,13 @@ impl f64: FuzzyEq {
#[test]
fn test_fuzzy_equals() {
assert (&1.0).fuzzy_eq(&1.0);
assert (&1.0f).fuzzy_eq(&1.0);
assert (&1.0f32).fuzzy_eq(&1.0f32);
assert (&1.0f64).fuzzy_eq(&1.0f64);
}
#[test]
fn test_fuzzy_eq_eps() {
assert (&1.2).fuzzy_eq_eps(&0.9, &0.5);
assert !(&1.5).fuzzy_eq_eps(&0.9, &0.5);
assert (&1.2f).fuzzy_eq_eps(&0.9, &0.5);
assert !(&1.5f).fuzzy_eq_eps(&0.9, &0.5);
}

View file

@ -9,7 +9,7 @@
// except according to those terms.
fn main() {
let v = [ (1, 2), (3, 4), (5, 6) ];
let v : &[(int,int)] = &[ (1, 2), (3, 4), (5, 6) ];
for v.each |&(x, y)| {
io::println(y.to_str());
io::println(x.to_str());

View file

@ -1,7 +1,7 @@
struct S<T>(T);
fn main() {
let s = S(2);
let s = S(2i);
io::println(s.to_str());
}

View file

@ -0,0 +1,8 @@
fn main() {
let mut x = 0;
for 4096.times {
x += 1;
}
assert x == 4096;
io::println(fmt!("x = %u", x));
}

View file

@ -0,0 +1,8 @@
fn main() {
let mut count = 0;
for 999_999.times() {
count += 1;
}
assert count == 999_999;
io::println(fmt!("%u", count));
}

View file

@ -15,17 +15,11 @@
fn main() {
// ints
// num
assert 15.add(&6) == 21;
assert 15i.add(&6) == 21;
assert 15i8.add(&6i8) == 21i8;
assert 15i16.add(&6i16) == 21i16;
assert 15i32.add(&6i32) == 21i32;
assert 15i64.add(&6i64) == 21i64;
// times
15.times(|| false);
15i8.times(|| false);
15i16.times(|| false);
15i32.times(|| false);
15i64.times(|| false);
// uints
// num
@ -34,12 +28,9 @@ fn main() {
assert 15u16.add(&6u16) == 21u16;
assert 15u32.add(&6u32) == 21u32;
assert 15u64.add(&6u64) == 21u64;
// times
15u.times(|| false);
15u8.times(|| false);
15u16.times(|| false);
15u32.times(|| false);
15u64.times(|| false);
// floats
// num