diff --git a/doc/guide-testing.md b/doc/guide-testing.md index eeed3c7d9a793..b8f7cf97412d1 100644 --- a/doc/guide-testing.md +++ b/doc/guide-testing.md @@ -33,7 +33,7 @@ test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured # Unit testing in Rust Rust has built in support for simple unit testing. Functions can be -marked as unit tests using the 'test' attribute. +marked as unit tests using the `test` attribute. ~~~ #[test] @@ -44,13 +44,13 @@ fn return_none_if_empty() { A test function's signature must have no arguments and no return value. To run the tests in a crate, it must be compiled with the -'--test' flag: `rustc myprogram.rs --test -o myprogram-tests`. Running +`--test` flag: `rustc myprogram.rs --test -o myprogram-tests`. Running the resulting executable will run all the tests in the crate. A test is considered successful if its function returns; if the task running the test fails, through a call to `fail!`, a failed `check` or `assert`, or some other (`assert_eq`, ...) means, then the test fails. -When compiling a crate with the '--test' flag '--cfg test' is also +When compiling a crate with the `--test` flag `--cfg test` is also implied, so that tests can be conditionally compiled. ~~~ @@ -63,18 +63,18 @@ mod tests { } ~~~ -Additionally #[test] items behave as if they also have the -#[cfg(test)] attribute, and will not be compiled when the --test flag +Additionally `#[test]` items behave as if they also have the +`#[cfg(test)]` attribute, and will not be compiled when the `--test` flag is not used. -Tests that should not be run can be annotated with the 'ignore' +Tests that should not be run can be annotated with the `ignore` attribute. The existence of these tests will be noted in the test runner output, but the test will not be run. Tests can also be ignored by configuration so, for example, to ignore a test on windows you can write `#[ignore(cfg(target_os = "win32"))]`. Tests that are intended to fail can be annotated with the -'should_fail' attribute. The test will be run, and if it causes its +`should_fail` attribute. The test will be run, and if it causes its task to fail then the test will be counted as successful; otherwise it will be counted as a failure. For example: @@ -87,11 +87,11 @@ fn test_out_of_bounds_failure() { } ~~~ -A test runner built with the '--test' flag supports a limited set of +A test runner built with the `--test` flag supports a limited set of arguments to control which tests are run: the first free argument passed to a test runner specifies a filter used to narrow down the set -of tests being run; the '--ignored' flag tells the test runner to run -only tests with the 'ignore' attribute. +of tests being run; the `--ignored` flag tells the test runner to run +only tests with the `ignore` attribute. ## Parallelism diff --git a/doc/rust.md b/doc/rust.md index ad93964d6aa87..bf0e9dd090ae4 100644 --- a/doc/rust.md +++ b/doc/rust.md @@ -2211,12 +2211,9 @@ dereferences (`*expr`), [indexing expressions](#index-expressions) (`expr[expr]`), and [field references](#field-expressions) (`expr.f`). All other expressions are rvalues. -The left operand of an [assignment](#assignment-expressions), -[binary move](#binary-move-expressions) or +The left operand of an [assignment](#assignment-expressions) or [compound-assignment](#compound-assignment-expressions) expression is an lvalue context, -as is the single operand of a unary [borrow](#unary-operator-expressions), -or [move](#unary-move-expressions) expression, -and _both_ operands of a [swap](#swap-expressions) expression. +as is the single operand of a unary [borrow](#unary-operator-expressions). All other expression contexts are rvalue contexts. When an lvalue is evaluated in an _lvalue context_, it denotes a memory location; @@ -2229,9 +2226,8 @@ A temporary's lifetime equals the largest lifetime of any reference that points When a [local variable](#memory-slots) is used as an [rvalue](#lvalues-rvalues-and-temporaries) -the variable will either be [moved](#move-expressions) or copied, -depending on its type. -For types that contain [owning pointers](#owning-pointers) +the variable will either be moved or copied, depending on its type. +For types that contain [owning pointers](#pointer-types) or values that implement the special trait `Drop`, the variable is moved. All other types are copied. @@ -2890,16 +2886,26 @@ match x { The first pattern matches lists constructed by applying `Cons` to any head value, and a tail value of `~Nil`. The second pattern matches _any_ list constructed with `Cons`, -ignoring the values of its arguments. The difference between `_` and `*` is that the pattern `C(_)` is only type-correct if -`C` has exactly one argument, while the pattern `C(..)` is type-correct for any enum variant `C`, regardless of how many arguments `C` has. - -To execute an `match` expression, first the head expression is evaluated, then -its value is sequentially compared to the patterns in the arms until a match +ignoring the values of its arguments. The difference between `_` and `*` is that the pattern +`C(_)` is only type-correct if `C` has exactly one argument, while the pattern `C(..)` is +type-correct for any enum variant `C`, regardless of how many arguments `C` has. + +A `match` behaves differently depending on whether or not the head expression +is an [lvalue or an rvalue](#lvalues-rvalues-and-temporaries). +If the head expression is an rvalue, it is +first evaluated into a temporary location, and the resulting value +is sequentially compared to the patterns in the arms until a match is found. The first arm with a matching pattern is chosen as the branch target of the `match`, any variables bound by the pattern are assigned to local variables in the arm's block, and control enters the block. -An example of an `match` expression: +When the head expression is an lvalue, the match does not allocate a +temporary location (however, a by-value binding may copy or move from +the lvalue). When possible, it is preferable to match on lvalues, as the +lifetime of these matches inherits the lifetime of the lvalue, rather +than being restricted to the inside of the match. + +An example of a `match` expression: ~~~~ # fn process_pair(a: int, b: int) { } @@ -2929,19 +2935,31 @@ Patterns that bind variables default to binding to a copy or move of the matched value (depending on the matched value's type). This can be changed to bind to a reference by -using the ```ref``` keyword, -or to a mutable reference using ```ref mut```. - -A pattern that's just an identifier, -like `Nil` in the previous answer, -could either refer to an enum variant that's in scope, -or bind a new variable. -The compiler resolves this ambiguity by forbidding variable bindings that occur in ```match``` patterns from shadowing names of variants that are in scope. -For example, wherever ```List``` is in scope, -a ```match``` pattern would not be able to bind ```Nil``` as a new name. -The compiler interprets a variable pattern `x` as a binding _only_ if there is no variant named `x` in scope. -A convention you can use to avoid conflicts is simply to name variants with upper-case letters, -and local variables with lower-case letters. +using the `ref` keyword, +or to a mutable reference using `ref mut`. + +Patterns can also dereference pointers by using the `&`, +`~` or `@` symbols, as appropriate. For example, these two matches +on `x: &int` are equivalent: + +~~~~ +# let x = &3; +let y = match *x { 0 => "zero", _ => "some" }; +let z = match x { &0 => "zero", _ => "some" }; + +assert_eq!(y, z); +~~~~ + +A pattern that's just an identifier, like `Nil` in the previous answer, +could either refer to an enum variant that's in scope, or bind a new variable. +The compiler resolves this ambiguity by forbidding variable bindings that occur +in `match` patterns from shadowing names of variants that are in scope. +For example, wherever `List` is in scope, +a `match` pattern would not be able to bind `Nil` as a new name. +The compiler interprets a variable pattern `x` as a binding _only_ if there is +no variant named `x` in scope. +A convention you can use to avoid conflicts is simply to name variants with +upper-case letters, and local variables with lower-case letters. Multiple match patterns may be joined with the `|` operator. A range of values may be specified with `..`. @@ -3122,19 +3140,20 @@ A `struct` *type* is a heterogeneous product of other types, called the *fields* the *record* types of the ML family, or the *structure* types of the Lisp family.] -New instances of a `struct` can be constructed with a [struct expression](#struct-expressions). +New instances of a `struct` can be constructed with a [struct expression](#structure-expressions). The memory order of fields in a `struct` is given by the item defining it. Fields may be given in any order in a corresponding struct *expression*; the resulting `struct` value will always be laid out in memory in the order specified by the corresponding *item*. -The fields of a `struct` may be qualified by [visibility modifiers](#visibility-modifiers), +The fields of a `struct` may be qualified by [visibility modifiers](#re-exporting-and-visibility), to restrict access to implementation-private data in a structure. A _tuple struct_ type is just like a structure type, except that the fields are anonymous. A _unit-like struct_ type is like a structure type, except that it has no fields. -The one value constructed by the associated [structure expression](#structure-expression) is the only value that inhabits such a type. +The one value constructed by the associated [structure expression](#structure-expressions) +is the only value that inhabits such a type. ### Enumerated types @@ -3805,7 +3824,7 @@ over the output format of a Rust crate. ### Logging system The runtime contains a system for directing [logging -expressions](#log-expressions) to a logging console and/or internal logging +expressions](#logging-expressions) to a logging console and/or internal logging buffers. Logging can be enabled per module. Logging output is enabled by setting the `RUST_LOG` environment diff --git a/mk/docs.mk b/mk/docs.mk index 71ea4ba44d177..bacf39e1307db 100644 --- a/mk/docs.mk +++ b/mk/docs.mk @@ -17,16 +17,16 @@ CDOCS := DOCS_L10N := HTML_DEPS := -BASE_DOC_OPTS := --include-before-body=doc/version_info.html --standalone \ - --toc --number-sections -HTML_OPTS = $(BASE_DOC_OPTS) --to=html5 --section-divs --css=rust.css \ - --include-in-header=doc/favicon.inc -TEX_OPTS = $(BASE_DOC_OPTS) --to=latex +BASE_DOC_OPTS := --standalone --toc --number-sections +HTML_OPTS = $(BASE_DOC_OPTS) --to=html5 --section-divs --css=rust.css \ + --include-before-body=doc/version_info.html --include-in-header=doc/favicon.inc +TEX_OPTS = $(BASE_DOC_OPTS) --include-before-body=doc/version.md --to=latex EPUB_OPTS = $(BASE_DOC_OPTS) --to=epub ###################################################################### # Rust version ###################################################################### + doc/version.md: $(MKFILE_DEPS) $(wildcard $(S)doc/*.*) @$(call E, version-stamp: $@) $(Q)echo "$(CFG_VERSION)" >$@ @@ -84,7 +84,7 @@ doc/rust.tex: rust.md doc/version.md $(CFG_PANDOC) $(TEX_OPTS) --output=$@ DOCS += doc/rust.epub -doc/rust.epub: rust.md doc/version_info.html doc/rust.css +doc/rust.epub: rust.md @$(call E, pandoc: $@) $(Q)$(CFG_NODE) $(S)doc/prep.js --highlight $< | \ $(CFG_PANDOC) $(EPUB_OPTS) --output=$@ @@ -114,7 +114,7 @@ doc/tutorial.tex: tutorial.md doc/version.md $(CFG_PANDOC) $(TEX_OPTS) --output=$@ DOCS += doc/tutorial.epub -doc/tutorial.epub: tutorial.md doc/version_info.html doc/rust.css +doc/tutorial.epub: tutorial.md @$(call E, pandoc: $@) $(Q)$(CFG_NODE) $(S)doc/prep.js --highlight $< | \ $(CFG_PANDOC) $(EPUB_OPTS) --output=$@ @@ -265,6 +265,7 @@ endif # No pandoc / node ###################################################################### # LLnextgen (grammar analysis from refman) ###################################################################### + ifeq ($(CFG_LLNEXTGEN),) $(info cfg: no llnextgen found, omitting grammar-verification) else diff --git a/src/libstd/num/f32.rs b/src/libstd/num/f32.rs index e77348268c79e..5b0c75ef17493 100644 --- a/src/libstd/num/f32.rs +++ b/src/libstd/num/f32.rs @@ -96,6 +96,9 @@ delegate!( fn tanh(n: c_float) -> c_float = cmath::c_float::tanh ) +// FIXME(#11621): These constants should be deprecated once CTFE is implemented +// in favour of calling their respective functions in `Bounded` and `Float`. + pub static RADIX: uint = 2u; pub static MANTISSA_DIGITS: uint = 53u; @@ -122,6 +125,10 @@ pub static NEG_INFINITY: f32 = -1.0_f32/0.0_f32; pub mod consts { // FIXME (requires Issue #1433 to fix): replace with mathematical // staticants from cmath. + + // FIXME(#11621): These constants should be deprecated once CTFE is + // implemented in favour of calling their respective functions in `Real`. + /// Archimedes' constant pub static PI: f32 = 3.14159265358979323846264338327950288_f32; @@ -554,16 +561,7 @@ impl Bounded for f32 { fn max_value() -> f32 { 3.40282347e+38 } } -impl Primitive for f32 { - #[inline] - fn bits(_: Option) -> uint { 32 } - - #[inline] - fn bytes(_: Option) -> uint { Primitive::bits(Some(0f32)) / 8 } - - #[inline] - fn is_signed(_: Option) -> bool { true } -} +impl Primitive for f32 {} impl Float for f32 { #[inline] @@ -1173,13 +1171,6 @@ mod tests { assert!(!NAN.is_negative()); } - #[test] - fn test_primitive() { - let none: Option = None; - assert_eq!(Primitive::bits(none), mem::size_of::() * 8); - assert_eq!(Primitive::bytes(none), mem::size_of::()); - } - #[test] fn test_is_normal() { let nan: f32 = Float::nan(); diff --git a/src/libstd/num/f64.rs b/src/libstd/num/f64.rs index 7a06ef2e1aff8..95e5797ae9356 100644 --- a/src/libstd/num/f64.rs +++ b/src/libstd/num/f64.rs @@ -101,6 +101,9 @@ delegate!( // FIXME (#1433): obtain these in a different way +// FIXME(#11621): These constants should be deprecated once CTFE is implemented +// in favour of calling their respective functions in `Bounded` and `Float`. + pub static RADIX: uint = 2u; pub static MANTISSA_DIGITS: uint = 53u; @@ -129,6 +132,10 @@ pub static NEG_INFINITY: f64 = -1.0_f64/0.0_f64; pub mod consts { // FIXME (requires Issue #1433 to fix): replace with mathematical // constants from cmath. + + // FIXME(#11621): These constants should be deprecated once CTFE is + // implemented in favour of calling their respective functions in `Real`. + /// Archimedes' constant pub static PI: f64 = 3.14159265358979323846264338327950288_f64; @@ -556,16 +563,7 @@ impl Bounded for f64 { fn max_value() -> f64 { 1.7976931348623157e+308 } } -impl Primitive for f64 { - #[inline] - fn bits(_: Option) -> uint { 64 } - - #[inline] - fn bytes(_: Option) -> uint { Primitive::bits(Some(0f64)) / 8 } - - #[inline] - fn is_signed(_: Option) -> bool { true } -} +impl Primitive for f64 {} impl Float for f64 { #[inline] @@ -1178,13 +1176,6 @@ mod tests { assert!(!NAN.is_negative()); } - #[test] - fn test_primitive() { - let none: Option = None; - assert_eq!(Primitive::bits(none), mem::size_of::() * 8); - assert_eq!(Primitive::bytes(none), mem::size_of::()); - } - #[test] fn test_is_normal() { let nan: f64 = Float::nan(); diff --git a/src/libstd/num/int_macros.rs b/src/libstd/num/int_macros.rs index add0991f7afb9..7102a8997584e 100644 --- a/src/libstd/num/int_macros.rs +++ b/src/libstd/num/int_macros.rs @@ -13,11 +13,19 @@ macro_rules! int_module (($T:ty, $bits:expr) => ( +// FIXME(#11621): Should be deprecated once CTFE is implemented in favour of +// calling the `mem::size_of` function. pub static bits : uint = $bits; +// FIXME(#11621): Should be deprecated once CTFE is implemented in favour of +// calling the `mem::size_of` function. pub static bytes : uint = ($bits / 8); +// FIXME(#11621): Should be deprecated once CTFE is implemented in favour of +// calling the `Bounded::min_value` function. pub static min_value: $T = (-1 as $T) << (bits - 1); // FIXME(#9837): Compute min_value like this so the high bits that shouldn't exist are 0. +// FIXME(#11621): Should be deprecated once CTFE is implemented in favour of +// calling the `Bounded::max_value` function. pub static max_value: $T = !min_value; impl CheckedDiv for $T { @@ -361,16 +369,7 @@ impl Bounded for $T { impl Int for $T {} -impl Primitive for $T { - #[inline] - fn bits(_: Option<$T>) -> uint { bits } - - #[inline] - fn bytes(_: Option<$T>) -> uint { bits / 8 } - - #[inline] - fn is_signed(_: Option<$T>) -> bool { true } -} +impl Primitive for $T {} // String conversion functions and impl str -> num @@ -639,13 +638,6 @@ mod tests { assert_eq!((0b010101 as $T).population_count(), 3); } - #[test] - fn test_primitive() { - let none: Option<$T> = None; - assert_eq!(Primitive::bits(none), mem::size_of::<$T>() * 8); - assert_eq!(Primitive::bytes(none), mem::size_of::<$T>()); - } - #[test] fn test_from_str() { assert_eq!(from_str::<$T>("0"), Some(0 as $T)); diff --git a/src/libstd/num/mod.rs b/src/libstd/num/mod.rs index bcc95d6c48db2..bdbf0344b47eb 100644 --- a/src/libstd/num/mod.rs +++ b/src/libstd/num/mod.rs @@ -17,6 +17,7 @@ use clone::{Clone, DeepClone}; use cmp::{Eq, Ord}; +use mem::size_of; use ops::{Add, Sub, Mul, Div, Rem, Neg}; use ops::{Not, BitAnd, BitOr, BitXor, Shl, Shr}; use option::{Option, Some, None}; @@ -425,19 +426,7 @@ pub trait Primitive: Clone + Num + NumCast + Orderable - + Bounded - + Neg - + Add - + Sub - + Mul - + Div - + Rem { - // FIXME (#5527): These should be associated constants - // FIXME (#8888): Removing `unused_self` requires #8888 to be fixed. - fn bits(unused_self: Option) -> uint; - fn bytes(unused_self: Option) -> uint; - fn is_signed(unused_self: Option) -> bool; -} + + Bounded {} /// A collection of traits relevant to primitive signed and unsigned integers pub trait Int: Integer @@ -580,7 +569,7 @@ pub trait ToPrimitive { macro_rules! impl_to_primitive_int_to_int( ($SrcT:ty, $DstT:ty) => ( { - if Primitive::bits(None::<$SrcT>) <= Primitive::bits(None::<$DstT>) { + if size_of::<$SrcT>() <= size_of::<$DstT>() { Some(*self as $DstT) } else { let n = *self as i64; @@ -665,7 +654,7 @@ macro_rules! impl_to_primitive_uint_to_int( macro_rules! impl_to_primitive_uint_to_uint( ($SrcT:ty, $DstT:ty) => ( { - if Primitive::bits(None::<$SrcT>) <= Primitive::bits(None::<$DstT>) { + if size_of::<$SrcT>() <= size_of::<$DstT>() { Some(*self as $DstT) } else { let zero: $SrcT = Zero::zero(); @@ -721,7 +710,7 @@ impl_to_primitive_uint!(u64) macro_rules! impl_to_primitive_float_to_float( ($SrcT:ty, $DstT:ty) => ( - if Primitive::bits(None::<$SrcT>) <= Primitive::bits(None::<$DstT>) { + if size_of::<$SrcT>() <= size_of::<$DstT>() { Some(*self as $DstT) } else { let n = *self as f64; diff --git a/src/libstd/num/uint_macros.rs b/src/libstd/num/uint_macros.rs index 97e547a2d4280..1b822a491c6f3 100644 --- a/src/libstd/num/uint_macros.rs +++ b/src/libstd/num/uint_macros.rs @@ -285,16 +285,7 @@ impl ToStrRadix for $T { } } -impl Primitive for $T { - #[inline] - fn bits(_: Option<$T>) -> uint { bits } - - #[inline] - fn bytes(_: Option<$T>) -> uint { bits / 8 } - - #[inline] - fn is_signed(_: Option<$T>) -> bool { false } -} +impl Primitive for $T {} impl Bitwise for $T { /// Counts the number of bits set. Wraps LLVM's `ctpop` intrinsic. @@ -415,13 +406,6 @@ mod tests { assert_eq!((0b010101 as $T).population_count(), 3); } - #[test] - fn test_primitive() { - let none: Option<$T> = None; - assert_eq!(Primitive::bits(none), mem::size_of::<$T>() * 8); - assert_eq!(Primitive::bytes(none), mem::size_of::<$T>()); - } - #[test] pub fn test_to_str() { assert_eq!((0 as $T).to_str_radix(10u), ~"0"); diff --git a/src/test/bench/shootout-reverse-complement.rs b/src/test/bench/shootout-reverse-complement.rs index 161f23182d1e7..43167458e8600 100644 --- a/src/test/bench/shootout-reverse-complement.rs +++ b/src/test/bench/shootout-reverse-complement.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// xfail-android doesn't terminate? + use std::iter::range_step; use std::io::{stdin, stdout, File}; diff --git a/src/test/run-pass/macro-crate.rs b/src/test/run-pass-fulldeps/macro-crate.rs similarity index 100% rename from src/test/run-pass/macro-crate.rs rename to src/test/run-pass-fulldeps/macro-crate.rs