diff --git a/src/compiletest/header.rs b/src/compiletest/header.rs index 6ef2a52086e..aa96f3e2727 100644 --- a/src/compiletest/header.rs +++ b/src/compiletest/header.rs @@ -36,6 +36,10 @@ pub struct TestProps { pub no_prefer_dynamic: bool, // Don't run --pretty expanded when running pretty printing tests pub no_pretty_expanded: bool, + // Which pretty mode are we testing with, default to 'normal' + pub pretty_mode: String, + // Only compare pretty output and don't try compiling + pub pretty_compare_only: bool, } // Load any test directives embedded in the file @@ -51,6 +55,8 @@ pub fn load_props(testfile: &Path) -> TestProps { let mut check_stdout = false; let mut no_prefer_dynamic = false; let mut no_pretty_expanded = false; + let mut pretty_mode = None; + let mut pretty_compare_only = false; iter_header(testfile, |ln| { match parse_error_pattern(ln) { Some(ep) => error_patterns.push(ep), @@ -85,6 +91,14 @@ pub fn load_props(testfile: &Path) -> TestProps { no_pretty_expanded = parse_no_pretty_expanded(ln); } + if pretty_mode.is_none() { + pretty_mode = parse_pretty_mode(ln); + } + + if !pretty_compare_only { + pretty_compare_only = parse_pretty_compare_only(ln); + } + match parse_aux_build(ln) { Some(ab) => { aux_builds.push(ab); } None => {} @@ -115,6 +129,8 @@ pub fn load_props(testfile: &Path) -> TestProps { check_stdout: check_stdout, no_prefer_dynamic: no_prefer_dynamic, no_pretty_expanded: no_pretty_expanded, + pretty_mode: pretty_mode.unwrap_or("normal".to_string()), + pretty_compare_only: pretty_compare_only } } @@ -205,6 +221,14 @@ fn parse_no_pretty_expanded(line: &str) -> bool { parse_name_directive(line, "no-pretty-expanded") } +fn parse_pretty_mode(line: &str) -> Option { + parse_name_value_directive(line, "pretty-mode") +} + +fn parse_pretty_compare_only(line: &str) -> bool { + parse_name_directive(line, "pretty-compare-only") +} + fn parse_exec_env(line: &str) -> Option<(String, String)> { parse_name_value_directive(line, "exec-env").map(|nv| { // nv is either FOO or FOO=BAR diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs index 6720b9a530f..b8a55fb234d 100644 --- a/src/compiletest/runtest.rs +++ b/src/compiletest/runtest.rs @@ -168,7 +168,7 @@ fn run_pretty_test(config: &Config, props: &TestProps, testfile: &Path) { props, testfile, srcs[round].to_string(), - "normal"); + props.pretty_mode.as_slice()); if !proc_res.status.success() { fatal_proc_rec(format!("pretty-printing failed in round {}", @@ -200,6 +200,9 @@ fn run_pretty_test(config: &Config, props: &TestProps, testfile: &Path) { compare_source(expected.as_slice(), actual.as_slice()); + // If we're only making sure that the output matches then just stop here + if props.pretty_compare_only { return; } + // Finally, let's make sure it actually appears to remain valid code let proc_res = typecheck_source(config, props, testfile, actual); diff --git a/src/doc/index.md b/src/doc/index.md index c54f4e00905..c96f10a0be8 100644 --- a/src/doc/index.md +++ b/src/doc/index.md @@ -84,6 +84,7 @@ as that for which this documentation was generated.* * [Reddit](http://reddit.com/r/rust) * [Stack Overflow](http://stackoverflow.com/questions/tagged/rust) +* [Developer Forum](http://discuss.rust-lang.org/) * The Rust IRC channels on [irc.mozilla.org](http://irc.mozilla.org/): * [`#rust`](http://chat.mibbit.com/?server=irc.mozilla.org&channel=%23rust) - general discussion * [`#rust-gamedev`](http://chat.mibbit.com/?server=irc.mozilla.org&channel=%23rust-gamedev) - game development diff --git a/src/doc/intro.md b/src/doc/intro.md index 32c5f346de1..128d5c9d320 100644 --- a/src/doc/intro.md +++ b/src/doc/intro.md @@ -36,8 +36,8 @@ int add_one(void) } ``` -**Note: obviously this is very simple and non-idiomatic C++. -You wouldn't write it in practice; it is for illustrative purposes.** +**Note: The above C++ code is deliberately simple and non-idiomatic for the purpose +of demonstration. It is not representative of production-quality C++ code.** This function allocates an integer on the stack, and stores it in a variable, `i`. diff --git a/src/doc/rust.md b/src/doc/rust.md index b015cb0fbb8..79222112b92 100644 --- a/src/doc/rust.md +++ b/src/doc/rust.md @@ -1950,6 +1950,12 @@ interpreted: - `unsafe_no_drop_flag` - on structs, remove the flag that prevents destructors from being run twice. Destructors might be run multiple times on the same object with this attribute. +- `phase` - on `extern crate` statements, allows specifying which "phase" of + compilation the crate should be loaded for. Currently, there are two + choices: `link` and `plugin`. `link` is the default. `plugin` will load the + crate at compile-time and use any syntax extensions or lints that the crate + defines. They can both be specified, `#[phase(link, plugin)]` to use a crate + both at runtime and compiletime. ### Conditional compilation @@ -2395,17 +2401,17 @@ The currently implemented features of the reference compiler are: closure as `once` is unlikely to be supported going forward. So they are hidden behind this feature until they are to be removed. -* `managed_boxes` - Usage of `@` pointers is gated due to many +* `asm` - The `asm!` macro provides a means for inline assembly. This is often + useful, but the exact syntax for this feature along with its semantics + are likely to change, so this macro usage must be opted into. + +* `managed_boxes` - Usage of `@` is gated due to many planned changes to this feature. In the past, this has meant "a GC pointer", but the current implementation uses reference counting and will likely change drastically over time. Additionally, the `@` syntax will no longer be used to create GC boxes. -* `asm` - The `asm!` macro provides a means for inline assembly. This is often - useful, but the exact syntax for this feature along with its semantics - are likely to change, so this macro usage must be opted into. - * `non_ascii_idents` - The compiler supports the use of non-ascii identifiers, but the implementation is a little rough around the edges, so this can be seen as an experimental feature for @@ -2427,6 +2433,66 @@ The currently implemented features of the reference compiler are: if the system linker is not used then specifying custom flags doesn't have much meaning. +* `phase` - Usage of the `#[phase]` attribute allows loading compiler plugins + for custom lints or syntax extensions. The implementation is considered + unwholesome and in need of overhaul, and it is not clear what they + will look like moving forward. + +* `plugin_registrar` - Indicates that a crate has compiler plugins that it + wants to load. As with `phase`, the implementation is + in need of a overhaul, and it is not clear that plugins + defined using this will continue to work. + +* `log_syntax` - Allows use of the `log_syntax` macro attribute, which is a + nasty hack that will certainly be removed. + +* `trace_macros` - Allows use of the `trace_macros` macro, which is a nasty + hack that will certainly be removed. + +* `concat_idents` - Allows use of the `concat_idents` macro, which is in many + ways insufficient for concatenating identifiers, and may + be removed entirely for something more wholsome. + +* `unsafe_destructor` - Allows use of the `#[unsafe_destructor]` attribute, + which is considered wildly unsafe and will be + obsoleted by language improvements. + +* `intrinsics` - Allows use of the "rust-intrinsics" ABI. Compiler intrinsics + are inherently unstable and no promise about them is made. + +* `lang_items` - Allows use of the `#[lang]` attribute. Like `intrinsics`, + lang items are inherently unstable and no promise about + them is made. + +* `simd` - Allows use of the `#[simd]` attribute, which is overly simple and + not the SIMD interface we want to expose in the long term. + +* `default_type_params` - Allows use of default type parameters. The future of + this feature is uncertain. + +* `quote` - Allows use of the `quote_*!` family of macros, which are + implemented very poorly and will likely change significantly + with a proper implementation. + +* `linkage` - Allows use of the `linkage` attribute, which is not portable. + +* `struct_inherit` - Allows using struct inheritance, which is barely + implemented and will probably be removed. Don't use this. + +* `overloaded_calls` - Allow implementing the `Fn*` family of traits on user + types, allowing overloading the call operator (`()`). + This feature may still undergo changes before being + stabilized. + +* `unboxed_closure_sugar` - Allows using `|Foo| -> Bar` as a trait bound + meaning one of the `Fn` traits. Still + experimental. + +* `rustc_diagnostic_macros`- A mysterious feature, used in the implementation + of rustc, not meant for mortals. + +* `unboxed_closures` - A work in progress feature with many known bugs. + If a feature is promoted to a language feature, then all existing programs will start to receive compilation warnings about #[feature] directives which enabled the new feature (because the directive is no longer necessary). However, if diff --git a/src/etc/gedit/share/gtksourceview-3.0/language-specs/rust.lang b/src/etc/gedit/share/gtksourceview-3.0/language-specs/rust.lang index 7c9780456cf..a934c426857 100644 --- a/src/etc/gedit/share/gtksourceview-3.0/language-specs/rust.lang +++ b/src/etc/gedit/share/gtksourceview-3.0/language-specs/rust.lang @@ -269,6 +269,14 @@ \\\%{common_escape} + + r(#*)" + "\%{1@start} + + + + + " " @@ -287,6 +295,8 @@ \] + + @@ -305,6 +315,7 @@ + diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs index 1ac2c9fc6be..bf477781aab 100644 --- a/src/liballoc/arc.rs +++ b/src/liballoc/arc.rs @@ -92,7 +92,7 @@ impl Arc { } #[inline] - fn inner<'a>(&'a self) -> &'a ArcInner { + fn inner(&self) -> &ArcInner { // This unsafety is ok because while this arc is alive we're guaranteed // that the inner pointer is valid. Furthermore, we know that the // `ArcInner` structure itself is `Share` because the inner data is @@ -142,7 +142,7 @@ impl Clone for Arc { #[experimental = "Deref is experimental."] impl Deref for Arc { #[inline] - fn deref<'a>(&'a self) -> &'a T { + fn deref(&self) -> &T { &self.inner().data } } @@ -155,7 +155,7 @@ impl Arc { /// data is cloned if the reference count is greater than one. #[inline] #[experimental] - pub fn make_unique<'a>(&'a mut self) -> &'a mut T { + pub fn make_unique(&mut self) -> &mut T { // Note that we hold a strong reference, which also counts as // a weak reference, so we only clone if there is an // additional reference of either kind. @@ -238,7 +238,7 @@ impl Weak { } #[inline] - fn inner<'a>(&'a self) -> &'a ArcInner { + fn inner(&self) -> &ArcInner { // See comments above for why this is "safe" unsafe { &*self._ptr } } diff --git a/src/libcollections/dlist.rs b/src/libcollections/dlist.rs index 68b6416b69b..5e3ce75eb95 100644 --- a/src/libcollections/dlist.rs +++ b/src/libcollections/dlist.rs @@ -29,6 +29,7 @@ use core::fmt; use core::iter; use core::mem; use core::ptr; +use std::hash::{Writer, Hash}; use {Collection, Mutable, Deque, MutableSeq}; @@ -707,10 +708,20 @@ impl fmt::Show for DList { } } +impl> Hash for DList { + fn hash(&self, state: &mut S) { + self.len().hash(state); + for elt in self.iter() { + elt.hash(state); + } + } +} + #[cfg(test)] mod tests { use std::prelude::*; use std::rand; + use std::hash; use test::Bencher; use test; @@ -1075,6 +1086,24 @@ mod tests { assert!(n != m); } + #[test] + fn test_hash() { + let mut x = DList::new(); + let mut y = DList::new(); + + assert!(hash::hash(&x) == hash::hash(&y)); + + x.push_back(1i); + x.push_back(2); + x.push_back(3); + + y.push_front(3i); + y.push_front(2); + y.push_front(1); + + assert!(hash::hash(&x) == hash::hash(&y)); + } + #[test] fn test_ord() { let n: DList = list_from([]); diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs index 64062dc0ccb..5b1722b2769 100644 --- a/src/libcollections/slice.rs +++ b/src/libcollections/slice.rs @@ -579,7 +579,7 @@ pub trait MutableVectorAllocating<'a, T> { * * * src - A mutable vector of `T` * * start - The index into `src` to start copying from - * * end - The index into `str` to stop copying from + * * end - The index into `src` to stop copying from */ fn move_from(self, src: Vec, start: uint, end: uint) -> uint; } diff --git a/src/libcore/num/f32.rs b/src/libcore/num/f32.rs index 82745663e0c..d4cf10b384f 100644 --- a/src/libcore/num/f32.rs +++ b/src/libcore/num/f32.rs @@ -117,23 +117,23 @@ impl Float for f32 { #[inline] fn neg_zero() -> f32 { -0.0 } - /// Returns `true` if the number is NaN + /// Returns `true` if the number is NaN. #[inline] fn is_nan(self) -> bool { self != self } - /// Returns `true` if the number is infinite + /// Returns `true` if the number is infinite. #[inline] fn is_infinite(self) -> bool { self == Float::infinity() || self == Float::neg_infinity() } - /// Returns `true` if the number is neither infinite or NaN + /// Returns `true` if the number is neither infinite or NaN. #[inline] fn is_finite(self) -> bool { !(self.is_nan() || self.is_infinite()) } - /// Returns `true` if the number is neither zero, infinite, subnormal or NaN + /// Returns `true` if the number is neither zero, infinite, subnormal or NaN. #[inline] fn is_normal(self) -> bool { self.classify() == FPNormal @@ -195,25 +195,25 @@ impl Float for f32 { (mantissa as u64, exponent, sign) } - /// Round half-way cases toward `NEG_INFINITY` + /// Rounds towards minus infinity. #[inline] fn floor(self) -> f32 { unsafe { intrinsics::floorf32(self) } } - /// Round half-way cases toward `INFINITY` + /// Rounds towards plus infinity. #[inline] fn ceil(self) -> f32 { unsafe { intrinsics::ceilf32(self) } } - /// Round half-way cases away from `0.0` + /// Rounds to nearest integer. Rounds half-way cases away from zero. #[inline] fn round(self) -> f32 { unsafe { intrinsics::roundf32(self) } } - /// The integer part of the number (rounds towards `0.0`) + /// Returns the integer part of the number (rounds towards zero). #[inline] fn trunc(self) -> f32 { unsafe { intrinsics::truncf32(self) } @@ -236,7 +236,7 @@ impl Float for f32 { unsafe { intrinsics::fmaf32(self, a, b) } } - /// The reciprocal (multiplicative inverse) of the number + /// Returns the reciprocal (multiplicative inverse) of the number. #[inline] fn recip(self) -> f32 { 1.0 / self } @@ -325,45 +325,45 @@ impl Float for f32 { #[inline] fn ln_10() -> f32 { consts::LN_10 } - /// Returns the exponential of the number + /// Returns the exponential of the number. #[inline] fn exp(self) -> f32 { unsafe { intrinsics::expf32(self) } } - /// Returns 2 raised to the power of the number + /// Returns 2 raised to the power of the number. #[inline] fn exp2(self) -> f32 { unsafe { intrinsics::exp2f32(self) } } - /// Returns the natural logarithm of the number + /// Returns the natural logarithm of the number. #[inline] fn ln(self) -> f32 { unsafe { intrinsics::logf32(self) } } - /// Returns the logarithm of the number with respect to an arbitrary base + /// Returns the logarithm of the number with respect to an arbitrary base. #[inline] fn log(self, base: f32) -> f32 { self.ln() / base.ln() } - /// Returns the base 2 logarithm of the number + /// Returns the base 2 logarithm of the number. #[inline] fn log2(self) -> f32 { unsafe { intrinsics::log2f32(self) } } - /// Returns the base 10 logarithm of the number + /// Returns the base 10 logarithm of the number. #[inline] fn log10(self) -> f32 { unsafe { intrinsics::log10f32(self) } } - /// Converts to degrees, assuming the number is in radians + /// Converts to degrees, assuming the number is in radians. #[inline] fn to_degrees(self) -> f32 { self * (180.0f32 / Float::pi()) } - /// Converts to radians, assuming the number is in degrees + /// Converts to radians, assuming the number is in degrees. #[inline] fn to_radians(self) -> f32 { let value: f32 = Float::pi(); diff --git a/src/libcore/num/f64.rs b/src/libcore/num/f64.rs index a3a82aeec5e..a3ae8e7c79e 100644 --- a/src/libcore/num/f64.rs +++ b/src/libcore/num/f64.rs @@ -123,23 +123,23 @@ impl Float for f64 { #[inline] fn neg_zero() -> f64 { -0.0 } - /// Returns `true` if the number is NaN + /// Returns `true` if the number is NaN. #[inline] fn is_nan(self) -> bool { self != self } - /// Returns `true` if the number is infinite + /// Returns `true` if the number is infinite. #[inline] fn is_infinite(self) -> bool { self == Float::infinity() || self == Float::neg_infinity() } - /// Returns `true` if the number is neither infinite or NaN + /// Returns `true` if the number is neither infinite or NaN. #[inline] fn is_finite(self) -> bool { !(self.is_nan() || self.is_infinite()) } - /// Returns `true` if the number is neither zero, infinite, subnormal or NaN + /// Returns `true` if the number is neither zero, infinite, subnormal or NaN. #[inline] fn is_normal(self) -> bool { self.classify() == FPNormal @@ -201,25 +201,25 @@ impl Float for f64 { (mantissa, exponent, sign) } - /// Round half-way cases toward `NEG_INFINITY` + /// Rounds towards minus infinity. #[inline] fn floor(self) -> f64 { unsafe { intrinsics::floorf64(self) } } - /// Round half-way cases toward `INFINITY` + /// Rounds towards plus infinity. #[inline] fn ceil(self) -> f64 { unsafe { intrinsics::ceilf64(self) } } - /// Round half-way cases away from `0.0` + /// Rounds to nearest integer. Rounds half-way cases away from zero. #[inline] fn round(self) -> f64 { unsafe { intrinsics::roundf64(self) } } - /// The integer part of the number (rounds towards `0.0`) + /// Returns the integer part of the number (rounds towards zero). #[inline] fn trunc(self) -> f64 { unsafe { intrinsics::truncf64(self) } @@ -242,7 +242,7 @@ impl Float for f64 { unsafe { intrinsics::fmaf64(self, a, b) } } - /// The reciprocal (multiplicative inverse) of the number + /// Returns the reciprocal (multiplicative inverse) of the number. #[inline] fn recip(self) -> f64 { 1.0 / self } @@ -332,46 +332,45 @@ impl Float for f64 { #[inline] fn ln_10() -> f64 { consts::LN_10 } - /// Returns the exponential of the number + /// Returns the exponential of the number. #[inline] fn exp(self) -> f64 { unsafe { intrinsics::expf64(self) } } - /// Returns 2 raised to the power of the number + /// Returns 2 raised to the power of the number. #[inline] fn exp2(self) -> f64 { unsafe { intrinsics::exp2f64(self) } } - /// Returns the natural logarithm of the number + /// Returns the natural logarithm of the number. #[inline] fn ln(self) -> f64 { unsafe { intrinsics::logf64(self) } } - /// Returns the logarithm of the number with respect to an arbitrary base + /// Returns the logarithm of the number with respect to an arbitrary base. #[inline] fn log(self, base: f64) -> f64 { self.ln() / base.ln() } - /// Returns the base 2 logarithm of the number + /// Returns the base 2 logarithm of the number. #[inline] fn log2(self) -> f64 { unsafe { intrinsics::log2f64(self) } } - /// Returns the base 10 logarithm of the number + /// Returns the base 10 logarithm of the number. #[inline] fn log10(self) -> f64 { unsafe { intrinsics::log10f64(self) } } - - /// Converts to degrees, assuming the number is in radians + /// Converts to degrees, assuming the number is in radians. #[inline] fn to_degrees(self) -> f64 { self * (180.0f64 / Float::pi()) } - /// Converts to radians, assuming the number is in degrees + /// Converts to radians, assuming the number is in degrees. #[inline] fn to_radians(self) -> f64 { let value: f64 = Float::pi(); diff --git a/src/libnum/bigint.rs b/src/libnum/bigint.rs index acba750aaf4..4dd3817e475 100644 --- a/src/libnum/bigint.rs +++ b/src/libnum/bigint.rs @@ -514,9 +514,14 @@ impl Integer for BigUint { #[inline] fn lcm(&self, other: &BigUint) -> BigUint { ((*self * *other) / self.gcd(other)) } - /// Returns `true` if the number can be divided by `other` without leaving a remainder. + /// Deprecated, use `is_multiple_of` instead. + #[deprecated = "function renamed to `is_multiple_of`"] #[inline] - fn divides(&self, other: &BigUint) -> bool { (*self % *other).is_zero() } + fn divides(&self, other: &BigUint) -> bool { return self.is_multiple_of(other); } + + /// Returns `true` if the number is a multiple of `other`. + #[inline] + fn is_multiple_of(&self, other: &BigUint) -> bool { (*self % *other).is_zero() } /// Returns `true` if the number is divisible by `2`. #[inline] @@ -1112,9 +1117,14 @@ impl Integer for BigInt { BigInt::from_biguint(Plus, self.data.lcm(&other.data)) } - /// Returns `true` if the number can be divided by `other` without leaving a remainder. + /// Deprecated, use `is_multiple_of` instead. + #[deprecated = "function renamed to `is_multiple_of`"] #[inline] - fn divides(&self, other: &BigInt) -> bool { self.data.divides(&other.data) } + fn divides(&self, other: &BigInt) -> bool { return self.is_multiple_of(other); } + + /// Returns `true` if the number is a multiple of `other`. + #[inline] + fn is_multiple_of(&self, other: &BigInt) -> bool { self.data.is_multiple_of(&other.data) } /// Returns `true` if the number is divisible by `2`. #[inline] diff --git a/src/libnum/integer.rs b/src/libnum/integer.rs index bcaebbd1368..b06e2b448d4 100644 --- a/src/libnum/integer.rs +++ b/src/libnum/integer.rs @@ -77,16 +77,20 @@ pub trait Integer: Num + PartialOrd /// ~~~ fn lcm(&self, other: &Self) -> Self; - /// Returns `true` if `other` divides evenly into `self`. + /// Deprecated, use `is_multiple_of` instead. + #[deprecated = "function renamed to `is_multiple_of`"] + fn divides(&self, other: &Self) -> bool; + + /// Returns `true` if `other` is a multiple of `self`. /// /// # Examples /// /// ~~~ /// # use num::Integer; - /// assert_eq!(9i.divides(&3), true); - /// assert_eq!(3i.divides(&9), false); + /// assert_eq!(9i.is_multiple_of(&3), true); + /// assert_eq!(3i.is_multiple_of(&9), false); /// ~~~ - fn divides(&self, other: &Self) -> bool; + fn is_multiple_of(&self, other: &Self) -> bool; /// Returns `true` if the number is even. /// @@ -231,10 +235,14 @@ macro_rules! impl_integer_for_int { ((*self * *other) / self.gcd(other)).abs() } - /// Returns `true` if the number can be divided by `other` without - /// leaving a remainder + /// Deprecated, use `is_multiple_of` instead. + #[deprecated = "function renamed to `is_multiple_of`"] #[inline] - fn divides(&self, other: &$T) -> bool { *self % *other == 0 } + fn divides(&self, other: &$T) -> bool { return self.is_multiple_of(other); } + + /// Returns `true` if the number is a multiple of `other`. + #[inline] + fn is_multiple_of(&self, other: &$T) -> bool { *self % *other == 0 } /// Returns `true` if the number is divisible by `2` #[inline] @@ -393,21 +401,26 @@ macro_rules! impl_integer_for_uint { n } - /// Calculates the Lowest Common Multiple (LCM) of the number and `other` + /// Calculates the Lowest Common Multiple (LCM) of the number and `other`. #[inline] fn lcm(&self, other: &$T) -> $T { (*self * *other) / self.gcd(other) } - /// Returns `true` if the number can be divided by `other` without leaving a remainder + /// Deprecated, use `is_multiple_of` instead. + #[deprecated = "function renamed to `is_multiple_of`"] #[inline] - fn divides(&self, other: &$T) -> bool { *self % *other == 0 } + fn divides(&self, other: &$T) -> bool { return self.is_multiple_of(other); } - /// Returns `true` if the number is divisible by `2` + /// Returns `true` if the number is a multiple of `other`. + #[inline] + fn is_multiple_of(&self, other: &$T) -> bool { *self % *other == 0 } + + /// Returns `true` if the number is divisible by `2`. #[inline] fn is_even(&self) -> bool { self & 1 == 0 } - /// Returns `true` if the number is not divisible by `2` + /// Returns `true` if the number is not divisible by `2`. #[inline] fn is_odd(&self) -> bool { !self.is_even() } } @@ -449,10 +462,10 @@ macro_rules! impl_integer_for_uint { } #[test] - fn test_divides() { - assert!((6 as $T).divides(&(6 as $T))); - assert!((6 as $T).divides(&(3 as $T))); - assert!((6 as $T).divides(&(1 as $T))); + fn test_is_multiple_of() { + assert!((6 as $T).is_multiple_of(&(6 as $T))); + assert!((6 as $T).is_multiple_of(&(3 as $T))); + assert!((6 as $T).is_multiple_of(&(1 as $T))); } #[test] diff --git a/src/libnum/rational.rs b/src/libnum/rational.rs index a279ede6fa5..e0f6b4fb9af 100644 --- a/src/libnum/rational.rs +++ b/src/libnum/rational.rs @@ -38,13 +38,13 @@ pub type BigRational = Ratio; impl Ratio { - /// Create a ratio representing the integer `t`. + /// Creates a ratio representing the integer `t`. #[inline] pub fn from_integer(t: T) -> Ratio { Ratio::new_raw(t, One::one()) } - /// Create a ratio without checking for `denom == 0` or reducing. + /// Creates a ratio without checking for `denom == 0` or reducing. #[inline] pub fn new_raw(numer: T, denom: T) -> Ratio { Ratio { numer: numer, denom: denom } @@ -61,7 +61,7 @@ impl ret } - /// Convert to an integer. + /// Converts to an integer. #[inline] pub fn to_integer(&self) -> T { self.trunc().numer @@ -79,7 +79,7 @@ impl &self.denom } - /// Return true if the rational number is an integer (denominator is 1). + /// Returns true if the rational number is an integer (denominator is 1). #[inline] pub fn is_integer(&self) -> bool { self.denom == One::one() @@ -103,19 +103,21 @@ impl } } - /// Return a `reduce`d copy of self. + /// Returns a `reduce`d copy of self. pub fn reduced(&self) -> Ratio { let mut ret = self.clone(); ret.reduce(); ret } - /// Return the reciprocal + /// Returns the reciprocal. #[inline] pub fn recip(&self) -> Ratio { Ratio::new_raw(self.denom.clone(), self.numer.clone()) } + /// Rounds towards minus infinity. + #[inline] pub fn floor(&self) -> Ratio { if *self < Zero::zero() { Ratio::from_integer((self.numer - self.denom + One::one()) / self.denom) @@ -124,6 +126,8 @@ impl } } + /// Rounds towards plus infinity. + #[inline] pub fn ceil(&self) -> Ratio { if *self < Zero::zero() { Ratio::from_integer(self.numer / self.denom) @@ -132,8 +136,12 @@ impl } } + /// Rounds to the nearest integer. Rounds half-way cases away from zero. + /// + /// Note: This function is currently broken and always rounds away from zero. #[inline] pub fn round(&self) -> Ratio { + // FIXME(#15826) if *self < Zero::zero() { Ratio::from_integer((self.numer - self.denom + One::one()) / self.denom) } else { @@ -141,18 +149,21 @@ impl } } + /// Rounds towards zero. #[inline] pub fn trunc(&self) -> Ratio { Ratio::from_integer(self.numer / self.denom) } + ///Returns the fractional part of a number. + #[inline] pub fn fract(&self) -> Ratio { Ratio::new_raw(self.numer % self.denom, self.denom.clone()) } } impl Ratio { - /// Converts a float into a rational number + /// Converts a float into a rational number. pub fn from_float(f: T) -> Option { if !f.is_finite() { return None; @@ -328,7 +339,7 @@ impl ToStrRadix for Ratio { impl FromStr for Ratio { - /// Parses `numer/denom` or just `numer` + /// Parses `numer/denom` or just `numer`. fn from_str(s: &str) -> Option> { let mut split = s.splitn('/', 1); diff --git a/src/librustc/back/link.rs b/src/librustc/back/link.rs index c7dca1b93ef..0a8aae5d139 100644 --- a/src/librustc/back/link.rs +++ b/src/librustc/back/link.rs @@ -1230,7 +1230,7 @@ fn link_natively(sess: &Session, trans: &CrateTranslation, dylib: bool, // the symbols if (sess.targ_cfg.os == abi::OsMacos || sess.targ_cfg.os == abi::OsiOS) && (sess.opts.debuginfo != NoDebugInfo) { - match Command::new("dsymutil").arg(out_filename).status() { + match Command::new("dsymutil").arg(out_filename).output() { Ok(..) => {} Err(e) => { sess.err(format!("failed to run dsymutil: {}", e).as_slice()); diff --git a/src/librustc/front/feature_gate.rs b/src/librustc/front/feature_gate.rs index 9f15c9a9b3f..99855c7345c 100644 --- a/src/librustc/front/feature_gate.rs +++ b/src/librustc/front/feature_gate.rs @@ -69,6 +69,8 @@ static KNOWN_FEATURES: &'static [(&'static str, Status)] = &[ ("rustc_diagnostic_macros", Active), ("unboxed_closures", Active), + // if you change this list without updating src/doc/rust.md, cmr will be sad + // A temporary feature gate used to enable parser extensions needed // to bootstrap fix for #5723. ("issue_5723_bootstrap", Active), diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 3f4f5123699..1667f2b6d5f 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -358,9 +358,9 @@ impl LintPass for CTypes { def::DefTy(def_id) => { if !adt::is_ffi_safe(cx.tcx, def_id) { cx.span_lint(CTYPES, ty.span, - "found enum type without foreign-function-safe \ - representation annotation in foreign module"); - // hmm... this message could be more helpful + "found enum type without foreign-function-safe + representation annotation in foreign module, consider \ + adding a #[repr(...)] attribute to the enumeration"); } } _ => () diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs index d202e61abf3..5e7426f3ae7 100644 --- a/src/librustc/middle/typeck/astconv.rs +++ b/src/librustc/middle/typeck/astconv.rs @@ -877,6 +877,7 @@ pub fn ast_ty_to_ty( } } ast::TyFixedLengthVec(ty, e) => { + typeck::write_ty_to_tcx(tcx, e.id, ty::mk_uint()); match const_eval::eval_const_expr_partial(tcx, &*e) { Ok(ref r) => { match *r { diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index 08a26eefa22..bbb6e162ecb 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -430,6 +430,18 @@ impl<'a> Visitor<()> for GatherLocalsVisitor<'a> { self.fcx.with_region_lb(b.id, || visit::walk_block(self, b, ())); } + // Since an expr occurs as part of the type fixed size arrays we + // need to record the type for that node + fn visit_ty(&mut self, t: &ast::Ty, _: ()) { + match t.node { + ast::TyFixedLengthVec(ref ty, ref count_expr) => { + self.visit_ty(&**ty, ()); + check_expr_with_hint(self.fcx, &**count_expr, ty::mk_uint()); + } + _ => visit::walk_ty(self, t, ()) + } + } + // Don't descend into fns and items fn visit_fn(&mut self, _: &visit::FnKind, _: &ast::FnDecl, _: &ast::Block, _: Span, _: ast::NodeId, _: ()) { } @@ -3444,6 +3456,12 @@ fn check_expr_with_unifier(fcx: &FnCtxt, } } ast::ExprCast(ref e, ref t) => { + match t.node { + ast::TyFixedLengthVec(_, ref count_expr) => { + check_expr_with_hint(fcx, &**count_expr, ty::mk_uint()); + } + _ => {} + } check_cast(fcx, &**e, &**t, id, expr.span); } ast::ExprVec(ref args) => { diff --git a/src/librustc/middle/typeck/check/writeback.rs b/src/librustc/middle/typeck/check/writeback.rs index c3e7d06f3f8..d94ac103ceb 100644 --- a/src/librustc/middle/typeck/check/writeback.rs +++ b/src/librustc/middle/typeck/check/writeback.rs @@ -181,8 +181,14 @@ impl<'cx> Visitor<()> for WritebackCx<'cx> { visit::walk_local(self, l, ()); } - fn visit_ty(&mut self, _t: &ast::Ty, _: ()) { - // ignore + fn visit_ty(&mut self, t: &ast::Ty, _: ()) { + match t.node { + ast::TyFixedLengthVec(ref ty, ref count_expr) => { + self.visit_ty(&**ty, ()); + write_ty_to_tcx(self.tcx(), count_expr.id, ty::mk_uint()); + } + _ => visit::walk_ty(self, t, ()) + } } } diff --git a/src/librustdoc/html/static/main.css b/src/librustdoc/html/static/main.css index c22dd64d2b4..45e6694853c 100644 --- a/src/librustdoc/html/static/main.css +++ b/src/librustdoc/html/static/main.css @@ -129,6 +129,14 @@ pre { padding: 20px; } +.content.source { + margin-top: 50px; + max-width: none; + overflow: visible; + margin-left: 0px; + min-width: 70em; +} + nav.sub { font-size: 16px; text-transform: uppercase; diff --git a/src/libstd/io/fs.rs b/src/libstd/io/fs.rs index 790fe6cb8b9..fcb41c8f6fc 100644 --- a/src/libstd/io/fs.rs +++ b/src/libstd/io/fs.rs @@ -114,7 +114,7 @@ impl File { /// `FileMode` and `FileAccess` provide information about the permissions /// context in which a given stream is created. More information about them /// can be found in `std::io`'s docs. If a file is opened with `Write` - /// or `ReadWrite` access, then it will be created it does not already + /// or `ReadWrite` access, then it will be created if it does not already /// exist. /// /// Note that, with this function, a `File` is returned regardless of the diff --git a/src/libstd/path/mod.rs b/src/libstd/path/mod.rs index 0c93f8e6de9..1e9ec32d759 100644 --- a/src/libstd/path/mod.rs +++ b/src/libstd/path/mod.rs @@ -178,16 +178,13 @@ pub trait GenericPath: Clone + GenericPathUnsafe { fn into_vec(self) -> Vec; /// Returns an object that implements `Show` for printing paths - /// - /// This will print the equivalent of `to_display_str()` when used with a {} format parameter. fn display<'a>(&'a self) -> Display<'a, Self> { Display{ path: self, filename: false } } /// Returns an object that implements `Show` for printing filenames /// - /// This will print the equivalent of `to_filename_display_str()` when used with a {} - /// format parameter. If there is no filename, nothing will be printed. + /// If there is no filename, nothing will be printed. fn filename_display<'a>(&'a self) -> Display<'a, Self> { Display{ path: self, filename: true } } diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index f82796b480a..a51a79b6d58 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -536,13 +536,16 @@ fn expand_non_macro_stmt(s: &Stmt, fld: &mut MacroExpander) } => { // take it apart: let Local { - ty: _, + ty: ty, pat: pat, init: init, id: id, span: span, source: source, } = **local; + // expand the ty since TyFixedLengthVec contains an Expr + // and thus may have a macro use + let expanded_ty = fld.fold_ty(ty); // expand the pat (it might contain macro uses): let expanded_pat = fld.fold_pat(pat); // find the PatIdents in the pattern: @@ -566,7 +569,7 @@ fn expand_non_macro_stmt(s: &Stmt, fld: &mut MacroExpander) let new_init_opt = init.map(|e| fld.fold_expr(e)); let rewritten_local = box(GC) Local { - ty: local.ty, + ty: expanded_ty, pat: rewritten_pat, init: new_init_opt, id: id, diff --git a/src/llvm b/src/llvm index cd24b5c6633..0d999e5b315 160000 --- a/src/llvm +++ b/src/llvm @@ -1 +1 @@ -Subproject commit cd24b5c6633b27df2b84249a65a46a610b734494 +Subproject commit 0d999e5b315b6ff78fcea772466d985ce53fd8dc diff --git a/src/rustllvm/llvm-auto-clean-trigger b/src/rustllvm/llvm-auto-clean-trigger index bdc5bfdc10a..afba5a4dfd8 100644 --- a/src/rustllvm/llvm-auto-clean-trigger +++ b/src/rustllvm/llvm-auto-clean-trigger @@ -1,4 +1,4 @@ # If this file is modified, then llvm will be forcibly cleaned and then rebuilt. # The actual contents of this file do not matter, but to trigger a change on the # build bots then the contents should be changed so git updates the mtime. -2014-07-22 +2014-07-29 diff --git a/src/test/pretty/issue-4264.pp b/src/test/pretty/issue-4264.pp new file mode 100644 index 00000000000..a9f57a48f44 --- /dev/null +++ b/src/test/pretty/issue-4264.pp @@ -0,0 +1,95 @@ +#![feature(phase)] +#![no_std] +#![feature(globs)] +#[phase(plugin, link)] +extern crate std = "std"; +extern crate rt = "native"; +use std::prelude::*; +// Copyright 2014 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// pretty-compare-only +// pretty-mode:typed +// pp-exact:issue-4264.pp + +// #4264 fixed-length vector types + +pub fn foo(_: [int, ..(3 as uint)]) { } + +pub fn bar() { + static FOO: uint = ((5u as uint) - (4u as uint) as uint); + let _: [(), ..(FOO as uint)] = ([(() as ())] as [(), .. 1]); + + let _: [(), ..(1u as uint)] = ([(() as ())] as [(), .. 1]); + + let _ = + (((&((([(1i as int), (2 as int), (3 as int)] as [int, .. 3])) as + [int, .. 3]) as &[int, .. 3]) as *const _ as + *const [int, .. 3]) as *const [int, ..(3u as uint)] as + *const [int, .. 3]); + (match (() as ()) { + () => { + #[inline] + #[allow(dead_code)] + static __STATIC_FMTSTR: + [::std::fmt::rt::Piece<'static>, ..(1u as uint)] = + ([((::std::fmt::rt::String as + fn(&'static str) -> core::fmt::rt::Piece<'static>)(("test" + as + &'static str)) + as core::fmt::rt::Piece<'static>)] as + [core::fmt::rt::Piece<'static>, .. 1]); + let __args_vec = + (&([] as &'static [core::fmt::Argument<'static>]) as + &'static [core::fmt::Argument<'static>]); + let __args = + (unsafe { + ((::std::fmt::Arguments::new as + unsafe fn(&'static [core::fmt::rt::Piece<'static>], &'a [core::fmt::Argument<'a>]) -> core::fmt::Arguments<'a>)((__STATIC_FMTSTR + as + [core::fmt::rt::Piece<'static>, .. 1]), + (__args_vec + as + &'static [core::fmt::Argument<'static>])) + as core::fmt::Arguments<'static>) + } as core::fmt::Arguments<'static>); + + + + + + + + + ((::std::fmt::format as + fn(&core::fmt::Arguments<'_>) -> collections::string::String)((&(__args + as + core::fmt::Arguments<'static>) + as + &core::fmt::Arguments<'static>)) + as collections::string::String) + } + } as collections::string::String); +} +pub type Foo = [int, ..(3u as uint)]; +pub struct Bar { + pub x: [int, ..(3u as uint)], +} +pub struct TupleBar([int, ..(4u as uint)]); +pub enum Baz { BazVariant([int, ..(5u as uint)]), } +pub fn id(x: T) -> T { (x as T) } +pub fn use_id() { + let _ = + ((id::<[int, ..(3u as uint)]> as + fn([int, .. 3]) -> [int, .. 3])(([(1 as int), (2 as int), + (3 as int)] as [int, .. 3])) as + [int, .. 3]); +} +fn main() { } diff --git a/src/test/pretty/issue-4264.rs b/src/test/pretty/issue-4264.rs new file mode 100644 index 00000000000..ad407f48a7a --- /dev/null +++ b/src/test/pretty/issue-4264.rs @@ -0,0 +1,49 @@ +// Copyright 2014 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// pretty-compare-only +// pretty-mode:typed +// pp-exact:issue-4264.pp + +// #4264 fixed-length vector types + +pub fn foo(_: [int, ..3]) {} + +pub fn bar() { + static FOO: uint = 5u - 4u; + let _: [(), ..FOO] = [()]; + + let _ : [(), ..1u] = [()]; + + let _ = &([1i,2,3]) as *const _ as *const [int, ..3u]; + + format!("test"); +} + +pub type Foo = [int, ..3u]; + +pub struct Bar { + pub x: [int, ..3u] +} + +pub struct TupleBar([int, ..4u]); + +pub enum Baz { + BazVariant([int, ..5u]) +} + +pub fn id(x: T) -> T { x } + +pub fn use_id() { + let _ = id::<[int, ..3u]>([1,2,3]); +} + + +fn main() {} diff --git a/src/test/run-pass/macro-invocation-in-count-expr-fixed-array-type.rs b/src/test/run-pass/macro-invocation-in-count-expr-fixed-array-type.rs new file mode 100644 index 00000000000..847024d42ba --- /dev/null +++ b/src/test/run-pass/macro-invocation-in-count-expr-fixed-array-type.rs @@ -0,0 +1,18 @@ +// Copyright 2014 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(macro_rules)] + +macro_rules! four ( + () => (4) +) +fn main() { + let _x: [u16, ..four!()]; +}