I think whether vector element is mutable is decided by whether vector reference is mutable.
: Elements can be subtracted.
`mul`
: Elements can be multiplied.
-`quot`
- : Elements have a quotient operation.
+`div`
+ : Elements have a division operation.
`rem`
: Elements have a remainder operation.
`neg`
Calls the `mul` method on the `core::ops::Mul` trait.
`/`
: Quotient.
- Calls the `quot` method on the `core::ops::Quot` trait.
+ Calls the `div` method on the `core::ops::Div` trait.
`%`
: Remainder.
Calls the `rem` method on the `core::ops::Rem` trait.
An example of an `match` expression:
-~~~~ {.xfail-test}
+~~~~
# fn process_pair(a: int, b: int) { }
# fn process_ten() { }
$(Q)rm -f $(RUSTLLVM_LIB_OBJS) $(RUSTLLVM_OBJS_OBJS) $(RUSTLLVM_DEF)
$(Q)rm -Rf $(DOCS)
$(Q)rm -Rf $(GENERATED)
- $(Q)rm -f tmp/*.log tmp/*.rc tmp/*.rs tmp/*.ok
+ $(Q)rm -f tmp/*
$(Q)rm -Rf rust-stage0-*.tar.bz2 $(PKG_NAME)-*.tar.gz dist
$(Q)rm -Rf $(foreach ext, \
html aux cp fn ky log pdf pg toc tp vr cps, \
}
pub fn is_test_ignored(config: config, testfile: &Path) -> bool {
- let mut found = false;
for iter_header(testfile) |ln| {
if parse_name_directive(ln, ~"xfail-test") { return true; }
if parse_name_directive(ln, xfail_target()) { return true; }
if config.mode == common::mode_pretty &&
parse_name_directive(ln, ~"xfail-pretty") { return true; }
};
- return found;
+ return false;
fn xfail_target() -> ~str {
~"xfail-" + str::from_slice(os::SYSNAME)
fatal_ProcRes(~"test run failed!", ProcRes);
}
} else {
- let mut ProcRes = jit_test(config, props, testfile);
+ let ProcRes = jit_test(config, props, testfile);
if ProcRes.status != 0 { fatal_ProcRes(~"jit failed!", ProcRes); }
}
--- /dev/null
+#!/usr/bin/env python
+# xfail-license
+
+# This creates the tables used for distributions implemented using the
+# ziggurat algorithm in `core::rand::distributions;`. They are
+# (basically) the tables as used in the ZIGNOR variant (Doornik 2005).
+# They are changed rarely, so the generated file should be checked in
+# to git.
+#
+# It creates 3 tables: X as in the paper, F which is f(x_i), and
+# F_DIFF which is f(x_i) - f(x_{i-1}). The latter two are just cached
+# values which is not done in that paper (but is done in other
+# variants). Note that the adZigR table is unnecessary because of
+# algebra.
+#
+# It is designed to be compatible with Python 2 and 3.
+
+from math import exp, sqrt, log, floor
+import random
+
+# The order should match the return value of `tables`
+TABLE_NAMES = ['X', 'F', 'F_DIFF']
+
+# The actual length of the table is 1 more, to stop
+# index-out-of-bounds errors. This should match the bitwise operation
+# to find `i` in `zigurrat` in `libstd/rand/mod.rs`. Also the *_R and
+# *_V constants below depend on this value.
+TABLE_LEN = 256
+
+# equivalent to `zigNorInit` in Doornik2005, but generalised to any
+# distribution. r = dR, v = dV, f = probability density function,
+# f_inv = inverse of f
+def tables(r, v, f, f_inv):
+ # compute the x_i
+ xvec = [0]*(TABLE_LEN+1)
+
+ xvec[0] = v / f(r)
+ xvec[1] = r
+
+ for i in range(2, TABLE_LEN):
+ last = xvec[i-1]
+ xvec[i] = f_inv(v / last + f(last))
+
+ # cache the f's
+ fvec = [0]*(TABLE_LEN+1)
+ fdiff = [0]*(TABLE_LEN+1)
+ for i in range(TABLE_LEN+1):
+ fvec[i] = f(xvec[i])
+ if i > 0:
+ fdiff[i] = fvec[i] - fvec[i-1]
+
+ return xvec, fvec, fdiff
+
+# Distributions
+# N(0, 1)
+def norm_f(x):
+ return exp(-x*x/2.0)
+def norm_f_inv(y):
+ return sqrt(-2.0*log(y))
+
+NORM_R = 3.6541528853610088
+NORM_V = 0.00492867323399
+
+NORM = tables(NORM_R, NORM_V,
+ norm_f, norm_f_inv)
+
+# Exp(1)
+def exp_f(x):
+ return exp(-x)
+def exp_f_inv(y):
+ return -log(y)
+
+EXP_R = 7.69711747013104972
+EXP_V = 0.0039496598225815571993
+
+EXP = tables(EXP_R, EXP_V,
+ exp_f, exp_f_inv)
+
+
+# Output the tables/constants/types
+
+def render_static(name, type, value):
+ # no space or
+ return 'pub static %s: %s =%s;\n' % (name, type, value)
+
+# static `name`: [`type`, .. `len(values)`] =
+# [values[0], ..., values[3],
+# values[4], ..., values[7],
+# ... ];
+def render_table(name, values):
+ rows = []
+ # 4 values on each row
+ for i in range(0, len(values), 4):
+ row = values[i:i+4]
+ rows.append(', '.join('%.18f' % f for f in row))
+
+ rendered = '\n [%s]' % ',\n '.join(rows)
+ return render_static(name, '[f64, .. %d]' % len(values), rendered)
+
+
+with open('ziggurat_tables.rs', 'w') as f:
+ f.write('''// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Tables for distributions which are sampled using the ziggurat
+// algorithm. Autogenerated by `ziggurat_tables.py`.
+
+pub type ZigTable = &\'static [f64, .. %d];
+''' % (TABLE_LEN + 1))
+ for name, tables, r in [('NORM', NORM, NORM_R),
+ ('EXP', EXP, EXP_R)]:
+ f.write(render_static('ZIG_%s_R' % name, 'f64', ' %.18f' % r))
+ for (tabname, table) in zip(TABLE_NAMES, tables):
+ f.write(render_table('ZIG_%s_%s' % (name, tabname), table))
//! Utilities for manipulating the char type
+#[cfg(notest)]
use cmp::Ord;
use option::{None, Option, Some};
use str;
#[warn(vecs_implicitly_copyable)];
#[deny(non_camel_case_types)];
#[allow(deprecated_mutable_fields)];
-#[allow(deprecated_drop)];
// Make core testable by not duplicating lang items. See #2912
#[cfg(test)] extern mod realcore(name = "core", vers = "0.7-pre");
#[cfg(stage0)]
pub use ops::{Add, Sub, Mul, Div, Modulo, Neg, Not};
#[cfg(not(stage0))]
-pub use ops::{Add, Sub, Mul, Quot, Rem, Neg, Not};
+pub use ops::{Add, Sub, Mul, Div, Rem, Neg, Not};
pub use ops::{BitAnd, BitOr, BitXor};
pub use ops::{Shl, Shr, Index};
*/
+use cmp::Ord;
+use option::{Option, Some, None};
+
pub trait Times {
fn times(&self, it: &fn() -> bool);
}
true
}
+/**
+ * Return the first element where `predicate` returns `true`. Return `None` if no element is found.
+ *
+ * # Example:
+ *
+ * ~~~~
+ * let xs = ~[1u, 2, 3, 4, 5, 6];
+ * assert_eq!(*find(|& &x: & &uint| x > 3, |f| xs.each(f)).unwrap(), 4);
+ * ~~~~
+ */
+#[inline(always)]
+pub fn find<T>(predicate: &fn(&T) -> bool, iter: &fn(f: &fn(T) -> bool)) -> Option<T> {
+ for iter |x| {
+ if predicate(&x) {
+ return Some(x);
+ }
+ }
+ None
+}
+
+/**
+ * Return the largest item yielded by an iterator. Return `None` if the iterator is empty.
+ *
+ * # Example:
+ *
+ * ~~~~
+ * let xs = ~[8, 2, 3, 1, -5, 9, 11, 15];
+ * assert_eq!(max(|f| xs.each(f)).unwrap(), &15);
+ * ~~~~
+ */
+#[inline]
+pub fn max<T: Ord>(iter: &fn(f: &fn(T) -> bool)) -> Option<T> {
+ let mut result = None;
+ for iter |x| {
+ match result {
+ Some(ref mut y) => {
+ if x > *y {
+ *y = x;
+ }
+ }
+ None => result = Some(x)
+ }
+ }
+ result
+}
+
+/**
+ * Return the smallest item yielded by an iterator. Return `None` if the iterator is empty.
+ *
+ * # Example:
+ *
+ * ~~~~
+ * let xs = ~[8, 2, 3, 1, -5, 9, 11, 15];
+ * assert_eq!(max(|f| xs.each(f)).unwrap(), &-5);
+ * ~~~~
+ */
+#[inline]
+pub fn min<T: Ord>(iter: &fn(f: &fn(T) -> bool)) -> Option<T> {
+ let mut result = None;
+ for iter |x| {
+ match result {
+ Some(ref mut y) => {
+ if x < *y {
+ *y = x;
+ }
+ }
+ None => result = Some(x)
+ }
+ }
+ result
+}
+
#[cfg(test)]
mod tests {
use super::*;
assert!(all(|x: uint| x < 6, |f| uint::range(1, 6, f)));
assert!(!all(|x: uint| x < 5, |f| uint::range(1, 6, f)));
}
+
+ #[test]
+ fn test_find() {
+ let xs = ~[1u, 2, 3, 4, 5, 6];
+ assert_eq!(*find(|& &x: & &uint| x > 3, |f| xs.each(f)).unwrap(), 4);
+ }
+
+ #[test]
+ fn test_max() {
+ let xs = ~[8, 2, 3, 1, -5, 9, 11, 15];
+ assert_eq!(max(|f| xs.each(f)).unwrap(), &15);
+ }
+
+ #[test]
+ fn test_min() {
+ let xs = ~[8, 2, 3, 1, -5, 9, 11, 15];
+ assert_eq!(min(|f| xs.each(f)).unwrap(), &-5);
+ }
}
pub use libc::funcs::posix01::stat_::*;
pub use libc::funcs::posix01::unistd::*;
+pub use libc::funcs::posix01::glob::*;
pub use libc::funcs::posix08::unistd::*;
pub use libc::funcs::bsd44::*;
#[cfg(target_os = "android")]
pub mod os {
pub mod common {
- pub mod posix01 {}
+ pub mod posix01 {
+ use libc::types::common::c95::{c_void};
+ use libc::types::os::arch::c95::{c_char, size_t};
+ pub struct glob_t {
+ gl_pathc: size_t,
+ gl_pathv: **c_char,
+ gl_offs: size_t,
+
+ __unused1: *c_void,
+ __unused2: *c_void,
+ __unused3: *c_void,
+ __unused4: *c_void,
+ __unused5: *c_void,
+ }
+ }
}
#[cfg(target_arch = "x86")]
#[cfg(target_os = "freebsd")]
pub mod os {
pub mod common {
- pub mod posix01 {}
+ pub mod posix01 {
+ use libc::types::common::c95::{c_void};
+ use libc::types::os::arch::c95::{c_char, c_int, size_t};
+ pub struct glob_t {
+ gl_pathc: size_t,
+ __unused1: size_t,
+ gl_offs: size_t,
+ __unused2: c_int,
+ gl_pathv: **c_char,
+
+ __unused3: *c_void,
+
+ __unused4: *c_void,
+ __unused5: *c_void,
+ __unused6: *c_void,
+ __unused7: *c_void,
+ __unused8: *c_void,
+ }
+ }
}
#[cfg(target_arch = "x86_64")]
pub mod os {
pub mod common {
pub mod posix01 {
+ use libc::types::common::c95::{c_void};
+ use libc::types::os::arch::c95::{c_char, c_int, size_t};
+ pub struct glob_t {
+ gl_pathc: size_t,
+ __unused1: c_int,
+ gl_offs: size_t,
+ __unused2: c_int,
+ gl_pathv: **c_char,
+
+ __unused3: *c_void,
+
+ __unused4: *c_void,
+ __unused5: *c_void,
+ __unused6: *c_void,
+ __unused7: *c_void,
+ __unused8: *c_void,
+ }
}
}
}
pub mod posix01 {
pub static SIGTRAP : int = 5;
+
+ pub static GLOB_ERR : int = 1 << 0;
+ pub static GLOB_MARK : int = 1 << 1;
+ pub static GLOB_NOSORT : int = 1 << 2;
+ pub static GLOB_DOOFFS : int = 1 << 3;
+ pub static GLOB_NOCHECK : int = 1 << 4;
+ pub static GLOB_APPEND : int = 1 << 5;
+ pub static GLOB_NOESCAPE : int = 1 << 6;
+
+ pub static GLOB_NOSPACE : int = 1;
+ pub static GLOB_ABORTED : int = 2;
+ pub static GLOB_NOMATCH : int = 3;
}
pub mod posix08 {
}
}
pub mod posix01 {
pub static SIGTRAP : int = 5;
+
+ pub static GLOB_APPEND : int = 0x0001;
+ pub static GLOB_DOOFFS : int = 0x0002;
+ pub static GLOB_ERR : int = 0x0004;
+ pub static GLOB_MARK : int = 0x0008;
+ pub static GLOB_NOCHECK : int = 0x0010;
+ pub static GLOB_NOSORT : int = 0x0020;
+ pub static GLOB_NOESCAPE : int = 0x2000;
+
+ pub static GLOB_NOSPACE : int = -1;
+ pub static GLOB_ABORTED : int = -2;
+ pub static GLOB_NOMATCH : int = -3;
}
pub mod posix08 {
}
}
pub mod posix01 {
pub static SIGTRAP : int = 5;
+
+ pub static GLOB_APPEND : int = 0x0001;
+ pub static GLOB_DOOFFS : int = 0x0002;
+ pub static GLOB_ERR : int = 0x0004;
+ pub static GLOB_MARK : int = 0x0008;
+ pub static GLOB_NOCHECK : int = 0x0010;
+ pub static GLOB_NOSORT : int = 0x0020;
+ pub static GLOB_NOESCAPE : int = 0x2000;
+
+ pub static GLOB_NOSPACE : int = -1;
+ pub static GLOB_ABORTED : int = -2;
+ pub static GLOB_NOMATCH : int = -3;
}
pub mod posix08 {
}
-> pid_t;
}
}
+
+ #[nolink]
+ #[abi = "cdecl"]
+ pub mod glob {
+ use libc::types::common::c95::{c_void};
+ use libc::types::os::arch::c95::{c_char, c_int};
+ use libc::types::os::common::posix01::{glob_t};
+
+ pub extern {
+ unsafe fn glob(pattern: *c_char, flags: c_int,
+ errfunc: *c_void, // XXX callback
+ pglob: *mut glob_t);
+ unsafe fn globfree(pglob: *mut glob_t);
+ }
+ }
}
#[cfg(target_os = "win32")]
pub mod unistd {
}
+
+ pub mod glob {
+ }
}
pub fn mul(x: f32, y: f32) -> f32 { return x * y; }
#[inline(always)]
-pub fn quot(x: f32, y: f32) -> f32 { return x / y; }
+pub fn div(x: f32, y: f32) -> f32 { return x / y; }
#[inline(always)]
pub fn rem(x: f32, y: f32) -> f32 { return x % y; }
fn mul(&self, other: &f32) -> f32 { *self * *other }
}
-#[cfg(stage0,notest)]
+#[cfg(notest)]
impl Div<f32,f32> for f32 {
#[inline(always)]
fn div(&self, other: &f32) -> f32 { *self / *other }
}
-#[cfg(not(stage0),notest)]
-impl Quot<f32,f32> for f32 {
- #[inline(always)]
- fn quot(&self, other: &f32) -> f32 { *self / *other }
-}
#[cfg(stage0,notest)]
impl Modulo<f32,f32> for f32 {
pub fn mul(x: f64, y: f64) -> f64 { return x * y; }
#[inline(always)]
-pub fn quot(x: f64, y: f64) -> f64 { return x / y; }
+pub fn div(x: f64, y: f64) -> f64 { return x / y; }
#[inline(always)]
pub fn rem(x: f64, y: f64) -> f64 { return x % y; }
impl Mul<f64,f64> for f64 {
fn mul(&self, other: &f64) -> f64 { *self * *other }
}
-#[cfg(stage0,notest)]
+#[cfg(notest)]
impl Div<f64,f64> for f64 {
fn div(&self, other: &f64) -> f64 { *self / *other }
}
-#[cfg(not(stage0),notest)]
-impl Quot<f64,f64> for f64 {
- #[inline(always)]
- fn quot(&self, other: &f64) -> f64 { *self / *other }
-}
#[cfg(stage0,notest)]
impl Modulo<f64,f64> for f64 {
fn modulo(&self, other: &f64) -> f64 { *self % *other }
use num::{Zero, One, strconv};
use prelude::*;
-pub use f64::{add, sub, mul, quot, rem, lt, le, eq, ne, ge, gt};
+pub use f64::{add, sub, mul, div, rem, lt, le, eq, ne, ge, gt};
pub use f64::logarithm;
pub use f64::{acos, asin, atan2, cbrt, ceil, copysign, cosh, floor};
pub use f64::{erf, erfc, exp, expm1, exp2, abs_sub};
fn mul(&self, other: &float) -> float { *self * *other }
}
-#[cfg(stage0,notest)]
+#[cfg(notest)]
impl Div<float,float> for float {
#[inline(always)]
fn div(&self, other: &float) -> float { *self / *other }
}
-#[cfg(not(stage0),notest)]
-impl Quot<float,float> for float {
- #[inline(always)]
- fn quot(&self, other: &float) -> float { *self / *other }
-}
+
#[cfg(stage0,notest)]
impl Modulo<float,float> for float {
#[inline(always)]
#[inline(always)]
pub fn mul(x: T, y: T) -> T { x * y }
#[inline(always)]
-pub fn quot(x: T, y: T) -> T { x / y }
+pub fn div(x: T, y: T) -> T { x / y }
///
/// Returns the remainder of y / x.
fn mul(&self, other: &T) -> T { *self * *other }
}
-#[cfg(stage0,notest)]
+#[cfg(notest)]
impl Div<T,T> for T {
- #[inline(always)]
- fn div(&self, other: &T) -> T { *self / *other }
-}
-#[cfg(not(stage0),notest)]
-impl Quot<T,T> for T {
///
- /// Returns the integer quotient, truncated towards 0. As this behaviour reflects
- /// the underlying machine implementation it is more efficient than `Natural::div`.
+ /// Integer division, truncated towards 0. As this behaviour reflects the underlying
+ /// machine implementation it is more efficient than `Integer::div_floor`.
///
/// # Examples
///
/// ~~~
///
#[inline(always)]
- fn quot(&self, other: &T) -> T { *self / *other }
+ fn div(&self, other: &T) -> T { *self / *other }
}
#[cfg(stage0,notest)]
/// # Examples
///
/// ~~~
- /// assert!(( 8).div( 3) == 2);
- /// assert!(( 8).div(-3) == -3);
- /// assert!((-8).div( 3) == -3);
- /// assert!((-8).div(-3) == 2);
+ /// assert!(( 8).div_floor( 3) == 2);
+ /// assert!(( 8).div_floor(-3) == -3);
+ /// assert!((-8).div_floor( 3) == -3);
+ /// assert!((-8).div_floor(-3) == 2);
///
- /// assert!(( 1).div( 2) == 0);
- /// assert!(( 1).div(-2) == -1);
- /// assert!((-1).div( 2) == -1);
- /// assert!((-1).div(-2) == 0);
+ /// assert!(( 1).div_floor( 2) == 0);
+ /// assert!(( 1).div_floor(-2) == -1);
+ /// assert!((-1).div_floor( 2) == -1);
+ /// assert!((-1).div_floor(-2) == 0);
/// ~~~
///
#[inline(always)]
- fn div(&self, other: &T) -> T {
+ fn div_floor(&self, other: &T) -> T {
// Algorithm from [Daan Leijen. _Division and Modulus for Computer Scientists_,
// December 2001](http://research.microsoft.com/pubs/151917/divmodnote-letter.pdf)
- match self.quot_rem(other) {
- (q, r) if (r > 0 && *other < 0)
- || (r < 0 && *other > 0) => q - 1,
- (q, _) => q,
+ match self.div_rem(other) {
+ (d, r) if (r > 0 && *other < 0)
+ || (r < 0 && *other > 0) => d - 1,
+ (d, _) => d,
}
}
/// Integer modulo, satisfying:
///
/// ~~~
- /// assert!(n.div(d) * d + n.modulo(d) == n)
+ /// assert!(n.div_floor(d) * d + n.mod_floor(d) == n)
/// ~~~
///
/// # Examples
///
/// ~~~
- /// assert!(( 8).modulo( 3) == 2);
- /// assert!(( 8).modulo(-3) == -1);
- /// assert!((-8).modulo( 3) == 1);
- /// assert!((-8).modulo(-3) == -2);
+ /// assert!(( 8).mod_floor( 3) == 2);
+ /// assert!(( 8).mod_floor(-3) == -1);
+ /// assert!((-8).mod_floor( 3) == 1);
+ /// assert!((-8).mod_floor(-3) == -2);
///
- /// assert!(( 1).modulo( 2) == 1);
- /// assert!(( 1).modulo(-2) == -1);
- /// assert!((-1).modulo( 2) == 1);
- /// assert!((-1).modulo(-2) == -1);
+ /// assert!(( 1).mod_floor( 2) == 1);
+ /// assert!(( 1).mod_floor(-2) == -1);
+ /// assert!((-1).mod_floor( 2) == 1);
+ /// assert!((-1).mod_floor(-2) == -1);
/// ~~~
///
#[inline(always)]
- fn modulo(&self, other: &T) -> T {
+ fn mod_floor(&self, other: &T) -> T {
// Algorithm from [Daan Leijen. _Division and Modulus for Computer Scientists_,
// December 2001](http://research.microsoft.com/pubs/151917/divmodnote-letter.pdf)
match *self % *other {
}
}
- /// Calculates `div` and `modulo` simultaneously
+ /// Calculates `div_floor` and `mod_floor` simultaneously
#[inline(always)]
- fn div_mod(&self, other: &T) -> (T,T) {
+ fn div_mod_floor(&self, other: &T) -> (T,T) {
// Algorithm from [Daan Leijen. _Division and Modulus for Computer Scientists_,
// December 2001](http://research.microsoft.com/pubs/151917/divmodnote-letter.pdf)
- match self.quot_rem(other) {
- (q, r) if (r > 0 && *other < 0)
- || (r < 0 && *other > 0) => (q - 1, r + *other),
- (q, r) => (q, r),
+ match self.div_rem(other) {
+ (d, r) if (r > 0 && *other < 0)
+ || (r < 0 && *other > 0) => (d - 1, r + *other),
+ (d, r) => (d, r),
}
}
- /// Calculates `quot` (`\`) and `rem` (`%`) simultaneously
+ /// Calculates `div` (`\`) and `rem` (`%`) simultaneously
#[inline(always)]
- fn quot_rem(&self, other: &T) -> (T,T) {
+ fn div_rem(&self, other: &T) -> (T,T) {
(*self / *other, *self % *other)
}
}
#[test]
- fn test_quot_rem() {
- fn test_nd_qr(nd: (T,T), qr: (T,T)) {
+ fn test_div_rem() {
+ fn test_nd_dr(nd: (T,T), qr: (T,T)) {
let (n,d) = nd;
- let separate_quot_rem = (n / d, n % d);
- let combined_quot_rem = n.quot_rem(&d);
+ let separate_div_rem = (n / d, n % d);
+ let combined_div_rem = n.div_rem(&d);
- assert_eq!(separate_quot_rem, qr);
- assert_eq!(combined_quot_rem, qr);
+ assert_eq!(separate_div_rem, qr);
+ assert_eq!(combined_div_rem, qr);
- test_division_rule(nd, separate_quot_rem);
- test_division_rule(nd, combined_quot_rem);
+ test_division_rule(nd, separate_div_rem);
+ test_division_rule(nd, combined_div_rem);
}
- test_nd_qr(( 8, 3), ( 2, 2));
- test_nd_qr(( 8, -3), (-2, 2));
- test_nd_qr((-8, 3), (-2, -2));
- test_nd_qr((-8, -3), ( 2, -2));
+ test_nd_dr(( 8, 3), ( 2, 2));
+ test_nd_dr(( 8, -3), (-2, 2));
+ test_nd_dr((-8, 3), (-2, -2));
+ test_nd_dr((-8, -3), ( 2, -2));
- test_nd_qr(( 1, 2), ( 0, 1));
- test_nd_qr(( 1, -2), ( 0, 1));
- test_nd_qr((-1, 2), ( 0, -1));
- test_nd_qr((-1, -2), ( 0, -1));
+ test_nd_dr(( 1, 2), ( 0, 1));
+ test_nd_dr(( 1, -2), ( 0, 1));
+ test_nd_dr((-1, 2), ( 0, -1));
+ test_nd_dr((-1, -2), ( 0, -1));
}
#[test]
- fn test_div_mod() {
+ fn test_div_mod_floor() {
fn test_nd_dm(nd: (T,T), dm: (T,T)) {
let (n,d) = nd;
- let separate_div_mod = (n.div(&d), n.modulo(&d));
- let combined_div_mod = n.div_mod(&d);
+ let separate_div_mod_floor = (n.div_floor(&d), n.mod_floor(&d));
+ let combined_div_mod_floor = n.div_mod_floor(&d);
- assert_eq!(separate_div_mod, dm);
- assert_eq!(combined_div_mod, dm);
+ assert_eq!(separate_div_mod_floor, dm);
+ assert_eq!(combined_div_mod_floor, dm);
- test_division_rule(nd, separate_div_mod);
- test_division_rule(nd, combined_div_mod);
+ test_division_rule(nd, separate_div_mod_floor);
+ test_division_rule(nd, combined_div_mod_floor);
}
test_nd_dm(( 8, 3), ( 2, 2));
//! An interface for numeric types
use cmp::{Eq, Ord};
#[cfg(stage0)]
-use ops::{Add, Sub, Mul, Neg};
-#[cfg(stage0)]
-use Quot = ops::Div;
+use ops::{Add, Sub, Mul, Div, Neg};
#[cfg(stage0)]
use Rem = ops::Modulo;
#[cfg(not(stage0))]
-use ops::{Add, Sub, Mul, Quot, Rem, Neg};
+use ops::{Add, Sub, Mul, Div, Rem, Neg};
use ops::{Not, BitAnd, BitOr, BitXor, Shl, Shr};
use option::Option;
use kinds::Copy;
+ Add<Self,Self>
+ Sub<Self,Self>
+ Mul<Self,Self>
- + Quot<Self,Self>
+ + Div<Self,Self>
+ Rem<Self,Self> {}
pub trait IntConvertible {
pub trait Integer: Num
+ Orderable
- + Quot<Self,Self>
+ + Div<Self,Self>
+ Rem<Self,Self> {
- fn div(&self, other: &Self) -> Self;
- fn modulo(&self, other: &Self) -> Self;
- fn div_mod(&self, other: &Self) -> (Self,Self);
- fn quot_rem(&self, other: &Self) -> (Self,Self);
+ fn div_rem(&self, other: &Self) -> (Self,Self);
+
+ fn div_floor(&self, other: &Self) -> Self;
+ fn mod_floor(&self, other: &Self) -> Self;
+ fn div_mod_floor(&self, other: &Self) -> (Self,Self);
fn gcd(&self, other: &Self) -> Self;
fn lcm(&self, other: &Self) -> Self;
pub trait Fractional: Num
+ Orderable
+ Round
- + Quot<Self,Self> {
+ + Div<Self,Self> {
fn recip(&self) -> Self;
}
+ Add<Self,Self>
+ Sub<Self,Self>
+ Mul<Self,Self>
- + Quot<Self,Self>
+ + Div<Self,Self>
+ Rem<Self,Self> {
// FIXME (#5527): These should be associated constants
fn bits() -> uint;
/// - If code written to use this function doesn't care about it, it's
/// probably assuming that `x^0` always equals `1`.
///
-pub fn pow_with_uint<T:NumCast+One+Zero+Copy+Quot<T,T>+Mul<T,T>>(
+pub fn pow_with_uint<T:NumCast+One+Zero+Copy+Div<T,T>+Mul<T,T>>(
radix: uint, pow: uint) -> T {
let _0: T = Zero::zero();
let _1: T = One::one();
assert_eq!(ten.add(&two), cast(12));
assert_eq!(ten.sub(&two), cast(8));
assert_eq!(ten.mul(&two), cast(20));
- assert_eq!(ten.quot(&two), cast(5));
+ assert_eq!(ten.div(&two), cast(5));
assert_eq!(ten.rem(&two), cast(0));
assert_eq!(ten.add(&two), ten + two);
assert_eq!(ten.sub(&two), ten - two);
assert_eq!(ten.mul(&two), ten * two);
- assert_eq!(ten.quot(&two), ten / two);
+ assert_eq!(ten.div(&two), ten / two);
assert_eq!(ten.rem(&two), ten % two);
}
use core::cmp::{Ord, Eq};
#[cfg(stage0)]
-use ops::{Add, Sub, Mul, Neg};
-#[cfg(stage0)]
-use Quot = ops::Div;
+use ops::{Add, Sub, Mul, Div, Neg};
#[cfg(stage0)]
use Rem = ops::Modulo;
#[cfg(stage1)]
#[cfg(stage2)]
#[cfg(stage3)]
-use ops::{Add, Sub, Mul, Quot, Rem, Neg};
+use ops::{Add, Sub, Mul, Div, Rem, Neg};
use option::{None, Option, Some};
use char;
use str;
}
#[inline(always)]
-fn is_neg_zero<T:Eq+One+Zero+NumStrConv+Quot<T,T>>(num: &T) -> bool {
+fn is_neg_zero<T:Eq+One+Zero+NumStrConv+Div<T,T>>(num: &T) -> bool {
let _0: T = Zero::zero();
let _1: T = One::one();
* - Fails if `radix` < 2 or `radix` > 36.
*/
pub fn to_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+NumStrConv+Copy+
- Quot<T,T>+Neg<T>+Rem<T,T>+Mul<T,T>>(
+ Div<T,T>+Neg<T>+Rem<T,T>+Mul<T,T>>(
num: &T, radix: uint, negative_zero: bool,
sign: SignFormat, digits: SignificantDigits) -> (~[u8], bool) {
if (radix as int) < 2 {
*/
#[inline(always)]
pub fn to_str_common<T:NumCast+Zero+One+Eq+Ord+NumStrConv+Copy+
- Quot<T,T>+Neg<T>+Rem<T,T>+Mul<T,T>>(
+ Div<T,T>+Neg<T>+Rem<T,T>+Mul<T,T>>(
num: &T, radix: uint, negative_zero: bool,
sign: SignFormat, digits: SignificantDigits) -> (~str, bool) {
let (bytes, special) = to_str_bytes_common(num, radix,
* - Fails if `radix` > 18 and `special == true` due to conflict
* between digit and lowest first character in `inf` and `NaN`, the `'i'`.
*/
-pub fn from_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Copy+Quot<T,T>+
+pub fn from_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Copy+Div<T,T>+
Mul<T,T>+Sub<T,T>+Neg<T>+Add<T,T>+
NumStrConv>(
buf: &[u8], radix: uint, negative: bool, fractional: bool,
* `from_str_bytes_common()`, for details see there.
*/
#[inline(always)]
-pub fn from_str_common<T:NumCast+Zero+One+Eq+Ord+Copy+Quot<T,T>+Mul<T,T>+
+pub fn from_str_common<T:NumCast+Zero+One+Eq+Ord+Copy+Div<T,T>+Mul<T,T>+
Sub<T,T>+Neg<T>+Add<T,T>+NumStrConv>(
buf: &str, radix: uint, negative: bool, fractional: bool,
special: bool, exponent: ExponentFormat, empty_zero: bool,
#[inline(always)]
pub fn mul(x: T, y: T) -> T { x * y }
#[inline(always)]
-pub fn quot(x: T, y: T) -> T { x / y }
+pub fn div(x: T, y: T) -> T { x / y }
#[inline(always)]
pub fn rem(x: T, y: T) -> T { x % y }
fn mul(&self, other: &T) -> T { *self * *other }
}
-#[cfg(stage0,notest)]
+#[cfg(notest)]
impl Div<T,T> for T {
#[inline(always)]
fn div(&self, other: &T) -> T { *self / *other }
}
-#[cfg(not(stage0),notest)]
-impl Quot<T,T> for T {
- #[inline(always)]
- fn quot(&self, other: &T) -> T { *self / *other }
-}
#[cfg(stage0,notest)]
impl Modulo<T,T> for T {
impl Unsigned for T {}
impl Integer for T {
- /// Unsigned integer division. Returns the same result as `quot` (`/`).
+ /// Calculates `div` (`\`) and `rem` (`%`) simultaneously
#[inline(always)]
- fn div(&self, other: &T) -> T { *self / *other }
+ fn div_rem(&self, other: &T) -> (T,T) {
+ (*self / *other, *self % *other)
+ }
- /// Unsigned integer modulo operation. Returns the same result as `rem` (`%`).
+ /// Unsigned integer division. Returns the same result as `div` (`/`).
#[inline(always)]
- fn modulo(&self, other: &T) -> T { *self / *other }
+ fn div_floor(&self, other: &T) -> T { *self / *other }
- /// Calculates `div` and `modulo` simultaneously
+ /// Unsigned integer modulo operation. Returns the same result as `rem` (`%`).
#[inline(always)]
- fn div_mod(&self, other: &T) -> (T,T) {
- (*self / *other, *self % *other)
- }
+ fn mod_floor(&self, other: &T) -> T { *self / *other }
- /// Calculates `quot` (`\`) and `rem` (`%`) simultaneously
+ /// Calculates `div_floor` and `modulo_floor` simultaneously
#[inline(always)]
- fn quot_rem(&self, other: &T) -> (T,T) {
+ fn div_mod_floor(&self, other: &T) -> (T,T) {
(*self / *other, *self % *other)
}
}
#[lang="div"]
-#[cfg(stage0)]
pub trait Div<RHS,Result> {
fn div(&self, rhs: &RHS) -> Result;
}
-#[lang="quot"]
-#[cfg(not(stage0))]
-pub trait Quot<RHS,Result> {
- fn quot(&self, rhs: &RHS) -> Result;
-}
#[lang="modulo"]
#[cfg(stage0)]
use str;
use task;
use uint;
+use unstable::finally::Finally;
use vec;
pub use libc::fclose;
}
}
+/// Changes the current working directory to the specified
+/// path while acquiring a global lock, then calls `action`.
+/// If the change is successful, releases the lock and restores the
+/// CWD to what it was before, returning true.
+/// Returns false if the directory doesn't exist or if the directory change
+/// is otherwise unsuccessful.
+pub fn change_dir_locked(p: &Path, action: &fn()) -> bool {
+ use unstable::global::global_data_clone_create;
+ use unstable::{Exclusive, exclusive};
+
+ fn key(_: Exclusive<()>) { }
+
+ let result = unsafe {
+ global_data_clone_create(key, || {
+ ~exclusive(())
+ })
+ };
+
+ do result.with_imm() |_| {
+ let old_dir = os::getcwd();
+ if change_dir(p) {
+ action();
+ change_dir(&old_dir)
+ }
+ else {
+ false
+ }
+ }
+}
+
/// Copies a file from one location to another
pub fn copy_file(from: &Path, to: &Path) -> bool {
return do_copy_file(from, to);
}
}
+// FIXME #6100 we should really use an internal implementation of this - using
+// the POSIX glob functions isn't portable to windows, probably has slight
+// inconsistencies even where it is implemented, and makes extending
+// functionality a lot more difficult
+// FIXME #6101 also provide a non-allocating version - each_glob or so?
+/// Returns a vector of Path objects that match the given glob pattern
+#[cfg(target_os = "linux")]
+#[cfg(target_os = "android")]
+#[cfg(target_os = "freebsd")]
+#[cfg(target_os = "macos")]
+pub fn glob(pattern: &str) -> ~[Path] {
+ #[cfg(target_os = "linux")]
+ #[cfg(target_os = "android")]
+ fn default_glob_t () -> libc::glob_t {
+ libc::glob_t {
+ gl_pathc: 0,
+ gl_pathv: ptr::null(),
+ gl_offs: 0,
+ __unused1: ptr::null(),
+ __unused2: ptr::null(),
+ __unused3: ptr::null(),
+ __unused4: ptr::null(),
+ __unused5: ptr::null(),
+ }
+ }
+
+ #[cfg(target_os = "freebsd")]
+ fn default_glob_t () -> libc::glob_t {
+ libc::glob_t {
+ gl_pathc: 0,
+ __unused1: 0,
+ gl_offs: 0,
+ __unused2: 0,
+ gl_pathv: ptr::null(),
+ __unused3: ptr::null(),
+ __unused4: ptr::null(),
+ __unused5: ptr::null(),
+ __unused6: ptr::null(),
+ __unused7: ptr::null(),
+ __unused8: ptr::null(),
+ }
+ }
+
+ #[cfg(target_os = "macos")]
+ fn default_glob_t () -> libc::glob_t {
+ libc::glob_t {
+ gl_pathc: 0,
+ __unused1: 0,
+ gl_offs: 0,
+ __unused2: 0,
+ gl_pathv: ptr::null(),
+ __unused3: ptr::null(),
+ __unused4: ptr::null(),
+ __unused5: ptr::null(),
+ __unused6: ptr::null(),
+ __unused7: ptr::null(),
+ __unused8: ptr::null(),
+ }
+ }
+
+ let mut g = default_glob_t();
+ do str::as_c_str(pattern) |c_pattern| {
+ unsafe { libc::glob(c_pattern, 0, ptr::null(), &mut g) }
+ };
+ do(|| {
+ let paths = unsafe {
+ vec::raw::from_buf_raw(g.gl_pathv, g.gl_pathc as uint)
+ };
+ do paths.map |&c_str| {
+ Path(unsafe { str::raw::from_c_str(c_str) })
+ }
+ }).finally {
+ unsafe { libc::globfree(&mut g) };
+ }
+}
+
+/// Returns a vector of Path objects that match the given glob pattern
+#[cfg(target_os = "win32")]
+pub fn glob(pattern: &str) -> ~[Path] {
+ fail!(~"glob() is unimplemented on Windows")
+}
+
#[cfg(target_os = "macos")]
extern {
// These functions are in crt_externs.h.
use either::{Either, Left, Right};
use kinds::Owned;
use libc;
+use ops::Drop;
use option::{None, Option, Some};
+use unstable::finally::Finally;
use unstable::intrinsics;
use ptr;
use task;
let p_ = p.unwrap();
let p = unsafe { &*p_ };
- #[unsafe_destructor]
- struct DropState<'self> {
- p: &'self PacketHeader,
-
- drop {
- unsafe {
- if task::failing() {
- self.p.state = Terminated;
- let old_task = swap_task(&mut self.p.blocked_task,
- ptr::null());
- if !old_task.is_null() {
- rustrt::rust_task_deref(old_task);
- }
+ do (|| {
+ try_recv_(p)
+ }).finally {
+ unsafe {
+ if task::failing() {
+ p.header.state = Terminated;
+ let old_task = swap_task(&mut p.header.blocked_task, ptr::null());
+ if !old_task.is_null() {
+ rustrt::rust_task_deref(old_task);
}
}
}
- };
-
- let _drop_state = DropState { p: &p.header };
+ }
+}
+fn try_recv_<T:Owned>(p: &Packet<T>) -> Option<T> {
// optimistic path
match p.header.state {
Full => {
Blocked);
match old_state {
Empty => {
- debug!("no data available on %?, going to sleep.", p_);
+ debug!("no data available on %?, going to sleep.", p);
if count == 0 {
wait_event(this);
}
#[cfg(stage0)]
pub use ops::{Add, Sub, Mul, Div, Modulo, Neg, Not};
#[cfg(not(stage0))]
-pub use ops::{Add, Sub, Mul, Quot, Rem, Neg, Not};
+pub use ops::{Add, Sub, Mul, Div, Rem, Neg, Not};
pub use ops::{BitAnd, BitOr, BitXor};
pub use ops::{Drop};
pub use ops::{Shl, Shr, Index};
means that often a simple call to `rand::random()` or `rng.gen()` will
suffice, but sometimes an annotation is required, e.g. `rand::random::<float>()`.
+See the `distributions` submodule for sampling random numbers from
+distributions like normal and exponential.
+
# Examples
~~~
use core::rand::RngUtil;
use vec;
use libc::size_t;
+#[path="rand/distributions.rs"]
+pub mod distributions;
+
/// A type that can be randomly generated using an Rng
pub trait Rand {
fn rand<R: Rng>(rng: &R) -> Self;
--- /dev/null
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Sampling from random distributions
+
+// Some implementations use the Ziggurat method
+// https://en.wikipedia.org/wiki/Ziggurat_algorithm
+//
+// The version used here is ZIGNOR [Doornik 2005, "An Improved
+// Ziggurat Method to Generate Normal Random Samples"] which is slower
+// (about double, it generates an extra random number) than the
+// canonical version [Marsaglia & Tsang 2000, "The Ziggurat Method for
+// Generating Random Variables"], but more robust. If one wanted, one
+// could implement VIZIGNOR the ZIGNOR paper for more speed.
+
+use prelude::*;
+use rand::{Rng,Rand};
+
+mod ziggurat_tables;
+
+// inlining should mean there is no performance penalty for this
+#[inline(always)]
+fn ziggurat<R:Rng>(rng: &R,
+ center_u: bool,
+ X: ziggurat_tables::ZigTable,
+ F: ziggurat_tables::ZigTable,
+ F_DIFF: ziggurat_tables::ZigTable,
+ pdf: &'static fn(f64) -> f64, // probability density function
+ zero_case: &'static fn(&R, f64) -> f64) -> f64 {
+ loop {
+ let u = if center_u {2.0 * rng.gen() - 1.0} else {rng.gen()};
+ let i: uint = rng.gen::<uint>() & 0xff;
+ let x = u * X[i];
+
+ let test_x = if center_u {f64::abs(x)} else {x};
+
+ // algebraically equivalent to |u| < X[i+1]/X[i] (or u < X[i+1]/X[i])
+ if test_x < X[i + 1] {
+ return x;
+ }
+ if i == 0 {
+ return zero_case(rng, u);
+ }
+ // algebraically equivalent to f1 + DRanU()*(f0 - f1) < 1
+ if F[i+1] + F_DIFF[i+1] * rng.gen() < pdf(x) {
+ return x;
+ }
+ }
+}
+
+/// A wrapper around an `f64` to generate N(0, 1) random numbers (a.k.a. a
+/// standard normal, or Gaussian). Multiplying the generated values by the
+/// desired standard deviation `sigma` then adding the desired mean `mu` will
+/// give N(mu, sigma^2) distributed random numbers.
+///
+/// Note that this has to be unwrapped before use as an `f64` (using either
+/// `*` or `cast::transmute` is safe).
+///
+/// # Example
+///
+/// ~~~
+/// use core::rand::distributions::StandardNormal;
+///
+/// fn main() {
+/// let normal = 2.0 + (*rand::random::<StandardNormal>()) * 3.0;
+/// println(fmt!("%f is from a N(2, 9) distribution", normal))
+/// }
+/// ~~~
+pub struct StandardNormal(f64);
+
+impl Rand for StandardNormal {
+ fn rand<R:Rng>(rng: &R) -> StandardNormal {
+ #[inline(always)]
+ fn pdf(x: f64) -> f64 {
+ f64::exp((-x*x/2.0) as f64) as f64
+ }
+ #[inline(always)]
+ fn zero_case<R:Rng>(rng: &R, u: f64) -> f64 {
+ // compute a random number in the tail by hand
+
+ // strange initial conditions, because the loop is not
+ // do-while, so the condition should be true on the first
+ // run, they get overwritten anyway (0 < 1, so these are
+ // good).
+ let mut x = 1.0, y = 0.0;
+
+ // XXX infinities?
+ while -2.0*y < x * x {
+ x = f64::ln(rng.gen()) / ziggurat_tables::ZIG_NORM_R;
+ y = f64::ln(rng.gen());
+ }
+ if u < 0.0 {x-ziggurat_tables::ZIG_NORM_R} else {ziggurat_tables::ZIG_NORM_R-x}
+ }
+
+ StandardNormal(ziggurat(
+ rng,
+ true, // this is symmetric
+ &ziggurat_tables::ZIG_NORM_X,
+ &ziggurat_tables::ZIG_NORM_F, &ziggurat_tables::ZIG_NORM_F_DIFF,
+ pdf, zero_case))
+ }
+}
+
+/// A wrapper around an `f64` to generate Exp(1) random numbers. Dividing by
+/// the desired rate `lambda` will give Exp(lambda) distributed random
+/// numbers.
+///
+/// Note that this has to be unwrapped before use as an `f64` (using either
+/// `*` or `cast::transmute` is safe).
+///
+/// # Example
+///
+/// ~~~
+/// use core::rand::distributions::Exp1;
+///
+/// fn main() {
+/// let exp2 = (*rand::random::<Exp1>()) * 0.5;
+/// println(fmt!("%f is from a Exp(2) distribution", exp2));
+/// }
+/// ~~~
+pub struct Exp1(f64);
+
+// This could be done via `-f64::ln(rng.gen::<f64>())` but that is slower.
+impl Rand for Exp1 {
+ #[inline]
+ fn rand<R:Rng>(rng: &R) -> Exp1 {
+ #[inline(always)]
+ fn pdf(x: f64) -> f64 {
+ f64::exp(-x)
+ }
+ #[inline(always)]
+ fn zero_case<R:Rng>(rng: &R, _u: f64) -> f64 {
+ ziggurat_tables::ZIG_EXP_R - f64::ln(rng.gen())
+ }
+
+ Exp1(ziggurat(rng, false,
+ &ziggurat_tables::ZIG_EXP_X,
+ &ziggurat_tables::ZIG_EXP_F, &ziggurat_tables::ZIG_EXP_F_DIFF,
+ pdf, zero_case))
+ }
+}
--- /dev/null
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Tables for distributions which are sampled using the ziggurat
+// algorithm. Autogenerated by `ziggurat_tables.py`.
+
+pub type ZigTable = &'static [f64, .. 257];
+pub static ZIG_NORM_R: f64 = 3.654152885361008796;
+pub static ZIG_NORM_X: [f64, .. 257] =
+ [3.910757959537090045, 3.654152885361008796, 3.449278298560964462, 3.320244733839166074,
+ 3.224575052047029100, 3.147889289517149969, 3.083526132001233044, 3.027837791768635434,
+ 2.978603279880844834, 2.934366867207854224, 2.894121053612348060, 2.857138730872132548,
+ 2.822877396825325125, 2.790921174000785765, 2.760944005278822555, 2.732685359042827056,
+ 2.705933656121858100, 2.680514643284522158, 2.656283037575502437, 2.633116393630324570,
+ 2.610910518487548515, 2.589575986706995181, 2.569035452680536569, 2.549221550323460761,
+ 2.530075232158516929, 2.511544441625342294, 2.493583041269680667, 2.476149939669143318,
+ 2.459208374333311298, 2.442725318198956774, 2.426670984935725972, 2.411018413899685520,
+ 2.395743119780480601, 2.380822795170626005, 2.366237056715818632, 2.351967227377659952,
+ 2.337996148795031370, 2.324308018869623016, 2.310888250599850036, 2.297723348901329565,
+ 2.284800802722946056, 2.272108990226823888, 2.259637095172217780, 2.247375032945807760,
+ 2.235313384928327984, 2.223443340090905718, 2.211756642882544366, 2.200245546609647995,
+ 2.188902771624720689, 2.177721467738641614, 2.166695180352645966, 2.155817819875063268,
+ 2.145083634046203613, 2.134487182844320152, 2.124023315687815661, 2.113687150684933957,
+ 2.103474055713146829, 2.093379631137050279, 2.083399693996551783, 2.073530263516978778,
+ 2.063767547809956415, 2.054107931648864849, 2.044547965215732788, 2.035084353727808715,
+ 2.025713947862032960, 2.016433734904371722, 2.007240830558684852, 1.998132471356564244,
+ 1.989106007615571325, 1.980158896898598364, 1.971288697931769640, 1.962493064942461896,
+ 1.953769742382734043, 1.945116560006753925, 1.936531428273758904, 1.928012334050718257,
+ 1.919557336591228847, 1.911164563769282232, 1.902832208548446369, 1.894558525668710081,
+ 1.886341828534776388, 1.878180486290977669, 1.870072921069236838, 1.862017605397632281,
+ 1.854013059758148119, 1.846057850283119750, 1.838150586580728607, 1.830289919680666566,
+ 1.822474540091783224, 1.814703175964167636, 1.806974591348693426, 1.799287584547580199,
+ 1.791640986550010028, 1.784033659547276329, 1.776464495522344977, 1.768932414909077933,
+ 1.761436365316706665, 1.753975320315455111, 1.746548278279492994, 1.739154261283669012,
+ 1.731792314050707216, 1.724461502945775715, 1.717160915015540690, 1.709889657069006086,
+ 1.702646854797613907, 1.695431651932238548, 1.688243209434858727, 1.681080704722823338,
+ 1.673943330923760353, 1.666830296159286684, 1.659740822855789499, 1.652674147080648526,
+ 1.645629517902360339, 1.638606196773111146, 1.631603456932422036, 1.624620582830568427,
+ 1.617656869570534228, 1.610711622367333673, 1.603784156023583041, 1.596873794420261339,
+ 1.589979870021648534, 1.583101723393471438, 1.576238702733332886, 1.569390163412534456,
+ 1.562555467528439657, 1.555733983466554893, 1.548925085471535512, 1.542128153226347553,
+ 1.535342571438843118, 1.528567729435024614, 1.521803020758293101, 1.515047842773992404,
+ 1.508301596278571965, 1.501563685112706548, 1.494833515777718391, 1.488110497054654369,
+ 1.481394039625375747, 1.474683555695025516, 1.467978458615230908, 1.461278162507407830,
+ 1.454582081885523293, 1.447889631277669675, 1.441200224845798017, 1.434513276002946425,
+ 1.427828197027290358, 1.421144398672323117, 1.414461289772464658, 1.407778276843371534,
+ 1.401094763676202559, 1.394410150925071257, 1.387723835686884621, 1.381035211072741964,
+ 1.374343665770030531, 1.367648583594317957, 1.360949343030101844, 1.354245316759430606,
+ 1.347535871177359290, 1.340820365893152122, 1.334098153216083604, 1.327368577624624679,
+ 1.320630975217730096, 1.313884673146868964, 1.307128989027353860, 1.300363230327433728,
+ 1.293586693733517645, 1.286798664489786415, 1.279998415710333237, 1.273185207661843732,
+ 1.266358287014688333, 1.259516886060144225, 1.252660221891297887, 1.245787495544997903,
+ 1.238897891102027415, 1.231990574742445110, 1.225064693752808020, 1.218119375481726552,
+ 1.211153726239911244, 1.204166830140560140, 1.197157747875585931, 1.190125515422801650,
+ 1.183069142678760732, 1.175987612011489825, 1.168879876726833800, 1.161744859441574240,
+ 1.154581450355851802, 1.147388505416733873, 1.140164844363995789, 1.132909248648336975,
+ 1.125620459211294389, 1.118297174115062909, 1.110938046009249502, 1.103541679420268151,
+ 1.096106627847603487, 1.088631390649514197, 1.081114409698889389, 1.073554065787871714,
+ 1.065948674757506653, 1.058296483326006454, 1.050595664586207123, 1.042844313139370538,
+ 1.035040439828605274, 1.027181966030751292, 1.019266717460529215, 1.011292417434978441,
+ 1.003256679539591412, 0.995156999629943084, 0.986990747093846266, 0.978755155288937750,
+ 0.970447311058864615, 0.962064143217605250, 0.953602409875572654, 0.945058684462571130,
+ 0.936429340280896860, 0.927710533396234771, 0.918898183643734989, 0.909987953490768997,
+ 0.900975224455174528, 0.891855070726792376, 0.882622229578910122, 0.873271068082494550,
+ 0.863795545546826915, 0.854189171001560554, 0.844444954902423661, 0.834555354079518752,
+ 0.824512208745288633, 0.814306670128064347, 0.803929116982664893, 0.793369058833152785,
+ 0.782615023299588763, 0.771654424216739354, 0.760473406422083165, 0.749056662009581653,
+ 0.737387211425838629, 0.725446140901303549, 0.713212285182022732, 0.700661841097584448,
+ 0.687767892786257717, 0.674499822827436479, 0.660822574234205984, 0.646695714884388928,
+ 0.632072236375024632, 0.616896989996235545, 0.601104617743940417, 0.584616766093722262,
+ 0.567338257040473026, 0.549151702313026790, 0.529909720646495108, 0.509423329585933393,
+ 0.487443966121754335, 0.463634336771763245, 0.437518402186662658, 0.408389134588000746,
+ 0.375121332850465727, 0.335737519180459465, 0.286174591747260509, 0.215241895913273806,
+ 0.000000000000000000];
+pub static ZIG_NORM_F: [f64, .. 257] =
+ [0.000477467764586655, 0.001260285930498598, 0.002609072746106363, 0.004037972593371872,
+ 0.005522403299264754, 0.007050875471392110, 0.008616582769422917, 0.010214971439731100,
+ 0.011842757857943104, 0.013497450601780807, 0.015177088307982072, 0.016880083152595839,
+ 0.018605121275783350, 0.020351096230109354, 0.022117062707379922, 0.023902203305873237,
+ 0.025705804008632656, 0.027527235669693315, 0.029365939758230111, 0.031221417192023690,
+ 0.033093219458688698, 0.034980941461833073, 0.036884215688691151, 0.038802707404656918,
+ 0.040736110656078753, 0.042684144916619378, 0.044646552251446536, 0.046623094902089664,
+ 0.048613553216035145, 0.050617723861121788, 0.052635418276973649, 0.054666461325077916,
+ 0.056710690106399467, 0.058767952921137984, 0.060838108349751806, 0.062921024437977854,
+ 0.065016577971470438, 0.067124653828023989, 0.069245144397250269, 0.071377949059141965,
+ 0.073522973714240991, 0.075680130359194964, 0.077849336702372207, 0.080030515814947509,
+ 0.082223595813495684, 0.084428509570654661, 0.086645194450867782, 0.088873592068594229,
+ 0.091113648066700734, 0.093365311913026619, 0.095628536713353335, 0.097903279039215627,
+ 0.100189498769172020, 0.102487158942306270, 0.104796225622867056, 0.107116667775072880,
+ 0.109448457147210021, 0.111791568164245583, 0.114145977828255210, 0.116511665626037014,
+ 0.118888613443345698, 0.121276805485235437, 0.123676228202051403, 0.126086870220650349,
+ 0.128508722280473636, 0.130941777174128166, 0.133386029692162844, 0.135841476571757352,
+ 0.138308116449064322, 0.140785949814968309, 0.143274978974047118, 0.145775208006537926,
+ 0.148286642733128721, 0.150809290682410169, 0.153343161060837674, 0.155888264725064563,
+ 0.158444614156520225, 0.161012223438117663, 0.163591108232982951, 0.166181285765110071,
+ 0.168782774801850333, 0.171395595638155623, 0.174019770082499359, 0.176655321444406654,
+ 0.179302274523530397, 0.181960655600216487, 0.184630492427504539, 0.187311814224516926,
+ 0.190004651671193070, 0.192709036904328807, 0.195425003514885592, 0.198152586546538112,
+ 0.200891822495431333, 0.203642749311121501, 0.206405406398679298, 0.209179834621935651,
+ 0.211966076307852941, 0.214764175252008499, 0.217574176725178370, 0.220396127481011589,
+ 0.223230075764789593, 0.226076071323264877, 0.228934165415577484, 0.231804410825248525,
+ 0.234686861873252689, 0.237581574432173676, 0.240488605941449107, 0.243408015423711988,
+ 0.246339863502238771, 0.249284212419516704, 0.252241126056943765, 0.255210669955677150,
+ 0.258192911338648023, 0.261187919133763713, 0.264195763998317568, 0.267216518344631837,
+ 0.270250256366959984, 0.273297054069675804, 0.276356989296781264, 0.279430141762765316,
+ 0.282516593084849388, 0.285616426816658109, 0.288729728483353931, 0.291856585618280984,
+ 0.294997087801162572, 0.298151326697901342, 0.301319396102034120, 0.304501391977896274,
+ 0.307697412505553769, 0.310907558127563710, 0.314131931597630143, 0.317370638031222396,
+ 0.320623784958230129, 0.323891482377732021, 0.327173842814958593, 0.330470981380537099,
+ 0.333783015832108509, 0.337110066638412809, 0.340452257045945450, 0.343809713148291340,
+ 0.347182563958251478, 0.350570941482881204, 0.353974980801569250, 0.357394820147290515,
+ 0.360830600991175754, 0.364282468130549597, 0.367750569780596226, 0.371235057669821344,
+ 0.374736087139491414, 0.378253817247238111, 0.381788410875031348, 0.385340034841733958,
+ 0.388908860020464597, 0.392495061461010764, 0.396098818517547080, 0.399720314981931668,
+ 0.403359739222868885, 0.407017284331247953, 0.410693148271983222, 0.414387534042706784,
+ 0.418100649839684591, 0.421832709231353298, 0.425583931339900579, 0.429354541031341519,
+ 0.433144769114574058, 0.436954852549929273, 0.440785034667769915, 0.444635565397727750,
+ 0.448506701509214067, 0.452398706863882505, 0.456311852680773566, 0.460246417814923481,
+ 0.464202689050278838, 0.468180961407822172, 0.472181538469883255, 0.476204732721683788,
+ 0.480250865911249714, 0.484320269428911598, 0.488413284707712059, 0.492530263646148658,
+ 0.496671569054796314, 0.500837575128482149, 0.505028667945828791, 0.509245245998136142,
+ 0.513487720749743026, 0.517756517232200619, 0.522052074674794864, 0.526374847174186700,
+ 0.530725304406193921, 0.535103932383019565, 0.539511234259544614, 0.543947731192649941,
+ 0.548413963257921133, 0.552910490428519918, 0.557437893621486324, 0.561996775817277916,
+ 0.566587763258951771, 0.571211506738074970, 0.575868682975210544, 0.580559996103683473,
+ 0.585286179266300333, 0.590047996335791969, 0.594846243770991268, 0.599681752622167719,
+ 0.604555390700549533, 0.609468064928895381, 0.614420723892076803, 0.619414360609039205,
+ 0.624450015550274240, 0.629528779928128279, 0.634651799290960050, 0.639820277456438991,
+ 0.645035480824251883, 0.650298743114294586, 0.655611470583224665, 0.660975147780241357,
+ 0.666391343912380640, 0.671861719900766374, 0.677388036222513090, 0.682972161648791376,
+ 0.688616083008527058, 0.694321916130032579, 0.700091918140490099, 0.705928501336797409,
+ 0.711834248882358467, 0.717811932634901395, 0.723864533472881599, 0.729995264565802437,
+ 0.736207598131266683, 0.742505296344636245, 0.748892447223726720, 0.755373506511754500,
+ 0.761953346841546475, 0.768637315803334831, 0.775431304986138326, 0.782341832659861902,
+ 0.789376143571198563, 0.796542330428254619, 0.803849483176389490, 0.811307874318219935,
+ 0.818929191609414797, 0.826726833952094231, 0.834716292992930375, 0.842915653118441077,
+ 0.851346258465123684, 0.860033621203008636, 0.869008688043793165, 0.878309655816146839,
+ 0.887984660763399880, 0.898095921906304051, 0.908726440060562912, 0.919991505048360247,
+ 0.932060075968990209, 0.945198953453078028, 0.959879091812415930, 0.977101701282731328,
+ 1.000000000000000000];
+pub static ZIG_NORM_F_DIFF: [f64, .. 257] =
+ [0.000000000000000000, 0.000782818165911943, 0.001348786815607765, 0.001428899847265509,
+ 0.001484430705892882, 0.001528472172127356, 0.001565707298030807, 0.001598388670308183,
+ 0.001627786418212004, 0.001654692743837703, 0.001679637706201265, 0.001702994844613767,
+ 0.001725038123187510, 0.001745974954326004, 0.001765966477270568, 0.001785140598493315,
+ 0.001803600702759419, 0.001821431661060659, 0.001838704088536796, 0.001855477433793579,
+ 0.001871802266665008, 0.001887722003144375, 0.001903274226858077, 0.001918491715965767,
+ 0.001933403251421835, 0.001948034260540625, 0.001962407334827158, 0.001976542650643127,
+ 0.001990458313945481, 0.002004170645086643, 0.002017694415851860, 0.002031043048104267,
+ 0.002044228781321551, 0.002057262814738517, 0.002070155428613822, 0.002082916088226049,
+ 0.002095553533492583, 0.002108075856553551, 0.002120490569226280, 0.002132804661891696,
+ 0.002145024655099026, 0.002157156644953973, 0.002169206343177243, 0.002181179112575302,
+ 0.002193079998548175, 0.002204913757158977, 0.002216684880213121, 0.002228397617726446,
+ 0.002240055998106505, 0.002251663846325885, 0.002263224800326716, 0.002274742325862292,
+ 0.002286219729956393, 0.002297660173134250, 0.002309066680560787, 0.002320442152205823,
+ 0.002331789372137141, 0.002343111017035562, 0.002354409664009627, 0.002365687797781804,
+ 0.002376947817308683, 0.002388192041889739, 0.002399422716815966, 0.002410642018598946,
+ 0.002421852059823287, 0.002433054893654529, 0.002444252518034679, 0.002455446879594508,
+ 0.002466639877306970, 0.002477833365903986, 0.002489029159078809, 0.002500229032490808,
+ 0.002511434726590794, 0.002522647949281448, 0.002533870378427505, 0.002545103664226889,
+ 0.002556349431455662, 0.002567609281597438, 0.002578884794865288, 0.002590177532127119,
+ 0.002601489036740262, 0.002612820836305291, 0.002624174444343735, 0.002635551361907296,
+ 0.002646953079123743, 0.002658381076686089, 0.002669836827288052, 0.002681321797012387,
+ 0.002692837446676144, 0.002704385233135737, 0.002715966610556786, 0.002727583031652520,
+ 0.002739235948893221, 0.002750926815690169, 0.002762657087557796, 0.002774428223256353,
+ 0.002786241685917290, 0.002798098944155558, 0.002810001473169871, 0.002821950755833219,
+ 0.002833948283778004, 0.002845995558475284, 0.002858094092312607, 0.002870245409671041,
+ 0.002882451048004164, 0.002894712558920987, 0.002907031509275432, 0.002919409482262880,
+ 0.002931848078526783, 0.002944348917277934, 0.002956913637427061, 0.002969543898733384,
+ 0.002982241382970874, 0.002995007795115689, 0.003007844864553855, 0.003020754346314269,
+ 0.003033738022328147, 0.003046797702715820, 0.003059935227105459, 0.003073152465984053,
+ 0.003086451322084072, 0.003099833731808721, 0.003113301666695822, 0.003126857134927052,
+ 0.003140502182881588, 0.003154238896738770, 0.003168069404132778, 0.003181995875862154,
+ 0.003196020527657495, 0.003210145622009941, 0.003224373470066433, 0.003238706433592253,
+ 0.003253146927007733, 0.003267697419501892, 0.003282360437226572, 0.003297138565578506,
+ 0.003312034451571411, 0.003327050806304299, 0.003342190407532641, 0.003357456102345890,
+ 0.003372850809960137, 0.003388377524629727, 0.003404039318688046, 0.003419839345721265,
+ 0.003435780843885239, 0.003451867139373843, 0.003468101650046629, 0.003484487889225119,
+ 0.003501029469670069, 0.003517730107746697, 0.003534593627793237, 0.003551623966702611,
+ 0.003568825178730639, 0.003586201440546166, 0.003603757056536316, 0.003621496464384588,
+ 0.003639424240937217, 0.003657545108379068, 0.003675863940735269, 0.003694385770723563,
+ 0.003713115796977806, 0.003732059391668707, 0.003751222108547281, 0.003770609691440940,
+ 0.003790228083232539, 0.003810083435355216, 0.003830182117840641, 0.003850530729957835,
+ 0.003871136111486317, 0.003892005354668437, 0.003913145816891062, 0.003934565134149914,
+ 0.003956271235355358, 0.003978272357543333, 0.004000577062061084, 0.004023194251800533,
+ 0.004046133189565926, 0.004069403517661885, 0.004093015278800460, 0.004116978938436600,
+ 0.004141305408647655, 0.004166006073685835, 0.004191092817346642, 0.004216578052307351,
+ 0.004242474751606884, 0.004268796482457593, 0.004295557442594244, 0.004322772499391836,
+ 0.004350457232007221, 0.004378627976825644, 0.004407301876525049, 0.004436496933105327,
+ 0.004466232065271192, 0.004496527170598785, 0.004527403192966406, 0.004558882195791591,
+ 0.004590987441673855, 0.004623743479123199, 0.004657176237135574, 0.004691313128472929,
+ 0.004726183162616859, 0.004761817069491636, 0.004798247435199299, 0.004835508851176451,
+ 0.004873638078381815, 0.004912674228345848, 0.004952658963181422, 0.004993636716962402,
+ 0.005035654941235035, 0.005078764377854039, 0.005123019362831771, 0.005168478165478940,
+ 0.005215203367812893, 0.005263262290042703, 0.005312727468930079, 0.005363677197016692,
+ 0.005416196132139284, 0.005470375988385734, 0.005526316321746716, 0.005584125426278286,
+ 0.005643921359735682, 0.005705833121505521, 0.005770002010457520, 0.005836583196307310,
+ 0.005905747545561058, 0.005977683752542928, 0.006052600837980204, 0.006130731092920838,
+ 0.006212333565464245, 0.006297698213369562, 0.006387150879090475, 0.006481059288027780,
+ 0.006579840329791975, 0.006683968961788356, 0.006793989182803495, 0.006910527673723577,
+ 0.007034310911336661, 0.007166186857056056, 0.007307152748134871, 0.007458391141830445,
+ 0.007621317291194862, 0.007797642342679434, 0.007989459040836144, 0.008199360125510702,
+ 0.008430605346682607, 0.008687362737884952, 0.008975066840784529, 0.009300967772353674,
+ 0.009675004947253041, 0.010111261142904171, 0.010630518154258861, 0.011265064987797335,
+ 0.012068570920629962, 0.013138877484087819, 0.014680138359337902, 0.017222609470315398,
+ 0.022898298717268672];
+pub static ZIG_EXP_R: f64 = 7.697117470131050077;
+pub static ZIG_EXP_X: [f64, .. 257] =
+ [8.697117470131052741, 7.697117470131050077, 6.941033629377212577, 6.478378493832569696,
+ 6.144164665772472667, 5.882144315795399869, 5.666410167454033697, 5.482890627526062488,
+ 5.323090505754398016, 5.181487281301500047, 5.054288489981304089, 4.938777085901250530,
+ 4.832939741025112035, 4.735242996601741083, 4.644491885420085175, 4.559737061707351380,
+ 4.480211746528421912, 4.405287693473573185, 4.334443680317273007, 4.267242480277365857,
+ 4.203313713735184365, 4.142340865664051464, 4.084051310408297830, 4.028208544647936762,
+ 3.974606066673788796, 3.923062500135489739, 3.873417670399509127, 3.825529418522336744,
+ 3.779270992411667862, 3.734528894039797375, 3.691201090237418825, 3.649195515760853770,
+ 3.608428813128909507, 3.568825265648337020, 3.530315889129343354, 3.492837654774059608,
+ 3.456332821132760191, 3.420748357251119920, 3.386035442460300970, 3.352149030900109405,
+ 3.319047470970748037, 3.286692171599068679, 3.255047308570449882, 3.224079565286264160,
+ 3.193757903212240290, 3.164053358025972873, 3.134938858084440394, 3.106389062339824481,
+ 3.078380215254090224, 3.050890016615455114, 3.023897504455676621, 2.997382949516130601,
+ 2.971327759921089662, 2.945714394895045718, 2.920526286512740821, 2.895747768600141825,
+ 2.871364012015536371, 2.847360965635188812, 2.823725302450035279, 2.800444370250737780,
+ 2.777506146439756574, 2.754899196562344610, 2.732612636194700073, 2.710636095867928752,
+ 2.688959688741803689, 2.667573980773266573, 2.646469963151809157, 2.625639026797788489,
+ 2.605072938740835564, 2.584763820214140750, 2.564704126316905253, 2.544886627111869970,
+ 2.525304390037828028, 2.505950763528594027, 2.486819361740209455, 2.467904050297364815,
+ 2.449198932978249754, 2.430698339264419694, 2.412396812688870629, 2.394289099921457886,
+ 2.376370140536140596, 2.358635057409337321, 2.341079147703034380, 2.323697874390196372,
+ 2.306486858283579799, 2.289441870532269441, 2.272558825553154804, 2.255833774367219213,
+ 2.239262898312909034, 2.222842503111036816, 2.206569013257663858, 2.190438966723220027,
+ 2.174449009937774679, 2.158595893043885994, 2.142876465399842001, 2.127287671317368289,
+ 2.111826546019042183, 2.096490211801715020, 2.081275874393225145, 2.066180819490575526,
+ 2.051202409468584786, 2.036338080248769611, 2.021585338318926173, 2.006941757894518563,
+ 1.992404978213576650, 1.977972700957360441, 1.963642687789548313, 1.949412758007184943,
+ 1.935280786297051359, 1.921244700591528076, 1.907302480018387536, 1.893452152939308242,
+ 1.879691795072211180, 1.866019527692827973, 1.852433515911175554, 1.838931967018879954,
+ 1.825513128903519799, 1.812175288526390649, 1.798916770460290859, 1.785735935484126014,
+ 1.772631179231305643, 1.759600930889074766, 1.746643651946074405, 1.733757834985571566,
+ 1.720942002521935299, 1.708194705878057773, 1.695514524101537912, 1.682900062917553896,
+ 1.670349953716452118, 1.657862852574172763, 1.645437439303723659, 1.633072416535991334,
+ 1.620766508828257901, 1.608518461798858379, 1.596327041286483395, 1.584191032532688892,
+ 1.572109239386229707, 1.560080483527888084, 1.548103603714513499, 1.536177455041032092,
+ 1.524300908219226258, 1.512472848872117082, 1.500692176842816750, 1.488957805516746058,
+ 1.477268661156133867, 1.465623682245745352, 1.454021818848793446, 1.442462031972012504,
+ 1.430943292938879674, 1.419464582769983219, 1.408024891569535697, 1.396623217917042137,
+ 1.385258568263121992, 1.373929956328490576, 1.362636402505086775, 1.351376933258335189,
+ 1.340150580529504643, 1.328956381137116560, 1.317793376176324749, 1.306660610415174117,
+ 1.295557131686601027, 1.284481990275012642, 1.273434238296241139, 1.262412929069615330,
+ 1.251417116480852521, 1.240445854334406572, 1.229498195693849105, 1.218573192208790124,
+ 1.207669893426761121, 1.196787346088403092, 1.185924593404202199, 1.175080674310911677,
+ 1.164254622705678921, 1.153445466655774743, 1.142652227581672841, 1.131873919411078511,
+ 1.121109547701330200, 1.110358108727411031, 1.099618588532597308, 1.088889961938546813,
+ 1.078171191511372307, 1.067461226479967662, 1.056759001602551429, 1.046063435977044209,
+ 1.035373431790528542, 1.024687873002617211, 1.014005623957096480, 1.003325527915696735,
+ 0.992646405507275897, 0.981967053085062602, 0.971286240983903260, 0.960602711668666509,
+ 0.949915177764075969, 0.939222319955262286, 0.928522784747210395, 0.917815182070044311,
+ 0.907098082715690257, 0.896370015589889935, 0.885629464761751528, 0.874874866291025066,
+ 0.864104604811004484, 0.853317009842373353, 0.842510351810368485, 0.831682837734273206,
+ 0.820832606554411814, 0.809957724057418282, 0.799056177355487174, 0.788125868869492430,
+ 0.777164609759129710, 0.766170112735434672, 0.755139984181982249, 0.744071715500508102,
+ 0.732962673584365398, 0.721810090308756203, 0.710611050909655040, 0.699362481103231959,
+ 0.688061132773747808, 0.676703568029522584, 0.665286141392677943, 0.653804979847664947,
+ 0.642255960424536365, 0.630634684933490286, 0.618936451394876075, 0.607156221620300030,
+ 0.595288584291502887, 0.583327712748769489, 0.571267316532588332, 0.559100585511540626,
+ 0.546820125163310577, 0.534417881237165604, 0.521885051592135052, 0.509211982443654398,
+ 0.496388045518671162, 0.483401491653461857, 0.470239275082169006, 0.456886840931420235,
+ 0.443327866073552401, 0.429543940225410703, 0.415514169600356364, 0.401214678896277765,
+ 0.386617977941119573, 0.371692145329917234, 0.356399760258393816, 0.340696481064849122,
+ 0.324529117016909452, 0.307832954674932158, 0.290527955491230394, 0.272513185478464703,
+ 0.253658363385912022, 0.233790483059674731, 0.212671510630966620, 0.189958689622431842,
+ 0.165127622564187282, 0.137304980940012589, 0.104838507565818778, 0.063852163815001570,
+ 0.000000000000000000];
+pub static ZIG_EXP_F: [f64, .. 257] =
+ [0.000167066692307963, 0.000454134353841497, 0.000967269282327174, 0.001536299780301573,
+ 0.002145967743718907, 0.002788798793574076, 0.003460264777836904, 0.004157295120833797,
+ 0.004877655983542396, 0.005619642207205489, 0.006381905937319183, 0.007163353183634991,
+ 0.007963077438017043, 0.008780314985808977, 0.009614413642502212, 0.010464810181029981,
+ 0.011331013597834600, 0.012212592426255378, 0.013109164931254991, 0.014020391403181943,
+ 0.014945968011691148, 0.015885621839973156, 0.016839106826039941, 0.017806200410911355,
+ 0.018786700744696024, 0.019780424338009740, 0.020787204072578114, 0.021806887504283581,
+ 0.022839335406385240, 0.023884420511558174, 0.024942026419731787, 0.026012046645134221,
+ 0.027094383780955803, 0.028188948763978646, 0.029295660224637411, 0.030414443910466622,
+ 0.031545232172893622, 0.032687963508959555, 0.033842582150874358, 0.035009037697397431,
+ 0.036187284781931443, 0.037377282772959382, 0.038578995503074871, 0.039792391023374139,
+ 0.041017441380414840, 0.042254122413316254, 0.043502413568888197, 0.044762297732943289,
+ 0.046033761076175184, 0.047316792913181561, 0.048611385573379504, 0.049917534282706379,
+ 0.051235237055126281, 0.052564494593071685, 0.053905310196046080, 0.055257689676697030,
+ 0.056621641283742870, 0.057997175631200659, 0.059384305633420280, 0.060783046445479660,
+ 0.062193415408541036, 0.063615431999807376, 0.065049117786753805, 0.066494496385339816,
+ 0.067951593421936643, 0.069420436498728783, 0.070901055162371843, 0.072393480875708752,
+ 0.073897746992364746, 0.075413888734058410, 0.076941943170480517, 0.078481949201606435,
+ 0.080033947542319905, 0.081597980709237419, 0.083174093009632397, 0.084762330532368146,
+ 0.086362741140756927, 0.087975374467270231, 0.089600281910032886, 0.091237516631040197,
+ 0.092887133556043569, 0.094549189376055873, 0.096223742550432825, 0.097910853311492213,
+ 0.099610583670637132, 0.101322997425953631, 0.103048160171257702, 0.104786139306570145,
+ 0.106537004050001632, 0.108300825451033755, 0.110077676405185357, 0.111867631670056283,
+ 0.113670767882744286, 0.115487163578633506, 0.117316899211555525, 0.119160057175327641,
+ 0.121016721826674792, 0.122886979509545108, 0.124770918580830933, 0.126668629437510671,
+ 0.128580204545228199, 0.130505738468330773, 0.132445327901387494, 0.134399071702213602,
+ 0.136367070926428829, 0.138349428863580176, 0.140346251074862399, 0.142357645432472146,
+ 0.144383722160634720, 0.146424593878344889, 0.148480375643866735, 0.150551185001039839,
+ 0.152637142027442801, 0.154738369384468027, 0.156854992369365148, 0.158987138969314129,
+ 0.161134939917591952, 0.163298528751901734, 0.165478041874935922, 0.167673618617250081,
+ 0.169885401302527550, 0.172113535315319977, 0.174358169171353411, 0.176619454590494829,
+ 0.178897546572478278, 0.181192603475496261, 0.183504787097767436, 0.185834262762197083,
+ 0.188181199404254262, 0.190545769663195363, 0.192928149976771296, 0.195328520679563189,
+ 0.197747066105098818, 0.200183974691911210, 0.202639439093708962, 0.205113656293837654,
+ 0.207606827724221982, 0.210119159388988230, 0.212650861992978224, 0.215202151075378628,
+ 0.217773247148700472, 0.220364375843359439, 0.222975768058120111, 0.225607660116683956,
+ 0.228260293930716618, 0.230933917169627356, 0.233628783437433291, 0.236345152457059560,
+ 0.239083290262449094, 0.241843469398877131, 0.244625969131892024, 0.247431075665327543,
+ 0.250259082368862240, 0.253110290015629402, 0.255985007030415324, 0.258883549749016173,
+ 0.261806242689362922, 0.264753418835062149, 0.267725419932044739, 0.270722596799059967,
+ 0.273745309652802915, 0.276793928448517301, 0.279868833236972869, 0.282970414538780746,
+ 0.286099073737076826, 0.289255223489677693, 0.292439288161892630, 0.295651704281261252,
+ 0.298892921015581847, 0.302163400675693528, 0.305463619244590256, 0.308794066934560185,
+ 0.312155248774179606, 0.315547685227128949, 0.318971912844957239, 0.322428484956089223,
+ 0.325917972393556354, 0.329440964264136438, 0.332998068761809096, 0.336589914028677717,
+ 0.340217149066780189, 0.343880444704502575, 0.347580494621637148, 0.351318016437483449,
+ 0.355093752866787626, 0.358908472948750001, 0.362762973354817997, 0.366658079781514379,
+ 0.370594648435146223, 0.374573567615902381, 0.378595759409581067, 0.382662181496010056,
+ 0.386773829084137932, 0.390931736984797384, 0.395136981833290435, 0.399390684475231350,
+ 0.403694012530530555, 0.408048183152032673, 0.412454465997161457, 0.416914186433003209,
+ 0.421428728997616908, 0.425999541143034677, 0.430628137288459167, 0.435316103215636907,
+ 0.440065100842354173, 0.444876873414548846, 0.449753251162755330, 0.454696157474615836,
+ 0.459707615642138023, 0.464789756250426511, 0.469944825283960310, 0.475175193037377708,
+ 0.480483363930454543, 0.485871987341885248, 0.491343869594032867, 0.496901987241549881,
+ 0.502549501841348056, 0.508289776410643213, 0.514126393814748894, 0.520063177368233931,
+ 0.526104213983620062, 0.532253880263043655, 0.538516872002862246, 0.544898237672440056,
+ 0.551403416540641733, 0.558038282262587892, 0.564809192912400615, 0.571723048664826150,
+ 0.578787358602845359, 0.586010318477268366, 0.593400901691733762, 0.600968966365232560,
+ 0.608725382079622346, 0.616682180915207878, 0.624852738703666200, 0.633251994214366398,
+ 0.641896716427266423, 0.650805833414571433, 0.660000841079000145, 0.669506316731925177,
+ 0.679350572264765806, 0.689566496117078431, 0.700192655082788606, 0.711274760805076456,
+ 0.722867659593572465, 0.735038092431424039, 0.747868621985195658, 0.761463388849896838,
+ 0.775956852040116218, 0.791527636972496285, 0.808421651523009044, 0.826993296643051101,
+ 0.847785500623990496, 0.871704332381204705, 0.900469929925747703, 0.938143680862176477,
+ 1.000000000000000000];
+pub static ZIG_EXP_F_DIFF: [f64, .. 257] =
+ [0.000000000000000000, 0.000287067661533533, 0.000513134928485678, 0.000569030497974398,
+ 0.000609667963417335, 0.000642831049855169, 0.000671465984262828, 0.000697030342996893,
+ 0.000720360862708599, 0.000741986223663093, 0.000762263730113694, 0.000781447246315807,
+ 0.000799724254382053, 0.000817237547791934, 0.000834098656693235, 0.000850396538527769,
+ 0.000866203416804620, 0.000881578828420777, 0.000896572504999613, 0.000911226471926952,
+ 0.000925576608509206, 0.000939653828282008, 0.000953484986066785, 0.000967093584871414,
+ 0.000980500333784669, 0.000993723593313716, 0.001006779734568374, 0.001019683431705467,
+ 0.001032447902101660, 0.001045085105172934, 0.001057605908173612, 0.001070020225402434,
+ 0.001082337135821582, 0.001094564983022843, 0.001106711460658764, 0.001118783685829211,
+ 0.001130788262427001, 0.001142731336065933, 0.001154618641914802, 0.001166455546523074,
+ 0.001178247084534012, 0.001189997991027938, 0.001201712730115490, 0.001213395520299268,
+ 0.001225050357040701, 0.001236681032901414, 0.001248291155571943, 0.001259884164055092,
+ 0.001271463343231895, 0.001283031837006378, 0.001294592660197942, 0.001306148709326875,
+ 0.001317702772419903, 0.001329257537945404, 0.001340815602974395, 0.001352379480650950,
+ 0.001363951607045839, 0.001375534347457789, 0.001387130002219621, 0.001398740812059381,
+ 0.001410368963061376, 0.001422016591266340, 0.001433685786946429, 0.001445378598586011,
+ 0.001457097036596827, 0.001468843076792140, 0.001480618663643060, 0.001492425713336909,
+ 0.001504266116655995, 0.001516141741693663, 0.001528054436422108, 0.001540006031125918,
+ 0.001551998340713470, 0.001564033166917514, 0.001576112300394977, 0.001588237522735750,
+ 0.001600410608388780, 0.001612633326513305, 0.001624907442762655, 0.001637234721007311,
+ 0.001649616925003372, 0.001662055820012304, 0.001674553174376953, 0.001687110761059388,
+ 0.001699730359144919, 0.001712413755316500, 0.001725162745304071, 0.001737979135312442,
+ 0.001750864743431488, 0.001763821401032123, 0.001776850954151601, 0.001789955264870927,
+ 0.001803136212688003, 0.001816395695889220, 0.001829735632922019, 0.001843157963772116,
+ 0.001856664651347151, 0.001870257682870316, 0.001883939071285826, 0.001897710856679738,
+ 0.001911575107717528, 0.001925533923102574, 0.001939589433056721, 0.001953743800826108,
+ 0.001967999224215228, 0.001982357937151347, 0.001996822211282223, 0.002011394357609747,
+ 0.002026076728162574, 0.002040871717710169, 0.002055781765521847, 0.002070809357173103,
+ 0.002085957026402963, 0.002101227357025226, 0.002116622984897121, 0.002132146599948981,
+ 0.002147800948277823, 0.002163588834309782, 0.002179513123034188, 0.002195576742314159,
+ 0.002211782685277469, 0.002228134012792427, 0.002244633856033434, 0.002261285419141418,
+ 0.002278091981983449, 0.002295056903017983, 0.002312183622271174, 0.002329475664429648,
+ 0.002346936642057179, 0.002364570258941101, 0.002382380313575932, 0.002400370702791893,
+ 0.002418545425535629, 0.002436908586812392, 0.002455464401797752, 0.002474217200128692,
+ 0.002493171430384328, 0.002512331664766249, 0.002531702603989994, 0.002551289082400404,
+ 0.002571096073321844, 0.002591128694658967, 0.002611392214760672, 0.002631892058563845,
+ 0.002652633814032662, 0.002673623238910738, 0.002694866267805934, 0.002716369019626269,
+ 0.002738137805389534, 0.002760179136428037, 0.002782499733014893, 0.002805106533435520,
+ 0.002828006703534697, 0.002851207646767162, 0.002874717014785921, 0.002898542718600849,
+ 0.002922692940346749, 0.002947176145699226, 0.002972001096982591, 0.002997176867015228,
+ 0.003022712853742948, 0.003048618795714386, 0.003074904788455568, 0.003101581301807876,
+ 0.003128659198296080, 0.003156149752600867, 0.003184064672214937, 0.003212416119368622,
+ 0.003241216734320596, 0.003270479660111680, 0.003300218568896729, 0.003330447689969929,
+ 0.003361181839619420, 0.003392436452949343, 0.003424227617828290, 0.003456572111131984,
+ 0.003489487437467131, 0.003522991870580083, 0.003557104497672658, 0.003591845266868621,
+ 0.003627235038102472, 0.003663295637722386, 0.003700049917134574, 0.003737521815846301,
+ 0.003775736429304177, 0.003814720081962375, 0.003854500406067995, 0.003895106426696382,
+ 0.003936568653631844, 0.003978919180756157, 0.004022191793678687, 0.004066422086428989,
+ 0.004111647588127876, 0.004157907900659452, 0.004205244848493050, 0.004253702641940915,
+ 0.004303328055299205, 0.004354170621502118, 0.004406282845128784, 0.004459720435841752,
+ 0.004514542564613699, 0.004570812145417769, 0.004628596145424491, 0.004687965927177740,
+ 0.004748997626717266, 0.004811772572194672, 0.004876377748206484, 0.004942906311860507,
+ 0.005011458167522187, 0.005082140608288488, 0.005155069033533799, 0.005230367753417398,
+ 0.005308170893076836, 0.005388623411430704, 0.005471882252147620, 0.005558117647517014,
+ 0.005647514599798176, 0.005740274569295156, 0.005836617404105682, 0.005936783553485037,
+ 0.006041036615386131, 0.006149666279423593, 0.006262991739818591, 0.006381365669577810,
+ 0.006505178868201678, 0.006634865721946159, 0.006770910649812723, 0.006913855752425535,
+ 0.007064309938019209, 0.007222959874423007, 0.007390583214465396, 0.007568064673498798,
+ 0.007756415714389786, 0.007956798835585532, 0.008170557788458321, 0.008399255510700199,
+ 0.008644722212900025, 0.008909116987305010, 0.009195007664428712, 0.009505475652925033,
+ 0.009844255532840629, 0.010215923852312625, 0.010626158965710175, 0.011082105722287849,
+ 0.011592898788496009, 0.012170432837851575, 0.012830529553771619, 0.013594766864701180,
+ 0.014493463190219380, 0.015570784932380066, 0.016894014550512759, 0.018571645120042057,
+ 0.020792203980939394, 0.023918831757214210, 0.028765597544542998, 0.037673750936428774,
+ 0.061856319137823523];
use task::rt::{task_id, sched_id, rust_task};
use util;
use util::replace;
+use unstable::finally::Finally;
#[cfg(test)] use comm::SharedChan;
* ~~~
*/
pub unsafe fn unkillable<U>(f: &fn() -> U) -> U {
- struct AllowFailure {
- t: *rust_task,
- drop {
- unsafe {
- rt::rust_task_allow_kill(self.t);
- }
- }
- }
-
- fn AllowFailure(t: *rust_task) -> AllowFailure{
- AllowFailure {
- t: t
- }
- }
-
let t = rt::rust_get_task();
- let _allow_failure = AllowFailure(t);
- rt::rust_task_inhibit_kill(t);
- f()
+ do (|| {
+ rt::rust_task_inhibit_kill(t);
+ f()
+ }).finally {
+ rt::rust_task_allow_kill(t);
+ }
}
/// The inverse of unkillable. Only ever to be used nested in unkillable().
pub unsafe fn rekillable<U>(f: &fn() -> U) -> U {
- struct DisallowFailure {
- t: *rust_task,
- drop {
- unsafe {
- rt::rust_task_inhibit_kill(self.t);
- }
- }
- }
-
- fn DisallowFailure(t: *rust_task) -> DisallowFailure {
- DisallowFailure {
- t: t
- }
- }
-
let t = rt::rust_get_task();
- let _allow_failure = DisallowFailure(t);
- rt::rust_task_allow_kill(t);
- f()
+ do (|| {
+ rt::rust_task_allow_kill(t);
+ f()
+ }).finally {
+ rt::rust_task_inhibit_kill(t);
+ }
}
/**
* For use with exclusive ARCs, which use pthread mutexes directly.
*/
pub unsafe fn atomically<U>(f: &fn() -> U) -> U {
- struct DeferInterrupts {
- t: *rust_task,
- drop {
- unsafe {
- rt::rust_task_allow_yield(self.t);
- rt::rust_task_allow_kill(self.t);
- }
- }
- }
-
- fn DeferInterrupts(t: *rust_task) -> DeferInterrupts {
- DeferInterrupts {
- t: t
- }
- }
-
let t = rt::rust_get_task();
- let _interrupts = DeferInterrupts(t);
- rt::rust_task_inhibit_kill(t);
- rt::rust_task_inhibit_yield(t);
- f()
+ do (|| {
+ rt::rust_task_inhibit_kill(t);
+ rt::rust_task_inhibit_yield(t);
+ f()
+ }).finally {
+ rt::rust_task_allow_yield(t);
+ rt::rust_task_allow_kill(t);
+ }
}
#[test] #[should_fail] #[ignore(cfg(windows))]
obj_filename: &Path,
out_filename: &Path,
lm: LinkMeta) {
+ // In the future, FreeBSD will use clang as default compiler.
+ // It would be flexible to use cc (system's default C compiler)
+ // instead of hard-coded gcc.
+ // For win32, there is no cc command,
+ // so we add a condition to make it use gcc.
+ let cc_prog: ~str = if sess.targ_cfg.os == session::os_android {
+ match &sess.opts.android_cross_path {
+ &Some(copy path) => {
+ fmt!("%s/bin/arm-linux-androideabi-gcc", path)
+ }
+ &None => {
+ sess.fatal(~"need Android NDK path for linking \
+ (--android-cross-path)")
+ }
+ }
+ } else if sess.targ_cfg.os == session::os_win32 { ~"gcc" }
+ else { ~"cc" };
+ // The invocations of cc share some flags across platforms
+
+
+ let output = if *sess.building_library {
+ let long_libname = output_dll_filename(sess.targ_cfg.os, lm);
+ debug!("link_meta.name: %s", lm.name);
+ debug!("long_libname: %s", long_libname);
+ debug!("out_filename: %s", out_filename.to_str());
+ debug!("dirname(out_filename): %s", out_filename.dir_path().to_str());
+
+ out_filename.dir_path().push(long_libname)
+ } else {
+ /*bad*/copy *out_filename
+ };
+
+ debug!("output: %s", output.to_str());
+ let mut cc_args = link_args(sess, obj_filename, out_filename, lm);
+ debug!("%s link args: %s", cc_prog, str::connect(cc_args, ~" "));
+ // We run 'cc' here
+ let prog = run::program_output(cc_prog, cc_args);
+ if 0 != prog.status {
+ sess.err(fmt!("linking with `%s` failed with code %d",
+ cc_prog, prog.status));
+ sess.note(fmt!("%s arguments: %s",
+ cc_prog, str::connect(cc_args, ~" ")));
+ sess.note(prog.err + prog.out);
+ sess.abort_if_errors();
+ }
+
+ // Clean up on Darwin
+ if sess.targ_cfg.os == session::os_macos {
+ run::run_program(~"dsymutil", ~[output.to_str()]);
+ }
+
+ // Remove the temporary object file if we aren't saving temps
+ if !sess.opts.save_temps {
+ if ! os::remove_file(obj_filename) {
+ sess.warn(fmt!("failed to delete object file `%s`",
+ obj_filename.to_str()));
+ }
+ }
+}
+
+pub fn link_args(sess: Session,
+ obj_filename: &Path,
+ out_filename: &Path,
+ lm:LinkMeta) -> ~[~str] {
+
// Converts a library file-stem into a cc -l argument
fn unlib(config: @session::config, stem: ~str) -> ~str {
if stem.starts_with("lib") &&
}
}
+
let output = if *sess.building_library {
let long_libname = output_dll_filename(sess.targ_cfg.os, lm);
- debug!("link_meta.name: %s", lm.name);
- debug!("long_libname: %s", long_libname);
- debug!("out_filename: %s", out_filename.to_str());
- debug!("dirname(out_filename): %s", out_filename.dir_path().to_str());
-
out_filename.dir_path().push(long_libname)
} else {
/*bad*/copy *out_filename
};
- debug!("output: %s", output.to_str());
-
// The default library location, we need this to find the runtime.
// The location of crates will be determined as needed.
let stage: ~str = ~"-L" + sess.filesearch.get_target_lib_path().to_str();
- // In the future, FreeBSD will use clang as default compiler.
- // It would be flexible to use cc (system's default C compiler)
- // instead of hard-coded gcc.
- // For win32, there is no cc command,
- // so we add a condition to make it use gcc.
- let cc_prog: ~str = if sess.targ_cfg.os == session::os_android {
- match &sess.opts.android_cross_path {
- &Some(copy path) => {
- fmt!("%s/bin/arm-linux-androideabi-gcc", path)
- }
- &None => {
- sess.fatal(~"need Android NDK path for linking \
- (--android-cross-path)")
- }
- }
- } else if sess.targ_cfg.os == session::os_win32 { ~"gcc" }
- else { ~"cc" };
- // The invocations of cc share some flags across platforms
+ let mut args = vec::append(~[stage], sess.targ_cfg.target_strs.cc_args);
- let mut cc_args =
- vec::append(~[stage], sess.targ_cfg.target_strs.cc_args);
- cc_args.push(~"-o");
- cc_args.push(output.to_str());
- cc_args.push(obj_filename.to_str());
+ args.push(~"-o");
+ args.push(output.to_str());
+ args.push(obj_filename.to_str());
let lib_cmd;
let os = sess.targ_cfg.os;
let cstore = sess.cstore;
for cstore::get_used_crate_files(cstore).each |cratepath| {
if cratepath.filetype() == Some(~".rlib") {
- cc_args.push(cratepath.to_str());
+ args.push(cratepath.to_str());
loop;
}
let dir = cratepath.dirname();
- if dir != ~"" { cc_args.push(~"-L" + dir); }
+ if dir != ~"" { args.push(~"-L" + dir); }
let libarg = unlib(sess.targ_cfg, cratepath.filestem().get());
- cc_args.push(~"-l" + libarg);
+ args.push(~"-l" + libarg);
}
let ula = cstore::get_used_link_args(cstore);
- for ula.each |arg| { cc_args.push(/*bad*/copy *arg); }
+ for ula.each |arg| { args.push(/*bad*/copy *arg); }
// Add all the link args for external crates.
do cstore::iter_crate_data(cstore) |crate_num, _| {
let link_args = csearch::get_link_args_for_crate(cstore, crate_num);
do vec::consume(link_args) |_, link_arg| {
- cc_args.push(link_arg);
+ args.push(link_arg);
}
}
// forces to make sure that library can be found at runtime.
for sess.opts.addl_lib_search_paths.each |path| {
- cc_args.push(~"-L" + path.to_str());
+ args.push(~"-L" + path.to_str());
}
// The names of the extern libraries
let used_libs = cstore::get_used_libraries(cstore);
- for used_libs.each |l| { cc_args.push(~"-l" + *l); }
+ for used_libs.each |l| { args.push(~"-l" + *l); }
if *sess.building_library {
- cc_args.push(lib_cmd);
+ args.push(lib_cmd);
// On mac we need to tell the linker to let this library
// be rpathed
if sess.targ_cfg.os == session::os_macos {
- cc_args.push(~"-Wl,-install_name,@rpath/"
+ args.push(~"-Wl,-install_name,@rpath/"
+ output.filename().get());
}
}
// On linux librt and libdl are an indirect dependencies via rustrt,
// and binutils 2.22+ won't add them automatically
if sess.targ_cfg.os == session::os_linux {
- cc_args.push_all(~[~"-lrt", ~"-ldl"]);
+ args.push_all(~[~"-lrt", ~"-ldl"]);
// LLVM implements the `frem` instruction as a call to `fmod`,
// which lives in libm. Similar to above, on some linuxes we
// have to be explicit about linking to it. See #2510
- cc_args.push(~"-lm");
+ args.push(~"-lm");
}
else if sess.targ_cfg.os == session::os_android {
- cc_args.push_all(~[~"-ldl", ~"-llog", ~"-lsupc++",
+ args.push_all(~[~"-ldl", ~"-llog", ~"-lsupc++",
~"-lgnustl_shared"]);
- cc_args.push(~"-lm");
+ args.push(~"-lm");
}
if sess.targ_cfg.os == session::os_freebsd {
- cc_args.push_all(~[~"-pthread", ~"-lrt",
- ~"-L/usr/local/lib", ~"-lexecinfo",
- ~"-L/usr/local/lib/gcc46",
- ~"-L/usr/local/lib/gcc44", ~"-lstdc++",
- ~"-Wl,-z,origin",
- ~"-Wl,-rpath,/usr/local/lib/gcc46",
- ~"-Wl,-rpath,/usr/local/lib/gcc44"]);
+ args.push_all(~[~"-pthread", ~"-lrt",
+ ~"-L/usr/local/lib", ~"-lexecinfo",
+ ~"-L/usr/local/lib/gcc46",
+ ~"-L/usr/local/lib/gcc44", ~"-lstdc++",
+ ~"-Wl,-z,origin",
+ ~"-Wl,-rpath,/usr/local/lib/gcc46",
+ ~"-Wl,-rpath,/usr/local/lib/gcc44"]);
}
// OS X 10.6 introduced 'compact unwind info', which is produced by the
// understand how to unwind our __morestack frame, so we have to turn it
// off. This has impacted some other projects like GHC.
if sess.targ_cfg.os == session::os_macos {
- cc_args.push(~"-Wl,-no_compact_unwind");
+ args.push(~"-Wl,-no_compact_unwind");
}
// Stack growth requires statically linking a __morestack function
- cc_args.push(~"-lmorestack");
+ args.push(~"-lmorestack");
// Always want the runtime linked in
- cc_args.push(~"-lrustrt");
+ args.push(~"-lrustrt");
// FIXME (#2397): At some point we want to rpath our guesses as to where
// extern libraries might live, based on the addl_lib_search_paths
- cc_args.push_all(rpath::get_rpath_flags(sess, &output));
+ args.push_all(rpath::get_rpath_flags(sess, &output));
- debug!("%s link args: %s", cc_prog, str::connect(cc_args, ~" "));
- // We run 'cc' here
- let prog = run::program_output(cc_prog, cc_args);
- if 0 != prog.status {
- sess.err(fmt!("linking with `%s` failed with code %d",
- cc_prog, prog.status));
- sess.note(fmt!("%s arguments: %s",
- cc_prog, str::connect(cc_args, ~" ")));
- sess.note(prog.err + prog.out);
- sess.abort_if_errors();
- }
+ // Finally add all the linker arguments provided on the command line
+ args.push_all(sess.opts.linker_args);
- // Clean up on Darwin
- if sess.targ_cfg.os == session::os_macos {
- run::run_program(~"dsymutil", ~[output.to_str()]);
- }
-
- // Remove the temporary object file if we aren't saving temps
- if !sess.opts.save_temps {
- if ! os::remove_file(obj_filename) {
- sess.warn(fmt!("failed to delete object file `%s`",
- obj_filename.to_str()));
- }
- }
+ return args;
}
+
//
// Local Variables:
// mode: rust
let rp_set = time(time_passes, ~"region parameterization inference", ||
middle::region::determine_rp_in_crate(sess, ast_map, def_map, crate));
-
let outputs = outputs.get();
let (llmod, link_meta) = {
};
+ if (sess.opts.debugging_opts & session::print_link_args) != 0 {
+ io::println(str::connect(link::link_args(sess,
+ &outputs.obj_filename, &outputs.out_filename, link_meta), " "));
+ }
+
// NB: Android hack
if sess.targ_cfg.arch == abi::Arm &&
(sess.opts.output_type == link::output_type_object ||
Some(s) => s
};
- let addl_lib_search_paths =
- getopts::opt_strs(matches, ~"L")
- .map(|s| Path(*s));
+ let addl_lib_search_paths = getopts::opt_strs(matches, ~"L").map(|s| Path(*s));
+
+ let linker_args = getopts::opt_strs(matches, ~"link-args").flat_map( |a| {
+ let mut args = ~[];
+ for str::each_split_char(*a, ',') |arg| {
+ args.push(str::from_slice(arg));
+ }
+ args
+ });
+
let cfg = parse_cfgspecs(getopts::opt_strs(matches, ~"cfg"), demitter);
let test = opt_present(matches, ~"test");
let android_cross_path = getopts::opt_maybe_str(
matches, ~"android-cross-path");
+
let sopts = @session::options {
crate_type: crate_type,
is_static: static,
jit: jit,
output_type: output_type,
addl_lib_search_paths: addl_lib_search_paths,
+ linker_args: linker_args,
maybe_sysroot: sysroot_opt,
target_triple: target,
target_feature: target_feature,
// rustc command line options
pub fn optgroups() -> ~[getopts::groups::OptGroup] {
~[
- optflag(~"", ~"bin", ~"Compile an executable crate (default)"),
- optflag(~"c", ~"", ~"Compile and assemble, but do not link"),
- optmulti(~"", ~"cfg", ~"Configure the compilation
- environment", ~"SPEC"),
- optflag(~"", ~"emit-llvm",
- ~"Produce an LLVM bitcode file"),
- optflag(~"h", ~"help",~"Display this message"),
- optmulti(~"L", ~"", ~"Add a directory to the library search path",
- ~"PATH"),
- optflag(~"", ~"lib", ~"Compile a library crate"),
- optflag(~"", ~"ls", ~"List the symbols defined by a library crate"),
- optflag(~"", ~"no-trans",
- ~"Run all passes except translation; no output"),
- optflag(~"O", ~"", ~"Equivalent to --opt-level=2"),
- optopt(~"o", ~"", ~"Write output to <filename>", ~"FILENAME"),
- optopt(~"", ~"opt-level",
- ~"Optimize with possible levels 0-3", ~"LEVEL"),
- optopt( ~"", ~"out-dir",
- ~"Write output to compiler-chosen filename
- in <dir>", ~"DIR"),
- optflag(~"", ~"parse-only",
- ~"Parse only; do not compile, assemble, or link"),
- optflagopt(~"", ~"pretty",
- ~"Pretty-print the input instead of compiling;
+ optflag("", "bin", "Compile an executable crate (default)"),
+ optflag("c", "", "Compile and assemble, but do not link"),
+ optmulti("", "cfg", "Configure the compilation
+ environment", "SPEC"),
+ optflag("", "emit-llvm",
+ "Produce an LLVM bitcode file"),
+ optflag("h", "help","Display this message"),
+ optmulti("L", "", "Add a directory to the library search path",
+ "PATH"),
+ optflag("", "lib", "Compile a library crate"),
+ optmulti("", "link-args", "FLAGS is a comma-separated list of flags
+ passed to the linker", "FLAGS"),
+ optflag("", "ls", "List the symbols defined by a library crate"),
+ optflag("", "no-trans",
+ "Run all passes except translation; no output"),
+ optflag("O", "", "Equivalent to --opt-level=2"),
+ optopt("o", "", "Write output to <filename>", "FILENAME"),
+ optopt("", "opt-level",
+ "Optimize with possible levels 0-3", "LEVEL"),
+ optopt( "", "out-dir",
+ "Write output to compiler-chosen filename
+ in <dir>", "DIR"),
+ optflag("", "parse-only",
+ "Parse only; do not compile, assemble, or link"),
+ optflagopt("", "pretty",
+ "Pretty-print the input instead of compiling;
valid types are: normal (un-annotated source),
expanded (crates expanded),
typed (crates expanded, with type annotations),
or identified (fully parenthesized,
- AST nodes and blocks with IDs)", ~"TYPE"),
- optflag(~"S", ~"", ~"Compile only; do not assemble or link"),
- optflag(~"", ~"save-temps",
- ~"Write intermediate files (.bc, .opt.bc, .o)
+ AST nodes and blocks with IDs)", "TYPE"),
+ optflag("S", "", "Compile only; do not assemble or link"),
+ optflag("", "save-temps",
+ "Write intermediate files (.bc, .opt.bc, .o)
in addition to normal output"),
- optopt(~"", ~"sysroot",
- ~"Override the system root", ~"PATH"),
- optflag(~"", ~"test", ~"Build a test harness"),
- optopt(~"", ~"target",
- ~"Target triple cpu-manufacturer-kernel[-os]
+ optopt("", "sysroot",
+ "Override the system root", "PATH"),
+ optflag("", "test", "Build a test harness"),
+ optopt("", "target",
+ "Target triple cpu-manufacturer-kernel[-os]
to compile for (see chapter 3.4 of http://www.sourceware.org/autobook/
- for detail)", ~"TRIPLE"),
- optopt(~"", ~"target-feature",
- ~"Target specific attributes (llc -mattr=help
- for detail)", ~"FEATURE"),
- optopt(~"", ~"android-cross-path",
- ~"The path to the Android NDK", "PATH"),
- optmulti(~"W", ~"warn",
- ~"Set lint warnings", ~"OPT"),
- optmulti(~"A", ~"allow",
- ~"Set lint allowed", ~"OPT"),
- optmulti(~"D", ~"deny",
- ~"Set lint denied", ~"OPT"),
- optmulti(~"F", ~"forbid",
- ~"Set lint forbidden", ~"OPT"),
- optmulti(~"Z", ~"", ~"Set internal debugging options", "FLAG"),
- optflag( ~"v", ~"version",
- ~"Print version info and exit"),
+ for detail)", "TRIPLE"),
+ optopt("", "target-feature",
+ "Target specific attributes (llc -mattr=help
+ for detail)", "FEATURE"),
+ optopt("", "android-cross-path",
+ "The path to the Android NDK", "PATH"),
+ optmulti("W", "warn",
+ "Set lint warnings", "OPT"),
+ optmulti("A", "allow",
+ "Set lint allowed", "OPT"),
+ optmulti("D", "deny",
+ "Set lint denied", "OPT"),
+ optmulti("F", "forbid",
+ "Set lint forbidden", "OPT"),
+ optmulti("Z", "", "Set internal debugging options", "FLAG"),
+ optflag( "v", "version",
+ "Print version info and exit"),
]
}
pub static debug_info: uint = 1 << 20;
pub static extra_debug_info: uint = 1 << 21;
pub static static: uint = 1 << 22;
+pub static print_link_args: uint = 1 << 23;
pub fn debugging_opts_map() -> ~[(~str, ~str, uint)] {
~[(~"verbose", ~"in general, enable more debug printouts", verbose),
(~"no-opt", ~"do not optimize, even if -O is passed", no_opt),
(~"no-monomorphic-collapse", ~"do not collapse template instantiations",
no_monomorphic_collapse),
+ (~"print-link-args", ~"Print the arguments passed to the linker", print_link_args),
(~"gc", ~"Garbage collect shared data (experimental)", gc),
(~"jit", ~"Execute using JIT (experimental)", jit),
(~"extra-debug-info", ~"Extra debugging info (experimental)",
jit: bool,
output_type: back::link::output_type,
addl_lib_search_paths: ~[Path],
+ linker_args: ~[~str],
maybe_sysroot: Option<Path>,
target_triple: ~str,
target_feature: ~str,
jit: false,
output_type: link::output_type_exe,
addl_lib_search_paths: ~[],
+ linker_args:~[],
maybe_sysroot: None,
target_triple: host_triple(),
target_feature: ~"",
different tags.
*/
pub static tag_item_impl_method: uint = 0x48u;
-pub static tag_item_dtor: uint = 0x49u;
pub static tag_item_trait_method_self_ty: uint = 0x4b;
pub static tag_item_trait_method_self_ty_region: uint = 0x4c;
decoder::get_impl_method(cstore.intr, cdata, def.node, mname)
}
-/* If def names a class with a dtor, return it. Otherwise, return none. */
-pub fn struct_dtor(cstore: @mut cstore::CStore, def: ast::def_id)
- -> Option<ast::def_id> {
- let cdata = cstore::get_crate_data(cstore, def.crate);
- decoder::struct_dtor(cdata, def.node)
-}
-
pub fn get_item_visibility(cstore: @mut cstore::CStore,
def_id: ast::def_id)
-> ast::visibility {
found.get()
}
-pub fn struct_dtor(cdata: cmd, id: ast::node_id) -> Option<ast::def_id> {
- let items = reader::get_doc(reader::Doc(cdata.data), tag_items);
- let mut found = None;
- let cls_items = match maybe_find_item(id, items) {
- Some(it) => it,
- None => fail!(fmt!("struct_dtor: class id not found \
- when looking up dtor for %d", id))
- };
- for reader::tagged_docs(cls_items, tag_item_dtor) |doc| {
- let doc1 = reader::get_doc(doc, tag_def_id);
- let did = reader::with_doc_data(doc1, |d| parse_def_id(d));
- found = Some(translate_def_id(cdata, did));
- };
- found
-}
-
pub fn get_symbol(data: @~[u8], id: ast::node_id) -> ~str {
return item_symbol(lookup_item(id, data));
}
class itself */
let idx = encode_info_for_struct(ecx, ebml_w, path,
struct_def.fields, index);
- /* Encode the dtor */
- for struct_def.dtor.each |dtor| {
- index.push(entry {val: dtor.node.id, pos: ebml_w.writer.tell()});
- encode_info_for_ctor(ecx,
- ebml_w,
- dtor.node.id,
- ecx.tcx.sess.ident_of(
- *ecx.tcx.sess.str_of(item.ident) +
- ~"_dtor"),
- path,
- if generics.ty_params.len() > 0u {
- Some(ii_dtor(copy *dtor,
- item.ident,
- copy *generics,
- local_def(item.id))) }
- else {
- None
- },
- generics);
- }
/* Index the class*/
add_to_index();
encode_name(ecx, ebml_w, item.ident);
encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident));
encode_region_param(ecx, ebml_w, item);
- /* Encode the dtor */
- /* Encode id for dtor */
- for struct_def.dtor.each |dtor| {
- do ebml_w.wr_tag(tag_item_dtor) {
- encode_def_id(ebml_w, local_def(dtor.node.id));
- }
- };
/* Encode def_ids for each field and method
for methods, write all the stuff get_trait_method
ast::ii_foreign(i) => {
ast::ii_foreign(fld.fold_foreign_item(i))
}
- ast::ii_dtor(ref dtor, nm, ref tps, parent_id) => {
- let dtor_body = fld.fold_block(&dtor.node.body);
- ast::ii_dtor(
- codemap::spanned {
- node: ast::struct_dtor_ { body: dtor_body,
- .. /*bad*/copy (*dtor).node },
- .. (/*bad*/copy *dtor) },
- nm, /*bad*/copy *tps, parent_id)
- }
}
}
ast::ii_foreign(i) => {
ast::ii_foreign(fld.fold_foreign_item(i))
}
- ast::ii_dtor(ref dtor, nm, ref generics, parent_id) => {
- let dtor_body = fld.fold_block(&dtor.node.body);
- let dtor_attrs = fld.fold_attributes(/*bad*/copy (*dtor).node.attrs);
- let new_generics = fold::fold_generics(generics, fld);
- let dtor_id = fld.new_id((*dtor).node.id);
- let new_parent = xcx.tr_def_id(parent_id);
- let new_self = fld.new_id((*dtor).node.self_id);
- ast::ii_dtor(
- codemap::spanned {
- node: ast::struct_dtor_ { id: dtor_id,
- attrs: dtor_attrs,
- self_id: new_self,
- body: dtor_body },
- .. (/*bad*/copy *dtor)
- },
- nm, new_generics, new_parent)
- }
}
}
let declared_purity, src;
match *fk {
- visit::fk_item_fn(*) | visit::fk_method(*) |
- visit::fk_dtor(*) => {
+ visit::fk_item_fn(*) | visit::fk_method(*) => {
declared_purity = ty::ty_fn_purity(fty);
src = id;
}
// inherits the fn_args from enclosing ctxt
}
visit::fk_anon(*) | visit::fk_fn_block(*) |
- visit::fk_method(*) | visit::fk_item_fn(*) |
- visit::fk_dtor(*) => {
+ visit::fk_method(*) | visit::fk_item_fn(*) => {
let mut fn_args = ~[];
for decl.inputs.each |input| {
// For the purposes of purity, only consider function-
match *fk {
visit::fk_anon(*) | visit::fk_fn_block(*) => {}
- visit::fk_item_fn(*) | visit::fk_method(*) |
- visit::fk_dtor(*) => {
+ visit::fk_item_fn(*) | visit::fk_method(*) => {
self.item_ub = body.node.id;
}
}
Some(vec::append(args, vec::from_slice(r.tail())))
}
def_variant(_, _) => None,
+
+ def_fn(*) |
def_struct(*) => {
// FIXME #4731: Is this right? --pcw
let new_args;
add => Ok(const_float(a + b)),
subtract => Ok(const_float(a - b)),
mul => Ok(const_float(a * b)),
- quot => Ok(const_float(a / b)),
+ div => Ok(const_float(a / b)),
rem => Ok(const_float(a % b)),
eq => fromb(a == b),
lt => fromb(a < b),
add => Ok(const_int(a + b)),
subtract => Ok(const_int(a - b)),
mul => Ok(const_int(a * b)),
- quot if b == 0 => Err(~"attempted quotient with a divisor of zero"),
- quot => Ok(const_int(a / b)),
+ div if b == 0 => Err(~"attempted to divide by zero"),
+ div => Ok(const_int(a / b)),
rem if b == 0 => Err(~"attempted remainder with a divisor of zero"),
rem => Ok(const_int(a % b)),
and | bitand => Ok(const_int(a & b)),
add => Ok(const_uint(a + b)),
subtract => Ok(const_uint(a - b)),
mul => Ok(const_uint(a * b)),
- quot if b == 0 => Err(~"attempted quotient with a divisor of zero"),
- quot => Ok(const_uint(a / b)),
+ div if b == 0 => Err(~"attempted to divide by zero"),
+ div => Ok(const_uint(a / b)),
rem if b == 0 => Err(~"attempted remainder with a divisor of zero"),
rem => Ok(const_uint(a % b)),
and | bitand => Ok(const_uint(a & b)),
}
}
}
- item_struct(struct_def, _) => {
- match struct_def.dtor {
- None => {}
- Some(ref dtor) => {
- let struct_did = def_id { crate: 0, node: item.id };
- check_struct_safe_for_destructor(cx,
- dtor.span,
- struct_did);
- }
- }
- }
_ => {}
}
}
AddTraitLangItem, // 5
SubTraitLangItem, // 6
MulTraitLangItem, // 7
- QuotTraitLangItem, // 8
+ DivTraitLangItem, // 8
RemTraitLangItem, // 9
NegTraitLangItem, // 10
NotTraitLangItem, // 11
5 => "add",
6 => "sub",
7 => "mul",
- 8 => "quot",
+ 8 => "div",
9 => "rem",
10 => "neg",
11 => "not",
pub fn mul_trait(&const self) -> def_id {
self.items[MulTraitLangItem as uint].get()
}
- pub fn quot_trait(&const self) -> def_id {
- self.items[QuotTraitLangItem as uint].get()
+ pub fn div_trait(&const self) -> def_id {
+ self.items[DivTraitLangItem as uint].get()
}
pub fn rem_trait(&const self) -> def_id {
self.items[RemTraitLangItem as uint].get()
item_refs.insert(@~"add", AddTraitLangItem as uint);
item_refs.insert(@~"sub", SubTraitLangItem as uint);
item_refs.insert(@~"mul", MulTraitLangItem as uint);
- item_refs.insert(@~"quot", QuotTraitLangItem as uint);
+ item_refs.insert(@~"div", DivTraitLangItem as uint);
item_refs.insert(@~"rem", RemTraitLangItem as uint);
item_refs.insert(@~"neg", NegTraitLangItem as uint);
item_refs.insert(@~"not", NotTraitLangItem as uint);
type_limits,
default_methods,
deprecated_mutable_fields,
- deprecated_drop,
unused_unsafe,
managed_heap_memory,
default: deny
}),
- (~"deprecated_drop",
- LintSpec {
- lint: deprecated_drop,
- desc: "deprecated \"drop\" notation for the destructor",
- default: deny
- }),
-
(~"unused_unsafe",
LintSpec {
lint: unused_unsafe,
check_item_type_limits(cx, i);
check_item_default_methods(cx, i);
check_item_deprecated_mutable_fields(cx, i);
- check_item_deprecated_drop(cx, i);
check_item_unused_unsafe(cx, i);
check_item_unused_mut(cx, i);
}
}
}
-fn check_item_deprecated_drop(cx: ty::ctxt, item: @ast::item) {
- match item.node {
- ast::item_struct(struct_def, _) => {
- match struct_def.dtor {
- None => {}
- Some(ref dtor) => {
- cx.sess.span_lint(deprecated_drop,
- item.id,
- item.id,
- dtor.span,
- ~"`drop` notation for destructors is \
- deprecated; implement the `Drop` \
- trait instead");
- }
- }
- }
- _ => {}
- }
-}
-
fn check_item_ctypes(cx: ty::ctxt, it: @ast::item) {
fn check_foreign_fn(cx: ty::ctxt, fn_id: ast::node_id,
use syntax::codemap::span;
use syntax::parse::token::special_idents;
use syntax::print::pprust::{expr_to_str, block_to_str};
-use syntax::visit::{fk_anon, fk_dtor, fk_fn_block, fk_item_fn, fk_method};
+use syntax::visit::{fk_anon, fk_fn_block, fk_item_fn, fk_method};
use syntax::visit::{vt};
use syntax::{visit, ast_util};
sty_static => {}
}
}
- fk_dtor(_, _, self_id, _) => {
- fn_maps.add_variable(Arg(self_id, special_idents::self_));
- }
fk_item_fn(*) | fk_anon(*) | fk_fn_block(*) => {}
}
self.cat_pattern(subcmt, *subpat, op);
}
}
+ Some(&ast::def_fn(*)) |
Some(&ast::def_struct(*)) => {
for subpats.each |subpat| {
let cmt_field = self.cat_anon_struct_field(*subpat,
cx: ctxt,
visitor: visit::vt<ctxt>) {
let fn_cx = match *fk {
- visit::fk_item_fn(*) | visit::fk_method(*) |
- visit::fk_dtor(*) => {
+ visit::fk_item_fn(*) | visit::fk_method(*) => {
// Top-level functions are a root scope.
ctxt {parent: Some(id),.. cx}
}
use syntax::ast::{expr_binary, expr_break, expr_field};
use syntax::ast::{expr_fn_block, expr_index, expr_method_call, expr_path};
use syntax::ast::{def_prim_ty, def_region, def_self, def_ty, def_ty_param};
-use syntax::ast::{def_upvar, def_use, def_variant, quot, eq};
+use syntax::ast::{def_upvar, def_use, def_variant, div, eq};
use syntax::ast::{expr, expr_again, expr_assign_op};
use syntax::ast::{expr_index, expr_loop};
use syntax::ast::{expr_path, expr_struct, expr_unary, fn_decl};
use syntax::ast::{Path, pat_lit, pat_range, pat_struct};
use syntax::ast::{prim_ty, private, provided};
use syntax::ast::{public, required, rem, self_ty_, shl, shr, stmt_decl};
-use syntax::ast::{struct_dtor, struct_field, struct_variant_kind};
+use syntax::ast::{struct_field, struct_variant_kind};
use syntax::ast::{sty_static, subtract, trait_ref, tuple_variant_kind, Ty};
use syntax::ast::{ty_bool, ty_char, ty_f, ty_f32, ty_f64, ty_float, ty_i};
use syntax::ast::{ty_i16, ty_i32, ty_i64, ty_i8, ty_int, TyParam, ty_path};
self.resolve_struct(item.id,
generics,
struct_def.fields,
- &struct_def.dtor,
visitor);
}
id: node_id,
generics: &Generics,
fields: &[@struct_field],
- optional_destructor: &Option<struct_dtor>,
visitor: ResolveVisitor) {
// If applicable, create a rib for the type parameters.
do self.with_type_parameter_rib(HasTypeParameters
for fields.each |field| {
self.resolve_type(field.node.ty, visitor);
}
-
- // Resolve the destructor, if applicable.
- match *optional_destructor {
- None => {
- // Nothing to do.
- }
- Some(ref destructor) => {
- self.resolve_function(NormalRibKind,
- None,
- NoTypeParameters,
- &destructor.node.body,
- HasSelfBinding
- ((*destructor).node.self_id,
- true),
- visitor);
- }
- }
}
}
pat_enum(path, _) => {
// This must be an enum variant, struct or const.
match self.resolve_path(path, ValueNS, false, visitor) {
+ Some(def @ def_fn(*)) |
Some(def @ def_variant(*)) |
Some(def @ def_struct(*)) |
Some(def @ def_const(*)) => {
self.add_fixed_trait_for_expr(expr.id,
self.lang_items.mul_trait());
}
- expr_binary(quot, _, _) | expr_assign_op(quot, _, _) => {
+ expr_binary(div, _, _) | expr_assign_op(div, _, _) => {
self.add_fixed_trait_for_expr(expr.id,
- self.lang_items.quot_trait());
+ self.lang_items.div_trait());
}
expr_binary(rem, _, _) | expr_assign_op(rem, _, _) => {
self.add_fixed_trait_for_expr(expr.id,
}
::core::util::unreachable();
}
+ ast::def_fn(*) |
ast::def_struct(_) => {
return lit(UnitLikeStructLit(pat_id));
}
// This could be one of: a tuple-like enum variant, a
// struct-like enum variant, or a struct.
match ccx.tcx.def_map.find(&cur.id) {
+ Some(&ast::def_fn(*)) |
Some(&ast::def_variant(*)) => {
add_to_set(ccx.tcx, &mut found,
variant_opt(bcx, cur.id));
match pat.node {
ast::pat_enum(_, Some(_)) => {
match bcx.tcx().def_map.find(&pat.id) {
+ Some(&ast::def_fn(*)) |
Some(&ast::def_struct(*)) => true,
_ => false
}
}
}
}
+ Some(&ast::def_fn(*)) |
Some(&ast::def_struct(*)) => {
match *sub_pats {
None => {
st.fields.len() - (if dtor { 1 } else { 0 })
}
General(ref cases) => cases[discr as uint].fields.len() - 1,
- NullablePointer{ nonnull: ref nonnull, nndiscr, _ } => {
- if discr == nndiscr { nonnull.fields.len() } else { 0 }
+ NullablePointer{ nonnull: ref nonnull, nndiscr, nullfields: ref nullfields, _ } => {
+ if discr == nndiscr { nonnull.fields.len() } else { nullfields.len() }
}
}
}
}
}
-pub fn fail_if_zero(cx: block, span: span, quotrem: ast::binop,
+pub fn fail_if_zero(cx: block, span: span, divrem: ast::binop,
rhs: ValueRef, rhs_t: ty::t) -> block {
- let text = if quotrem == ast::quot {
- @~"attempted quotient with a divisor of zero"
+ let text = if divrem == ast::div {
+ @~"attempted to divide by zero"
} else {
@~"attempted remainder with a divisor of zero"
};
finish_fn(fcx, lltop);
}
-pub fn trans_struct_dtor(ccx: @CrateContext,
- path: path,
- body: &ast::blk,
- dtor_id: ast::node_id,
- psubsts: Option<@param_substs>,
- hash_id: Option<mono_id>,
- parent_id: ast::def_id)
- -> ValueRef {
- let tcx = ccx.tcx;
- /* Look up the parent class's def_id */
- let mut class_ty = ty::lookup_item_type(tcx, parent_id).ty;
- /* Substitute in the class type if necessary */
- for psubsts.each |ss| {
- class_ty = ty::subst_tps(tcx, ss.tys, ss.self_ty, class_ty);
- }
-
- /* The dtor takes a (null) output pointer, and a self argument,
- and returns () */
- let lldty = type_of_dtor(ccx, class_ty);
-
- // XXX: Bad copies.
- let s = get_dtor_symbol(ccx, copy path, dtor_id, psubsts);
-
- /* Register the dtor as a function. It has external linkage */
- let lldecl = decl_internal_cdecl_fn(ccx.llmod, s, lldty);
- lib::llvm::SetLinkage(lldecl, lib::llvm::ExternalLinkage);
-
- /* If we're monomorphizing, register the monomorphized decl
- for the dtor */
- for hash_id.each |h_id| {
- ccx.monomorphized.insert(*h_id, lldecl);
- }
- /* Translate the dtor body */
- let decl = ast_util::dtor_dec();
- trans_fn(ccx,
- path,
- &decl,
- body,
- lldecl,
- impl_self(class_ty),
- psubsts,
- dtor_id,
- None,
- []);
- lldecl
-}
-
pub fn trans_enum_def(ccx: @CrateContext, enum_definition: &ast::enum_def,
id: ast::node_id,
path: @ast_map::path, vi: @~[ty::VariantInfo],
// Nothing to do.
}
ast::struct_variant_kind(struct_def) => {
- trans_struct_def(ccx, struct_def, path,
- variant.node.id);
+ trans_struct_def(ccx, struct_def);
}
}
}
}
ast::item_struct(struct_def, ref generics) => {
if !generics.is_type_parameterized() {
- trans_struct_def(ccx, struct_def, path, item.id);
+ trans_struct_def(ccx, struct_def);
}
}
_ => {/* fall through */ }
}
}
-pub fn trans_struct_def(ccx: @CrateContext, struct_def: @ast::struct_def,
- path: @ast_map::path,
- id: ast::node_id) {
- // Translate the destructor.
- for struct_def.dtor.each |dtor| {
- trans_struct_dtor(ccx, /*bad*/copy *path, &dtor.node.body,
- dtor.node.id, None, None, local_def(id));
- };
-
+pub fn trans_struct_def(ccx: @CrateContext, struct_def: @ast::struct_def) {
// If this is a tuple-like struct, translate the constructor.
match struct_def.ctor_id {
// We only need to translate a constructor if there are fields;
vec::append(/*bad*/copy *base, ~[path_name(i.ident)])
}
-/* If there's already a symbol for the dtor with <id> and substs <substs>,
- return it; otherwise, create one and register it, returning it as well */
-pub fn get_dtor_symbol(ccx: @CrateContext,
- path: path,
- id: ast::node_id,
- substs: Option<@param_substs>)
- -> ~str {
- let t = ty::node_id_to_type(ccx.tcx, id);
- match ccx.item_symbols.find(&id) {
- Some(s) => (/*bad*/copy *s),
- None if substs.is_none() => {
- let s = mangle_exported_name(
- ccx,
- vec::append(path, ~[path_name((ccx.names)(~"dtor"))]),
- t);
- // XXX: Bad copy, use `@str`?
- ccx.item_symbols.insert(id, copy s);
- s
- }
- None => {
- // Monomorphizing, so just make a symbol, don't add
- // this to item_symbols
- match substs {
- Some(ss) => {
- let mono_ty = ty::subst_tps(ccx.tcx, ss.tys, ss.self_ty, t);
- mangle_exported_name(
- ccx,
- vec::append(path,
- ~[path_name((ccx.names)(~"dtor"))]),
- mono_ty)
- }
- None => {
- ccx.sess.bug(fmt!("get_dtor_symbol: not monomorphizing and \
- couldn't find a symbol for dtor %?", path));
- }
- }
- }
- }
-}
-
pub fn get_item_val(ccx: @CrateContext, id: ast::node_id) -> ValueRef {
debug!("get_item_val(id=`%?`)", id);
let tcx = ccx.tcx;
}
}
}
- ast_map::node_dtor(_, dt, parent_id, pt) => {
- /*
- Don't just call register_fn, since we don't want to add
- the implicit self argument automatically (we want to make sure
- it has the right type)
- */
- // Want parent_id and not id, because id is the dtor's type
- let class_ty = ty::lookup_item_type(tcx, parent_id).ty;
- // This code shouldn't be reached if the class is generic
- assert!(!ty::type_has_params(class_ty));
- let lldty = T_fn(~[
- T_ptr(T_i8()),
- T_ptr(type_of(ccx, class_ty))
- ],
- T_nil());
- let s = get_dtor_symbol(ccx, /*bad*/copy *pt, dt.node.id, None);
-
- /* Make the declaration for the dtor */
- let llfn = decl_internal_cdecl_fn(ccx.llmod, s, lldty);
- lib::llvm::SetLinkage(llfn, lib::llvm::ExternalLinkage);
- llfn
- }
ast_map::node_variant(ref v, enm, pth) => {
let llfn;
if is_float { llvm::LLVMConstFMul(te1, te2) }
else { llvm::LLVMConstMul(te1, te2) }
}
- ast::quot => {
+ ast::div => {
if is_float { llvm::LLVMConstFDiv(te1, te2) }
else if signed { llvm::LLVMConstSDiv(te1, te2) }
else { llvm::LLVMConstUDiv(te1, te2) }
expected an expr_fn_block here")
}
}
- ast_map::node_dtor(_, _, did, _) => {
- ((dbg_cx.names)(~"dtor"), ast_util::dtor_ty(), did.node)
- }
_ => fcx.ccx.sess.bug(~"create_function: unexpected \
sort of node")
};
if is_float { FMul(bcx, lhs, rhs) }
else { Mul(bcx, lhs, rhs) }
}
- ast::quot => {
+ ast::div => {
if is_float {
FDiv(bcx, lhs, rhs)
} else {
}
local_def(mth.id)
}
- csearch::found(ast::ii_dtor(ref dtor, _, _, _)) => {
- ccx.external.insert(fn_id, Some((*dtor).node.id));
- local_def((*dtor).node.id)
- }
}
}
}
use lib::llvm::ValueRef;
use middle::trans::base::{get_insn_ctxt};
use middle::trans::base::{set_inline_hint_if_appr, set_inline_hint};
-use middle::trans::base::{trans_enum_variant, trans_struct_dtor};
+use middle::trans::base::{trans_enum_variant};
use middle::trans::base::{trans_fn, decl_internal_cdecl_fn};
use middle::trans::base::{get_item_val, no_self};
use middle::trans::base;
use syntax::ast_map::path_name;
use syntax::ast_util::local_def;
use syntax::opt_vec;
-use syntax::parse::token::special_idents;
use syntax::abi::AbiSet;
pub fn monomorphic_fn(ccx: @CrateContext,
// Foreign externs don't have to be monomorphized.
return (get_item_val(ccx, fn_id.node), true);
}
- ast_map::node_dtor(_, dtor, _, pt) =>
- (pt, special_idents::dtor, dtor.span),
ast_map::node_trait_method(@ast::provided(m), _, pt) => {
(pt, m.ident, m.span)
}
meth::trans_method(ccx, pt, mth, psubsts, None, d, impl_did);
d
}
- ast_map::node_dtor(_, dtor, _, pt) => {
- let parent_id = match ty::ty_to_def_id(ty::node_id_to_type(ccx.tcx,
- dtor.node.self_id)) {
- Some(did) => did,
- None => ccx.sess.span_bug(dtor.span, ~"Bad self ty in \
- dtor")
- };
- trans_struct_dtor(ccx, /*bad*/copy *pt, &dtor.node.body,
- dtor.node.id, psubsts, Some(hash_id), parent_id)
- }
ast_map::node_trait_method(@ast::provided(mth), _, pt) => {
let d = mk_lldecl();
set_inline_hint_if_appr(/*bad*/copy mth.attrs, d);
}
}
}
- item_struct(ref struct_def, ref generics) => {
+ item_struct(ref struct_def, _) => {
for struct_def.ctor_id.each |&ctor_id| {
cx.rmap.insert(ctor_id);
}
- for struct_def.dtor.each |dtor| {
- cx.rmap.insert(dtor.node.id);
- if generics.ty_params.len() > 0u ||
- attr::find_inline_attr(dtor.node.attrs) != attr::ia_none
- {
- traverse_inline_body(cx, &dtor.node.body);
- }
- }
}
item_ty(t, _) => {
traverse_ty(t, cx,
visit_item: |i, cx, v| {
visit::visit_item(i, cx, v);
match i.node {
- item_struct(sdef, _) if sdef.dtor.is_some() => {
- traverse_public_item(cx, i);
- }
item_impl(*) => {
traverse_public_item(cx, i);
}
for uint::range(0u, n_tps) |n| { cx.uses[n] |= flags;}
}
}
- ast_map::node_dtor(_, ref dtor, _, _) => {
- handle_body(cx, &dtor.node.body);
- }
ast_map::node_struct_ctor(*) => {
// Similarly to node_variant, this monomorphized function just uses
// the representations of all of its type parameters.
Otherwise return none. */
pub fn ty_dtor(cx: ctxt, struct_id: def_id) -> DtorKind {
match cx.destructor_for_type.find(&struct_id) {
- Some(&method_def_id) => return TraitDtor(method_def_id),
- None => {} // Continue.
- }
-
- if is_local(struct_id) {
- match cx.items.find(&struct_id.node) {
- Some(&ast_map::node_item(@ast::item {
- node: ast::item_struct(@ast::struct_def { dtor: Some(ref dtor),
- _ },
- _),
- _
- }, _)) =>
- LegacyDtor(local_def((*dtor).node.id)),
- _ =>
- NoDtor
- }
- }
- else {
- match csearch::struct_dtor(cx.sess.cstore, struct_id) {
+ Some(&method_def_id) => TraitDtor(method_def_id),
None => NoDtor,
- Some(did) => LegacyDtor(did),
- }
}
}
ast_map::path_name((*variant).node.name))
}
- ast_map::node_dtor(_, _, _, path) => {
- vec::append_one(/*bad*/copy *path, ast_map::path_name(
- syntax::parse::token::special_idents::literally_dtor))
- }
-
ast_map::node_struct_ctor(_, item, path) => {
vec::append_one(/*bad*/copy *path, ast_map::path_name(item.ident))
}
ast::add => opcat_add,
ast::subtract => opcat_sub,
ast::mul => opcat_mult,
- ast::quot => opcat_mult,
+ ast::div => opcat_mult,
ast::rem => opcat_mult,
ast::and => opcat_logic,
ast::or => opcat_logic,
kind_name = "structure";
}
_ => {
- tcx.sess.span_fatal(
- pat.span,
- fmt!("mismatched types: expected `%s` but found enum or \
- structure",
- fcx.infcx().ty_to_str(expected)));
+ let resolved_expected =
+ fcx.infcx().ty_to_str(fcx.infcx().resolve_type_vars_if_possible(expected));
+ fcx.infcx().type_error_message_str(pat.span,
+ |actual| {
+ fmt!("mismatched types: expected `%s` but found %s",
+ resolved_expected, actual)},
+ ~"an enum or structure pattern",
+ None);
+ fcx.write_error(pat.id);
+ kind_name = "[error]";
+ arg_types = (copy subpats).get_or_default(~[]).map(|_|
+ ty::mk_err());
}
}
}
ast::pat_tup(ref elts) => {
let s = structure_of(fcx, pat.span, expected);
- let ex_elts = match s {
- ty::ty_tup(ref elts) => elts,
- _ => {
- tcx.sess.span_fatal
- (pat.span,
- fmt!("mismatched types: expected `%s`, found tuple",
- fcx.infcx().ty_to_str(expected)));
- }
- };
let e_count = elts.len();
- if e_count != ex_elts.len() {
- tcx.sess.span_fatal
- (pat.span, fmt!("mismatched types: expected a tuple \
- with %u fields, found one with %u \
- fields", ex_elts.len(), e_count));
- }
- let mut i = 0u;
- for elts.each |elt| {
- check_pat(pcx, *elt, ex_elts[i]);
- i += 1u;
+ match s {
+ ty::ty_tup(ref ex_elts) if e_count == ex_elts.len() => {
+ for elts.eachi |i, elt| {
+ check_pat(pcx, *elt, ex_elts[i]);
+ }
+ fcx.write_ty(pat.id, expected);
+ }
+ _ => {
+ for elts.each |elt| {
+ check_pat(pcx, *elt, ty::mk_err());
+ }
+ let actual = ty::mk_tup(tcx, elts.map(|pat_var| {
+ fcx.node_ty(pat_var.id)
+ }));
+ // use terr_tuple_size if both types are tuples
+ let type_error = match s {
+ ty::ty_tup(ref ex_elts) =>
+ ty::terr_tuple_size(ty::expected_found{expected: ex_elts.len(),
+ found: e_count}),
+ _ => ty::terr_mismatch
+ };
+ fcx.infcx().report_mismatched_types(pat.span,
+ expected,
+ actual,
+ &type_error);
+ fcx.write_error(pat.id);
+ }
}
-
- fcx.write_ty(pat.id, expected);
}
ast::pat_box(inner) => {
- match structure_of(fcx, pat.span, expected) {
- ty::ty_box(e_inner) => {
- check_pat(pcx, inner, e_inner.ty);
- fcx.write_ty(pat.id, expected);
- }
- _ => {
- tcx.sess.span_fatal(
- pat.span,
- ~"mismatched types: expected `" +
- fcx.infcx().ty_to_str(expected) +
- ~"` found box");
- }
- }
+ check_pointer_pat(pcx, Managed, inner, pat.id, pat.span, expected);
}
ast::pat_uniq(inner) => {
- match structure_of(fcx, pat.span, expected) {
- ty::ty_uniq(e_inner) => {
- check_pat(pcx, inner, e_inner.ty);
- fcx.write_ty(pat.id, expected);
- }
- _ => {
- tcx.sess.span_fatal(
- pat.span,
- ~"mismatched types: expected `" +
- fcx.infcx().ty_to_str(expected) +
- ~"` found uniq");
- }
- }
+ check_pointer_pat(pcx, Owned, inner, pat.id, pat.span, expected);
}
ast::pat_region(inner) => {
- match structure_of(fcx, pat.span, expected) {
- ty::ty_rptr(_, e_inner) => {
- check_pat(pcx, inner, e_inner.ty);
- fcx.write_ty(pat.id, expected);
- }
- _ => {
- tcx.sess.span_fatal(
- pat.span,
- ~"mismatched types: expected `" +
- fcx.infcx().ty_to_str(expected) +
- ~"` found borrowed pointer");
- }
- }
+ check_pointer_pat(pcx, Borrowed, inner, pat.id, pat.span, expected);
}
ast::pat_vec(ref before, slice, ref after) => {
let default_region_var =
(mt, default_region_var)
},
_ => {
- tcx.sess.span_fatal(
- pat.span,
- fmt!("mismatched type: expected `%s` but found vector",
- fcx.infcx().ty_to_str(expected))
- );
+ for before.each |&elt| {
+ check_pat(pcx, elt, ty::mk_err());
+ }
+ for slice.each |&elt| {
+ check_pat(pcx, elt, ty::mk_err());
+ }
+ for after.each |&elt| {
+ check_pat(pcx, elt, ty::mk_err());
+ }
+ let resolved_expected =
+ fcx.infcx().ty_to_str(fcx.infcx().resolve_type_vars_if_possible(expected));
+ fcx.infcx().type_error_message_str(pat.span,
+ |actual| {
+ fmt!("mismatched types: expected `%s` but found %s",
+ resolved_expected, actual)},
+ ~"a vector pattern",
+ None);
+ fcx.write_error(pat.id);
+ return;
}
};
for before.each |elt| {
}
}
+// Helper function to check @, ~ and & patterns
+pub fn check_pointer_pat(pcx: &pat_ctxt,
+ pointer_kind: PointerKind,
+ inner: @ast::pat,
+ pat_id: ast::node_id,
+ span: span,
+ expected: ty::t) {
+ let fcx = pcx.fcx;
+ let check_inner: &fn(ty::mt) = |e_inner| {
+ check_pat(pcx, inner, e_inner.ty);
+ fcx.write_ty(pat_id, expected);
+ };
+ match structure_of(fcx, span, expected) {
+ ty::ty_box(e_inner) if pointer_kind == Managed => {
+ check_inner(e_inner);
+ }
+ ty::ty_uniq(e_inner) if pointer_kind == Owned => {
+ check_inner(e_inner);
+ }
+ ty::ty_rptr(_, e_inner) if pointer_kind == Borrowed => {
+ check_inner(e_inner);
+ }
+ _ => {
+ check_pat(pcx, inner, ty::mk_err());
+ let resolved_expected =
+ fcx.infcx().ty_to_str(fcx.infcx().resolve_type_vars_if_possible(expected));
+ fcx.infcx().type_error_message_str(span, |actual| {
+ fmt!("mismatched types: expected `%s` but found %s",
+ resolved_expected, actual)},
+ fmt!("%s pattern", match pointer_kind {
+ Managed => "an @-box",
+ Owned => "a ~-box",
+ Borrowed => "an &-pointer"
+ }),
+ None);
+ fcx.write_error(pat_id);
+ }
+ }
+}
+
+#[deriving(Eq)]
+enum PointerKind { Managed, Owned, Borrowed }
+
}
}
-pub fn check_struct(ccx: @mut CrateCtxt,
- struct_def: @ast::struct_def,
- id: ast::node_id,
- span: span) {
- let tcx = ccx.tcx;
- let self_ty = ty::node_id_to_type(tcx, id);
-
- for struct_def.dtor.each |dtor| {
- let class_t = SelfInfo {
- self_ty: self_ty,
- self_id: dtor.node.self_id,
- span: dtor.span,
- };
- // typecheck the dtor
- let dtor_dec = ast_util::dtor_dec();
- check_bare_fn(
- ccx,
- &dtor_dec,
- &dtor.node.body,
- dtor.node.id,
- Some(class_t)
- );
- };
-
+pub fn check_struct(ccx: @mut CrateCtxt, id: ast::node_id, span: span) {
// Check that the class is instantiable
check_instantiable(ccx.tcx, span, id);
}
}
}
}
- ast::item_struct(struct_def, _) => {
- check_struct(ccx, struct_def, it.id, it.span);
+ ast::item_struct(*) => {
+ check_struct(ccx, it.id, it.span);
}
ast::item_ty(t, ref generics) => {
let tpt_ty = ty::node_id_to_type(ccx.tcx, it.id);
use syntax::ast;
use syntax::ast_map;
use syntax::ast_util::{local_def, split_trait_methods};
-use syntax::ast_util;
use syntax::codemap::span;
use syntax::codemap;
use syntax::print::pprust::{path_to_str, self_ty_to_str};
id: ast::node_id) {
let tcx = ccx.tcx;
- for struct_def.dtor.each |dtor| {
- let region_parameterization =
- RegionParameterization::from_variance_and_generics(rp, generics);
-
- // Write the dtor type
- let t_dtor = ty::mk_bare_fn(
- tcx,
- astconv::ty_of_bare_fn(
- ccx,
- &type_rscope(region_parameterization),
- ast::impure_fn,
- AbiSet::Rust(),
- &opt_vec::Empty,
- &ast_util::dtor_dec()));
- write_ty_to_tcx(tcx, dtor.node.id, t_dtor);
- tcx.tcache.insert(local_def(dtor.node.id),
- ty_param_bounds_and_ty {
- generics: ty::Generics {
- type_param_defs: tpt.generics.type_param_defs,
- region_param: rp
- },
- ty: t_dtor});
- };
-
// Write the type of each of the members
for struct_def.fields.each |f| {
convert_field(ccx, rp, tpt.generics.type_param_defs, *f, generics);
}
}
- fn type_error_message(@mut self, sp: span, mk_msg: &fn(~str) -> ~str,
- actual_ty: ty::t, err: Option<&ty::type_err>) {
- let actual_ty = self.resolve_type_vars_if_possible(actual_ty);
- // Don't report an error if actual type is ty_err.
- if ty::type_is_error(actual_ty) {
- return;
- }
+ fn type_error_message_str(@mut self, sp: span, mk_msg: &fn(~str) -> ~str,
+ actual_ty: ~str, err: Option<&ty::type_err>) {
let error_str = err.map_default(~"", |t_err|
fmt!(" (%s)",
ty::type_err_to_str(self.tcx, *t_err)));
self.tcx.sess.span_err(sp,
- fmt!("%s%s", mk_msg(self.ty_to_str(actual_ty)),
- error_str));
+ fmt!("%s%s", mk_msg(actual_ty), error_str));
for err.each |err| {
ty::note_and_explain_type_err(self.tcx, *err)
}
}
+ fn type_error_message(@mut self, sp: span, mk_msg: &fn(~str) -> ~str,
+ actual_ty: ty::t, err: Option<&ty::type_err>) {
+ let actual_ty = self.resolve_type_vars_if_possible(actual_ty);
+
+ // Don't report an error if actual type is ty_err.
+ if ty::type_is_error(actual_ty) {
+ return;
+ }
+
+ self.type_error_message_str(sp, mk_msg, self.ty_to_str(actual_ty),
+ err);
+ }
+
fn report_mismatched_types(@mut self, sp: span, e: ty::t, a: ty::t,
err: &ty::type_err) {
let resolved_expected =
/// what I actually want
fn strip_struct_extra_stuff(item: @ast::item) -> @ast::item {
let node = match copy item.node {
- ast::item_struct(def, tys) => {
- let def = @ast::struct_def {
- dtor: None, // Remove the drop { } block
- .. copy *def
- };
- ast::item_struct(def, tys)
- }
+ ast::item_struct(def, tys) => ast::item_struct(def, tys),
_ => fail!(~"not a struct")
};
"struct S {"));
}
- #[test]
- fn should_not_serialize_struct_drop_blocks() {
- // All we care about are the fields
- let doc = mk_doc(~"struct S { field: (), drop { } }");
- assert!(!(&doc.cratemod().structs()[0].sig).get().contains("drop"));
- }
-
#[test]
fn should_not_serialize_struct_attrs() {
// All we care about are the fields
A BigUint-typed value BigUint { data: @[a, b, c] } represents a number
(a + b * BigDigit::base + c * BigDigit::base^2).
*/
+#[deriving(Clone)]
pub struct BigUint {
priv data: ~[BigDigit]
}
}
}
-impl Quot<BigUint, BigUint> for BigUint {
+impl Div<BigUint, BigUint> for BigUint {
#[inline(always)]
- fn quot(&self, other: &BigUint) -> BigUint {
- let (q, _) = self.quot_rem(other);
+ fn div(&self, other: &BigUint) -> BigUint {
+ let (q, _) = self.div_rem(other);
return q;
}
}
impl Rem<BigUint, BigUint> for BigUint {
#[inline(always)]
fn rem(&self, other: &BigUint) -> BigUint {
- let (_, r) = self.quot_rem(other);
+ let (_, r) = self.div_rem(other);
return r;
}
}
impl Integer for BigUint {
#[inline(always)]
- fn div(&self, other: &BigUint) -> BigUint {
- let (d, _) = self.div_mod(other);
+ fn div_rem(&self, other: &BigUint) -> (BigUint, BigUint) {
+ self.div_mod_floor(other)
+ }
+
+ #[inline(always)]
+ fn div_floor(&self, other: &BigUint) -> BigUint {
+ let (d, _) = self.div_mod_floor(other);
return d;
}
#[inline(always)]
- fn modulo(&self, other: &BigUint) -> BigUint {
- let (_, m) = self.div_mod(other);
+ fn mod_floor(&self, other: &BigUint) -> BigUint {
+ let (_, m) = self.div_mod_floor(other);
return m;
}
#[inline(always)]
- fn div_mod(&self, other: &BigUint) -> (BigUint, BigUint) {
+ fn div_mod_floor(&self, other: &BigUint) -> (BigUint, BigUint) {
if other.is_zero() { fail!() }
if self.is_zero() { return (Zero::zero(), Zero::zero()); }
if *other == One::one() { return (copy *self, Zero::zero()); }
shift += 1;
}
assert!(shift < BigDigit::bits);
- let (d, m) = div_mod_inner(self << shift, other << shift);
+ let (d, m) = div_mod_floor_inner(self << shift, other << shift);
return (d, m >> shift);
#[inline(always)]
- fn div_mod_inner(a: BigUint, b: BigUint) -> (BigUint, BigUint) {
+ fn div_mod_floor_inner(a: BigUint, b: BigUint) -> (BigUint, BigUint) {
let mut m = a;
let mut d = Zero::zero::<BigUint>();
let mut n = 1;
}
}
- #[inline(always)]
- fn quot_rem(&self, other: &BigUint) -> (BigUint, BigUint) {
- self.div_mod(other)
- }
-
/**
* Calculates the Greatest Common Divisor (GCD) of the number and `other`
*
let mut result = ~[];
let mut m = n;
while m > divider {
- let (d, m0) = m.div_mod(÷r);
+ let (d, m0) = m.div_mod_floor(÷r);
result += [m0.to_uint() as BigDigit];
m = d;
}
}
/// A Sign is a BigInt's composing element.
-#[deriving(Eq)]
+#[deriving(Eq, Clone)]
pub enum Sign { Minus, Zero, Plus }
impl Ord for Sign {
}
/// A big signed integer type.
+#[deriving(Clone)]
pub struct BigInt {
priv sign: Sign,
priv data: BigUint
#[inline(always)]
fn abs(&self) -> BigInt {
match self.sign {
- Plus | Zero => copy *self,
- Minus => BigInt::from_biguint(Plus, copy self.data)
+ Plus | Zero => self.clone(),
+ Minus => BigInt::from_biguint(Plus, self.data.clone())
}
}
#[inline(always)]
fn add(&self, other: &BigInt) -> BigInt {
match (self.sign, other.sign) {
- (Zero, _) => copy *other,
- (_, Zero) => copy *self,
+ (Zero, _) => other.clone(),
+ (_, Zero) => self.clone(),
(Plus, Plus) => BigInt::from_biguint(Plus,
self.data + other.data),
(Plus, Minus) => self - (-*other),
fn sub(&self, other: &BigInt) -> BigInt {
match (self.sign, other.sign) {
(Zero, _) => -other,
- (_, Zero) => copy *self,
+ (_, Zero) => self.clone(),
(Plus, Plus) => match self.data.cmp(&other.data) {
Less => BigInt::from_biguint(Minus, other.data - self.data),
Greater => BigInt::from_biguint(Plus, self.data - other.data),
}
}
-impl Quot<BigInt, BigInt> for BigInt {
+impl Div<BigInt, BigInt> for BigInt {
#[inline(always)]
- fn quot(&self, other: &BigInt) -> BigInt {
- let (q, _) = self.quot_rem(other);
+ fn div(&self, other: &BigInt) -> BigInt {
+ let (q, _) = self.div_rem(other);
return q;
}
}
impl Rem<BigInt, BigInt> for BigInt {
#[inline(always)]
fn rem(&self, other: &BigInt) -> BigInt {
- let (_, r) = self.quot_rem(other);
+ let (_, r) = self.div_rem(other);
return r;
}
}
impl Neg<BigInt> for BigInt {
#[inline(always)]
fn neg(&self) -> BigInt {
- BigInt::from_biguint(self.sign.neg(), copy self.data)
+ BigInt::from_biguint(self.sign.neg(), self.data.clone())
}
}
impl Integer for BigInt {
#[inline(always)]
- fn div(&self, other: &BigInt) -> BigInt {
- let (d, _) = self.div_mod(other);
+ fn div_rem(&self, other: &BigInt) -> (BigInt, BigInt) {
+ // r.sign == self.sign
+ let (d_ui, r_ui) = self.data.div_mod_floor(&other.data);
+ let d = BigInt::from_biguint(Plus, d_ui);
+ let r = BigInt::from_biguint(Plus, r_ui);
+ match (self.sign, other.sign) {
+ (_, Zero) => fail!(),
+ (Plus, Plus) | (Zero, Plus) => ( d, r),
+ (Plus, Minus) | (Zero, Minus) => (-d, r),
+ (Minus, Plus) => (-d, -r),
+ (Minus, Minus) => ( d, -r)
+ }
+ }
+
+ #[inline(always)]
+ fn div_floor(&self, other: &BigInt) -> BigInt {
+ let (d, _) = self.div_mod_floor(other);
return d;
}
#[inline(always)]
- fn modulo(&self, other: &BigInt) -> BigInt {
- let (_, m) = self.div_mod(other);
+ fn mod_floor(&self, other: &BigInt) -> BigInt {
+ let (_, m) = self.div_mod_floor(other);
return m;
}
#[inline(always)]
- fn div_mod(&self, other: &BigInt) -> (BigInt, BigInt) {
+ fn div_mod_floor(&self, other: &BigInt) -> (BigInt, BigInt) {
// m.sign == other.sign
- let (d_ui, m_ui) = self.data.quot_rem(&other.data);
+ let (d_ui, m_ui) = self.data.div_rem(&other.data);
let d = BigInt::from_biguint(Plus, d_ui),
m = BigInt::from_biguint(Plus, m_ui);
match (self.sign, other.sign) {
}
}
- #[inline(always)]
- fn quot_rem(&self, other: &BigInt) -> (BigInt, BigInt) {
- // r.sign == self.sign
- let (q_ui, r_ui) = self.data.div_mod(&other.data);
- let q = BigInt::from_biguint(Plus, q_ui);
- let r = BigInt::from_biguint(Plus, r_ui);
- match (self.sign, other.sign) {
- (_, Zero) => fail!(),
- (Plus, Plus) | (Zero, Plus) => ( q, r),
- (Plus, Minus) | (Zero, Minus) => (-q, r),
- (Minus, Plus) => (-q, -r),
- (Minus, Minus) => ( q, -r)
- }
- }
-
/**
* Calculates the Greatest Common Divisor (GCD) of the number and `other`
*
#[cfg(test)]
mod biguint_tests {
-
- use core::*;
+ use super::*;
use core::num::{IntConvertible, Zero, One, FromStrRadix};
use core::cmp::{Less, Equal, Greater};
- use super::{BigUint, BigDigit};
#[test]
fn test_from_slice() {
(&[ 0, 0, 1], &[ 0, 0, 0, 1], &[0, 0, 0, 0, 0, 1])
];
- static quot_rem_quadruples: &'static [(&'static [BigDigit],
+ static div_rem_quadruples: &'static [(&'static [BigDigit],
&'static [BigDigit],
&'static [BigDigit],
&'static [BigDigit])]
assert!(b * a == c);
}
- for quot_rem_quadruples.each |elm| {
+ for div_rem_quadruples.each |elm| {
let (aVec, bVec, cVec, dVec) = *elm;
let a = BigUint::from_slice(aVec);
let b = BigUint::from_slice(bVec);
}
#[test]
- fn test_quot_rem() {
+ fn test_div_rem() {
for mul_triples.each |elm| {
let (aVec, bVec, cVec) = *elm;
let a = BigUint::from_slice(aVec);
let c = BigUint::from_slice(cVec);
if !a.is_zero() {
- assert!(c.quot_rem(&a) == (copy b, Zero::zero()));
+ assert!(c.div_rem(&a) == (b.clone(), Zero::zero()));
}
if !b.is_zero() {
- assert!(c.quot_rem(&b) == (copy a, Zero::zero()));
+ assert!(c.div_rem(&b) == (a.clone(), Zero::zero()));
}
}
- for quot_rem_quadruples.each |elm| {
+ for div_rem_quadruples.each |elm| {
let (aVec, bVec, cVec, dVec) = *elm;
let a = BigUint::from_slice(aVec);
let b = BigUint::from_slice(bVec);
let c = BigUint::from_slice(cVec);
let d = BigUint::from_slice(dVec);
- if !b.is_zero() { assert!(a.quot_rem(&b) == (c, d)); }
+ if !b.is_zero() { assert!(a.div_rem(&b) == (c, d)); }
}
}
#[cfg(test)]
mod bigint_tests {
- use super::{BigInt, BigUint, BigDigit, Sign, Minus, Zero, Plus};
- use core::*;
+ use super::*;
use core::cmp::{Less, Equal, Greater};
use core::num::{IntConvertible, Zero, One, FromStrRadix};
(&[ 0, 0, 1], &[ 0, 0, 0, 1], &[0, 0, 0, 0, 0, 1])
];
- static quot_rem_quadruples: &'static [(&'static [BigDigit],
- &'static [BigDigit],
- &'static [BigDigit],
- &'static [BigDigit])]
+ static div_rem_quadruples: &'static [(&'static [BigDigit],
+ &'static [BigDigit],
+ &'static [BigDigit],
+ &'static [BigDigit])]
= &[
(&[ 1], &[ 2], &[], &[1]),
(&[ 1, 1], &[ 2], &[-1/2+1], &[1]),
assert!((-b) * a == -c);
}
- for quot_rem_quadruples.each |elm| {
+ for div_rem_quadruples.each |elm| {
let (aVec, bVec, cVec, dVec) = *elm;
let a = BigInt::from_slice(Plus, aVec);
let b = BigInt::from_slice(Plus, bVec);
}
#[test]
- fn test_div_mod() {
+ fn test_div_mod_floor() {
fn check_sub(a: &BigInt, b: &BigInt, ans_d: &BigInt, ans_m: &BigInt) {
- let (d, m) = a.div_mod(b);
+ let (d, m) = a.div_mod_floor(b);
if !m.is_zero() {
assert!(m.sign == b.sign);
}
if !b.is_zero() { check(&c, &b, &a, &Zero::zero()); }
}
- for quot_rem_quadruples.each |elm| {
+ for div_rem_quadruples.each |elm| {
let (aVec, bVec, cVec, dVec) = *elm;
let a = BigInt::from_slice(Plus, aVec);
let b = BigInt::from_slice(Plus, bVec);
#[test]
- fn test_quot_rem() {
+ fn test_div_rem() {
fn check_sub(a: &BigInt, b: &BigInt, ans_q: &BigInt, ans_r: &BigInt) {
- let (q, r) = a.quot_rem(b);
+ let (q, r) = a.div_rem(b);
if !r.is_zero() {
assert!(r.sign == a.sign);
}
if !b.is_zero() { check(&c, &b, &a, &Zero::zero()); }
}
- for quot_rem_quadruples.each |elm| {
+ for div_rem_quadruples.each |elm| {
let (aVec, bVec, cVec, dVec) = *elm;
let a = BigInt::from_slice(Plus, aVec);
let b = BigInt::from_slice(Plus, bVec);
// (a + i b) / (c + i d) == [(a + i b) * (c - i d)] / (c*c + d*d)
// == [(a*c + b*d) / (c*c + d*d)] + i [(b*c - a*d) / (c*c + d*d)]
-impl<T: Copy + Num> Quot<Cmplx<T>, Cmplx<T>> for Cmplx<T> {
+impl<T: Copy + Num> Div<Cmplx<T>, Cmplx<T>> for Cmplx<T> {
#[inline]
- fn quot(&self, other: &Cmplx<T>) -> Cmplx<T> {
+ fn div(&self, other: &Cmplx<T>) -> Cmplx<T> {
let norm_sqr = other.norm_sqr();
Cmplx::new((self.re*other.re + self.im*other.im) / norm_sqr,
(self.im*other.re - self.re*other.im) / norm_sqr)
}
}
#[test]
- fn test_quot() {
+ fn test_div() {
assert_eq!(_neg1_1i / _0_1i, _1_1i);
for all_consts.each |&c| {
if c != Zero::zero() {
// (a/b) / (c/d) = (a*d)/(b*c)
impl<T: Copy + Num + Ord>
- Quot<Ratio<T>,Ratio<T>> for Ratio<T> {
+ Div<Ratio<T>,Ratio<T>> for Ratio<T> {
#[inline]
- fn quot(&self, rhs: &Ratio<T>) -> Ratio<T> {
+ fn div(&self, rhs: &Ratio<T>) -> Ratio<T> {
Ratio::new(self.numer * rhs.denom, self.denom * rhs.numer)
}
}
}
#[test]
- fn test_quot() {
+ fn test_div() {
assert_eq!(_1 / _1_2, _2);
assert_eq!(_3_2 / _1_2, _1 + _2);
assert_eq!(_1 / _neg1_2, _neg1_2 + _neg1_2 + _neg1_2 + _neg1_2);
}
#[test]
#[should_fail]
- fn test_quot_0() {
+ fn test_div_0() {
let _a = _1 / _0;
}
}
use core::libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR};
use core::os;
- let root = mkdtemp(&os::tmpdir(), "temp").expect("recursive_mkdir_rel");
- os::change_dir(&root);
- let path = Path("frob");
- assert!(os::mkdir_recursive(&path, (S_IRUSR | S_IWUSR | S_IXUSR) as i32));
- assert!(os::path_is_dir(&path));
- assert!(os::mkdir_recursive(&path, (S_IRUSR | S_IWUSR | S_IXUSR) as i32));
- assert!(os::path_is_dir(&path));
+ let root = mkdtemp(&os::tmpdir(), "recursive_mkdir_rel").
+ expect("recursive_mkdir_rel");
+ assert!(do os::change_dir_locked(&root) {
+ let path = Path("frob");
+ debug!("recursive_mkdir_rel: Making: %s in cwd %s [%?]", path.to_str(),
+ os::getcwd().to_str(),
+ os::path_exists(&path));
+ assert!(os::mkdir_recursive(&path, (S_IRUSR | S_IWUSR | S_IXUSR) as i32));
+ assert!(os::path_is_dir(&path));
+ assert!(os::mkdir_recursive(&path, (S_IRUSR | S_IWUSR | S_IXUSR) as i32));
+ assert!(os::path_is_dir(&path));
+ });
}
#[test]
use core::libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR};
use core::os;
- let root = mkdtemp(&os::tmpdir(), "temp").expect("recursive_mkdir_rel_2");
- os::change_dir(&root);
- let path = Path("./frob/baz");
- debug!("...Making: %s in cwd %s", path.to_str(), os::getcwd().to_str());
- assert!(os::mkdir_recursive(&path, (S_IRUSR | S_IWUSR | S_IXUSR) as i32));
- assert!(os::path_is_dir(&path));
- assert!(os::path_is_dir(&path.pop()));
- let path2 = Path("quux/blat");
- debug!("Making: %s in cwd %s", path2.to_str(), os::getcwd().to_str());
- assert!(os::mkdir_recursive(&path2, (S_IRUSR | S_IWUSR | S_IXUSR) as i32));
- assert!(os::path_is_dir(&path2));
- assert!(os::path_is_dir(&path2.pop()));
+ let root = mkdtemp(&os::tmpdir(), "recursive_mkdir_rel_2").
+ expect("recursive_mkdir_rel_2");
+ assert!(do os::change_dir_locked(&root) {
+ let path = Path("./frob/baz");
+ debug!("recursive_mkdir_rel_2: Making: %s in cwd %s [%?]", path.to_str(),
+ os::getcwd().to_str(), os::path_exists(&path));
+ assert!(os::mkdir_recursive(&path, (S_IRUSR | S_IWUSR | S_IXUSR) as i32));
+ assert!(os::path_is_dir(&path));
+ assert!(os::path_is_dir(&path.pop()));
+ let path2 = Path("quux/blat");
+ debug!("recursive_mkdir_rel_2: Making: %s in cwd %s", path2.to_str(),
+ os::getcwd().to_str());
+ assert!(os::mkdir_recursive(&path2, (S_IRUSR | S_IWUSR | S_IXUSR) as i32));
+ assert!(os::path_is_dir(&path2));
+ assert!(os::path_is_dir(&path2.pop()));
+ });
}
-
-}
\ No newline at end of file
+}
add,
subtract,
mul,
- quot,
+ div,
rem,
and,
or,
kind: struct_field_kind,
id: node_id,
ty: @Ty,
+ attrs: ~[attribute],
}
pub type struct_field = spanned<struct_field_>;
#[auto_decode]
#[deriving(Eq)]
pub struct struct_def {
- fields: ~[@struct_field], /* fields */
- /* (not including ctor or dtor) */
- /* dtor is optional */
- dtor: Option<struct_dtor>,
+ fields: ~[@struct_field], /* fields, not including ctor */
/* ID of the constructor. This is only used for tuple- or enum-like
* structs. */
ctor_id: Option<node_id>
}
}
-pub type struct_dtor = spanned<struct_dtor_>;
-
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
-pub struct struct_dtor_ {
- id: node_id,
- attrs: ~[attribute],
- self_id: node_id,
- body: blk,
-}
-
#[auto_encode]
#[auto_decode]
#[deriving(Eq)]
ii_item(@item),
ii_method(def_id /* impl id */, @method),
ii_foreign(@foreign_item),
- ii_dtor(struct_dtor, ident, Generics, def_id /* parent id */)
}
/* hold off on tests ... they appear in a later merge.
use ast_util::{inlined_item_utils, stmt_id};
use ast_util;
use codemap;
-use codemap::spanned;
use diagnostic::span_handler;
use parse::token::ident_interner;
use print::pprust;
// order they are introduced.
node_arg(arg, uint),
node_local(uint),
- // Destructor for a struct
- node_dtor(Generics, @struct_dtor, def_id, @path),
node_block(blk),
node_struct_ctor(@struct_def, @item, @path),
}
// don't decode and instantiate the impl, but just the method, we have to
// add it to the table now:
match *ii {
- ii_item(*) | ii_dtor(*) => { /* fallthrough */ }
+ ii_item(*) => { /* fallthrough */ }
ii_foreign(i) => {
cx.map.insert(i.id, node_foreign_item(i,
AbiSet::Intrinsic(),
node_arg(/* FIXME (#2543) */ copy *a, cx.local_id));
cx.local_id += 1u;
}
- match *fk {
- visit::fk_dtor(generics, ref attrs, self_id, parent_id) => {
- let dt = @spanned {
- node: ast::struct_dtor_ {
- id: id,
- attrs: /* FIXME (#2543) */ vec::from_slice(*attrs),
- self_id: self_id,
- body: /* FIXME (#2543) */ copy *body,
- },
- span: sp,
- };
- cx.map.insert(
- id,
- node_dtor(
- /* FIXME (#2543) */ copy *generics,
- dt,
- parent_id,
- @/* FIXME (#2543) */ copy cx.path));
- }
- _ => ()
- }
visit::visit_fn(fk, decl, body, sp, id, cx, v);
}
Some(&node_local(_)) => { // add more info here
fmt!("local (id=%?)", id)
}
- Some(&node_dtor(*)) => { // add more info here
- fmt!("node_dtor (id=%?)", id)
- }
Some(&node_block(_)) => {
fmt!("block")
}
use ast::*;
use ast;
use ast_util;
-use codemap::{span, dummy_sp, spanned};
+use codemap::{span, spanned};
use parse::token;
use visit;
use opt_vec;
add => return ~"+",
subtract => return ~"-",
mul => return ~"*",
- quot => return ~"/",
+ div => return ~"/",
rem => return ~"%",
and => return ~"&&",
or => return ~"||",
add => return Some(~"add"),
subtract => return Some(~"sub"),
mul => return Some(~"mul"),
- quot => return Some(~"quot"),
+ div => return Some(~"div"),
rem => return Some(~"rem"),
bitxor => return Some(~"bitxor"),
bitand => return Some(~"bitand"),
ii_item(i) => /* FIXME (#2543) */ copy i.ident,
ii_foreign(i) => /* FIXME (#2543) */ copy i.ident,
ii_method(_, m) => /* FIXME (#2543) */ copy m.ident,
- ii_dtor(_, nm, _, _) => /* FIXME (#2543) */ copy nm
}
}
ii_item(i) => i.id,
ii_foreign(i) => i.id,
ii_method(_, m) => m.id,
- ii_dtor(ref dtor, _, _, _) => (*dtor).node.id
}
}
ii_item(i) => (v.visit_item)(i, e, v),
ii_foreign(i) => (v.visit_foreign_item)(i, e, v),
ii_method(_, m) => visit::visit_method_helper(m, e, v),
- ii_dtor(/*bad*/ copy dtor, _, ref generics, parent_id) => {
- visit::visit_struct_dtor_helper(dtor, generics,
- parent_id, e, v);
- }
}
}
}
/// Maps a binary operator to its precedence
pub fn operator_prec(op: ast::binop) -> uint {
match op {
- mul | quot | rem => 12u,
+ mul | div | rem => 12u,
// 'as' sits between here with 11
add | subtract => 10u,
shl | shr => 9u,
/// not appearing in the prior table.
pub static as_prec: uint = 11u;
-pub fn dtor_ty() -> @ast::Ty {
- @ast::Ty {id: 0, node: ty_nil, span: dummy_sp()}
-}
-
-pub fn dtor_dec() -> fn_decl {
- let nil_t = dtor_ty();
- // dtor has no args
- ast::fn_decl {
- inputs: ~[],
- output: nil_t,
- cf: return_val,
- }
-}
-
pub fn empty_generics() -> Generics {
Generics {lifetimes: opt_vec::Empty,
ty_params: opt_vec::Empty}
vfn(id);
match *fk {
- visit::fk_dtor(generics, _, self_id, parent_id) => {
- visit_generics(generics);
- vfn(id);
- vfn(self_id);
- vfn(parent_id.node);
- }
visit::fk_item_fn(_, generics, _, _) => {
visit_generics(generics);
}
ast::struct_immutable,
ast::inherited),
id: cx.next_id(),
- ty: fty
+ ty: fty,
+ attrs: ~[],
},
span: dummy_sp()
}
dummy_sp(),
ast::struct_def {
fields: fields,
- dtor: None,
ctor_id: None
},
cx.strip_bounds(&generics))
fn noop_fold_struct_field(sf: @struct_field, fld: @ast_fold)
-> @struct_field {
+ let fold_attribute = |x| fold_attribute_(x, fld);
+
@spanned { node: ast::struct_field_ { kind: copy sf.node.kind,
id: sf.node.id,
- ty: fld.fold_ty(sf.node.ty) },
+ ty: fld.fold_ty(sf.node.ty),
+ attrs: sf.node.attrs.map(|e| fold_attribute(*e)) },
span: sf.span }
}
fn fold_struct_def(struct_def: @ast::struct_def, fld: @ast_fold)
-> @ast::struct_def {
- let dtor = do struct_def.dtor.map |dtor| {
- let dtor_body = fld.fold_block(&dtor.node.body);
- let dtor_id = fld.new_id(dtor.node.id);
- spanned {
- node: ast::struct_dtor_ {
- body: dtor_body,
- id: dtor_id,
- .. copy dtor.node
- },
- span: copy dtor.span
- }
- };
@ast::struct_def {
fields: struct_def.fields.map(|f| fold_struct_field(*f, fld)),
- dtor: dtor,
ctor_id: struct_def.ctor_id.map(|cid| fld.new_id(*cid)),
}
}
kind: copy f.node.kind,
id: fld.new_id(f.node.id),
ty: fld.fold_ty(f.node.ty),
+ attrs: /* FIXME (#2543) */ copy f.node.attrs,
},
span: fld.new_span(f.span),
}
})
}
struct_variant_kind(struct_def) => {
- let dtor = do struct_def.dtor.map |dtor| {
- let dtor_body = fld.fold_block(&dtor.node.body);
- let dtor_id = fld.new_id(dtor.node.id);
- spanned {
- node: ast::struct_dtor_ {
- body: dtor_body,
- id: dtor_id,
- .. copy dtor.node
- },
- .. copy *dtor
- }
- };
kind = struct_variant_kind(@ast::struct_def {
fields: vec::map(struct_def.fields,
|f| fld.fold_struct_field(*f)),
- dtor: dtor,
ctor_id: struct_def.ctor_id.map(|c| fld.new_id(*c))
})
}
kind: copy sf.node.kind,
id: sf.node.id,
ty: (self as @ast_fold).fold_ty(sf.node.ty),
+ attrs: copy sf.node.attrs,
},
span: (self.new_span)(sf.span),
}
use core::io;
use core::option::{None, Option, Some};
use core::path::Path;
-use core::result::{Err, Ok, Result};
+use core::result::{Err, Ok};
pub mod lexer;
pub mod parser;
*/
-use ast::{expr, expr_lit, lit_nil};
+use ast::{expr, expr_lit, lit_nil, attribute};
use ast;
use codemap::{span, respan};
use parse::parser::Parser;
}
}
- fn try_parse_obsolete_priv_section(&self) -> bool {
+ fn try_parse_obsolete_priv_section(&self, attrs: ~[attribute]) -> bool {
if self.is_keyword(&~"priv") && self.look_ahead(1) == token::LBRACE {
self.obsolete(copy *self.span, ObsoletePrivSection);
self.eat_keyword(&~"priv");
self.bump();
while *self.token != token::RBRACE {
- self.parse_single_struct_field(ast::private);
+ self.parse_single_struct_field(ast::private, attrs);
}
self.bump();
true
use ast::{bind_by_copy, bitand, bitor, bitxor, blk};
use ast::{blk_check_mode, box};
use ast::{crate, crate_cfg, decl, decl_item};
-use ast::{decl_local, default_blk, deref, quot, enum_def};
+use ast::{decl_local, default_blk, deref, div, enum_def};
use ast::{expr, expr_, expr_addr_of, expr_match, expr_again};
use ast::{expr_assign, expr_assign_op, expr_binary, expr_block};
use ast::{expr_break, expr_call, expr_cast, expr_copy, expr_do_body};
RESTRICT_NO_BAR_OR_DOUBLEBAR_OP,
}
-// So that we can distinguish a class dtor from other class members
-
-enum class_contents { dtor_decl(blk, ~[attribute], codemap::span),
- members(~[@struct_field]) }
-
type arg_or_capture_item = Either<arg, ()>;
type item_info = (ident, item_, Option<~[attribute]>);
token::PLUS => aop = add,
token::MINUS => aop = subtract,
token::STAR => aop = mul,
- token::SLASH => aop = quot,
+ token::SLASH => aop = div,
token::PERCENT => aop = rem,
token::CARET => aop = bitxor,
token::AND => aop = bitand,
}
// parse a structure field
- fn parse_name_and_ty(&self, pr: visibility) -> @struct_field {
+ fn parse_name_and_ty(&self,
+ pr: visibility,
+ attrs: ~[attribute]) -> @struct_field {
let mut is_mutbl = struct_immutable;
let lo = self.span.lo;
if self.eat_keyword(&~"mut") {
@spanned(lo, self.last_span.hi, ast::struct_field_ {
kind: named_field(name, is_mutbl, pr),
id: self.get_id(),
- ty: ty
+ ty: ty,
+ attrs: attrs,
})
}
}
let mut fields: ~[@struct_field];
- let mut the_dtor: Option<(blk, ~[attribute], codemap::span)> = None;
let is_tuple_like;
if self.eat(&token::LBRACE) {
is_tuple_like = false;
fields = ~[];
while *self.token != token::RBRACE {
- match self.parse_struct_decl_field() {
- dtor_decl(ref blk, ref attrs, s) => {
- match the_dtor {
- Some((_, _, s_first)) => {
- self.span_note(s, fmt!("Duplicate destructor \
- declaration for class %s",
- *self.interner.get(class_name)));
- self.span_fatal(copy s_first, ~"First destructor \
- declared here");
- }
- None => {
- the_dtor = Some((copy *blk, copy *attrs, s));
- }
- }
- }
- members(mms) => {
- for mms.each |struct_field| {
- fields.push(*struct_field)
- }
- }
+ for self.parse_struct_decl_field().each |struct_field| {
+ fields.push(*struct_field)
}
}
if fields.len() == 0 {
&token::RPAREN,
seq_sep_trailing_allowed(token::COMMA)
) |p| {
+ let attrs = self.parse_outer_attributes();
let lo = p.span.lo;
let struct_field_ = ast::struct_field_ {
kind: unnamed_field,
id: self.get_id(),
- ty: p.parse_ty(false)
+ ty: p.parse_ty(false),
+ attrs: attrs,
};
@spanned(lo, p.span.hi, struct_field_)
};
);
}
- let actual_dtor = do the_dtor.map |dtor| {
- let (d_body, d_attrs, d_s) = copy *dtor;
- codemap::spanned { node: ast::struct_dtor_ { id: self.get_id(),
- attrs: d_attrs,
- self_id: self.get_id(),
- body: d_body},
- span: d_s}};
let _ = self.get_id(); // XXX: Workaround for crazy bug.
let new_id = self.get_id();
(class_name,
item_struct(@ast::struct_def {
fields: fields,
- dtor: actual_dtor,
ctor_id: if is_tuple_like { Some(new_id) } else { None }
}, generics),
None)
}
// parse a structure field declaration
- fn parse_single_struct_field(&self, vis: visibility) -> @struct_field {
+ fn parse_single_struct_field(&self,
+ vis: visibility,
+ attrs: ~[attribute]) -> @struct_field {
if self.eat_obsolete_ident("let") {
self.obsolete(*self.last_span, ObsoleteLet);
}
- let a_var = self.parse_name_and_ty(vis);
+ let a_var = self.parse_name_and_ty(vis, attrs);
match *self.token {
token::SEMI => {
self.obsolete(copy *self.span, ObsoleteFieldTerminator);
}
// parse an element of a struct definition
- fn parse_struct_decl_field(&self) -> class_contents {
-
- if self.try_parse_obsolete_priv_section() {
- return members(~[]);
- }
+ fn parse_struct_decl_field(&self) -> ~[@struct_field] {
let attrs = self.parse_outer_attributes();
+ if self.try_parse_obsolete_priv_section(attrs) {
+ return ~[];
+ }
+
if self.eat_keyword(&~"priv") {
- return members(~[self.parse_single_struct_field(private)])
+ return ~[self.parse_single_struct_field(private, attrs)]
}
if self.eat_keyword(&~"pub") {
- return members(~[self.parse_single_struct_field(public)]);
+ return ~[self.parse_single_struct_field(public, attrs)];
}
if self.try_parse_obsolete_struct_ctor() {
- return members(~[]);
+ return ~[];
}
- if self.eat_keyword(&~"drop") {
- let lo = self.last_span.lo;
- let body = self.parse_block();
- return dtor_decl(body, attrs, mk_sp(lo, self.last_span.hi))
- }
- else {
- return members(~[self.parse_single_struct_field(inherited)]);
- }
+ return ~[self.parse_single_struct_field(inherited, attrs)];
}
// parse visiility: PUB, PRIV, or nothing
// parse a structure-like enum variant definition
// this should probably be renamed or refactored...
fn parse_struct_def(&self) -> @struct_def {
- let mut the_dtor: Option<(blk, ~[attribute], codemap::span)> = None;
let mut fields: ~[@struct_field] = ~[];
while *self.token != token::RBRACE {
- match self.parse_struct_decl_field() {
- dtor_decl(ref blk, ref attrs, s) => {
- match the_dtor {
- Some((_, _, s_first)) => {
- self.span_note(s, ~"duplicate destructor \
- declaration");
- self.span_fatal(copy s_first,
- ~"first destructor \
- declared here");
- }
- None => {
- the_dtor = Some((copy *blk, copy *attrs, s));
- }
- }
- }
- members(mms) => {
- for mms.each |struct_field| {
- fields.push(*struct_field);
- }
- }
+ for self.parse_struct_decl_field().each |struct_field| {
+ fields.push(*struct_field);
}
}
self.bump();
- let actual_dtor = do the_dtor.map |dtor| {
- let (d_body, d_attrs, d_s) = copy *dtor;
- codemap::spanned { node: ast::struct_dtor_ { id: self.get_id(),
- attrs: d_attrs,
- self_id: self.get_id(),
- body: d_body },
- span: d_s }
- };
return @ast::struct_def {
fields: fields,
- dtor: actual_dtor,
ctor_id: None
};
}
pub mod special_idents {
use ast::ident;
- pub static underscore : ident = ident { repr: 0u, ctxt: 0};
- pub static anon : ident = ident { repr: 1u, ctxt: 0};
- pub static dtor : ident = ident { repr: 2u, ctxt: 0}; // 'drop', but that's
- // reserved
- pub static invalid : ident = ident { repr: 3u, ctxt: 0}; // ''
- pub static unary : ident = ident { repr: 4u, ctxt: 0};
- pub static not_fn : ident = ident { repr: 5u, ctxt: 0};
- pub static idx_fn : ident = ident { repr: 6u, ctxt: 0};
- pub static unary_minus_fn : ident = ident { repr: 7u, ctxt: 0};
- pub static clownshoes_extensions : ident = ident { repr: 8u, ctxt: 0};
-
- pub static self_ : ident = ident { repr: 9u, ctxt: 0}; // 'self'
+ pub static underscore : ident = ident { repr: 0, ctxt: 0};
+ pub static anon : ident = ident { repr: 1, ctxt: 0};
+ pub static invalid : ident = ident { repr: 2, ctxt: 0}; // ''
+ pub static unary : ident = ident { repr: 3, ctxt: 0};
+ pub static not_fn : ident = ident { repr: 4, ctxt: 0};
+ pub static idx_fn : ident = ident { repr: 5, ctxt: 0};
+ pub static unary_minus_fn : ident = ident { repr: 6, ctxt: 0};
+ pub static clownshoes_extensions : ident = ident { repr: 7, ctxt: 0};
+
+ pub static self_ : ident = ident { repr: 8, ctxt: 0}; // 'self'
/* for matcher NTs */
- pub static item : ident = ident { repr: 10u, ctxt: 0};
- pub static block : ident = ident { repr: 11u, ctxt: 0};
- pub static stmt : ident = ident { repr: 12u, ctxt: 0};
- pub static pat : ident = ident { repr: 13u, ctxt: 0};
- pub static expr : ident = ident { repr: 14u, ctxt: 0};
- pub static ty : ident = ident { repr: 15u, ctxt: 0};
- pub static ident : ident = ident { repr: 16u, ctxt: 0};
- pub static path : ident = ident { repr: 17u, ctxt: 0};
- pub static tt : ident = ident { repr: 18u, ctxt: 0};
- pub static matchers : ident = ident { repr: 19u, ctxt: 0};
-
- pub static str : ident = ident { repr: 20u, ctxt: 0}; // for the type
+ pub static item : ident = ident { repr: 9, ctxt: 0};
+ pub static block : ident = ident { repr: 10, ctxt: 0};
+ pub static stmt : ident = ident { repr: 11, ctxt: 0};
+ pub static pat : ident = ident { repr: 12, ctxt: 0};
+ pub static expr : ident = ident { repr: 13, ctxt: 0};
+ pub static ty : ident = ident { repr: 14, ctxt: 0};
+ pub static ident : ident = ident { repr: 15, ctxt: 0};
+ pub static path : ident = ident { repr: 16, ctxt: 0};
+ pub static tt : ident = ident { repr: 17, ctxt: 0};
+ pub static matchers : ident = ident { repr: 18, ctxt: 0};
+
+ pub static str : ident = ident { repr: 19, ctxt: 0}; // for the type
/* outside of libsyntax */
- pub static ty_visitor : ident = ident { repr: 21u, ctxt: 0};
- pub static arg : ident = ident { repr: 22u, ctxt: 0};
- pub static descrim : ident = ident { repr: 23u, ctxt: 0};
- pub static clownshoe_abi : ident = ident { repr: 24u, ctxt: 0};
- pub static clownshoe_stack_shim : ident = ident { repr: 25u, ctxt: 0};
- pub static tydesc : ident = ident { repr: 26u, ctxt: 0};
- pub static literally_dtor : ident = ident { repr: 27u, ctxt: 0};
- pub static main : ident = ident { repr: 28u, ctxt: 0};
- pub static opaque : ident = ident { repr: 29u, ctxt: 0};
- pub static blk : ident = ident { repr: 30u, ctxt: 0};
- pub static static : ident = ident { repr: 31u, ctxt: 0};
- pub static intrinsic : ident = ident { repr: 32u, ctxt: 0};
- pub static clownshoes_foreign_mod: ident = ident { repr: 33u, ctxt: 0};
- pub static unnamed_field: ident = ident { repr: 34u, ctxt: 0};
- pub static c_abi: ident = ident { repr: 35u, ctxt: 0};
- pub static type_self: ident = ident { repr: 36u, ctxt: 0}; // `Self`
+ pub static ty_visitor : ident = ident { repr: 20, ctxt: 0};
+ pub static arg : ident = ident { repr: 21, ctxt: 0};
+ pub static descrim : ident = ident { repr: 22, ctxt: 0};
+ pub static clownshoe_abi : ident = ident { repr: 23, ctxt: 0};
+ pub static clownshoe_stack_shim : ident = ident { repr: 24, ctxt: 0};
+ pub static tydesc : ident = ident { repr: 25, ctxt: 0};
+ pub static main : ident = ident { repr: 26, ctxt: 0};
+ pub static opaque : ident = ident { repr: 27, ctxt: 0};
+ pub static blk : ident = ident { repr: 28, ctxt: 0};
+ pub static static : ident = ident { repr: 29, ctxt: 0};
+ pub static intrinsic : ident = ident { repr: 30, ctxt: 0};
+ pub static clownshoes_foreign_mod: ident = ident { repr: 31, ctxt: 0};
+ pub static unnamed_field: ident = ident { repr: 32, ctxt: 0};
+ pub static c_abi: ident = ident { repr: 33, ctxt: 0};
+ pub static type_self: ident = ident { repr: 34, ctxt: 0}; // `Self`
}
pub struct StringRef<'self>(&'self str);
pub fn token_to_binop(tok: Token) -> Option<ast::binop> {
match tok {
BINOP(STAR) => Some(ast::mul),
- BINOP(SLASH) => Some(ast::quot),
+ BINOP(SLASH) => Some(ast::div),
BINOP(PERCENT) => Some(ast::rem),
BINOP(PLUS) => Some(ast::add),
BINOP(MINUS) => Some(ast::subtract),
let init_vec = ~[
@~"_", // 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
- @~"<opaque>", // 29
- @~"blk", // 30
- @~"static", // 31
- @~"intrinsic", // 32
- @~"__foreign_mod__", // 33
- @~"__field__", // 34
- @~"C", // 35
- @~"Self", // 36
+ @~"", // 2
+ @~"unary", // 3
+ @~"!", // 4
+ @~"[]", // 5
+ @~"unary-", // 6
+ @~"__extensions__", // 7
+ @~"self", // 8
+ @~"item", // 9
+ @~"block", // 10
+ @~"stmt", // 11
+ @~"pat", // 12
+ @~"expr", // 13
+ @~"ty", // 14
+ @~"ident", // 15
+ @~"path", // 16
+ @~"tt", // 17
+ @~"matchers", // 18
+ @~"str", // 19
+ @~"TyVisitor", // 20
+ @~"arg", // 21
+ @~"descrim", // 22
+ @~"__rust_abi", // 23
+ @~"__rust_stack_shim", // 24
+ @~"TyDesc", // 25
+ @~"main", // 26
+ @~"<opaque>", // 27
+ @~"blk", // 28
+ @~"static", // 29
+ @~"intrinsic", // 30
+ @~"__foreign_mod__", // 31
+ @~"__field__", // 32
+ @~"C", // 33
+ @~"Self", // 34
];
let rv = @ident_interner {
nbsp(s);
bopen(s);
hardbreak_if_not_bol(s);
- for struct_def.dtor.each |dtor| {
- hardbreak_if_not_bol(s);
- maybe_print_comment(s, dtor.span.lo);
- print_outer_attributes(s, dtor.node.attrs);
- head(s, ~"drop");
- print_block(s, &dtor.node.body);
- }
for struct_def.fields.each |field| {
match field.node.kind {
ast::named_field(ident, mutability, visibility) => {
hardbreak_if_not_bol(s);
maybe_print_comment(s, field.span.lo);
+ print_outer_attributes(s, field.node.attrs);
print_visibility(s, visibility);
if mutability == ast::struct_mutable {
word_nbsp(s, ~"mut");
use abi::AbiSet;
use ast::*;
use ast;
-use ast_util;
use codemap::span;
use parse;
use opt_vec;
// |x, y| ...
fk_fn_block,
-
- fk_dtor( // class destructor
- &'self Generics,
- &'self [attribute],
- node_id /* self id */,
- def_id /* parent class id */
- )
}
pub fn name_of_fn(fk: &fn_kind) -> ident {
name
}
fk_anon(*) | fk_fn_block(*) => parse::token::special_idents::anon,
- fk_dtor(*) => parse::token::special_idents::dtor
}
}
pub fn generics_of_fn(fk: &fn_kind) -> Generics {
match *fk {
fk_item_fn(_, generics, _, _) |
- fk_method(_, generics, _) |
- fk_dtor(generics, _, _, _) => {
+ fk_method(_, generics, _) => {
copy *generics
}
fk_anon(*) | fk_fn_block(*) => {
);
}
-pub fn visit_struct_dtor_helper<E>(dtor: struct_dtor, generics: &Generics,
- parent_id: def_id, e: E, v: vt<E>) {
- (v.visit_fn)(
- &fk_dtor(
- generics,
- dtor.node.attrs,
- dtor.node.self_id,
- parent_id
- ),
- &ast_util::dtor_dec(),
- &dtor.node.body,
- dtor.span,
- dtor.node.id,
- e,
- v
- )
-
-}
-
pub fn visit_fn<E: Copy>(fk: &fn_kind, decl: &fn_decl, body: &blk, _sp: span,
_id: node_id, e: E, v: vt<E>) {
visit_fn_decl(decl, e, v);
pub fn visit_struct_def<E: Copy>(
sd: @struct_def,
_nm: ast::ident,
- generics: &Generics,
- id: node_id,
+ _generics: &Generics,
+ _id: node_id,
e: E,
v: vt<E>
) {
for sd.fields.each |f| {
(v.visit_struct_field)(*f, e, v);
}
- for sd.dtor.each |dtor| {
- visit_struct_dtor_helper(
- *dtor,
- generics,
- ast_util::local_def(id),
- e,
- v
- )
- }
}
pub fn visit_struct_field<E: Copy>(sf: @struct_field, e: E, v: vt<E>) {
-Subproject commit 56dd407f4f97a01b8df6554c569170d2fc276fcb
+Subproject commit 2e9f0d21fe321849a4759a01fc28eae82ef196d6
+++ /dev/null
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#[link(name = "issue2196a", vers = "0.1")];
-#[crate_type = "lib"];
-
+++ /dev/null
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#[link(name = "issue2196b", vers = "0.1")];
-#[crate_type = "lib"];
-
-use a(name = "issue2196a");
-
-type d = str;
-impl d for d { }
-
+++ /dev/null
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#[link(name = "issue2196c", vers = "0.1")];
-#[crate_type = "lib"];
-
-use b(name = "issue2196b");
-#[path = "issue-2196-d.rs"]
-mod d;
+++ /dev/null
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use b::d;
-
-type t = uint;
-
// option. This file may not be copied, modified, or distributed
// except according to those terms.
+#[link (name = "issue2378a")];
+#[crate_type = "lib"];
+
enum maybe<T> { just(T), nothing }
-impl copy> for maybe<T> for methods<T {
- fn ~[](idx: uint) -> T {
+impl <T:Copy> Index<uint,T> for maybe<T> {
+ fn index(&self, idx: &uint) -> T {
match self {
- just(t) { t }
- nothing { fail!(); }
+ &just(ref t) => copy *t,
+ ¬hing => { fail!(); }
}
}
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-use issue2378a;
+#[link (name = "issue2378b")];
+#[crate_type = "lib"];
+
+extern mod issue2378a;
use issue2378a::maybe;
-use issue2378a::methods;
-type two_maybes<T> = {a: maybe<T>, b: maybe<T>};
+struct two_maybes<T> {a: maybe<T>, b: maybe<T>}
-impl copy> for two_maybes<T> for methods<T {
- fn ~[](idx: uint) -> (T, T) {
- (self.a[idx], self.b[idx])
+impl <T:Copy> Index<uint,(T,T)> for two_maybes<T> {
+ fn index(&self, idx: &uint) -> (T, T) {
+ (self.a[*idx], self.b[*idx])
}
}
fn main() {
match () {
- [()] => { } //~ ERROR mismatched type: expected `()` but found vector
+ [()] => { } //~ ERROR mismatched types: expected `()` but found a vector pattern
}
}
fn main() {
match ~"foo" {
- ['f', 'o', .._] => { } //~ ERROR mismatched type: expected `~str` but found vector
+ ['f', 'o', .._] => { } //~ ERROR mismatched types: expected `~str` but found a vector pattern
_ => { }
}
}
enum test {
- quot_zero = 1/0, //~ERROR expected constant: attempted quotient with a divisor of zero
+ div_zero = 1/0, //~ERROR expected constant: attempted to divide by zero
rem_zero = 1%0 //~ERROR expected constant: attempted remainder with a divisor of zero
}
--- /dev/null
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+enum A { B, C }
+
+fn main() {
+ match (true, false) {
+ B => (), //~ ERROR expected `(bool,bool)` but found an enum or structure pattern
+ _ => ()
+ }
+
+ match (true, false) {
+ (true, false, false) => () //~ ERROR mismatched types: expected `(bool,bool)` but found `(bool,bool,bool)` (expected a tuple with 2 elements but found one with 3 elements)
+ }
+
+ match (true, false) {
+ @(true, false) => () //~ ERROR mismatched types: expected `(bool,bool)` but found an @-box pattern
+ }
+
+ match (true, false) {
+ ~(true, false) => () //~ ERROR mismatched types: expected `(bool,bool)` but found a ~-box pattern
+ }
+
+ match (true, false) {
+ &(true, false) => () //~ ERROR mismatched types: expected `(bool,bool)` but found an &-pointer pattern
+ }
+
+
+ let v = [('a', 'b') //~ ERROR expected function but found `(char,char)`
+ ('c', 'd'),
+ ('e', 'f')];
+
+ for v.each |&(x,y)| {} // should be OK
+
+ // Make sure none of the errors above were fatal
+ let x: char = true; //~ ERROR expected `char` but found `bool`
+}
--- /dev/null
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+
+
+// error-pattern:unresolved enum variant
+
+fn main() {
+ let z = match 3 {
+ x() => x
+ };
+ assert_eq!(z,3);
+}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-// error-pattern:attempted quotient with a divisor of zero
+// error-pattern:attempted to divide by zero
fn main() {
let y = 0;
let z = 1 / y;
--- /dev/null
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// xfail-fast
+// aux-build:newtype_struct_xc.rs
+
+extern mod newtype_struct_xc;
+
+fn main() {
+ let x = newtype_struct_xc::Au(21);
+ match x {
+ newtype_struct_xc::Au(n) => assert_eq!(n, 21)
+ }
+}
--- /dev/null
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+/*!
+ * This is a regression test for a bug in LLVM, fixed in upstream r179587,
+ * where the switch instructions generated for destructuring enums
+ * represented with nullable pointers could be misoptimized in some cases.
+ */
+
+enum List<X> { Nil, Cons(X, @List<X>) }
+pub fn main() {
+ match Cons(10, @Nil) {
+ Cons(10, _) => {}
+ Nil => {}
+ _ => fail!()
+ }
+}
+++ /dev/null
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// exec-env:RUST_CC_ZEAL=1
-// xfail-test
-
-pub fn main() {
- error!("%?", os::getenv(~"RUST_CC_ZEAL"));
- let _x = @{a: @10, b: ~true};
-}
+++ /dev/null
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-pub fn main() {
- let x = 1;
- let y: @fn() -> int = || x;
- let z = y();
-}
-
+++ /dev/null
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// exec-env:RUST_CC_ZEAL=1
-
-enum maybe_pointy {
- none,
- p(@mut Pointy)
-}
-
-struct Pointy {
- a : maybe_pointy,
- f : @fn()->(),
-}
-
-fn empty_pointy() -> @mut Pointy {
- return @mut Pointy{
- a : none,
- f : || {},
- }
-}
-
-pub fn main() {
- let v = ~[empty_pointy(), empty_pointy()];
- v[0].a = p(v[0]);
-}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-// xfail-test FIXME #2263
+// does the second one subsume the first?
+// xfail-test
// xfail-fast
+
+// notes on this test case:
+// On Thu, Apr 18, 2013 at 6:30 PM, John Clements <clements@brinckerhoff.org> wrote:
+// the "issue-2185.rs" test was xfailed with a ref to #2263. Issue #2263 is now fixed, so I tried it again, and after adding some &self parameters, I got this error:
+//
+// Running /usr/local/bin/rustc:
+// issue-2185.rs:24:0: 26:1 error: conflicting implementations for a trait
+// issue-2185.rs:24 impl iterable<uint> for @fn(&fn(uint)) {
+// issue-2185.rs:25 fn iter(&self, blk: &fn(v: uint)) { self( |i| blk(i) ) }
+// issue-2185.rs:26 }
+// issue-2185.rs:20:0: 22:1 note: note conflicting implementation here
+// issue-2185.rs:20 impl<A> iterable<A> for @fn(&fn(A)) {
+// issue-2185.rs:21 fn iter(&self, blk: &fn(A)) { self(blk); }
+// issue-2185.rs:22 }
+//
+// … so it looks like it's just not possible to implement both the generic iterable<uint> and iterable<A> for the type iterable<uint>. Is it okay if I just remove this test?
+//
+// but Niko responded:
+// think it's fine to remove this test, just because it's old and cruft and not hard to reproduce. *However* it should eventually be possible to implement the same interface for the same type multiple times with different type parameters, it's just that our current trait implementation has accidental limitations.
+
+// so I'm leaving it in.
+// actually, it looks like this is related to bug #3429. I'll rename this bug.
+
// This test had to do with an outdated version of the iterable trait.
// However, the condition it was testing seemed complex enough to
// warrant still having a test, so I inlined the old definitions.
trait iterable<A> {
- fn iter(blk: &fn(A));
+ fn iter(&self, blk: &fn(A));
}
impl<A> iterable<A> for @fn(&fn(A)) {
- fn iter(blk: &fn(A)) { self(blk); }
+ fn iter(&self, blk: &fn(A)) { self(blk); }
}
impl iterable<uint> for @fn(&fn(uint)) {
- fn iter(blk: &fn(&&v: uint)) { self( |i| blk(i) ) }
+ fn iter(&self, blk: &fn(v: uint)) { self( |i| blk(i) ) }
}
fn filter<A,IA:iterable<A>>(self: IA, prd: @fn(A) -> bool, blk: &fn(A)) {
+++ /dev/null
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// xfail-test
-// aux-build:issue-2196-a.rs
-// aux-build:issue-2196-b.rs
-// aux-build:issue-2196-c.rc
-
-use c(name = "issue2196c");
-use c::t;
-
-pub fn main() { }
+++ /dev/null
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// xfail-test
-enum pat { pat_ident(Option<uint>) }
-
-fn f(pat: pat) -> bool { true }
-
-fn num_bindings(pat: pat) -> uint {
- match pat {
- pat_ident(_) if f(pat) { 0 }
- pat_ident(None) { 1 }
- pat_ident(Some(sub)) { sub }
- }
-}
-
-pub fn main() {}
--- /dev/null
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub fn main() {
+ let x = 1;
+ let y: @fn() -> int = || x;
+ let z = y();
+}
+
+++ /dev/null
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// xfail-test
-type IMap<K:Copy,V:Copy> = ~[(K, V)];
-
-trait ImmutableMap<K:Copy,V:Copy>
-{
- fn contains_key(key: K) -> bool;
-}
-
-impl<K:Copy,V:Copy> IMap<K, V> : ImmutableMap<K, V>
-{
- fn contains_key(key: K) -> bool {
- vec::find(self, |e| {e.first() == key}).is_some()
- }
-}
-
-pub fn main() {}
}
}
-impl Point: Movable<int, int>;
+impl Movable<int, int> for Point;
pub fn main() {
let p = Point{ x: 1, y: 2};
--- /dev/null
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub fn main() {
+ match Left(@17) {
+ Right(()) => {}
+ _ => {}
+ }
+}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-// xfail-test -- #2378 unfixed
// aux-build:issue2378a.rs
// aux-build:issue2378b.rs
+// xfail-fast - check-fast doesn't understand aux-build
-use issue2378a;
-use issue2378b;
+extern mod issue2378a;
+extern mod issue2378b;
-use issue2378a::{just, methods};
-use issue2378b::{methods};
+use issue2378a::{just};
+use issue2378b::{two_maybes};
pub fn main() {
- let x = {a: just(3), b: just(5)};
+ let x = two_maybes{a: just(3), b: just(5)};
assert!(x[0u] == (3, 5));
}
// xfail-test
// -*- rust -*-
-extern mod std;
+extern mod core;
+use core::gc;
+use core::gc::rustrt;
-type cell = {c: @list};
+struct cell {c: @list}
enum list { link(@mut cell), nil, }
pub fn main() {
- let first: @cell = @mut {c: @nil()};
- let second: @cell = @mut {c: @link(first)};
+ let first: @cell = @mut cell{c: @nil()};
+ let second: @cell = @mut cell{c: @link(first)};
first._0 = @link(second);
- sys.rustrt.gc();
- let third: @cell = @mut {c: @nil()};
+ rustrt::gc();
+ let third: @cell = @mut cell{c: @nil()};
}
fn starve_main(alive: chan<int>) {
debug!("signalling main");
- alive <| 1;
+ alive.recv(1);
debug!("starving main");
let i: int = 0;
loop { i += 1; }
pub fn main() {
let alive: port<int> = port();
debug!("main started");
- let s: task = spawn starve_main(chan(alive));
+ let s: task = do task::spawn {
+ starve_main(chan(alive));
+ };
let i: int;
debug!("main waiting for alive signal");
- alive |> i;
+ alive.send(i);
debug!("main got alive signal");
while i < 50 { debug!("main iterated"); i += 1; }
debug!("main completed");
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-// xfail-test
-
// Issue #2263.
// Here, `f` is a function that takes a pointer `x` and a function
// `g`, where `g` requires its argument `y` to be in the same region
// that `x` is in.
-fn has_same_region(f: &fn(x: &a.int, g: &fn(y: &a.int))) {
+fn has_same_region(f: &fn<'a>(x: &'a int, g: &fn(y: &'a int))) {
// `f` should be the type that `wants_same_region` wants, but
// right now the compiler complains that it isn't.
wants_same_region(f);
}
-fn wants_same_region(_f: &fn(x: &b.int, g: &fn(y: &b.int))) {
+fn wants_same_region(_f: &fn<'b>(x: &'b int, g: &fn(y: &'b int))) {
}
pub fn main() {
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-// xfail-test
-
-tag a_tag<A> {
- a_tag(A);
+enum a_tag<A> {
+ a_tag(A)
}
-type t_rec = {
+struct t_rec {
c8: u8,
t: a_tag<u64>
-};
+}
fn mk_rec() -> t_rec {
- return { c8:0u8, t:a_tag(0u64) };
+ return t_rec { c8:0u8, t:a_tag(0u64) };
}
-fn is_8_byte_aligned(&&u: a_tag<u64>) -> bool {
+fn is_8_byte_aligned(u: &a_tag<u64>) -> bool {
let p = ptr::to_unsafe_ptr(u) as uint;
return (p & 7u) == 0u;
}
pub fn main() {
let x = mk_rec();
- assert!(is_8_byte_aligned(x.t));
+ assert!(is_8_byte_aligned(&x.t));
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-// xfail-test
-
-tag a_tag<A,B> {
- varA(A);
- varB(B);
+enum a_tag<A,B> {
+ varA(A),
+ varB(B)
}
-type t_rec<A,B> = {
+struct t_rec<A,B> {
chA: u8,
tA: a_tag<A,B>,
chB: u8,
tB: a_tag<A,B>
-};
+}
-fn mk_rec<A:copy,B:copy>(a: A, b: B) -> t_rec<A,B> {
- return { chA:0u8, tA:varA(a), chB:1u8, tB:varB(b) };
+fn mk_rec<A:Copy,B:Copy>(a: A, b: B) -> t_rec<A,B> {
+ return t_rec{ chA:0u8, tA:varA(a), chB:1u8, tB:varB(b) };
}
-fn is_aligned<A>(amnt: uint, &&u: A) -> bool {
+fn is_aligned<A>(amnt: uint, u: &A) -> bool {
let p = ptr::to_unsafe_ptr(u) as uint;
return (p & (amnt-1u)) == 0u;
}
-fn variant_data_is_aligned<A,B>(amnt: uint, &&u: a_tag<A,B>) -> bool {
+fn variant_data_is_aligned<A,B>(amnt: uint, u: &a_tag<A,B>) -> bool {
match u {
- varA(a) { is_aligned(amnt, a) }
- varB(b) { is_aligned(amnt, b) }
+ &varA(ref a) => is_aligned(amnt, a),
+ &varB(ref b) => is_aligned(amnt, b)
}
}
pub fn main() {
let x = mk_rec(22u64, 23u64);
- assert!(is_aligned(8u, x.tA));
- assert!(variant_data_is_aligned(8u, x.tA));
- assert!(is_aligned(8u, x.tB));
- assert!(variant_data_is_aligned(8u, x.tB));
+ assert!(is_aligned(8u, &x.tA));
+ assert!(variant_data_is_aligned(8u, &x.tA));
+ assert!(is_aligned(8u, &x.tB));
+ assert!(variant_data_is_aligned(8u, &x.tB));
let x = mk_rec(22u64, 23u32);
- assert!(is_aligned(8u, x.tA));
- assert!(variant_data_is_aligned(8u, x.tA));
- assert!(is_aligned(8u, x.tB));
- assert!(variant_data_is_aligned(4u, x.tB));
+ assert!(is_aligned(8u, &x.tA));
+ assert!(variant_data_is_aligned(8u, &x.tA));
+ assert!(is_aligned(8u, &x.tB));
+ assert!(variant_data_is_aligned(4u, &x.tB));
let x = mk_rec(22u32, 23u64);
- assert!(is_aligned(8u, x.tA));
- assert!(variant_data_is_aligned(4u, x.tA));
- assert!(is_aligned(8u, x.tB));
- assert!(variant_data_is_aligned(8u, x.tB));
+ assert!(is_aligned(8u, &x.tA));
+ assert!(variant_data_is_aligned(4u, &x.tA));
+ assert!(is_aligned(8u, &x.tB));
+ assert!(variant_data_is_aligned(8u, &x.tB));
let x = mk_rec(22u32, 23u32);
- assert!(is_aligned(4u, x.tA));
- assert!(variant_data_is_aligned(4u, x.tA));
- assert!(is_aligned(4u, x.tB));
- assert!(variant_data_is_aligned(4u, x.tB));
+ assert!(is_aligned(4u, &x.tA));
+ assert!(variant_data_is_aligned(4u, &x.tA));
+ assert!(is_aligned(4u, &x.tB));
+ assert!(variant_data_is_aligned(4u, &x.tB));
let x = mk_rec(22f64, 23f64);
- assert!(is_aligned(8u, x.tA));
- assert!(variant_data_is_aligned(8u, x.tA));
- assert!(is_aligned(8u, x.tB));
- assert!(variant_data_is_aligned(8u, x.tB));
+ assert!(is_aligned(8u, &x.tA));
+ assert!(variant_data_is_aligned(8u, &x.tA));
+ assert!(is_aligned(8u, &x.tB));
+ assert!(variant_data_is_aligned(8u, &x.tB));
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-// xfail-test
-//
-// See issue #1535
-
-tag a_tag {
- a_tag(u64);
+enum a_tag {
+ a_tag(u64)
}
-type t_rec = {
+struct t_rec {
c8: u8,
t: a_tag
-};
+}
pub fn main() {
- let x = {c8: 22u8, t: a_tag(44u64)};
+ let x = t_rec {c8: 22u8, t: a_tag(44u64)};
let y = fmt!("%?", x);
debug!("y = %s", y);
- assert!(y == "(22, a_tag(44))");
+ assert_eq!(y, ~"{c8: 22, t: a_tag(44)}");
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-// xfail-test
-tag a_tag {
- a_tag(u64);
+enum a_tag {
+ a_tag(u64)
}
-type t_rec = {
+struct t_rec {
c8: u8,
t: a_tag
-};
+}
fn mk_rec() -> t_rec {
- return { c8:0u8, t:a_tag(0u64) };
+ return t_rec { c8:0u8, t:a_tag(0u64) };
}
-fn is_8_byte_aligned(&&u: a_tag) -> bool {
+fn is_8_byte_aligned(u: &a_tag) -> bool {
let p = ptr::to_unsafe_ptr(u) as u64;
return (p & 7u64) == 0u64;
}
pub fn main() {
let x = mk_rec();
- assert!(is_8_byte_aligned(x.t));
+ assert!(is_8_byte_aligned(&x.t));
}
+++ /dev/null
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// xfail-win32
-// error-pattern:ran out of stack
-
-// Test that the task fails after hitting the recursion limit, but
-// that it doesn't bring down the whole proc
-
-pub fn main() {
- do task::spawn_unlinked {
- fn f() { f() };
- f();
- };
-}
+++ /dev/null
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// xfail-test
-
-fn is_even(i: int) -> bool { (i%2) == 0 }
-fn even(i: int) : is_even(i) -> int { i }
-
-fn test() {
- let v = 4;
- loop {
- check is_even(v);
- break;
- }
- even(v);
-}
-
-pub fn main() {
- test();
-}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-// xfail-test
-use sys::rustrt::size_of;
-extern mod std;
+extern mod core;
+use core::sys::size_of;
+
+struct t {a: u8, b: i8}
+struct u {a: u8, b: i8, c: u8}
+struct v {a: u8, b: i8, c: v2, d: u32}
+struct v2 {u: char, v: u8}
+struct w {a: int, b: ()}
+struct x {a: int, b: (), c: ()}
+struct y {x: int}
pub fn main() {
assert!((size_of::<u8>() == 1 as uint));
assert!((size_of::<char>() == 4 as uint));
assert!((size_of::<i8>() == 1 as uint));
assert!((size_of::<i32>() == 4 as uint));
- assert!((size_of::<{a: u8, b: i8}>() == 2 as uint));
- assert!((size_of::<{a: u8, b: i8, c: u8}>() == 3 as uint));
+ assert!((size_of::<t>() == 2 as uint));
+ assert!((size_of::<u>() == 3 as uint));
// Alignment causes padding before the char and the u32.
- assert!(size_of::<{a: u8, b: i8, c: {u: char, v: u8}, d: u32}>() ==
+ assert!(size_of::<v>() ==
16 as uint);
assert!((size_of::<int>() == size_of::<uint>()));
- assert!((size_of::<{a: int, b: ()}>() == size_of::<int>()));
- assert!((size_of::<{a: int, b: (), c: ()}>() == size_of::<int>()));
- assert!((size_of::<int>() == size_of::<{x: int}>()));
+ assert!((size_of::<w>() == size_of::<int>()));
+ assert!((size_of::<x>() == size_of::<int>()));
+ assert!((size_of::<int>() == size_of::<y>()));
}