diff --git a/src/libcore/f32.rs b/src/libcore/f32.rs index ce90f757769be..94f71d6541cc6 100644 --- a/src/libcore/f32.rs +++ b/src/libcore/f32.rs @@ -17,7 +17,13 @@ use cmp; use num; -pub use cmath::c_float_utils::*; +pub use cmath::c_float_utils::{acos, asin, atan, atan2, cbrt, ceil}; +pub use cmath::c_float_utils::{copysign, cos, cosh, erf, erfc, exp, expm1}; +pub use cmath::c_float_utils::{exp2, abs, abs_sub, mul_add, fmax, fmin}; +pub use cmath::c_float_utils::{nextafter, frexp, hypot, ldexp, lgamma}; +pub use cmath::c_float_utils::{ln, log_radix, ln1p, log10, log2, ilog_radix}; +pub use cmath::c_float_utils::{modf, pow, round, sin, sinh, sqrt, tan}; +pub use cmath::c_float_utils::{tanh, tgamma, trunc}; pub use cmath::c_float_targ_consts::*; // These are not defined inside consts:: for consistency with @@ -53,6 +59,10 @@ pub pure fn ge(x: f32, y: f32) -> bool { return x >= y; } pub pure fn gt(x: f32, y: f32) -> bool { return x > y; } +/// Returns `x` rounded down +#[inline(always)] +pub pure fn floor(x: f32) -> f32 { unsafe { floorf32(x) } } + // FIXME (#1999): replace the predicates below with llvm intrinsics or // calls to the libmath macros in the rust runtime for performance. @@ -185,6 +195,11 @@ impl f32: num::One { static pure fn one() -> f32 { 1.0 } } +#[abi="rust-intrinsic"] +pub extern { + fn floorf32(val: f32) -> f32; +} + // // Local Variables: // mode: rust diff --git a/src/libcore/f64.rs b/src/libcore/f64.rs index 97d9e8e758452..fc6cd113ebf0f 100644 --- a/src/libcore/f64.rs +++ b/src/libcore/f64.rs @@ -19,7 +19,13 @@ use cmp; use libc; use num; -pub use cmath::c_double_utils::*; +pub use cmath::c_double_utils::{acos, asin, atan, atan2, cbrt, ceil}; +pub use cmath::c_double_utils::{copysign, cos, cosh, erf, erfc, exp, expm1}; +pub use cmath::c_double_utils::{exp2, abs, abs_sub, mul_add, fmax, fmin}; +pub use cmath::c_double_utils::{nextafter, frexp, hypot, ldexp, lgamma}; +pub use cmath::c_double_utils::{ln, log_radix, ln1p, log10, log2, ilog_radix}; +pub use cmath::c_double_utils::{modf, pow, round, sin, sinh, sqrt, tan}; +pub use cmath::c_double_utils::{tanh, tgamma, trunc, j0, j1, jn, y0, y1, yn}; pub use cmath::c_double_targ_consts::*; // FIXME (#1433): obtain these in a different way @@ -113,11 +119,15 @@ pub pure fn is_infinite(x: f64) -> bool { return x == infinity || x == neg_infinity; } -/// Returns true if `x`is a finite number +/// Returns true if `x` is a finite number pub pure fn is_finite(x: f64) -> bool { return !(is_NaN(x) || is_infinite(x)); } +/// Returns `x` rounded down +#[inline(always)] +pub pure fn floor(x: f64) -> f64 { unsafe { floorf64(x) } } + // FIXME (#1999): add is_normal, is_subnormal, and fpclassify /* Module: consts */ @@ -206,6 +216,11 @@ impl f64: num::One { static pure fn one() -> f64 { 1.0 } } +#[abi="rust-intrinsic"] +pub extern { + fn floorf64(val: f64) -> f64; +} + // // Local Variables: // mode: rust diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index 4e5e9b97957e0..707b259db1f94 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -850,6 +850,8 @@ fn Resolver(session: Session, lang_items: LanguageItems, current_trait_refs: None, self_ident: special_idents::self_, + type_self_ident: special_idents::type_self, + primitive_type_table: @PrimitiveTypeTable(session. parse_sess.interner), @@ -905,6 +907,8 @@ struct Resolver { // The ident for the keyword "self". self_ident: ident, + // The ident for the non-keyword "Self". + type_self_ident: ident, // The idents for the primitive types. primitive_type_table: @PrimitiveTypeTable, @@ -3803,6 +3807,8 @@ impl Resolver { (*self.type_ribs).push(self_type_rib); self_type_rib.bindings.insert(self.self_ident, dl_def(def_self_ty(item.id))); + self_type_rib.bindings.insert(self.type_self_ident, + dl_def(def_self_ty(item.id))); // Create a new rib for the trait-wide type parameters. do self.with_type_parameter_rib diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index 606247b8cbede..93c030636239a 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -340,6 +340,7 @@ mod special_idents { const clownshoes_foreign_mod: ident = ident { repr: 33 }; const unnamed_field: ident = ident { repr: 34 }; const c_abi: ident = ident { repr: 35 }; + const type_self: ident = ident { repr: 36 }; // `Self` } struct ident_interner { @@ -379,15 +380,43 @@ fn mk_ident_interner() -> @ident_interner { // the indices here must correspond to the numbers in // special_idents. let init_vec = ~[ - @~"_", @~"anon", @~"drop", @~"", @~"unary", @~"!", - @~"[]", @~"unary-", @~"__extensions__", @~"self", - @~"item", @~"block", @~"stmt", @~"pat", @~"expr", - @~"ty", @~"ident", @~"path", @~"tt", @~"matchers", - @~"str", @~"TyVisitor", @~"arg", @~"descrim", - @~"__rust_abi", @~"__rust_stack_shim", @~"TyDesc", - @~"dtor", @~"main", @~"", @~"blk", @~"static", - @~"intrinsic", @~"__foreign_mod__", @~"__field__", - @~"C" + @~"_", // 0 + @~"anon", // 1 + @~"drop", // 2 + @~"", // 3 + @~"unary", // 4 + @~"!", // 5 + @~"[]", // 6 + @~"unary-", // 7 + @~"__extensions__", // 8 + @~"self", // 9 + @~"item", // 10 + @~"block", // 11 + @~"stmt", // 12 + @~"pat", // 13 + @~"expr", // 14 + @~"ty", // 15 + @~"ident", // 16 + @~"path", // 17 + @~"tt", // 18 + @~"matchers", // 19 + @~"str", // 20 + @~"TyVisitor", // 21 + @~"arg", // 22 + @~"descrim", // 23 + @~"__rust_abi", // 24 + @~"__rust_stack_shim", // 25 + @~"TyDesc", // 26 + @~"dtor", // 27 + @~"main", // 28 + @~"", // 29 + @~"blk", // 30 + @~"static", // 31 + @~"intrinsic", // 32 + @~"__foreign_mod__", // 33 + @~"__field__", // 34 + @~"C", // 35 + @~"Self", // 36 ]; let rv = @ident_interner { diff --git a/src/test/bench/noise.rs b/src/test/bench/noise.rs new file mode 100644 index 0000000000000..a07dcee35f4d3 --- /dev/null +++ b/src/test/bench/noise.rs @@ -0,0 +1,110 @@ +// Perlin noise benchmark from https://gist.github.com/1170424 + +struct Vec2 { + x: f32, + y: f32, +} + +fn lerp(a: f32, b: f32, v: f32) -> f32 { a * (1.0 - v) + b * v } +fn smooth(v: f32) -> f32 { v * v * (3.0 - 2.0 * v) } + +fn random_gradient(r: rand::Rng) -> Vec2 { + let v = r.gen_float() * float::consts::pi * 2.0; + Vec2{ + x: float::cos(v) as f32, + y: float::sin(v) as f32, + } +} + +fn gradient(orig: Vec2, grad: Vec2, p: Vec2) -> f32 { + let sp = Vec2{x: p.x - orig.x, y: p.y - orig.y}; + grad.x * sp.x + grad.y + sp.y +} + +struct Noise2DContext { + rgradients: [Vec2 * 256], + permutations: [int * 256], +} + +fn Noise2DContext() -> ~Noise2DContext { + let r = rand::Rng(); + let mut rgradients = [ Vec2 { x: 0.0, y: 0.0 }, ..256 ]; + for int::range(0, 256) |i| { rgradients[i] = random_gradient(r); } + let mut permutations = [ 0, ..256 ]; + for int::range(0, 256) |i| { permutations[i] = i; } + r.shuffle_mut(permutations); + + ~Noise2DContext{ + rgradients: move rgradients, + permutations: move permutations, + } +} + +impl Noise2DContext { + #[inline(always)] + fn get_gradient(&self, x: int, y: int) -> Vec2 { + let idx = self.permutations[x & 255] + self.permutations[y & 255]; + self.rgradients[idx & 255] + } + + #[inline(always)] + fn get_gradients(&self, gradients: &mut [Vec2 * 4], origins: &mut [Vec2 * 4], x: f32, y: f32) { + let x0f = f32::floor(x); + let y0f = f32::floor(y); + let x0 = x0f as int; + let y0 = y0f as int; + let x1 = x0 + 1; + let y1 = y0 + 1; + + gradients[0] = self.get_gradient(x0, y0); + gradients[1] = self.get_gradient(x1, y0); + gradients[2] = self.get_gradient(x0, y1); + gradients[3] = self.get_gradient(x1, y1); + + origins[0] = Vec2{x: x0f + 0.0, y: y0f + 0.0}; + origins[1] = Vec2{x: x0f + 1.0, y: y0f + 0.0}; + origins[2] = Vec2{x: x0f + 0.0, y: y0f + 1.0}; + origins[3] = Vec2{x: x0f + 1.0, y: y0f + 1.0}; + } + + fn get(&self, x: f32, y: f32) -> f32 { + let p = Vec2{x: x, y: y}; + let mut gradients = [ Vec2 { x: 0.0, y: 0.0 }, ..4 ]; + let mut origins = [ Vec2 { x: 0.0, y: 0.0 }, ..4 ]; + self.get_gradients(&mut gradients, &mut origins, x, y); + let v0 = gradient(origins[0], gradients[0], p); + let v1 = gradient(origins[1], gradients[1], p); + let v2 = gradient(origins[2], gradients[2], p); + let v3 = gradient(origins[3], gradients[3], p); + let fx = smooth(x - origins[0].x); + let vx0 = lerp(v0, v1, fx); + let vx1 = lerp(v2, v3, fx); + let fy = smooth(y - origins[0].y); + lerp(vx0, vx1, fy) + } +} + +fn main() { + let symbols = [" ", "░", "▒", "▓", "█", "█"]; + let mut pixels = vec::from_elem(256*256, 0f32); + let n2d = Noise2DContext(); + for int::range(0, 100) |_| { + for int::range(0, 256) |y| { + for int::range(0, 256) |x| { + let v = n2d.get( + x as f32 * 0.1f32, + y as f32 * 0.1f32 + ) * 0.5f32 + 0.5f32; + pixels[y*256+x] = v; + }; + }; + }; + + /*for int::range(0, 256) |y| { + for int::range(0, 256) |x| { + io::print(symbols[pixels[y*256+x] / 0.2f32 as int]); + } + io::println(""); + }*/ +} + diff --git a/src/test/run-pass/self-type-param.rs b/src/test/run-pass/self-type-param.rs new file mode 100644 index 0000000000000..ea42045fc46f1 --- /dev/null +++ b/src/test/run-pass/self-type-param.rs @@ -0,0 +1,16 @@ +trait MyTrait { + fn f(&self) -> Self; +} + +struct S { + x: int +} + +impl S : MyTrait { + fn f(&self) -> S { + S { x: 3 } + } +} + +fn main() {} +