]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #23156 - GuillaumeGomez:remove-proc, r=alexcrichton
authorbors <bors@rust-lang.org>
Wed, 11 Mar 2015 23:51:30 +0000 (23:51 +0000)
committerbors <bors@rust-lang.org>
Wed, 11 Mar 2015 23:51:30 +0000 (23:51 +0000)
This is the implementation of the [RFC 584](https://github.com/rust-lang/rfcs/pull/584).

146 files changed:
README.md
configure
man/rustc.1
man/rustdoc.1
src/compiletest/compiletest.rs
src/compiletest/errors.rs
src/doc/complement-design-faq.md
src/doc/grammar.md
src/doc/intro.md
src/doc/reference.md
src/doc/style/errors/ergonomics.md
src/doc/trpl/SUMMARY.md
src/doc/trpl/concurrency.md
src/doc/trpl/crates-and-modules.md
src/doc/trpl/method-syntax.md
src/doc/trpl/more-strings.md
src/doc/trpl/plugins.md
src/doc/trpl/pointers.md
src/doc/trpl/traits.md
src/libarena/lib.rs
src/libcollections/enum_set.rs
src/libcollections/fmt.rs
src/libcollections/lib.rs
src/libcollections/slice.rs
src/libcollections/str.rs
src/libcollections/string.rs
src/libcollections/vec.rs
src/libcollections/vec_deque.rs
src/libcollections/vec_map.rs
src/libcore/cell.rs
src/libcore/char.rs
src/libcore/intrinsics.rs
src/libcore/iter.rs
src/libcore/marker.rs
src/libcore/num/mod.rs
src/libcore/num/wrapping.rs
src/libcore/result.rs
src/libcore/str/mod.rs
src/libcoretest/cell.rs
src/libcoretest/char.rs
src/libcoretest/finally.rs
src/libcoretest/fmt/num.rs
src/libcoretest/iter.rs
src/libcoretest/option.rs
src/libcoretest/result.rs
src/libgetopts/lib.rs
src/librand/distributions/exponential.rs
src/librand/distributions/gamma.rs
src/librand/distributions/mod.rs
src/librand/distributions/normal.rs
src/librand/distributions/range.rs
src/librand/isaac.rs
src/librustc/metadata/common.rs
src/librustc/metadata/creader.rs
src/librustc/metadata/csearch.rs
src/librustc/metadata/decoder.rs
src/librustc/metadata/encoder.rs
src/librustc/middle/check_match.rs
src/librustc/middle/const_eval.rs
src/librustc/middle/ty.rs
src/librustc/util/ppaux.rs
src/librustc_back/sha2.rs
src/librustc_bitflags/lib.rs
src/librustc_borrowck/borrowck/mod.rs
src/librustc_driver/driver.rs
src/librustc_driver/lib.rs
src/librustc_lint/builtin.rs
src/librustc_lint/lib.rs
src/librustc_trans/trans/expr.rs
src/librustc_typeck/astconv.rs
src/librustc_typeck/check/dropck.rs
src/librustc_typeck/check/mod.rs
src/librustc_typeck/check/regionck.rs
src/librustc_typeck/check/wf.rs
src/librustc_typeck/coherence/impls.rs [deleted file]
src/librustc_typeck/coherence/mod.rs
src/librustc_typeck/coherence/orphan.rs
src/librustc_typeck/coherence/overlap.rs
src/librustc_typeck/collect.rs
src/librustc_typeck/diagnostics.rs
src/librustdoc/html/render.rs
src/librustdoc/html/static/main.css
src/librustdoc/test.rs
src/libserialize/json.rs
src/libstd/collections/hash/map.rs
src/libstd/env.rs
src/libstd/fs/mod.rs
src/libstd/num/f32.rs
src/libstd/num/f64.rs
src/libstd/old_io/buffered.rs
src/libstd/old_io/extensions.rs
src/libstd/old_io/mod.rs
src/libstd/old_io/process.rs
src/libstd/old_io/timer.rs
src/libstd/old_path/windows.rs
src/libstd/process.rs
src/libstd/rand/mod.rs
src/libstd/rand/reader.rs
src/libstd/sync/condvar.rs
src/libstd/sync/future.rs
src/libstd/sync/mpsc/mod.rs
src/libstd/sync/task_pool.rs
src/libstd/sys/common/wtf8.rs
src/libstd/thread.rs
src/libsyntax/ast.rs
src/libsyntax/ast_map/mod.rs
src/libsyntax/codemap.rs
src/libsyntax/ext/expand.rs
src/libsyntax/feature_gate.rs
src/libsyntax/parse/mod.rs
src/libsyntax/test.rs
src/libsyntax/util/interner.rs
src/libsyntax/util/small_vector.rs
src/libterm/lib.rs
src/libtest/lib.rs
src/libunicode/char.rs [new file with mode: 0644]
src/libunicode/lib.rs
src/libunicode/u_char.rs [deleted file]
src/libunicode/u_str.rs
src/snapshots.txt
src/test/auxiliary/typeck-default-trait-impl-cross-crate-coherence-lib.rs [new file with mode: 0644]
src/test/compile-fail-fulldeps/gated-quote.rs [new file with mode: 0644]
src/test/compile-fail/coherence-impls-builtin.rs [deleted file]
src/test/compile-fail/coherence-impls-copy.rs [new file with mode: 0644]
src/test/compile-fail/coherence-impls-send.rs [new file with mode: 0644]
src/test/compile-fail/coherence-impls-sized.rs [new file with mode: 0644]
src/test/compile-fail/coherence-orphan.rs
src/test/compile-fail/gated-link-args.rs [new file with mode: 0644]
src/test/compile-fail/gated-link-llvm-intrinsics.rs [new file with mode: 0644]
src/test/compile-fail/gated-plugin_registrar.rs
src/test/compile-fail/gated-thread-local.rs [new file with mode: 0644]
src/test/compile-fail/gated-unsafe-destructor.rs [new file with mode: 0644]
src/test/compile-fail/typeck-default-trait-impl-cross-crate-coherence.rs [new file with mode: 0644]
src/test/compile-fail/typeck-default-trait-impl-outside-crate.rs
src/test/run-fail/test-should-fail-bad-message.rs
src/test/run-make/bare-outfile/Makefile [new file with mode: 0644]
src/test/run-make/bare-outfile/foo.rs [new file with mode: 0644]
src/test/run-make/unicode-input/span_length.rs
src/test/run-pass/issue-4759-1.rs
src/test/run-pass/struct-order-of-eval-1.rs
src/test/run-pass/struct-order-of-eval-2.rs
src/test/run-pass/struct-order-of-eval-3.rs [new file with mode: 0644]
src/test/run-pass/struct-order-of-eval-4.rs [new file with mode: 0644]
src/test/run-pass/test-should-fail-good-message.rs
src/test/run-pass/unsized.rs
src/test/run-pass/unsized2.rs

index c88c237cbee896985663697ed030b018393d8e89..93f0daa7141f575fd5563643a1514b47fc1a0607 100644 (file)
--- a/README.md
+++ b/README.md
@@ -115,7 +115,7 @@ The Rust community congregates in a few places:
 
 ## Contributing
 
-To contribute to Rust, please see [CONTRIBUTING.md](CONTRIBUTING.md).
+To contribute to Rust, please see [CONTRIBUTING](CONTRIBUTING.md).
 
 Rust has an [IRC] culture and most real-time collaboration happens in a
 variety of channels on Mozilla's IRC network, irc.mozilla.org. The
@@ -131,4 +131,4 @@ Rust is primarily distributed under the terms of both the MIT license
 and the Apache License (Version 2.0), with portions covered by various
 BSD-like licenses.
 
-See LICENSE-APACHE, LICENSE-MIT, and COPYRIGHT for details.
+See [LICENSE-APACHE](LICENSE-APACHE), [LICENSE-MIT](LICENSE-MIT), and [COPYRIGHT](COPYRIGHT) for details.
index d56000b14e25509beeadb66e118f0443b284c628..b0d0c3f29b84a3e6f1f623c54a983b231accd662 100755 (executable)
--- a/configure
+++ b/configure
@@ -701,8 +701,8 @@ probe CFG_ADB        adb
 
 if [ ! -z "$CFG_PANDOC" ]
 then
+    # Extract "MAJOR MINOR" from Pandoc's version number
     PV_MAJOR_MINOR=$(pandoc --version | grep '^pandoc' |
-        # Extract "MAJOR MINOR" from Pandoc's version number
         sed -E 's/pandoc(.exe)? ([0-9]+)\.([0-9]+).*/\2 \3/')
 
     MIN_PV_MAJOR="1"
index 49056afa045abb46f7e970696fd03f6ec1ef0b24..f37e66001909305143f627359a9f392adbbfeb6d 100644 (file)
@@ -7,224 +7,267 @@ rustc \- The Rust compiler
 
 .SH DESCRIPTION
 This program is a compiler for the Rust language, available at
-<\fBhttps://www.rust-lang.org\fR>.
+.UR https://www.rust\-lang.org
+.UE .
 
 .SH OPTIONS
 
 .TP
 \fB\-h\fR, \fB\-\-help\fR
-Display the help message
+Display the help message.
 .TP
-\fB\-\-cfg\fR SPEC
-Configure the compilation environment
+\fB\-\-cfg\fR \fISPEC\fR
+Configure the compilation environment.
 .TP
-\fB\-L\fR [KIND=]PATH
-Add a directory to the library search path. The optional KIND can be one of:
-    dependency = only lookup transitive dependencies here
-    crate = only lookup local `extern crate` directives here
-    native = only lookup native libraries here
-    framework = only look for OSX frameworks here
-    all = look for anything here (the default)
+\fB\-L\fR [\fIKIND\fR=]\fIPATH\fR
+Add a directory to the library search path.
+The optional \fIKIND\fR can be one of:
+.RS
 .TP
-\fB\-l\fR [KIND=]NAME
-Link the generated crate(s) to the specified native library NAME. The optional
-KIND can be one of, static, dylib, or framework. If omitted, dylib is assumed.
+\fBdependency\fR
+only lookup transitive dependencies here
 .TP
-\fB\-\-crate-type\fR [bin|lib|rlib|dylib|staticlib]
-Comma separated list of types of crates for the compiler to emit
+.B crate
+only lookup local `extern crate` directives here
 .TP
-\fB\-\-crate-name NAME\fR
-Specify the name of the crate being built
+.B native
+only lookup native libraries here
 .TP
-\fB\-\-emit\fR [asm|llvm-bc|llvm-ir|obj|link|dep-info]
-Configure the output that rustc will produce
+.B framework
+only look for OSX frameworks here
 .TP
-\fB\-\-print\fR [crate-name|file-names|sysroot]
-Comma separated list of compiler information to print on stdout
+.B all
+look for anything here (the default)
+.RE
+.TP
+\fB\-l\fR [\fIKIND\fR=]\fINAME\fR
+Link the generated crate(s) to the specified native library \fINAME\fR.
+The optional \fIKIND\fR can be one of \fIstatic\fR, \fIdylib\fR, or
+\fIframework\fR.
+If omitted, \fIdylib\fR is assumed.
+.TP
+\fB\-\-crate\-type\fR [bin|lib|rlib|dylib|staticlib]
+Comma separated list of types of crates for the compiler to emit.
+.TP
+\fB\-\-crate\-name\fR \fINAME\fR
+Specify the name of the crate being built.
+.TP
+\fB\-\-emit\fR [asm|llvm\-bc|llvm\-ir|obj|link|dep\-info]
+Configure the output that \fBrustc\fR will produce.
+.TP
+\fB\-\-print\fR [crate\-name|file\-names|sysroot]
+Comma separated list of compiler information to print on stdout.
 .TP
 \fB\-g\fR
-Equivalent to \fI\-C\fR debuginfo=2
+Equivalent to \fI\-C\ debuginfo=2\fR.
 .TP
 \fB\-O\fR
-Equivalent to \fI\-C\fR opt-level=2
+Equivalent to \fI\-C\ opt\-level=2\fR.
 .TP
-\fB\-o\fR FILENAME
-Write output to <filename>. Ignored if multiple \fI\-\-emit\fR outputs are
-specified.
+\fB\-o\fR \fIFILENAME\fR
+Write output to \fIFILENAME\fR.
+Ignored if multiple \fI\-\-emit\fR outputs are specified.
 .TP
-\fB\-\-out\-dir\fR DIR
-Write output to compiler-chosen filename in <dir>. Ignored if \fI\-o\fR is
-specified. Defaults to the current directory.
+\fB\-\-out\-dir\fR \fIDIR\fR
+Write output to compiler\[hy]chosen filename in \fIDIR\fR.
+Ignored if \fI\-o\fR is specified.
+Defaults to the current directory.
 .TP
-\fB\-\-explain\fR OPT
-Provide a detailed explanation of an error message
+\fB\-\-explain\fR \fIOPT\fR
+Provide a detailed explanation of an error message.
 .TP
 \fB\-\-test\fR
-Build a test harness
+Build a test harness.
 .TP
-\fB\-\-target\fR TRIPLE
-Target triple cpu-manufacturer-kernel[-os] to compile for (see chapter 3.4 of
-http://www.sourceware.org/autobook/ for details)
+\fB\-\-target\fR \fITRIPLE\fR
+Target triple \fIcpu\fR\-\fImanufacturer\fR\-\fIkernel\fR[\-\fIos\fR]
+to compile for (see chapter 3.4 of
+.UR http://www.sourceware.org/autobook/
+.UE
+for details).
 .TP
-\fB\-W\fR help
-Print 'lint' options and default settings
+\fB\-W help\fR
+Print 'lint' options and default settings.
 .TP
-\fB\-W\fR OPT, \fB\-\-warn\fR OPT
-Set lint warnings
+\fB\-W\fR \fIOPT\fR, \fB\-\-warn\fR \fIOPT\fR
+Set lint warnings.
 .TP
-\fB\-A\fR OPT, \fB\-\-allow\fR OPT
-Set lint allowed
+\fB\-A\fR \fIOPT\fR, \fB\-\-allow\fR \fIOPT\fR
+Set lint allowed.
 .TP
-\fB\-D\fR OPT, \fB\-\-deny\fR OPT
-Set lint denied
+\fB\-D\fR \fIOPT\fR, \fB\-\-deny\fR \fIOPT\fR
+Set lint denied.
 .TP
-\fB\-F\fR OPT, \fB\-\-forbid\fR OPT
-Set lint forbidden
+\fB\-F\fR \fIOPT\fR, \fB\-\-forbid\fR \fIOPT\fR
+Set lint forbidden.
 .TP
-\fB\-C\fR FLAG[=VAL], \fB\-\-codegen\fR FLAG[=VAL]
-Set a codegen-related flag to the value specified. Use "-C help" to print
-available flags. See CODEGEN OPTIONS below
+\fB\-C\fR \fIFLAG\fR[=\fIVAL\fR], \fB\-\-codegen\fR \fIFLAG\fR[=\fIVAL\fR]
+Set a codegen\[hy]related flag to the value specified.
+Use \fI\-C help\fR to print available flags.
+See CODEGEN OPTIONS below.
 .TP
 \fB\-V\fR, \fB\-\-version\fR
-Print version info and exit
+Print version info and exit.
 .TP
 \fB\-v\fR, \fB\-\-verbose\fR
-Use verbose output
+Use verbose output.
 .TP
-\fB\-\-extern\fR NAME=PATH
-Specify where an external rust library is located
+\fB\-\-extern\fR \fINAME\fR=\fIPATH\fR
+Specify where an external rust library is located.
 .TP
-\fB\-\-sysroot\fR PATH
-Override the system root
+\fB\-\-sysroot\fR \fIPATH\fR
+Override the system root.
 .TP
-\fB\-Z\fR FLAG
-Set internal debugging options. Use "-Z help" to print available options.
+\fB\-Z\fR \fIFLAG\fR
+Set internal debugging options.
+Use \fI\-Z help\fR to print available options.
 .TP
 \fB\-\-color\fR auto|always|never
 Configure coloring of output:
-    auto = colorize, if output goes to a tty (default);
-    always = always colorize output;
-    never = never colorize output
+.RS
+.TP
+.B auto
+colorize, if output goes to a tty (default);
+.TP
+.B always
+always colorize output;
+.TP
+.B never
+never colorize output.
+.RE
 
 .SH CODEGEN OPTIONS
 
 .TP
-\fBar\fR=/path/to/ar
+\fBar\fR=\fI/path/to/ar\fR
 Path to the archive utility to use when assembling archives.
 .TP
-\fBlinker\fR=/path/to/cc
+\fBlinker\fR=\fI/path/to/cc\fR
 Path to the linker utility to use when linking libraries, executables, and
 objects.
 .TP
-\fBlink-args\fR='-flag1 -flag2'
-A space-separated list of extra arguments to pass to the linker when the linker
+\fBlink\-args\fR='\fI\-flag1 \-flag2\fR'
+A space\[hy]separated list of extra arguments to pass to the linker when the linker
 is invoked.
 .TP
 \fBlto\fR
-Perform LLVM link-time optimizations.
+Perform LLVM link\[hy]time optimizations.
 .TP
-\fBtarget-cpu\fR=help
-Selects a target processor. If the value is 'help', then a list of available
-CPUs is printed.
+\fBtarget\-cpu\fR=\fIhelp\fR
+Selects a target processor.
+If the value is 'help', then a list of available CPUs is printed.
 .TP
-\fBtarget-feature\fR='+feature1,-feature2'
-A comma-separated list of features to enable or disable for the target. A
-preceding '+' enables a feature while a preceding '-' disables it. Available
-features can be discovered through target-cpu=help.
+\fBtarget\-feature\fR='\fI+feature1\fR,\fI\-feature2\fR'
+A comma\[hy]separated list of features to enable or disable for the target.
+A preceding '+' enables a feature while a preceding '\-' disables it.
+Available features can be discovered through \fItarget\-cpu=help\fR.
 .TP
-\fBpasses\fR=list
-A space-separated list of extra LLVM passes to run. A value of 'list' will
-cause rustc to print all known passes and exit. The passes specified are
-appended at the end of the normal pass manager.
+\fBpasses\fR=\fIval\fR
+A space\[hy]separated list of extra LLVM passes to run.
+A value of 'list' will cause \fBrustc\fR to print all known passes and
+exit.
+The passes specified are appended at the end of the normal pass manager.
 .TP
-\fBllvm-args\fR='-arg1 -arg2'
-A space-separated list of arguments to pass through to LLVM.
+\fBllvm\-args\fR='\fI\-arg1\fR \fI\-arg2\fR'
+A space\[hy]separated list of arguments to pass through to LLVM.
 .TP
-\fBsave-temps\fR
-If specified, the compiler will save more files (.bc, .o, .no-opt.bc) generated
+\fBsave\-temps\fR
+If specified, the compiler will save more files (.bc, .o, .no\-opt.bc) generated
 throughout compilation in the output directory.
 .TP
 \fBrpath\fR
 If specified, then the rpath value for dynamic libraries will be set in
 either dynamic library or executable outputs.
 .TP
-\fBno-prepopulate-passes\fR
-Suppresses pre-population of the LLVM pass manager that is run over the module.
+\fBno\-prepopulate\-passes\fR
+Suppresses pre\[hy]population of the LLVM pass manager that is run over the module.
 .TP
-\fBno-vectorize-loops\fR
+\fBno\-vectorize\-loops\fR
 Suppresses running the loop vectorization LLVM pass, regardless of optimization
 level.
 .TP
-\fBno-vectorize-slp\fR
+\fBno\-vectorize\-slp\fR
 Suppresses running the LLVM SLP vectorization pass, regardless of optimization
 level.
 .TP
-\fBsoft-float\fR
+\fBsoft\-float\fR
 Generates software floating point library calls instead of hardware
 instructions.
 .TP
-\fBprefer-dynamic\fR
+\fBprefer\-dynamic\fR
 Prefers dynamic linking to static linking.
 .TP
-\fBno-integrated-as\fR
+\fBno\-integrated\-as\fR
 Force usage of an external assembler rather than LLVM's integrated one.
 .TP
-\fBno-redzone\fR
+\fBno\-redzone\fR
 Disable the use of the redzone.
 .TP
-\fBrelocation-model\fR=[pic,static,dynamic-no-pic]
-The relocation model to use. (Default: pic)
+\fBrelocation\-model\fR=[pic,static,dynamic\-no\-pic]
+The relocation model to use.
+(Default: \fIpic\fR)
 .TP
-\fBcode-model\fR=[small,kernel,medium,large]
+\fBcode\-model\fR=[small,kernel,medium,large]
 Choose the code model to use.
 .TP
-\fBmetadata\fR=val
+\fBmetadata\fR=\fIval\fR
 Metadata to mangle symbol names with.
 .TP
-\fBextra-filename\fR=val
+\fBextra\-filename\fR=\fIval\fR
 Extra data to put in each output filename.
 .TP
-\fBcodegen-units\fR=val
-Divide crate into N units to optimize in parallel.
+\fBcodegen\-units\fR=\fIn\fR
+Divide crate into \fIn\fR units to optimize in parallel.
 .TP
-\fBremark\fR=val
+\fBremark\fR=\fIval\fR
 Print remarks for these optimization passes (space separated, or "all").
 .TP
-\fBno-stack-check\fR
-Disable checks for stack exhaustion (a memory-safety hazard!).
+\fBno\-stack\-check\fR
+Disable checks for stack exhaustion (a memory\[hy]safety hazard!).
 .TP
-\fBdebuginfo\fR=val
+\fBdebuginfo\fR=\fIval\fR
 Debug info emission level:
-    0 = no debug info;
-    1 = line-tables only (for stacktraces and breakpoints);
-    2 = full debug info with variable and type information.
+.RS
+.TP
+.B 0
+no debug info;
+.TP
+.B 1
+line\[hy]tables only (for stacktraces and breakpoints);
+.TP
+.B 2
+full debug info with variable and type information.
+.RE
 .TP
-\fBopt-level\fR=val
-Optimize with possible levels 0-3
+\fBopt\-level\fR=\fIVAL\fR
+Optimize with possible levels 0\[en]3
 
 .SH "EXAMPLES"
 To build an executable from a source file with a main function:
-    $ rustc -o hello hello.rs
+    $ rustc \-o hello hello.rs
 
 To build a library from a source file:
-    $ rustc --crate-type=lib hello-lib.rs
+    $ rustc \-\-crate\-type=lib hello\-lib.rs
 
 To build either with a crate (.rs) file:
     $ rustc hello.rs
 
 To build an executable with debug info:
-    $ rustc -g -o hello hello.rs
+    $ rustc \-g \-o hello hello.rs
 
 .SH "SEE ALSO"
 
-rustdoc
+.BR rustdoc (1)
 
 .SH "BUGS"
-See <\fBhttps://github.com/rust-lang/rust/issues\fR> for issues.
+See
+.UR https://github.com/rust\-lang/rust/issues
+.UE
+for issues.
 
 .SH "AUTHOR"
-See \fBAUTHORS.txt\fR in the Rust source distribution.
+See \fIAUTHORS.txt\fR in the Rust source distribution.
 
 .SH "COPYRIGHT"
-This work is dual-licensed under Apache 2.0 and MIT terms.  See \fBCOPYRIGHT\fR
-file in the rust source distribution.
+This work is dual\[hy]licensed under Apache\ 2.0 and MIT terms.
+See \fICOPYRIGHT\fR file in the rust source distribution.
index 830884b19bde204400dc43c82c372a34932305cb..1738354fb43d50b6d01376755e688d54925f1680 100644 (file)
@@ -8,76 +8,79 @@ rustdoc \- generate documentation from Rust source code
 .SH DESCRIPTION
 This tool generates API reference documentation by extracting comments from
 source code written in the Rust language, available at
-<\fBhttps://www.rust-lang.org\fR>. It accepts several input formats and provides
-several output formats for the generated documentation.
+.UR https://www.rust\-lang.org
+.UE .
+It accepts several input formats and provides several output formats
+for the generated documentation.
 
 .SH OPTIONS
 
 .TP
--r --input-format <val>
+\fB\-r\fR, \fB\-\-input\-format\fR \fIFORMAT\fR
 html or json (default: inferred)
 .TP
--w --output-format <val>
+\fB\-w\fR, \fB\-\-output\-format\fR \fIFORMAT\fR
 html or json (default: html)
 .TP
--o --output <val>
-where to place the output (default: doc/ for html, doc.json for json)
+\fB\-o\fR, \fB\-\-output\fR \fIOUTPUT\fR
+where to place the output (default: \fIdoc/\fR for html,
+\fIdoc.json\fR for json)
 .TP
---passes <val>
-space-separated list of passes to run (default: '')
+\fB\-\-passes\fR \fILIST\fR
+space\[hy]separated list of passes to run (default: '')
 .TP
---no-defaults
+\fB\-\-no\-defaults\fR
 don't run the default passes
 .TP
---plugins <val>
+\fB\-\-plugins\fR \fILIST\fR
 space-separated list of plugins to run (default: '')
 .TP
---plugin-path <val>
-directory to load plugins from (default: /tmp/rustdoc_ng/plugins)
+\fB\-\-plugin\-path\fR \fIDIR\fR
+directory to load plugins from (default: \fI/tmp/rustdoc_ng/plugins\fR)
 .TP
---target <val>
+\fB\-\-target\fR \fITRIPLE\fR
 target triple to document
 .TP
---crate-name <val>
+\fB\-\-crate\-name\fR \fINAME\fR
 specify the name of this crate
 .TP
--L --library-path <val>
+\fB\-L\fR, \fB\-\-library\-path\fR \fIDIR\fR
 directory to add to crate search path
 .TP
---cfg <val>
-pass a --cfg to rustc
+\fB\-\-cfg\fR \fISPEC\fR
+pass a \fI\-\-cfg\fR to rustc
 .TP
---extern <val>
-pass an --extern to rustc
+\fB\-\-extern\fR \fIVAL\fR
+pass an \fI\-\-extern\fR to rustc
 .TP
---test
+\fB\-\-test\fR
 run code examples as tests
 .TP
---test-args <val>
+\fB\-\-test\-args\fR \fIARGS\fR
 pass arguments to the test runner
 .TP
---html-in-header <val>
+\fB\-\-html\-in\-header\fR \fIFILE\fR
 file to add to <head>
 .TP
---html-before-content <val>
+\fB\-\-html\-before\-content\fR \fIFILE\fR
 file to add in <body>, before content
 .TP
---html-after-content <val>
+\fB\-\-html\-after\-content\fR \fIFILE\fR
 file to add in <body>, after content
 .TP
---markdown-css <val>
+\fB\-\-markdown\-css\fR \fIFILE\fR
 CSS files to include via <link> in a rendered Markdown file
 .TP
---markdown-playground-url <val>
+\fB\-\-markdown\-playground\-url\fR \fIURL\fR
 URL to send code snippets to
 .TP
---markdown-no-toc
+\fB\-\-markdown\-no\-toc\fR
 don't include table of contents
 .TP
--h, --help
+\fB\-h\fR, \fB\-\-help\fR
 Print help
 .TP
--V, --version
+\fB\-V\fR, \fB\-\-version\fR
 Print rustdoc's version
 
 .SH "OUTPUT FORMATS"
@@ -85,14 +88,15 @@ Print rustdoc's version
 The rustdoc tool can generate output in either an HTML or JSON format.
 
 If using an HTML format, then the specified output destination will be the root
-directory of an HTML structure for all the documentation. Pages will be placed
-into this directory, and source files will also possibly be rendered into it as
-well.
+directory of an HTML structure for all the documentation.
+Pages will be placed into this directory, and source files will also
+possibly be rendered into it as well.
 
 If using a JSON format, then the specified output destination will have the
-rustdoc output serialized as JSON into it. This output format exists to
-pre-compile documentation for crates, and for usage in non-rustdoc tools. The
-JSON output is the following hash:
+rustdoc output serialized as JSON into it.
+This output format exists to pre\[hy]compile documentation for crates,
+and for usage in non\[hy]rustdoc tools.
+The JSON output is the following hash:
 
     {
         "schema": VERSION,
@@ -100,11 +104,12 @@ JSON output is the following hash:
         "plugins": ...,
     }
 
-The schema version indicates what the structure of crate/plugins will look
-like. Within a schema version the structure will remain the same. The `crate`
-field will contain all relevant documentation for the source being documented,
-and the `plugins` field will contain the output of the plugins run over the
-crate.
+The schema version indicates what the structure of crate/plugins will
+look like.
+Within a schema version the structure will remain the same.
+The \fIcrate\fR field will contain all relevant documentation for the
+source being documented, and the \fIplugins\fR field will contain the
+output of the plugins run over the crate.
 
 .SH "EXAMPLES"
 
@@ -112,25 +117,28 @@ To generate documentation for the source in the current directory:
     $ rustdoc hello.rs
 
 List all available passes that rustdoc has, along with default passes:
-    $ rustdoc --passes list
+    $ rustdoc \-\-passes list
 
 To precompile the documentation for a crate, and then use it to render html at
 a later date:
-    $ rustdoc -w json hello.rs
+    $ rustdoc \-w json hello.rs
     $ rustdoc doc.json
 
 The generated HTML can be viewed with any standard web browser.
 
 .SH "SEE ALSO"
 
-rustc
+.BR rustc (1)
 
 .SH "BUGS"
-See <\fBhttps://github.com/rust-lang/rust/issues\fR> for issues.
+See
+.UR https://github.com/rust\-lang/rust/issues
+.UE
+for issues.
 
 .SH "AUTHOR"
-See \fBAUTHORS.txt\fR in the Rust source distribution.
+See \fIAUTHORS.txt\fR in the Rust source distribution.
 
 .SH "COPYRIGHT"
-This work is dual-licensed under Apache 2.0 and MIT terms.  See \fBCOPYRIGHT\fR
-file in the rust source distribution.
+This work is dual\[hy]licensed under Apache\ 2.0 and MIT terms.
+See \fICOPYRIGHT\fR file in the rust source distribution.
index 073f16e354d3a4eada298ca9503a4e1c9c66e17a..e32dacd2e6aaa5ff1d2c8aa31a5e95b536e7af5d 100644 (file)
@@ -19,7 +19,6 @@
 #![feature(unboxed_closures)]
 #![feature(std_misc)]
 #![feature(test)]
-#![feature(unicode)]
 #![feature(core)]
 #![feature(path)]
 #![feature(io)]
@@ -332,7 +331,7 @@ pub fn make_test<F>(config: &Config, testfile: &Path, f: F) -> test::TestDescAnd
         desc: test::TestDesc {
             name: make_test_name(config, testfile),
             ignore: header::is_test_ignored(config, testfile),
-            should_fail: test::ShouldFail::No,
+            should_panic: test::ShouldPanic::No,
         },
         testfn: f(),
     }
index 25f962c5785a175654e5511d3d827604057ad9dd..2b0e7985229e2bd85e81ba97b5a0b8c05b52dc35 100644 (file)
@@ -71,7 +71,7 @@ fn parse_expected(last_nonfollow_error: Option<uint>,
     let letters = line[kind_start..].chars();
     let kind = letters.skip_while(|c| c.is_whitespace())
                       .take_while(|c| !c.is_whitespace())
-                      .map(|c| c.to_lowercase())
+                      .flat_map(|c| c.to_lowercase())
                       .collect::<String>();
     let letters = line[kind_start..].chars();
     let msg = letters.skip_while(|c| c.is_whitespace())
index e57953db3a256fd2463ad6a04d3015dccd830c96..3edbcbe62c51172ea225fa122e62add202f9657b 100644 (file)
@@ -174,3 +174,10 @@ bindings.
 See also [a long thread][alt] on renaming `let mut` to `var`.
 
 [alt]: https://mail.mozilla.org/pipermail/rust-dev/2014-January/008319.html
+
+## Why no `--x` or `x++`?
+
+Preincrement and postincrement, while convenient, are also fairly complex. They
+require knowledge of evaluation order, and often lead to subtle bugs and
+undefined behavior in C and C++. `x = x + 1` or `x += 1` is only slightly
+longer, but unambiguous.
index d7a29ea530952a4f28a934c0834fce2558f7e845..68ca1cb72170ad1b7507da0bb78fc0b30ee7925a 100644 (file)
@@ -514,7 +514,7 @@ field_expr : expr '.' ident ;
 ### Array expressions
 
 ```antlr
-array_expr : '[' "mut" ? vec_elems? ']' ;
+array_expr : '[' "mut" ? array_elems? ']' ;
 
 array_elems : [expr [',' expr]*] | [expr ',' ".." expr] ;
 ```
index bb86de64e7af3bd3ef098c16d0f1d43bc748edcd..9e575abeee2173d415e7064599c89f30c86614d6 100644 (file)
@@ -389,11 +389,11 @@ safe concurrent programs.
 Here's an example of a concurrent Rust program:
 
 ```{rust}
-use std::thread::Thread;
+use std::thread;
 
 fn main() {
     let guards: Vec<_> = (0..10).map(|_| {
-        Thread::scoped(|| {
+        thread::scoped(|| {
             println!("Hello, world!");
         })
     }).collect();
@@ -421,16 +421,16 @@ problem.
 Let's see an example. This Rust code will not compile:
 
 ```{rust,ignore}
-use std::thread::Thread;
+use std::thread;
 
 fn main() {
     let mut numbers = vec![1, 2, 3];
 
     let guards: Vec<_> = (0..3).map(|i| {
-        Thread::scoped(move || {
+        thread::scoped(move || {
             numbers[i] += 1;
             println!("numbers[{}] is {}", i, numbers[i]);
-        });
+        })
     }).collect();
 }
 ```
@@ -439,10 +439,10 @@ It gives us this error:
 
 ```text
 7:25: 10:6 error: cannot move out of captured outer variable in an `FnMut` closure
-7     Thread::scoped(move || {
+7     thread::scoped(move || {
 8       numbers[i] += 1;
 9       println!("numbers[{}] is {}", i, numbers[i]);
-10     });
+10     })
 error: aborting due to previous error
 ```
 
@@ -471,7 +471,7 @@ mutation doesn't cause a data race.
 Here's what using an Arc with a Mutex looks like:
 
 ```{rust}
-use std::thread::Thread;
+use std::thread;
 use std::sync::{Arc,Mutex};
 
 fn main() {
@@ -479,11 +479,11 @@ fn main() {
 
     let guards: Vec<_> = (0..3).map(|i| {
         let number = numbers.clone();
-        Thread::scoped(move || {
+        thread::scoped(move || {
             let mut array = number.lock().unwrap();
             array[i] += 1;
             println!("numbers[{}] is {}", i, array[i]);
-        });
+        })
     }).collect();
 }
 ```
@@ -535,15 +535,15 @@ As an example, Rust's ownership system is _entirely_ at compile time. The
 safety check that makes this an error about moved values:
 
 ```{rust,ignore}
-use std::thread::Thread;
+use std::thread;
 
 fn main() {
     let numbers = vec![1, 2, 3];
 
     let guards: Vec<_> = (0..3).map(|i| {
-        Thread::scoped(move || {
+        thread::scoped(move || {
             println!("{}", numbers[i]);
-        });
+        })
     }).collect();
 }
 ```
index a772d98583e499f091b6fc3d8dda54fcfebe41e8..4f5f2a631adef5ba8e27c8858f72e861b2572f05 100644 (file)
@@ -229,14 +229,14 @@ cases mentioned in [Number literals](#number-literals) below.
 
 ##### Characters and strings
 
-|   | Example | Number of `#` pairs allowed | Available characters | Escapes | Equivalent to |
-|---|---------|-----------------------------|----------------------|---------|---------------|
-| [Character](#character-literals) | `'H'` | `N/A` | All unicode | `\'` & [Byte escapes](#byte-escapes) & [Unicode escapes](#unicode-escapes) | `N/A` |
-| [String](#string-literals) | `"hello"` | `N/A` | All unicode | `\"` & [Byte escapes](#byte-escapes) & [Unicode escapes](#unicode-escapes) | `N/A` |
-| [Raw](#raw-string-literals) | `r##"hello"##`  | `0...` | All unicode | `N/A` | `N/A` |
-| [Byte](#byte-literals) | `b'H'` | `N/A` | All ASCII | `\'` & [Byte escapes](#byte-escapes) | `u8` |
-| [Byte string](#byte-string-literals) | `b"hello"` | `N/A`  | All ASCII | `\"` & [Byte escapes](#byte-escapes) | `&'static [u8]` |
-| [Raw byte string](#raw-byte-string-literals) | `br##"hello"##` | `0...` | All ASCII | `N/A` | `&'static [u8]` (unsure...not stated) |
+|                                              | Example       | # sets | Characters  | Escapes             |
+|----------------------------------------------|---------------|--------|-------------|---------------------|
+| [Character](#character-literals)             | 'H'           | N/A    | All Unicode | \' & [Byte](#byte-escapes) & [Unicode](#unicode-escapes) |
+| [String](#string-literals)                   | "hello"       | N/A    | All Unicode | \" & [Byte](#byte-escapes) & [Unicode](#unicode-escapes) |
+| [Raw](#raw-string-literals)                  | r#"hello"#    | 0...   | All Unicode | N/A                                                      |
+| [Byte](#byte-literals)                       | b'H'          | N/A    | All ASCII   | \' & [Byte](#byte-escapes)                               |
+| [Byte string](#byte-string-literals)         | b"hello"      | N/A    | All ASCII   | \" & [Byte](#byte-escapes)                               |
+| [Raw byte string](#raw-byte-string-literals) | br#"hello"#   | 0...   | All ASCII   | N/A                                                      |
 
 ##### Byte escapes
 
@@ -2847,7 +2847,7 @@ automatically dereferenced to make the field access possible.
 ### Array expressions
 
 ```{.ebnf .gram}
-array_expr : '[' "mut" ? vec_elems? ']' ;
+array_expr : '[' "mut" ? array_elems? ']' ;
 
 array_elems : [expr [',' expr]*] | [expr ';' expr] ;
 ```
@@ -3007,10 +3007,6 @@ A type cast expression is denoted with the binary operator `as`.
 Executing an `as` expression casts the value on the left-hand side to the type
 on the right-hand side.
 
-A numeric value can be cast to any numeric type. A raw pointer value can be
-cast to or from any integral type or raw pointer type. Any other cast is
-unsupported and will fail to compile.
-
 An example of an `as` expression:
 
 ```
index 33f1e82b187e7ddb6ee68fa2465e131e16a0435e..d2fcf27e93cdf540627bf9e2c2e1255183493882 100644 (file)
@@ -22,9 +22,9 @@ fn write_info(info: &Info) -> Result<(), IoError> {
     let mut file = File::open_mode(&Path::new("my_best_friends.txt"),
                                    Open, Write);
     // Early return on error
-    try!(file.write_line(format!("name: {}", info.name).as_slice()));
-    try!(file.write_line(format!("age: {}", info.age).as_slice()));
-    try!(file.write_line(format!("rating: {}", info.rating).as_slice()));
+    try!(file.write_line(&format!("name: {}", info.name)));
+    try!(file.write_line(&format!("age: {}", info.age)));
+    try!(file.write_line(&format!("rating: {}", info.rating)));
     return Ok(());
 }
 ```
@@ -44,15 +44,15 @@ fn write_info(info: &Info) -> Result<(), IoError> {
     let mut file = File::open_mode(&Path::new("my_best_friends.txt"),
                                    Open, Write);
     // Early return on error
-    match file.write_line(format!("name: {}", info.name).as_slice()) {
+    match file.write_line(&format!("name: {}", info.name)) {
         Ok(_) => (),
         Err(e) => return Err(e)
     }
-    match file.write_line(format!("age: {}", info.age).as_slice()) {
+    match file.write_line(&format!("age: {}", info.age)) {
         Ok(_) => (),
         Err(e) => return Err(e)
     }
-    return file.write_line(format!("rating: {}", info.rating).as_slice());
+    return file.write_line(&format!("rating: {}", info.rating));
 }
 ```
 
index d57aff7f4f411fbc9974666127a02150b324301d..c65389287fbb8a19e4202689b8ea9d0d242dab7a 100644 (file)
     * [Standard Input](standard-input.md)
     * [Guessing Game](guessing-game.md)
 * [II: Intermediate Rust](intermediate.md)
-    * [More Strings](more-strings.md)
     * [Crates and Modules](crates-and-modules.md)
     * [Testing](testing.md)
     * [Pointers](pointers.md)
     * [Ownership](ownership.md)
+    * [More Strings](more-strings.md)
     * [Patterns](patterns.md)
     * [Method Syntax](method-syntax.md)
     * [Closures](closures.md)
index 842957bd601c61cd59fc479fce93e4d17659dd1b..9b6d6ca67f6c840c2328e986ed03ed9696e724a9 100644 (file)
@@ -223,15 +223,8 @@ method which has this signature:
 fn lock(&self) -> LockResult<MutexGuard<T>>
 ```
 
-If we [look at the code for MutexGuard](https://github.com/rust-lang/rust/blob/ca4b9674c26c1de07a2042cb68e6a062d7184cef/src/libstd/sync/mutex.rs#L172), we'll see
-this:
-
-```ignore
-__marker: marker::NoSend,
-```
-
-Because our guard is `NoSend`, it's not `Send`. Which means we can't actually
-transfer the guard across thread boundaries, which gives us our error.
+Because `Send` is not implemented for `MutexGuard<T>`, we can't transfer the
+guard across thread boundaries, which gives us our error.
 
 We can use `Arc<T>` to fix this. Here's the working version:
 
index f3c0195855c3436baecae176038888e748f96b96..8eaad5067f09e7dc84fc653d4be4c0ed6e791fde 100644 (file)
@@ -555,6 +555,13 @@ Here we have a `pub use` for each function we want to bring into the
 `japanese` scope. We could alternatively use the wildcard syntax to include
 everything from `greetings` into the current scope: `pub use self::greetings::*`. 
 
+What about the `self`? Well, by default, `use` declarations are absolute paths,
+starting from your crate root. `self` makes that path relative to your current
+place in the hierarchy instead. There's one more special form of `use`: you can
+`use super::` to reach one level up the tree from your current location. Some
+people like to think of `self` as `.` and `super` as `..`, from many shells'
+display for the current directory and the parent directory.
+
 Also, note that we `pub use`d before we declared our `mod`s. Rust requires that
 `use` declarations go first.
 
index 64d540582a3998bd7acd97c745379be9d2ba21ba..0625d649e3086b6de909a0c06632f41c0fe02775 100644 (file)
@@ -50,7 +50,29 @@ You can think of this first parameter as being the `x` in `x.foo()`. The three
 variants correspond to the three kinds of thing `x` could be: `self` if it's
 just a value on the stack, `&self` if it's a reference, and `&mut self` if it's
 a mutable reference. We should default to using `&self`, as it's the most
-common.
+common. Here's an example of all three variants:
+
+```rust
+struct Circle {
+    x: f64,
+    y: f64,
+    radius: f64,
+}
+
+impl Circle {
+    fn reference(&self) {
+       println!("taking self by reference!"); 
+    }
+
+    fn mutable_reference(&mut self) {
+       println!("taking self by mutable reference!"); 
+    }
+
+    fn takes_ownership(self) {
+       println!("taking ownership of self!"); 
+    }
+}
+```
 
 Finally, as you may remember, the value of the area of a circle is `π*r²`.
 Because we took the `&self` parameter to `area`, we can use it just like any
index a2a558094e1963c8f4b0c46423f3f69ef0eea45e..6567cd448f998611ee7bdaecc9a8067fddec7921 100644 (file)
@@ -278,7 +278,18 @@ This will print:
 
 Many more bytes than graphemes!
 
-# Other Documentation
+# `Deref` coercions
 
-* [the `&str` API documentation](../std/str/index.html)
-* [the `String` API documentation](../std/string/index.html)
+References to `String`s will automatically coerce into `&str`s. Like this:
+
+```
+fn hello(s: &str) {
+   println!("Hello, {}!", s);
+}
+
+let slice = "Steve";
+let string = "Steve".to_string();
+
+hello(slice);
+hello(&string);
+```
index a093b97eefbc4b34cbbd31e3eefee5c547ef0eae..33f0893466da604ad7472600230c3a5d4a390778 100644 (file)
@@ -63,7 +63,7 @@ that implements Roman numeral integer literals.
 
 ```ignore
 #![crate_type="dylib"]
-#![feature(plugin_registrar)]
+#![feature(plugin_registrar, rustc_private)]
 
 extern crate syntax;
 extern crate rustc;
@@ -92,13 +92,13 @@ fn expand_rn(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree])
         }
     };
 
-    let mut text = &text;
+    let mut text = &*text;
     let mut total = 0;
     while !text.is_empty() {
         match NUMERALS.iter().find(|&&(rn, _)| text.starts_with(rn)) {
             Some(&(rn, val)) => {
                 total += val;
-                text = text.slice_from(rn.len());
+                text = &text[rn.len()..];
             }
             None => {
                 cx.span_err(sp, "invalid Roman numeral");
@@ -107,7 +107,7 @@ fn expand_rn(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree])
         }
     }
 
-    MacEager::expr(cx.expr_usize(sp, total))
+    MacEager::expr(cx.expr_u32(sp, total))
 }
 
 #[plugin_registrar]
index e56706500a004f394e4bcc0b6a28c839a3f2ed5a..930a40c5050db4c001f0d306d4aa8e671000fa3d 100644 (file)
@@ -634,8 +634,8 @@ use-case for boxes.
 ### Returning data
 
 This is important enough to have its own section entirely. The TL;DR is this:
-you don't generally want to return pointers, even when you might in a language
-like C or C++.
+you don't want to return pointers, even when you might in a language like C or
+C++.
 
 See [Returning Pointers](#returning-pointers) below for more.
 
index abd9af1af33a097e805f0b64cba83d0ccbbc6cdf..676f1cc425ad4f3962487eb0ccc747b02e1bde63 100644 (file)
@@ -435,3 +435,46 @@ println!("the inverse of {} is {:?}", 2.0f64, inverse(2.0f64));
 println!("the inverse of {} is {:?}", 0.0f32, inverse(0.0f32));
 println!("the inverse of {} is {:?}", 0.0f64, inverse(0.0f64));
 ```
+
+## Default methods
+
+There's one last feature of traits we should cover: default methods. It's
+easiest just to show an example:
+
+```rust
+trait Foo {
+    fn bar(&self);
+
+    fn baz(&self) { println!("We called baz."); }
+}
+```
+
+Implementors of the `Foo` trait need to implement `bar()`, but they don't
+need to implement `baz()`. They'll get this default behavior. They can
+override the default if they so choose:
+
+```rust
+# trait Foo {
+# fn bar(&self);
+# fn baz(&self) { println!("We called baz."); }
+# }
+struct UseDefault;
+
+impl Foo for UseDefault {
+    fn bar(&self) { println!("We called bar."); }
+}
+
+struct OverrideDefault;
+
+impl Foo for OverrideDefault {
+    fn bar(&self) { println!("We called bar."); }
+
+    fn baz(&self) { println!("Override baz!"); }
+}
+
+let default = UseDefault;
+default.baz(); // prints "We called bar."
+
+let over = OverrideDefault;
+over.baz(); // prints "Override baz!"
+```
index 01fb8e3587240ecd6b342c67605e96d869013744..d08c9b3257a01bd01582980e0f3cc1cd9c5938ad 100644 (file)
@@ -323,7 +323,7 @@ fn test_arena_destructors() {
 }
 
 #[test]
-#[should_fail]
+#[should_panic]
 fn test_arena_destructors_fail() {
     let arena = Arena::new();
     // Put some stuff in the arena.
index 4c966c0d44b4d992ab833029f88735d6c339855d..68ff94cfbfb942f33ec251dceee5941156f5a90b 100644 (file)
@@ -490,7 +490,7 @@ fn test_operators() {
     }
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn test_overflow() {
         #[allow(dead_code)]
         #[derive(Copy)]
index c88be80679da45f888da4215f7b72757ea680b15..15a66bd80d02b32507286f2f174448a5412e113e 100644 (file)
 //!         // for details, and the function `pad` can be used to pad strings.
 //!         let decimals = f.precision().unwrap_or(3);
 //!         let string = f64::to_str_exact(magnitude, decimals);
-//!         f.pad_integral(true, "", string.as_slice())
+//!         f.pad_integral(true, "", &string)
 //!     }
 //! }
 //!
index 9c1c2cc5906ebca14ebd09ae361595ba4a9ad73d..f7943c0bb91402941e0dfa4f4b7afe92097daad8 100644 (file)
@@ -175,6 +175,7 @@ mod prelude {
 }
 
 /// An endpoint of a range of keys.
+#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
 pub enum Bound<T> {
     /// An inclusive bound.
     Included(T),
index abcb996e3ede1478ee7498d9917d8b29216b549b..cffa4bbfbf41134bf12a04d9ed8163bb88ade7a4 100644 (file)
@@ -1647,14 +1647,14 @@ fn test_tail_mut() {
     }
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn test_tail_empty() {
         let a = Vec::<i32>::new();
         a.tail();
     }
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn test_tail_mut_empty() {
         let mut a = Vec::<i32>::new();
         a.tail_mut();
@@ -1681,14 +1681,14 @@ fn test_init_mut() {
     }
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn test_init_empty() {
         let a = Vec::<i32>::new();
         a.init();
     }
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn test_init_mut_empty() {
         let mut a = Vec::<i32>::new();
         a.init_mut();
@@ -1790,7 +1790,7 @@ fn test_swap_remove() {
     }
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn test_swap_remove_fail() {
         let mut v = vec![1];
         let _ = v.swap_remove(0);
@@ -2205,7 +2205,7 @@ fn test_insert() {
     }
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn test_insert_oob() {
         let mut a = vec![1, 2, 3];
         a.insert(4, 5);
@@ -2229,7 +2229,7 @@ fn test_remove() {
     }
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn test_remove_fail() {
         let mut a = vec![1];
         let _ = a.remove(0);
@@ -2253,7 +2253,7 @@ fn test_slice_2() {
     }
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn test_permute_fail() {
         let v: [(Box<_>, Rc<_>); 4] =
             [(box 0, Rc::new(0)), (box 0, Rc::new(0)),
@@ -2528,7 +2528,7 @@ fn test_windowsator() {
     }
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn test_windowsator_0() {
         let v = &[1,2,3,4];
         let _it = v.windows(0);
@@ -2564,7 +2564,7 @@ fn test_chunksator() {
     }
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn test_chunksator_0() {
         let v = &[1,2,3,4];
         let _it = v.chunks(0);
@@ -2647,7 +2647,7 @@ fn test_bytes_set_memory() {
     }
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn test_overflow_does_not_cause_segfault() {
         let mut v = vec![];
         v.reserve_exact(-1);
@@ -2656,7 +2656,7 @@ fn test_overflow_does_not_cause_segfault() {
     }
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn test_overflow_does_not_cause_segfault_managed() {
         let mut v = vec![Rc::new(1)];
         v.reserve_exact(-1);
@@ -2833,7 +2833,7 @@ fn test_mut_chunks_rev() {
     }
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn test_mut_chunks_0() {
         let mut v = [1, 2, 3, 4];
         let _it = v.chunks_mut(0);
index 99547b9c60a8974e1c2e5fe316c42e33e813374b..28df6cf96d7e5e28010e9d6223f059658311e382 100644 (file)
 
 //! Unicode string manipulation (the [`str`](../primitive.str.html) type).
 //!
-//! Rust's [`str`](../primitive.str.html) type is one of the core primitive types of the
-//! language. `&str` is the borrowed string type. This type of string can only be created
-//! from other strings, unless it is a `&'static str` (see below). It is not possible to
-//! move out of borrowed strings because they are owned elsewhere.
+//! Rust's [`str`](../primitive.str.html) type is one of the core primitive
+//! types of the language. `&str` is the borrowed string type. This type of
+//! string can only be created from other strings, unless it is a `&'static str`
+//! (see below). It is not possible to move out of borrowed strings because they
+//! are owned elsewhere.
 //!
-//! Basic operations are implemented directly by the compiler, but more advanced operations are
-//! defined on the [`StrExt`](trait.StrExt.html) trait.
+//! Basic operations are implemented directly by the compiler, but more advanced
+//! operations are defined on the [`StrExt`](trait.StrExt.html) trait.
 //!
 //! # Examples
 //!
@@ -28,8 +29,9 @@
 //! let s = "Hello, world.";
 //! ```
 //!
-//! This `&str` is a `&'static str`, which is the type of string literals. They're `'static`
-//! because literals are available for the entire lifetime of the program.
+//! This `&str` is a `&'static str`, which is the type of string literals.
+//! They're `'static` because literals are available for the entire lifetime of
+//! the program.
 //!
 //! You can get a non-`'static` `&str` by taking a slice of a `String`:
 //!
 //!
 //! # Representation
 //!
-//! Rust's string type, `str`, is a sequence of Unicode scalar values encoded as a stream of UTF-8
-//! bytes. All [strings](../../reference.html#literals) are guaranteed to be validly encoded UTF-8
-//! sequences. Additionally, strings are not null-terminated and can thus contain null bytes.
+//! Rust's string type, `str`, is a sequence of Unicode scalar values encoded as
+//! a stream of UTF-8 bytes. All [strings](../../reference.html#literals) are
+//! guaranteed to be validly encoded UTF-8 sequences. Additionally, strings are
+//! not null-terminated and can thus contain null bytes.
 //!
-//! The actual representation of `str`s have direct mappings to slices: `&str` is the same as
-//! `&[u8]`.
+//! The actual representation of `str`s have direct mappings to slices: `&str`
+//! is the same as `&[u8]`.
 
 #![doc(primitive = "str")]
 #![stable(feature = "rust1", since = "1.0.0")]
 use self::RecompositionState::*;
 use self::DecompositionType::*;
 
-use core::char::CharExt;
 use core::clone::Clone;
 use core::iter::AdditiveIterator;
-use core::iter::{Iterator, IteratorExt};
+use core::iter::{Iterator, IteratorExt, Extend};
 use core::ops::Index;
 use core::ops::RangeFull;
 use core::option::Option::{self, Some, None};
 use core::result::Result;
 use core::slice::AsSlice;
 use core::str as core_str;
+use unicode::char::CharExt;
 use unicode::str::{UnicodeStr, Utf16Encoder};
 
 use vec_deque::VecDeque;
@@ -836,17 +839,19 @@ fn lines_any(&self) -> LinesAny {
 
     /// Returns a slice of the string from the character range [`begin`..`end`).
     ///
-    /// That is, start at the `begin`-th code point of the string and continue to the `end`-th code
-    /// point. This does not detect or handle edge cases such as leaving a combining character as
-    /// the first code point of the string.
+    /// That is, start at the `begin`-th code point of the string and continue
+    /// to the `end`-th code point. This does not detect or handle edge cases
+    /// such as leaving a combining character as the first code point of the
+    /// string.
     ///
-    /// Due to the design of UTF-8, this operation is `O(end)`. See `slice`, `slice_to` and
-    /// `slice_from` for `O(1)` variants that use byte indices rather than code point indices.
+    /// Due to the design of UTF-8, this operation is `O(end)`. See `slice`,
+    /// `slice_to` and `slice_from` for `O(1)` variants that use byte indices
+    /// rather than code point indices.
     ///
     /// # Panics
     ///
-    /// Panics if `begin` > `end` or the either `begin` or `end` are beyond the last character of
-    /// the string.
+    /// Panics if `begin` > `end` or the either `begin` or `end` are beyond the
+    /// last character of the string.
     ///
     /// # Examples
     ///
@@ -868,8 +873,8 @@ fn slice_chars(&self, begin: usize, end: usize) -> &str {
     ///
     /// # Unsafety
     ///
-    /// Caller must check both UTF-8 character boundaries and the boundaries of the entire slice as
-    /// well.
+    /// Caller must check both UTF-8 character boundaries and the boundaries of
+    /// the entire slice as well.
     ///
     /// # Examples
     ///
@@ -1506,6 +1511,32 @@ fn trim_left(&self) -> &str {
     fn trim_right(&self) -> &str {
         UnicodeStr::trim_right(&self[..])
     }
+
+    /// Returns the lowercase equivalent of this string.
+    ///
+    /// # Examples
+    ///
+    /// let s = "HELLO";
+    /// assert_eq!(s.to_lowercase(), "hello");
+    #[unstable(feature = "collections")]
+    fn to_lowercase(&self) -> String {
+        let mut s = String::with_capacity(self.len());
+        s.extend(self[..].chars().flat_map(|c| c.to_lowercase()));
+        return s;
+    }
+
+    /// Returns the uppercase equivalent of this string.
+    ///
+    /// # Examples
+    ///
+    /// let s = "hello";
+    /// assert_eq!(s.to_uppercase(), "HELLO");
+    #[unstable(feature = "collections")]
+    fn to_uppercase(&self) -> String {
+        let mut s = String::with_capacity(self.len());
+        s.extend(self[..].chars().flat_map(|c| c.to_uppercase()));
+        return s;
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -1877,7 +1908,7 @@ fn test_slice_2() {
     }
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn test_slice_fail() {
         "中华Việt Nam".slice(0, 2);
     }
@@ -2095,7 +2126,7 @@ fn test_as_bytes() {
     }
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn test_as_bytes_fail() {
         // Don't double free. (I'm not sure if this exercises the
         // original problem code path anymore.)
@@ -2132,7 +2163,7 @@ fn test_subslice_offset() {
     }
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn test_subslice_offset_2() {
         let a = "alchemiter";
         let b = "cruxtruder";
index d6ec8f0d979e0cde74402f03afdcc9dfa10cdb3f..83c63e47e506b8d977032561f5e531875b8ac28e 100644 (file)
@@ -139,7 +139,7 @@ pub fn from_utf8(vec: Vec<u8>) -> Result<String, FromUtf8Error> {
     /// ```rust
     /// let input = b"Hello \xF0\x90\x80World";
     /// let output = String::from_utf8_lossy(input);
-    /// assert_eq!(output.as_slice(), "Hello \u{FFFD}World");
+    /// assert_eq!(output, "Hello \u{FFFD}World");
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn from_utf8_lossy<'a>(v: &'a [u8]) -> Cow<'a, str> {
@@ -355,7 +355,7 @@ pub fn into_bytes(self) -> Vec<u8> {
     /// ```
     /// let mut s = String::from_str("foo");
     /// s.push_str("bar");
-    /// assert_eq!(s.as_slice(), "foobar");
+    /// assert_eq!(s, "foobar");
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -450,7 +450,7 @@ pub fn shrink_to_fit(&mut self) {
     /// s.push('1');
     /// s.push('2');
     /// s.push('3');
-    /// assert_eq!(s.as_slice(), "abc123");
+    /// assert_eq!(s, "abc123");
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -503,7 +503,7 @@ pub fn as_bytes(&self) -> &[u8] {
     /// ```
     /// let mut s = String::from_str("hello");
     /// s.truncate(2);
-    /// assert_eq!(s.as_slice(), "he");
+    /// assert_eq!(s, "he");
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -622,7 +622,7 @@ pub fn insert(&mut self, idx: usize, ch: char) {
     ///     assert!(vec == &[104, 101, 108, 108, 111]);
     ///     vec.reverse();
     /// }
-    /// assert_eq!(s.as_slice(), "olleh");
+    /// assert_eq!(s, "olleh");
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -1232,14 +1232,14 @@ fn test_str_truncate() {
     }
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn test_str_truncate_invalid_len() {
         let mut s = String::from_str("12345");
         s.truncate(6);
     }
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn test_str_truncate_split_codepoint() {
         let mut s = String::from_str("\u{FC}"); // ü
         s.truncate(1);
@@ -1272,7 +1272,7 @@ fn remove() {
         assert_eq!(s, "ไทย中华Vit Nam; foobar");
     }
 
-    #[test] #[should_fail]
+    #[test] #[should_panic]
     fn remove_bad() {
         "ศ".to_string().remove(1);
     }
@@ -1286,8 +1286,8 @@ fn insert() {
         assert_eq!(s, "ệfooยbar");
     }
 
-    #[test] #[should_fail] fn insert_bad1() { "".to_string().insert(1, 't'); }
-    #[test] #[should_fail] fn insert_bad2() { "ệ".to_string().insert(1, 't'); }
+    #[test] #[should_panic] fn insert_bad1() { "".to_string().insert(1, 't'); }
+    #[test] #[should_panic] fn insert_bad2() { "ệ".to_string().insert(1, 't'); }
 
     #[test]
     fn test_slicing() {
index 2e947ea24602aafdedb64848032d87ab8b53dc6a..ca0092a6e66ddb942c07d2b2b0cb8c55d6c38776 100644 (file)
@@ -2242,7 +2242,7 @@ fn drop(&mut self) {
     }
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn test_vec_truncate_fail() {
         struct BadElem(i32);
         impl Drop for BadElem {
@@ -2265,49 +2265,49 @@ fn test_index() {
     }
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn test_index_out_of_bounds() {
         let vec = vec![1, 2, 3];
         let _ = vec[3];
     }
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn test_slice_out_of_bounds_1() {
         let x = vec![1, 2, 3, 4, 5];
         &x[-1..];
     }
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn test_slice_out_of_bounds_2() {
         let x = vec![1, 2, 3, 4, 5];
         &x[..6];
     }
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn test_slice_out_of_bounds_3() {
         let x = vec![1, 2, 3, 4, 5];
         &x[-1..4];
     }
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn test_slice_out_of_bounds_4() {
         let x = vec![1, 2, 3, 4, 5];
         &x[1..6];
     }
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn test_slice_out_of_bounds_5() {
         let x = vec![1, 2, 3, 4, 5];
         &x[3..2];
     }
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn test_swap_remove_empty() {
         let mut vec= Vec::<i32>::new();
         vec.swap_remove(0);
@@ -2326,7 +2326,7 @@ fn test_move_iter_unwrap() {
     }
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn test_map_in_place_incompatible_types_fail() {
         let v = vec![0, 1, 2];
         v.map_in_place(|_| ());
index 551d28b91b4bf02a2f38a30f7ead39f35f143728..cab589d55beae584a18385f4911fb2830a72c959 100644 (file)
@@ -1884,7 +1884,7 @@ fn test_index() {
     }
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn test_index_out_of_bounds() {
         let mut deq = VecDeque::new();
         for i in 1..4 {
index 515de74e340ac9d5fd6f7b3c78d784a1e05d82a2..431c8d5df8c0a11dfa27efa2394b1a2db30a57a8 100644 (file)
@@ -1432,7 +1432,7 @@ fn test_index() {
     }
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn test_index_nonexistent() {
         let mut map = VecMap::new();
 
index b8a22c30f9e1ed14a9146b22772af699adc45901..4f77a20c7cac853e0367af0794deab2c74a82c79 100644 (file)
@@ -631,9 +631,6 @@ fn deref_mut<'a>(&'a mut self) -> &'a mut T {
 ///
 /// Types like `Cell<T>` and `RefCell<T>` use this type to wrap their internal data.
 ///
-/// `UnsafeCell<T>` doesn't opt-out from any marker traits, instead, types with an `UnsafeCell<T>`
-/// interior are expected to opt-out from those traits themselves.
-///
 /// # Examples
 ///
 /// ```
index 973070677d8ee9e9e2fb8e636fa608b6a9764e7d..010415b364aa04a75506c86f7d6d82a83e3d0602 100644 (file)
@@ -118,7 +118,7 @@ pub fn from_u32(i: u32) -> Option<char> {
 /// assert_eq!(c, Some('4'));
 /// ```
 #[inline]
-#[unstable(feature = "core", reason = "pending integer conventions")]
+#[stable(feature = "rust1", since = "1.0.0")]
 pub fn from_digit(num: u32, radix: u32) -> Option<char> {
     if radix > 36 {
         panic!("from_digit: radix is too high (maximum 36)");
@@ -136,230 +136,25 @@ pub fn from_digit(num: u32, radix: u32) -> Option<char> {
     }
 }
 
-/// Basic `char` manipulations.
-#[stable(feature = "rust1", since = "1.0.0")]
+// NB: the stabilization and documentation for this trait is in
+// unicode/char.rs, not here
+#[allow(missing_docs)] // docs in libunicode/u_char.rs
 pub trait CharExt {
-    /// Checks if a `char` parses as a numeric digit in the given radix.
-    ///
-    /// Compared to `is_numeric()`, this function only recognizes the characters
-    /// `0-9`, `a-z` and `A-Z`.
-    ///
-    /// # Return value
-    ///
-    /// Returns `true` if `c` is a valid digit under `radix`, and `false`
-    /// otherwise.
-    ///
-    /// # Panics
-    ///
-    /// Panics if given a radix > 36.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// let c = '1';
-    ///
-    /// assert!(c.is_digit(10));
-    ///
-    /// assert!('f'.is_digit(16));
-    /// ```
-    #[unstable(feature = "core",
-               reason = "pending integer conventions")]
     fn is_digit(self, radix: u32) -> bool;
-
-    /// Converts a character to the corresponding digit.
-    ///
-    /// # Return value
-    ///
-    /// If `c` is between '0' and '9', the corresponding value between 0 and
-    /// 9. If `c` is 'a' or 'A', 10. If `c` is 'b' or 'B', 11, etc. Returns
-    /// none if the character does not refer to a digit in the given radix.
-    ///
-    /// # Panics
-    ///
-    /// Panics if given a radix outside the range [0..36].
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// let c = '1';
-    ///
-    /// assert_eq!(c.to_digit(10), Some(1));
-    ///
-    /// assert_eq!('f'.to_digit(16), Some(15));
-    /// ```
-    #[unstable(feature = "core",
-               reason = "pending integer conventions")]
     fn to_digit(self, radix: u32) -> Option<u32>;
-
-    /// Returns an iterator that yields the hexadecimal Unicode escape of a character, as `char`s.
-    ///
-    /// All characters are escaped with Rust syntax of the form `\\u{NNNN}` where `NNNN` is the
-    /// shortest hexadecimal representation of the code point.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// for i in '❤'.escape_unicode() {
-    ///     println!("{}", i);
-    /// }
-    /// ```
-    ///
-    /// This prints:
-    ///
-    /// ```text
-    /// \
-    /// u
-    /// {
-    /// 2
-    /// 7
-    /// 6
-    /// 4
-    /// }
-    /// ```
-    ///
-    /// Collecting into a `String`:
-    ///
-    /// ```
-    /// let heart: String = '❤'.escape_unicode().collect();
-    ///
-    /// assert_eq!(heart, r"\u{2764}");
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
     fn escape_unicode(self) -> EscapeUnicode;
-
-    /// Returns an iterator that yields the 'default' ASCII and
-    /// C++11-like literal escape of a character, as `char`s.
-    ///
-    /// The default is chosen with a bias toward producing literals that are
-    /// legal in a variety of languages, including C++11 and similar C-family
-    /// languages. The exact rules are:
-    ///
-    /// * Tab, CR and LF are escaped as '\t', '\r' and '\n' respectively.
-    /// * Single-quote, double-quote and backslash chars are backslash-
-    ///   escaped.
-    /// * Any other chars in the range [0x20,0x7e] are not escaped.
-    /// * Any other chars are given hex Unicode escapes; see `escape_unicode`.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// for i in '"'.escape_default() {
-    ///     println!("{}", i);
-    /// }
-    /// ```
-    ///
-    /// This prints:
-    ///
-    /// ```text
-    /// \
-    /// "
-    /// ```
-    ///
-    /// Collecting into a `String`:
-    ///
-    /// ```
-    /// let quote: String = '"'.escape_default().collect();
-    ///
-    /// assert_eq!(quote, "\\\"");
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
     fn escape_default(self) -> EscapeDefault;
-
-    /// Returns the number of bytes this character would need if encoded in UTF-8.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// let n = 'ß'.len_utf8();
-    ///
-    /// assert_eq!(n, 2);
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
     fn len_utf8(self) -> usize;
-
-    /// Returns the number of bytes this character would need if encoded in UTF-16.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// let n = 'ß'.len_utf16();
-    ///
-    /// assert_eq!(n, 1);
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
     fn len_utf16(self) -> usize;
-
-    /// Encodes this character as UTF-8 into the provided byte buffer, and then returns the number
-    /// of bytes written.
-    ///
-    /// If the buffer is not large enough, nothing will be written into it and a `None` will be
-    /// returned.
-    ///
-    /// # Examples
-    ///
-    /// In both of these examples, 'ß' takes two bytes to encode.
-    ///
-    /// ```
-    /// let mut b = [0; 2];
-    ///
-    /// let result = 'ß'.encode_utf8(&mut b);
-    ///
-    /// assert_eq!(result, Some(2));
-    /// ```
-    ///
-    /// A buffer that's too small:
-    ///
-    /// ```
-    /// let mut b = [0; 1];
-    ///
-    /// let result = 'ß'.encode_utf8(&mut b);
-    ///
-    /// assert_eq!(result, None);
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
     fn encode_utf8(self, dst: &mut [u8]) -> Option<usize>;
-
-    /// Encodes this character as UTF-16 into the provided `u16` buffer, and then returns the
-    /// number of `u16`s written.
-    ///
-    /// If the buffer is not large enough, nothing will be written into it and a `None` will be
-    /// returned.
-    ///
-    /// # Examples
-    ///
-    /// In both of these examples, 'ß' takes one byte to encode.
-    ///
-    /// ```
-    /// let mut b = [0; 1];
-    ///
-    /// let result = 'ß'.encode_utf16(&mut b);
-    ///
-    /// assert_eq!(result, Some(1));
-    /// ```
-    ///
-    /// A buffer that's too small:
-    ///
-    /// ```
-    /// let mut b = [0; 0];
-    ///
-    /// let result = 'ß'.encode_utf8(&mut b);
-    ///
-    /// assert_eq!(result, None);
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
     fn encode_utf16(self, dst: &mut [u16]) -> Option<usize>;
 }
 
-#[stable(feature = "rust1", since = "1.0.0")]
 impl CharExt for char {
-    #[unstable(feature = "core",
-               reason = "pending integer conventions")]
     fn is_digit(self, radix: u32) -> bool {
         self.to_digit(radix).is_some()
     }
 
-    #[unstable(feature = "core",
-               reason = "pending integer conventions")]
     fn to_digit(self, radix: u32) -> Option<u32> {
         if radix > 36 {
             panic!("to_digit: radix is too high (maximum 36)");
@@ -374,12 +169,10 @@ fn to_digit(self, radix: u32) -> Option<u32> {
         else { None }
     }
 
-    #[stable(feature = "rust1", since = "1.0.0")]
     fn escape_unicode(self) -> EscapeUnicode {
         EscapeUnicode { c: self, state: EscapeUnicodeState::Backslash }
     }
 
-    #[stable(feature = "rust1", since = "1.0.0")]
     fn escape_default(self) -> EscapeDefault {
         let init_state = match self {
             '\t' => EscapeDefaultState::Backslash('t'),
@@ -395,7 +188,6 @@ fn escape_default(self) -> EscapeDefault {
     }
 
     #[inline]
-    #[stable(feature = "rust1", since = "1.0.0")]
     fn len_utf8(self) -> usize {
         let code = self as u32;
         if code < MAX_ONE_B {
@@ -410,22 +202,17 @@ fn len_utf8(self) -> usize {
     }
 
     #[inline]
-    #[stable(feature = "rust1", since = "1.0.0")]
     fn len_utf16(self) -> usize {
         let ch = self as u32;
         if (ch & 0xFFFF) == ch { 1 } else { 2 }
     }
 
     #[inline]
-    #[unstable(feature = "core",
-               reason = "pending decision about Iterator/Writer/Reader")]
     fn encode_utf8(self, dst: &mut [u8]) -> Option<usize> {
         encode_utf8_raw(self as u32, dst)
     }
 
     #[inline]
-    #[unstable(feature = "core",
-               reason = "pending decision about Iterator/Writer/Reader")]
     fn encode_utf16(self, dst: &mut [u16]) -> Option<usize> {
         encode_utf16_raw(self as u32, dst)
     }
@@ -437,7 +224,6 @@ fn encode_utf16(self, dst: &mut [u16]) -> Option<usize> {
 /// If the buffer is not large enough, nothing will be written into it
 /// and a `None` will be returned.
 #[inline]
-#[unstable(feature = "core")]
 pub fn encode_utf8_raw(code: u32, dst: &mut [u8]) -> Option<usize> {
     // Marked #[inline] to allow llvm optimizing it away
     if code < MAX_ONE_B && dst.len() >= 1 {
@@ -469,7 +255,6 @@ pub fn encode_utf8_raw(code: u32, dst: &mut [u8]) -> Option<usize> {
 /// If the buffer is not large enough, nothing will be written into it
 /// and a `None` will be returned.
 #[inline]
-#[unstable(feature = "core")]
 pub fn encode_utf16_raw(mut ch: u32, dst: &mut [u16]) -> Option<usize> {
     // Marked #[inline] to allow llvm optimizing it away
     if (ch & 0xFFFF) == ch  && dst.len() >= 1 {
@@ -497,7 +282,6 @@ pub struct EscapeUnicode {
 }
 
 #[derive(Clone)]
-#[unstable(feature = "core")]
 enum EscapeUnicodeState {
     Backslash,
     Type,
@@ -559,7 +343,6 @@ pub struct EscapeDefault {
 }
 
 #[derive(Clone)]
-#[unstable(feature = "core")]
 enum EscapeDefaultState {
     Backslash(char),
     Char(char),
index c6fc8ba5867abd7612a11caff90adbdf662fc158..7fccb93f2a0028ad5ef82c4a3bbaab72c3eadcc2 100644 (file)
@@ -545,11 +545,7 @@ pub fn volatile_copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T,
     pub fn u32_mul_with_overflow(x: u32, y: u32) -> (u32, bool);
     /// Performs checked `u64` multiplication.
     pub fn u64_mul_with_overflow(x: u64, y: u64) -> (u64, bool);
-}
 
-// SNAP 880fb89
-#[cfg(not(stage0))]
-extern "rust-intrinsic" {
     /// Returns (a + b) mod 2^N, where N is the width of N in bits.
     pub fn overflowing_add<T>(a: T, b: T) -> T;
     /// Returns (a - b) mod 2^N, where N is the width of N in bits.
index 32225b90f6b144b09ed389f71c6ded4a782dcc17..d5e891a156e9bb3b8f248a0cf352dad6e9751369 100644 (file)
@@ -611,7 +611,7 @@ fn partition<B, F>(self, mut f: F) -> (B, B) where
     ///
     /// ```
     /// let a = [1, 2, 3, 4, 5];
-    /// assert!(a.iter().fold(0, |a, &b| a + b) == 15);
+    /// assert!(a.iter().fold(0, |acc, &item| acc + item) == 15);
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
index 868a671b9560e2985188874f3b333463af95143d..fe53ea1f0af8413d6ef81333123448dcc5736aef 100644 (file)
@@ -193,14 +193,9 @@ pub trait Copy : MarkerTrait {
 /// the `sync` crate do ensure that any mutation cannot cause data
 /// races.  Hence these types are `Sync`.
 ///
-/// Users writing their own types with interior mutability (or anything
-/// else that is not thread-safe) should use the `NoSync` marker type
-/// (from `std::marker`) to ensure that the compiler doesn't
-/// consider the user-defined type to be `Sync`.  Any types with
-/// interior mutability must also use the `std::cell::UnsafeCell` wrapper
-/// around the value(s) which can be mutated when behind a `&`
-/// reference; not doing this is undefined behaviour (for example,
-/// `transmute`-ing from `&T` to `&mut T` is illegal).
+/// Any types with interior mutability must also use the `std::cell::UnsafeCell` wrapper around the
+/// value(s) which can be mutated when behind a `&` reference; not doing this is undefined
+/// behaviour (for example, `transmute`-ing from `&T` to `&mut T` is illegal).
 #[stable(feature = "rust1", since = "1.0.0")]
 #[lang="sync"]
 #[rustc_on_unimplemented = "`{Self}` cannot be shared between threads safely"]
@@ -351,7 +346,45 @@ pub trait PhantomFn<A:?Sized,R:?Sized=()> { }
 /// instance, it will behave *as if* an instance of the type `T` were
 /// present for the purpose of various automatic analyses.
 ///
-/// For example, embedding a `PhantomData<T>` will inform the compiler
+/// # Examples
+///
+/// When handling external resources over a foreign function interface, `PhantomData<T>` can
+/// prevent mismatches by enforcing types in the method implementations, although the struct
+/// doesn't actually contain values of the resource type.
+///
+/// ```
+/// # trait ResType { fn foo(&self); };
+/// # struct ParamType;
+/// # mod foreign_lib {
+/// # pub fn new(_: usize) -> *mut () { 42 as *mut () }
+/// # pub fn do_stuff(_: *mut (), _: usize) {}
+/// # }
+/// # fn convert_params(_: ParamType) -> usize { 42 }
+/// use std::marker::PhantomData;
+/// use std::mem;
+///
+/// struct ExternalResource<R> {
+///    resource_handle: *mut (),
+///    resource_type: PhantomData<R>,
+/// }
+///
+/// impl<R: ResType> ExternalResource<R> {
+///     fn new() -> ExternalResource<R> {
+///         let size_of_res = mem::size_of::<R>();
+///         ExternalResource {
+///             resource_handle: foreign_lib::new(size_of_res),
+///             resource_type: PhantomData,
+///         }
+///     }
+///
+///     fn do_stuff(&self, param: ParamType) {
+///         let foreign_params = convert_params(param);
+///         foreign_lib::do_stuff(self.resource_handle, foreign_params);
+///     }
+/// }
+/// ```
+///
+/// Another example: embedding a `PhantomData<T>` will inform the compiler
 /// that one or more instances of the type `T` could be dropped when
 /// instances of the type itself is dropped, though that may not be
 /// apparent from the other structure of the type itself. This is
index 76edec80896bb400c4a3d154960b1ed5c99cbd92..752eca797bd1398d5219b43220db75ed4cfaf6b7 100644 (file)
@@ -1517,7 +1517,7 @@ pub trait FromStrRadix {
     fn from_str_radix(str: &str, radix: u32) -> Result<Self, Self::Err>;
 }
 
-/// A utility function that just calls FromStrRadix::from_str_radix.
+/// A utility function that just calls `FromStrRadix::from_str_radix`.
 #[unstable(feature = "core", reason = "needs reevaluation")]
 pub fn from_str_radix<T: FromStrRadix>(str: &str, radix: u32)
                                        -> Result<T, T::Err> {
index 707e41a948be0d14537cf2f8b567063e81f0ed88..f8fc4ef27a1c9e1812feeff04836cf56c31973a8 100644 (file)
@@ -11,7 +11,6 @@
 
 use ops::*;
 
-#[cfg(not(stage0))]
 use intrinsics::{overflowing_add, overflowing_sub, overflowing_mul};
 
 use intrinsics::{i8_add_with_overflow, u8_add_with_overflow};
@@ -40,7 +39,6 @@ pub trait OverflowingOps {
     fn overflowing_mul(self, rhs: Self) -> (Self, bool);
 }
 
-#[cfg(not(stage0))]
 macro_rules! wrapping_impl {
     ($($t:ty)*) => ($(
         impl WrappingOps for $t {
@@ -66,26 +64,6 @@ fn wrapping_mul(self, rhs: $t) -> $t {
     )*)
 }
 
-#[cfg(stage0)]
-macro_rules! wrapping_impl {
-    ($($t:ty)*) => ($(
-        impl WrappingOps for $t {
-            #[inline(always)]
-            fn wrapping_add(self, rhs: $t) -> $t {
-                self + rhs
-            }
-            #[inline(always)]
-            fn wrapping_sub(self, rhs: $t) -> $t {
-                self - rhs
-            }
-            #[inline(always)]
-            fn wrapping_mul(self, rhs: $t) -> $t {
-                self * rhs
-            }
-        }
-    )*)
-}
-
 wrapping_impl! { uint u8 u16 u32 u64 int i8 i16 i32 i64 }
 
 #[unstable(feature = "core", reason = "may be removed, renamed, or relocated")]
index b8271562d2e670c22677a86ce61964f51325a053..6c3afdf884953ad0966eef3707fb5404cdcbfc9a 100644 (file)
 //! fn write_info(info: &Info) -> Result<(), IoError> {
 //!     let mut file = File::open_mode(&Path::new("my_best_friends.txt"), Open, Write);
 //!     // Early return on error
-//!     if let Err(e) = file.write_line(format!("name: {}", info.name).as_slice()) {
+//!     if let Err(e) = file.write_line(&format!("name: {}", info.name)) {
 //!         return Err(e)
 //!     }
-//!     if let Err(e) = file.write_line(format!("age: {}", info.age).as_slice()) {
+//!     if let Err(e) = file.write_line(&format!("age: {}", info.age)) {
 //!         return Err(e)
 //!     }
-//!     return file.write_line(format!("rating: {}", info.rating).as_slice());
+//!     return file.write_line(&format!("rating: {}", info.rating));
 //! }
 //! ```
 //!
 //! fn write_info(info: &Info) -> Result<(), IoError> {
 //!     let mut file = File::open_mode(&Path::new("my_best_friends.txt"), Open, Write);
 //!     // Early return on error
-//!     try!(file.write_line(format!("name: {}", info.name).as_slice()));
-//!     try!(file.write_line(format!("age: {}", info.age).as_slice()));
-//!     try!(file.write_line(format!("rating: {}", info.rating).as_slice()));
+//!     try!(file.write_line(&format!("name: {}", info.name)));
+//!     try!(file.write_line(&format!("age: {}", info.age)));
+//!     try!(file.write_line(&format!("rating: {}", info.rating)));
 //!     return Ok(());
 //! }
 //! ```
index 1d4b81512dda8e24213ef74ebf56d8bb965ac6cb..a5ade2ae2a5793345e602245f87f097594c5a1f3 100644 (file)
@@ -335,21 +335,20 @@ pub struct Chars<'a> {
     iter: slice::Iter<'a, u8>
 }
 
-// Return the initial codepoint accumulator for the first byte.
-// The first byte is special, only want bottom 5 bits for width 2, 4 bits
-// for width 3, and 3 bits for width 4
-macro_rules! utf8_first_byte {
-    ($byte:expr, $width:expr) => (($byte & (0x7F >> $width)) as u32)
-}
+/// Return the initial codepoint accumulator for the first byte.
+/// The first byte is special, only want bottom 5 bits for width 2, 4 bits
+/// for width 3, and 3 bits for width 4.
+#[inline]
+fn utf8_first_byte(byte: u8, width: u32) -> u32 { (byte & (0x7F >> width)) as u32 }
 
-// return the value of $ch updated with continuation byte $byte
-macro_rules! utf8_acc_cont_byte {
-    ($ch:expr, $byte:expr) => (($ch << 6) | ($byte & CONT_MASK) as u32)
-}
+/// Return the value of `ch` updated with continuation byte `byte`.
+#[inline]
+fn utf8_acc_cont_byte(ch: u32, byte: u8) -> u32 { (ch << 6) | (byte & CONT_MASK) as u32 }
 
-macro_rules! utf8_is_cont_byte {
-    ($byte:expr) => (($byte & !CONT_MASK) == TAG_CONT_U8)
-}
+/// Checks whether the byte is a UTF-8 continuation byte (i.e. starts with the
+/// bits `10`).
+#[inline]
+fn utf8_is_cont_byte(byte: u8) -> bool { (byte & !CONT_MASK) == TAG_CONT_U8 }
 
 #[inline]
 fn unwrap_or_0(opt: Option<&u8>) -> u8 {
@@ -374,20 +373,20 @@ pub fn next_code_point(bytes: &mut slice::Iter<u8>) -> Option<u32> {
     // Multibyte case follows
     // Decode from a byte combination out of: [[[x y] z] w]
     // NOTE: Performance is sensitive to the exact formulation here
-    let init = utf8_first_byte!(x, 2);
+    let init = utf8_first_byte(x, 2);
     let y = unwrap_or_0(bytes.next());
-    let mut ch = utf8_acc_cont_byte!(init, y);
+    let mut ch = utf8_acc_cont_byte(init, y);
     if x >= 0xE0 {
         // [[x y z] w] case
         // 5th bit in 0xE0 .. 0xEF is always clear, so `init` is still valid
         let z = unwrap_or_0(bytes.next());
-        let y_z = utf8_acc_cont_byte!((y & CONT_MASK) as u32, z);
+        let y_z = utf8_acc_cont_byte((y & CONT_MASK) as u32, z);
         ch = init << 12 | y_z;
         if x >= 0xF0 {
             // [x y z w] case
             // use only the lower 3 bits of `init`
             let w = unwrap_or_0(bytes.next());
-            ch = (init & 7) << 18 | utf8_acc_cont_byte!(y_z, w);
+            ch = (init & 7) << 18 | utf8_acc_cont_byte(y_z, w);
         }
     }
 
@@ -410,18 +409,18 @@ pub fn next_code_point_reverse(bytes: &mut slice::Iter<u8>) -> Option<u32> {
     // Decode from a byte combination out of: [x [y [z w]]]
     let mut ch;
     let z = unwrap_or_0(bytes.next_back());
-    ch = utf8_first_byte!(z, 2);
-    if utf8_is_cont_byte!(z) {
+    ch = utf8_first_byte(z, 2);
+    if utf8_is_cont_byte(z) {
         let y = unwrap_or_0(bytes.next_back());
-        ch = utf8_first_byte!(y, 3);
-        if utf8_is_cont_byte!(y) {
+        ch = utf8_first_byte(y, 3);
+        if utf8_is_cont_byte(y) {
             let x = unwrap_or_0(bytes.next_back());
-            ch = utf8_first_byte!(x, 4);
-            ch = utf8_acc_cont_byte!(ch, y);
+            ch = utf8_first_byte(x, 4);
+            ch = utf8_acc_cont_byte(ch, y);
         }
-        ch = utf8_acc_cont_byte!(ch, z);
+        ch = utf8_acc_cont_byte(ch, z);
     }
-    ch = utf8_acc_cont_byte!(ch, w);
+    ch = utf8_acc_cont_byte(ch, w);
 
     Some(ch)
 }
@@ -443,7 +442,10 @@ fn next(&mut self) -> Option<char> {
     #[inline]
     fn size_hint(&self) -> (usize, Option<usize>) {
         let (len, _) = self.iter.size_hint();
-        (len.saturating_add(3) / 4, Some(len))
+        // `(len + 3)` can't overflow, because we know that the `slice::Iter`
+        // belongs to a slice in memory which has a maximum length of
+        // `isize::MAX` (that's well below `usize::MAX`).
+        ((len + 3) / 4, Some(len))
     }
 }
 
@@ -1040,7 +1042,7 @@ macro_rules! next { () => {
         // ASCII characters are always valid, so only large
         // bytes need more examination.
         if first >= 128 {
-            let w = UTF8_CHAR_WIDTH[first as usize] as usize;
+            let w = UTF8_CHAR_WIDTH[first as usize];
             let second = next!();
             // 2-byte encoding is for codepoints  \u{0080} to  \u{07ff}
             //        first  C2 80        last DF BF
@@ -1594,14 +1596,14 @@ fn multibyte_char_range_at_reverse(s: &str, mut i: usize) -> CharRange {
                 i -= 1;
             }
 
-            let mut val = s.as_bytes()[i] as u32;
-            let w = UTF8_CHAR_WIDTH[val as usize] as usize;
-            assert!((w != 0));
+            let first= s.as_bytes()[i];
+            let w = UTF8_CHAR_WIDTH[first as usize];
+            assert!(w != 0);
 
-            val = utf8_first_byte!(val, w);
-            val = utf8_acc_cont_byte!(val, s.as_bytes()[i + 1]);
-            if w > 2 { val = utf8_acc_cont_byte!(val, s.as_bytes()[i + 2]); }
-            if w > 3 { val = utf8_acc_cont_byte!(val, s.as_bytes()[i + 3]); }
+            let mut val = utf8_first_byte(first, w as u32);
+            val = utf8_acc_cont_byte(val, s.as_bytes()[i + 1]);
+            if w > 2 { val = utf8_acc_cont_byte(val, s.as_bytes()[i + 2]); }
+            if w > 3 { val = utf8_acc_cont_byte(val, s.as_bytes()[i + 3]); }
 
             return CharRange {ch: unsafe { mem::transmute(val) }, next: i};
         }
@@ -1686,16 +1688,16 @@ pub fn char_range_at_raw(bytes: &[u8], i: usize) -> (u32, usize) {
 
     // Multibyte case is a fn to allow char_range_at to inline cleanly
     fn multibyte_char_range_at(bytes: &[u8], i: usize) -> (u32, usize) {
-        let mut val = bytes[i] as u32;
-        let w = UTF8_CHAR_WIDTH[val as usize] as usize;
-        assert!((w != 0));
+        let first = bytes[i];
+        let w = UTF8_CHAR_WIDTH[first as usize];
+        assert!(w != 0);
 
-        val = utf8_first_byte!(val, w);
-        val = utf8_acc_cont_byte!(val, bytes[i + 1]);
-        if w > 2 { val = utf8_acc_cont_byte!(val, bytes[i + 2]); }
-        if w > 3 { val = utf8_acc_cont_byte!(val, bytes[i + 3]); }
+        let mut val = utf8_first_byte(first, w as u32);
+        val = utf8_acc_cont_byte(val, bytes[i + 1]);
+        if w > 2 { val = utf8_acc_cont_byte(val, bytes[i + 2]); }
+        if w > 3 { val = utf8_acc_cont_byte(val, bytes[i + 3]); }
 
-        return (val, i + w);
+        return (val, i + w as usize);
     }
 
     multibyte_char_range_at(bytes, i)
index 317ef3a570143e9611f73d3e00047ccbf71c8045..3397cbb18faa09c38284194e5149a95cb7141047 100644 (file)
@@ -109,7 +109,7 @@ fn double_borrow_single_release_no_borrow_mut() {
 }
 
 #[test]
-#[should_fail]
+#[should_panic]
 fn discard_doesnt_unborrow() {
     let x = RefCell::new(0);
     let _b = x.borrow();
index 46d1f7ff3ae095772c7ef0d561224af10afb7ab1..65e941d160d0453d0fce8e837c2c1dda14f12c41 100644 (file)
@@ -57,35 +57,47 @@ fn test_to_digit() {
 
 #[test]
 fn test_to_lowercase() {
-    assert_eq!('A'.to_lowercase(), 'a');
-    assert_eq!('Ö'.to_lowercase(), 'ö');
-    assert_eq!('ß'.to_lowercase(), 'ß');
-    assert_eq!('Ü'.to_lowercase(), 'ü');
-    assert_eq!('💩'.to_lowercase(), '💩');
-    assert_eq!('Σ'.to_lowercase(), 'σ');
-    assert_eq!('Τ'.to_lowercase(), 'τ');
-    assert_eq!('Ι'.to_lowercase(), 'ι');
-    assert_eq!('Γ'.to_lowercase(), 'γ');
-    assert_eq!('Μ'.to_lowercase(), 'μ');
-    assert_eq!('Α'.to_lowercase(), 'α');
-    assert_eq!('Σ'.to_lowercase(), 'σ');
+    fn lower(c: char) -> char {
+        let mut it = c.to_lowercase();
+        let c = it.next().unwrap();
+        assert!(it.next().is_none());
+        c
+    }
+    assert_eq!(lower('A'), 'a');
+    assert_eq!(lower('Ö'), 'ö');
+    assert_eq!(lower('ß'), 'ß');
+    assert_eq!(lower('Ü'), 'ü');
+    assert_eq!(lower('💩'), '💩');
+    assert_eq!(lower('Σ'), 'σ');
+    assert_eq!(lower('Τ'), 'τ');
+    assert_eq!(lower('Ι'), 'ι');
+    assert_eq!(lower('Γ'), 'γ');
+    assert_eq!(lower('Μ'), 'μ');
+    assert_eq!(lower('Α'), 'α');
+    assert_eq!(lower('Σ'), 'σ');
 }
 
 #[test]
 fn test_to_uppercase() {
-    assert_eq!('a'.to_uppercase(), 'A');
-    assert_eq!('ö'.to_uppercase(), 'Ö');
-    assert_eq!('ß'.to_uppercase(), 'ß'); // not ẞ: Latin capital letter sharp s
-    assert_eq!('ü'.to_uppercase(), 'Ü');
-    assert_eq!('💩'.to_uppercase(), '💩');
-
-    assert_eq!('σ'.to_uppercase(), 'Σ');
-    assert_eq!('τ'.to_uppercase(), 'Τ');
-    assert_eq!('ι'.to_uppercase(), 'Ι');
-    assert_eq!('γ'.to_uppercase(), 'Γ');
-    assert_eq!('μ'.to_uppercase(), 'Μ');
-    assert_eq!('α'.to_uppercase(), 'Α');
-    assert_eq!('ς'.to_uppercase(), 'Σ');
+    fn upper(c: char) -> char {
+        let mut it = c.to_uppercase();
+        let c = it.next().unwrap();
+        assert!(it.next().is_none());
+        c
+    }
+    assert_eq!(upper('a'), 'A');
+    assert_eq!(upper('ö'), 'Ö');
+    assert_eq!(upper('ß'), 'ß'); // not ẞ: Latin capital letter sharp s
+    assert_eq!(upper('ü'), 'Ü');
+    assert_eq!(upper('💩'), '💩');
+
+    assert_eq!(upper('σ'), 'Σ');
+    assert_eq!(upper('τ'), 'Τ');
+    assert_eq!(upper('ι'), 'Ι');
+    assert_eq!(upper('γ'), 'Γ');
+    assert_eq!(upper('μ'), 'Μ');
+    assert_eq!(upper('α'), 'Α');
+    assert_eq!(upper('ς'), 'Σ');
 }
 
 #[test]
index 55fcb8498513c5a804cff7d0cbf3976e0b639171..2a48395271db3804ccb20a0b0c6be55bc67e72f4 100644 (file)
@@ -30,7 +30,7 @@ fn test_success() {
 }
 
 #[test]
-#[should_fail]
+#[should_panic]
 fn test_fail() {
     let mut i = 0;
     try_finally(
index bc3995439a0173c782f158f56daa1c835dd3b7ac..7db8db444ff20901b67040498155a4c2196a90a3 100644 (file)
@@ -161,7 +161,7 @@ fn test_format_radix() {
 }
 
 #[test]
-#[should_fail]
+#[should_panic]
 fn test_radix_base_too_large() {
     let _ = radix(55, 37);
 }
index 91d1ea2747657efb1d8ae45ee370981354a7f79b..0f4e7fcdda57bdb3469316492c823aa141acbdd9 100644 (file)
@@ -581,7 +581,7 @@ fn test_rposition() {
 }
 
 #[test]
-#[should_fail]
+#[should_panic]
 fn test_rposition_panic() {
     let v: [(Box<_>, Box<_>); 4] =
         [(box 0, box 0), (box 0, box 0),
index 59116f23d44b64ab7dbe50ba8e69702d4c557e41..fe0b10e91192bce5c1b62e288d0b0c9df9ffc748 100644 (file)
@@ -80,7 +80,7 @@ fn test_option_dance() {
     assert!(y.is_none());
 }
 
-#[test] #[should_fail]
+#[test] #[should_panic]
 fn test_option_too_much_dance() {
     let mut y = Some(marker::NoCopy);
     let _y2 = y.take().unwrap();
@@ -139,14 +139,14 @@ fn test_unwrap() {
 }
 
 #[test]
-#[should_fail]
+#[should_panic]
 fn test_unwrap_panic1() {
     let x: Option<int> = None;
     x.unwrap();
 }
 
 #[test]
-#[should_fail]
+#[should_panic]
 fn test_unwrap_panic2() {
     let x: Option<String> = None;
     x.unwrap();
index 10cc3ad64242720e59c2d5e9682a09d8f6aab45d..1c175ba99f7739619bd7c7b90148666d27c41052 100644 (file)
@@ -126,7 +126,7 @@ fn handler(msg: &'static str) -> int {
 }
 
 #[test]
-#[should_fail]
+#[should_panic]
 pub fn test_unwrap_or_else_panic() {
     fn handler(msg: &'static str) -> int {
         if msg == "I got this." {
index 617edb4bea60c2a73a424df5248bbdf114c439cf..38abf3881bdf63aaac1c47e870c1d44e6bd5996b 100644 (file)
@@ -46,7 +46,7 @@
 //!
 //! fn print_usage(program: &str, opts: &[OptGroup]) {
 //!     let brief = format!("Usage: {} [options]", program);
-//!     print!("{}", usage(brief.as_slice(), opts));
+//!     print!("{}", usage(brief, opts));
 //! }
 //!
 //! fn main() {
 //!         Err(f) => { panic!(f.to_string()) }
 //!     };
 //!     if matches.opt_present("h") {
-//!         print_usage(program.as_slice(), opts);
+//!         print_usage(program, opts);
 //!         return;
 //!     }
 //!     let output = matches.opt_str("o");
 //!     let input = if !matches.free.is_empty() {
 //!         matches.free[0].clone()
 //!     } else {
-//!         print_usage(program.as_slice(), opts);
+//!         print_usage(program, opts);
 //!         return;
 //!     };
-//!     do_work(input.as_slice(), output);
+//!     do_work(input, output);
 //! }
 //! ```
 
index e4927902cb3bb66184ad59f4c360818ee39491af..bf9d334e8a4734bf7814d31fdf5a30f49a458808 100644 (file)
@@ -109,12 +109,12 @@ fn test_exp() {
         }
     }
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn test_exp_invalid_lambda_zero() {
         Exp::new(0.0);
     }
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn test_exp_invalid_lambda_neg() {
         Exp::new(-10.0);
     }
index 38eba0cfc712f7221961113775972f80ad76cdc0..ae3724a2b431a1ca371465ced275fd5dfb13d88b 100644 (file)
@@ -356,7 +356,7 @@ fn test_chi_squared_large() {
         }
     }
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn test_chi_squared_invalid_dof() {
         ChiSquared::new(-1.0);
     }
index 12794ed69be38c7edd263b879969342f02a673bb..9775507b3cd578b38abd7c1225da82d0b8162369 100644 (file)
@@ -351,16 +351,16 @@ macro_rules! t {
            [50, 51, 52, 53, 54, 55, 56]);
     }
 
-    #[test] #[should_fail]
+    #[test] #[should_panic]
     fn test_weighted_choice_no_items() {
         WeightedChoice::<int>::new(&mut []);
     }
-    #[test] #[should_fail]
+    #[test] #[should_panic]
     fn test_weighted_choice_zero_weight() {
         WeightedChoice::new(&mut [Weighted { weight: 0, item: 0},
                                   Weighted { weight: 0, item: 1}]);
     }
-    #[test] #[should_fail]
+    #[test] #[should_panic]
     fn test_weighted_choice_weight_overflows() {
         let x = (-1) as uint / 2; // x + x + 2 is the overflow
         WeightedChoice::new(&mut [Weighted { weight: x, item: 0 },
index 83f202742d3f33da9dbdf016c32b1cbe541f93ce..ab5d03ad82557adfe8fbf28eca8dbd5d13df47e0 100644 (file)
@@ -175,7 +175,7 @@ fn test_normal() {
         }
     }
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn test_normal_invalid_sd() {
         Normal::new(10.0, -1.0);
     }
@@ -191,7 +191,7 @@ fn test_log_normal() {
         }
     }
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn test_log_normal_invalid_sd() {
         LogNormal::new(10.0, -1.0);
     }
index 4afc67d63c8f952c4ef4405016cb23a19874d56e..c5a260346e0adf17dc464bb62a57d4313d3e1e82 100644 (file)
@@ -169,12 +169,12 @@ mod tests {
     use distributions::{Sample, IndependentSample};
     use super::Range as Range;
 
-    #[should_fail]
+    #[should_panic]
     #[test]
     fn test_range_bad_limits_equal() {
         Range::new(10, 10);
     }
-    #[should_fail]
+    #[should_panic]
     #[test]
     fn test_range_bad_limits_flipped() {
         Range::new(10, 5);
index 5532e41028ad2aa6804e788d77465d1c41673d46..7ea62b7fd3f413b62d35b1d365872e645d3cc4ee 100644 (file)
 
 //! The ISAAC random number generator.
 
+#![allow(non_camel_case_types)]
+
 use core::prelude::*;
 use core::slice;
 use core::iter::{range_step, repeat};
-use core::num::wrapping::Wrapping;
+use core::num::wrapping::Wrapping as w;
 
 use {Rng, SeedableRng, Rand};
 
-const RAND_SIZE_LEN: u32 = 8;
-const RAND_SIZE: u32 = 1 << (RAND_SIZE_LEN as uint);
-const RAND_SIZE_UINT: uint = 1 << (RAND_SIZE_LEN as uint);
+type w32 = w<u32>;
+type w64 = w<u64>;
+
+const RAND_SIZE_LEN: usize = 8;
+const RAND_SIZE: u32 = 1 << RAND_SIZE_LEN;
+const RAND_SIZE_USIZE: usize = 1 << RAND_SIZE_LEN;
 
 /// A random number generator that uses the ISAAC algorithm[1].
 ///
 #[derive(Copy)]
 pub struct IsaacRng {
     cnt: u32,
-    rsl: [u32; RAND_SIZE_UINT],
-    mem: [u32; RAND_SIZE_UINT],
-    a: u32,
-    b: u32,
-    c: u32
+    rsl: [w32; RAND_SIZE_USIZE],
+    mem: [w32; RAND_SIZE_USIZE],
+    a: w32,
+    b: w32,
+    c: w32,
 }
 
 static EMPTY: IsaacRng = IsaacRng {
     cnt: 0,
-    rsl: [0; RAND_SIZE_UINT],
-    mem: [0; RAND_SIZE_UINT],
-    a: 0, b: 0, c: 0
+    rsl: [w(0); RAND_SIZE_USIZE],
+    mem: [w(0); RAND_SIZE_USIZE],
+    a: w(0), b: w(0), c: w(0),
 };
 
 impl IsaacRng {
@@ -61,7 +66,7 @@ pub fn new_unseeded() -> IsaacRng {
     /// of `rsl` as a seed, otherwise construct one algorithmically (not
     /// randomly).
     fn init(&mut self, use_rsl: bool) {
-        let mut a = Wrapping(0x9e3779b9);
+        let mut a = w(0x9e3779b9);
         let mut b = a;
         let mut c = a;
         let mut d = a;
@@ -90,16 +95,16 @@ macro_rules! mix {
         if use_rsl {
             macro_rules! memloop {
                 ($arr:expr) => {{
-                    for i in range_step(0, RAND_SIZE as uint, 8) {
-                        a=a+Wrapping($arr[i  ]); b=b+Wrapping($arr[i+1]);
-                        c=c+Wrapping($arr[i+2]); d=d+Wrapping($arr[i+3]);
-                        e=e+Wrapping($arr[i+4]); f=f+Wrapping($arr[i+5]);
-                        g=g+Wrapping($arr[i+6]); h=h+Wrapping($arr[i+7]);
+                    for i in range_step(0, RAND_SIZE_USIZE, 8) {
+                        a=a+$arr[i  ]; b=b+$arr[i+1];
+                        c=c+$arr[i+2]; d=d+$arr[i+3];
+                        e=e+$arr[i+4]; f=f+$arr[i+5];
+                        g=g+$arr[i+6]; h=h+$arr[i+7];
                         mix!();
-                        self.mem[i  ]=a.0; self.mem[i+1]=b.0;
-                        self.mem[i+2]=c.0; self.mem[i+3]=d.0;
-                        self.mem[i+4]=e.0; self.mem[i+5]=f.0;
-                        self.mem[i+6]=g.0; self.mem[i+7]=h.0;
+                        self.mem[i  ]=a; self.mem[i+1]=b;
+                        self.mem[i+2]=c; self.mem[i+3]=d;
+                        self.mem[i+4]=e; self.mem[i+5]=f;
+                        self.mem[i+6]=g; self.mem[i+7]=h;
                     }
                 }}
             }
@@ -107,12 +112,12 @@ macro_rules! memloop {
             memloop!(self.rsl);
             memloop!(self.mem);
         } else {
-            for i in range_step(0, RAND_SIZE as uint, 8) {
+            for i in range_step(0, RAND_SIZE_USIZE, 8) {
                 mix!();
-                self.mem[i  ]=a.0; self.mem[i+1]=b.0;
-                self.mem[i+2]=c.0; self.mem[i+3]=d.0;
-                self.mem[i+4]=e.0; self.mem[i+5]=f.0;
-                self.mem[i+6]=g.0; self.mem[i+7]=h.0;
+                self.mem[i  ]=a; self.mem[i+1]=b;
+                self.mem[i+2]=c; self.mem[i+3]=d;
+                self.mem[i+4]=e; self.mem[i+5]=f;
+                self.mem[i+6]=g; self.mem[i+7]=h;
             }
         }
 
@@ -123,32 +128,31 @@ macro_rules! memloop {
     #[inline]
     #[allow(unsigned_negation)]
     fn isaac(&mut self) {
-        self.c += 1;
+        self.c = self.c + w(1);
         // abbreviations
         let mut a = self.a;
         let mut b = self.b + self.c;
 
-        const MIDPOINT: uint = (RAND_SIZE / 2) as uint;
+        const MIDPOINT: usize = RAND_SIZE_USIZE / 2;
 
         macro_rules! ind {
-            ($x:expr) => (Wrapping( self.mem[(($x >> 2) as uint &
-                                              ((RAND_SIZE - 1) as uint))] ))
+            ($x:expr) => ( self.mem[($x >> 2).0 as usize & (RAND_SIZE_USIZE - 1)] )
         }
 
         let r = [(0, MIDPOINT), (MIDPOINT, 0)];
-        for &(mr_offset, m2_offset) in &r {
+        for &(mr_offset, m2_offset) in r.iter() {
 
             macro_rules! rngstepp {
                 ($j:expr, $shift:expr) => {{
                     let base = $j;
-                    let mix = a << $shift as uint;
+                    let mix = a << $shift;
 
                     let x = self.mem[base  + mr_offset];
-                    a = (Wrapping(a ^ mix) + Wrapping(self.mem[base + m2_offset])).0;
-                    let y = ind!(x) + Wrapping(a) + Wrapping(b);
-                    self.mem[base + mr_offset] = y.0;
+                    a = (a ^ mix) + self.mem[base + m2_offset];
+                    let y = ind!(x) + a + b;
+                    self.mem[base + mr_offset] = y;
 
-                    b = (ind!(y.0 >> RAND_SIZE_LEN as uint) + Wrapping(x)).0;
+                    b = ind!(y >> RAND_SIZE_LEN) + x;
                     self.rsl[base + mr_offset] = b;
                 }}
             }
@@ -156,14 +160,14 @@ macro_rules! rngstepp {
             macro_rules! rngstepn {
                 ($j:expr, $shift:expr) => {{
                     let base = $j;
-                    let mix = a >> $shift as uint;
+                    let mix = a >> $shift;
 
                     let x = self.mem[base  + mr_offset];
-                    a = (Wrapping(a ^ mix) + Wrapping(self.mem[base + m2_offset])).0;
-                    let y = ind!(x) + Wrapping(a) + Wrapping(b);
-                    self.mem[base + mr_offset] = y.0;
+                    a = (a ^ mix) + self.mem[base + m2_offset];
+                    let y = ind!(x) + a + b;
+                    self.mem[base + mr_offset] = y;
 
-                    b = (ind!(y.0 >> RAND_SIZE_LEN as uint) + Wrapping(x)).0;
+                    b = ind!(y >> RAND_SIZE_LEN) + x;
                     self.rsl[base + mr_offset] = b;
                 }}
             }
@@ -209,7 +213,7 @@ fn next_u32(&mut self) -> u32 {
         // (the % is cheaply telling the optimiser that we're always
         // in bounds, without unsafe. NB. this is a power of two, so
         // it optimises to a bitwise mask).
-        self.rsl[(self.cnt % RAND_SIZE) as uint]
+        self.rsl[(self.cnt % RAND_SIZE) as usize].0
     }
 }
 
@@ -220,12 +224,12 @@ fn reseed(&mut self, seed: &'a [u32]) {
         let seed_iter = seed.iter().cloned().chain(repeat(0));
 
         for (rsl_elem, seed_elem) in self.rsl.iter_mut().zip(seed_iter) {
-            *rsl_elem = seed_elem;
+            *rsl_elem = w(seed_elem);
         }
         self.cnt = 0;
-        self.a = 0;
-        self.b = 0;
-        self.c = 0;
+        self.a = w(0);
+        self.b = w(0);
+        self.c = w(0);
 
         self.init(true);
     }
@@ -248,21 +252,21 @@ fn rand<R: Rng>(other: &mut R) -> IsaacRng {
         unsafe {
             let ptr = ret.rsl.as_mut_ptr() as *mut u8;
 
-            let slice = slice::from_raw_parts_mut(ptr, (RAND_SIZE * 4) as uint);
+            let slice = slice::from_raw_parts_mut(ptr, RAND_SIZE_USIZE * 4);
             other.fill_bytes(slice);
         }
         ret.cnt = 0;
-        ret.a = 0;
-        ret.b = 0;
-        ret.c = 0;
+        ret.a = w(0);
+        ret.b = w(0);
+        ret.c = w(0);
 
         ret.init(true);
         return ret;
     }
 }
 
-const RAND_SIZE_64_LEN: uint = 8;
-const RAND_SIZE_64: uint = 1 << RAND_SIZE_64_LEN;
+const RAND_SIZE_64_LEN: usize = 8;
+const RAND_SIZE_64: usize = 1 << RAND_SIZE_64_LEN;
 
 /// A random number generator that uses ISAAC-64[1], the 64-bit
 /// variant of the ISAAC algorithm.
@@ -276,19 +280,19 @@ fn rand<R: Rng>(other: &mut R) -> IsaacRng {
 /// generator*](http://www.burtleburtle.net/bob/rand/isaacafa.html)
 #[derive(Copy)]
 pub struct Isaac64Rng {
-    cnt: uint,
-    rsl: [u64; RAND_SIZE_64],
-    mem: [u64; RAND_SIZE_64],
-    a: u64,
-    b: u64,
-    c: u64,
+    cnt: usize,
+    rsl: [w64; RAND_SIZE_64],
+    mem: [w64; RAND_SIZE_64],
+    a: w64,
+    b: w64,
+    c: w64,
 }
 
 static EMPTY_64: Isaac64Rng = Isaac64Rng {
     cnt: 0,
-    rsl: [0; RAND_SIZE_64],
-    mem: [0; RAND_SIZE_64],
-    a: 0, b: 0, c: 0,
+    rsl: [w(0); RAND_SIZE_64],
+    mem: [w(0); RAND_SIZE_64],
+    a: w(0), b: w(0), c: w(0),
 };
 
 impl Isaac64Rng {
@@ -306,7 +310,7 @@ pub fn new_unseeded() -> Isaac64Rng {
     fn init(&mut self, use_rsl: bool) {
         macro_rules! init {
             ($var:ident) => (
-                let mut $var = Wrapping(0x9e3779b97f4a7c13);
+                let mut $var = w(0x9e3779b97f4a7c13);
             )
         }
         init!(a); init!(b); init!(c); init!(d);
@@ -314,14 +318,14 @@ macro_rules! init {
 
         macro_rules! mix {
             () => {{
-                a=a-e; f=f^h>>9;  h=h+a;
-                b=b-f; g=g^a<<9;  a=a+b;
-                c=c-g; h=h^b>>23; b=b+c;
-                d=d-h; a=a^c<<15; c=c+d;
-                e=e-a; b=b^d>>14; d=d+e;
-                f=f-b; c=c^e<<20; e=e+f;
-                g=g-c; d=d^f>>17; f=f+g;
-                h=h-d; e=e^g<<14; g=g+h;
+                a=a-e; f=f^(h>>9);  h=h+a;
+                b=b-f; g=g^(a<<9);  a=a+b;
+                c=c-g; h=h^(b>>23); b=b+c;
+                d=d-h; a=a^(c<<15); c=c+d;
+                e=e-a; b=b^(d>>14); d=d+e;
+                f=f-b; c=c^(e<<20); e=e+f;
+                g=g-c; d=d^(f>>17); f=f+g;
+                h=h-d; e=e^(g<<14); g=g+h;
             }}
         }
 
@@ -333,15 +337,15 @@ macro_rules! mix {
             macro_rules! memloop {
                 ($arr:expr) => {{
                     for i in (0..RAND_SIZE_64 / 8).map(|i| i * 8) {
-                        a=a+Wrapping($arr[i  ]); b=b+Wrapping($arr[i+1]);
-                        c=c+Wrapping($arr[i+2]); d=d+Wrapping($arr[i+3]);
-                        e=e+Wrapping($arr[i+4]); f=f+Wrapping($arr[i+5]);
-                        g=g+Wrapping($arr[i+6]); h=h+Wrapping($arr[i+7]);
+                        a=a+$arr[i  ]; b=b+$arr[i+1];
+                        c=c+$arr[i+2]; d=d+$arr[i+3];
+                        e=e+$arr[i+4]; f=f+$arr[i+5];
+                        g=g+$arr[i+6]; h=h+$arr[i+7];
                         mix!();
-                        self.mem[i  ]=a.0; self.mem[i+1]=b.0;
-                        self.mem[i+2]=c.0; self.mem[i+3]=d.0;
-                        self.mem[i+4]=e.0; self.mem[i+5]=f.0;
-                        self.mem[i+6]=g.0; self.mem[i+7]=h.0;
+                        self.mem[i  ]=a; self.mem[i+1]=b;
+                        self.mem[i+2]=c; self.mem[i+3]=d;
+                        self.mem[i+4]=e; self.mem[i+5]=f;
+                        self.mem[i+6]=g; self.mem[i+7]=h;
                     }
                 }}
             }
@@ -351,10 +355,10 @@ macro_rules! memloop {
         } else {
             for i in (0..RAND_SIZE_64 / 8).map(|i| i * 8) {
                 mix!();
-                self.mem[i  ]=a.0; self.mem[i+1]=b.0;
-                self.mem[i+2]=c.0; self.mem[i+3]=d.0;
-                self.mem[i+4]=e.0; self.mem[i+5]=f.0;
-                self.mem[i+6]=g.0; self.mem[i+7]=h.0;
+                self.mem[i  ]=a; self.mem[i+1]=b;
+                self.mem[i+2]=c; self.mem[i+3]=d;
+                self.mem[i+4]=e; self.mem[i+5]=f;
+                self.mem[i+6]=g; self.mem[i+7]=h;
             }
         }
 
@@ -363,35 +367,35 @@ macro_rules! memloop {
 
     /// Refills the output buffer (`self.rsl`)
     fn isaac64(&mut self) {
-        self.c += 1;
+        self.c = self.c + w(1);
         // abbreviations
-        let mut a = Wrapping(self.a);
-        let mut b = Wrapping(self.b) + Wrapping(self.c);
-        const MIDPOINT: uint =  RAND_SIZE_64 / 2;
-        const MP_VEC: [(uint, uint); 2] = [(0,MIDPOINT), (MIDPOINT, 0)];
+        let mut a = self.a;
+        let mut b = self.b + self.c;
+        const MIDPOINT: usize =  RAND_SIZE_64 / 2;
+        const MP_VEC: [(usize, usize); 2] = [(0,MIDPOINT), (MIDPOINT, 0)];
         macro_rules! ind {
             ($x:expr) => {
-                *self.mem.get_unchecked(($x as uint >> 3) & (RAND_SIZE_64 - 1))
+                *self.mem.get_unchecked((($x >> 3).0 as usize) & (RAND_SIZE_64 - 1))
             }
         }
 
-        for &(mr_offset, m2_offset) in &MP_VEC {
+        for &(mr_offset, m2_offset) in MP_VEC.iter() {
             for base in (0..MIDPOINT / 4).map(|i| i * 4) {
 
                 macro_rules! rngstepp {
                     ($j:expr, $shift:expr) => {{
                         let base = base + $j;
-                        let mix = a ^ (a << $shift as uint);
+                        let mix = a ^ (a << $shift);
                         let mix = if $j == 0 {!mix} else {mix};
 
                         unsafe {
-                            let x = Wrapping(*self.mem.get_unchecked(base + mr_offset));
-                            a = mix + Wrapping(*self.mem.get_unchecked(base + m2_offset));
-                            let y = Wrapping(ind!(x.0)) + a + b;
-                            *self.mem.get_unchecked_mut(base + mr_offset) = y.0;
+                            let x = *self.mem.get_unchecked(base + mr_offset);
+                            a = mix + *self.mem.get_unchecked(base + m2_offset);
+                            let y = ind!(x) + a + b;
+                            *self.mem.get_unchecked_mut(base + mr_offset) = y;
 
-                            b = Wrapping(ind!(y.0 >> RAND_SIZE_64_LEN)) + x;
-                            *self.rsl.get_unchecked_mut(base + mr_offset) = b.0;
+                            b = ind!(y >> RAND_SIZE_64_LEN) + x;
+                            *self.rsl.get_unchecked_mut(base + mr_offset) = b;
                         }
                     }}
                 }
@@ -399,17 +403,17 @@ macro_rules! rngstepp {
                 macro_rules! rngstepn {
                     ($j:expr, $shift:expr) => {{
                         let base = base + $j;
-                        let mix = a ^ (a >> $shift as uint);
+                        let mix = a ^ (a >> $shift);
                         let mix = if $j == 0 {!mix} else {mix};
 
                         unsafe {
-                            let x = Wrapping(*self.mem.get_unchecked(base + mr_offset));
-                            a = mix + Wrapping(*self.mem.get_unchecked(base + m2_offset));
-                            let y = Wrapping(ind!(x.0)) + a + b;
-                            *self.mem.get_unchecked_mut(base + mr_offset) = y.0;
+                            let x = *self.mem.get_unchecked(base + mr_offset);
+                            a = mix + *self.mem.get_unchecked(base + m2_offset);
+                            let y = ind!(x) + a + b;
+                            *self.mem.get_unchecked_mut(base + mr_offset) = y;
 
-                            b = Wrapping(ind!(y.0 >> RAND_SIZE_64_LEN)) + x;
-                            *self.rsl.get_unchecked_mut(base + mr_offset) = b.0;
+                            b = ind!(y >> RAND_SIZE_64_LEN) + x;
+                            *self.rsl.get_unchecked_mut(base + mr_offset) = b;
                         }
                     }}
                 }
@@ -421,8 +425,8 @@ macro_rules! rngstepn {
             }
         }
 
-        self.a = a.0;
-        self.b = b.0;
+        self.a = a;
+        self.b = b;
         self.cnt = RAND_SIZE_64;
     }
 }
@@ -452,7 +456,7 @@ fn next_u64(&mut self) -> u64 {
         // See corresponding location in IsaacRng.next_u32 for
         // explanation.
         debug_assert!(self.cnt < RAND_SIZE_64);
-        self.rsl[(self.cnt % RAND_SIZE_64) as uint]
+        self.rsl[(self.cnt % RAND_SIZE_64) as usize].0
     }
 }
 
@@ -463,12 +467,12 @@ fn reseed(&mut self, seed: &'a [u64]) {
         let seed_iter = seed.iter().cloned().chain(repeat(0));
 
         for (rsl_elem, seed_elem) in self.rsl.iter_mut().zip(seed_iter) {
-            *rsl_elem = seed_elem;
+            *rsl_elem = w(seed_elem);
         }
         self.cnt = 0;
-        self.a = 0;
-        self.b = 0;
-        self.c = 0;
+        self.a = w(0);
+        self.b = w(0);
+        self.c = w(0);
 
         self.init(true);
     }
@@ -491,13 +495,13 @@ fn rand<R: Rng>(other: &mut R) -> Isaac64Rng {
         unsafe {
             let ptr = ret.rsl.as_mut_ptr() as *mut u8;
 
-            let slice = slice::from_raw_parts_mut(ptr, (RAND_SIZE_64 * 8) as uint);
+            let slice = slice::from_raw_parts_mut(ptr, RAND_SIZE_64 * 8);
             other.fill_bytes(slice);
         }
         ret.cnt = 0;
-        ret.a = 0;
-        ret.b = 0;
-        ret.c = 0;
+        ret.a = w(0);
+        ret.b = w(0);
+        ret.c = w(0);
 
         ret.init(true);
         return ret;
@@ -516,16 +520,16 @@ mod test {
     #[test]
     fn test_rng_32_rand_seeded() {
         let s = ::test::rng().gen_iter::<u32>().take(256).collect::<Vec<u32>>();
-        let mut ra: IsaacRng = SeedableRng::from_seed(&*s);
-        let mut rb: IsaacRng = SeedableRng::from_seed(&*s);
+        let mut ra: IsaacRng = SeedableRng::from_seed(&s[..]);
+        let mut rb: IsaacRng = SeedableRng::from_seed(&s[..]);
         assert!(order::equals(ra.gen_ascii_chars().take(100),
                               rb.gen_ascii_chars().take(100)));
     }
     #[test]
     fn test_rng_64_rand_seeded() {
         let s = ::test::rng().gen_iter::<u64>().take(256).collect::<Vec<u64>>();
-        let mut ra: Isaac64Rng = SeedableRng::from_seed(&*s);
-        let mut rb: Isaac64Rng = SeedableRng::from_seed(&*s);
+        let mut ra: Isaac64Rng = SeedableRng::from_seed(&s[..]);
+        let mut rb: Isaac64Rng = SeedableRng::from_seed(&s[..]);
         assert!(order::equals(ra.gen_ascii_chars().take(100),
                               rb.gen_ascii_chars().take(100)));
     }
@@ -550,7 +554,7 @@ fn test_rng_64_seeded() {
     #[test]
     fn test_rng_32_reseed() {
         let s = ::test::rng().gen_iter::<u32>().take(256).collect::<Vec<u32>>();
-        let mut r: IsaacRng = SeedableRng::from_seed(&*s);
+        let mut r: IsaacRng = SeedableRng::from_seed(&s[..]);
         let string1: String = r.gen_ascii_chars().take(100).collect();
 
         r.reseed(&s);
@@ -561,7 +565,7 @@ fn test_rng_32_reseed() {
     #[test]
     fn test_rng_64_reseed() {
         let s = ::test::rng().gen_iter::<u64>().take(256).collect::<Vec<u64>>();
-        let mut r: Isaac64Rng = SeedableRng::from_seed(&*s);
+        let mut r: Isaac64Rng = SeedableRng::from_seed(&s[..]);
         let string1: String = r.gen_ascii_chars().take(100).collect();
 
         r.reseed(&s);
index b28106a72e048603411146eb5baef7c07ddc8fb0..081c64ecae88102920ea0bbaa03e0b4a57d16422 100644 (file)
@@ -254,3 +254,5 @@ pub struct LinkMeta {
 pub const tag_codemap_filemap: uint = 0xa2;
 
 pub const tag_item_super_predicates: uint = 0xa3;
+
+pub const tag_defaulted_trait: uint = 0xa4;
index 515e85410d9fd031767da5a65446b7217daf4e3a..00a47ce17dae070a76d2a001265b1056563a9968 100644 (file)
@@ -493,7 +493,7 @@ fn read_extension_crate(&mut self, span: Span, info: &CrateInfo) -> ExtensionCra
         };
 
         let dylib = library.dylib.clone();
-        let register = should_link && self.existing_match(info.name.as_slice(),
+        let register = should_link && self.existing_match(&info.name,
                                                           None,
                                                           PathKind::Crate).is_none();
         let metadata = if register {
index c7785ff4c8772dde596ff9a2853b730a114d7e1f..ed5783c8dba661e4a1927964362abeb0b5e9a602 100644 (file)
@@ -407,7 +407,7 @@ pub fn is_associated_type(cstore: &cstore::CStore, def: ast::DefId) -> bool {
     decoder::is_associated_type(&*cdata, def.node)
 }
 
-pub fn is_default_trait(cstore: &cstore::CStore, def: ast::DefId) -> bool {
-    let cdata = cstore.get_crate_data(def.krate);
-    decoder::is_default_trait(&*cdata, def.node)
+pub fn is_defaulted_trait(cstore: &cstore::CStore, trait_def_id: ast::DefId) -> bool {
+    let cdata = cstore.get_crate_data(trait_def_id.krate);
+    decoder::is_defaulted_trait(&*cdata, trait_def_id.node)
 }
index f5f9bd41c8b8e4274d2cc410b2075cce0df04e23..dbbc17c018a2fc92b2b0c235db4750ff8db44b93 100644 (file)
@@ -1537,12 +1537,11 @@ pub fn is_associated_type(cdata: Cmd, id: ast::NodeId) -> bool {
     }
 }
 
-pub fn is_default_trait<'tcx>(cdata: Cmd, id: ast::NodeId) -> bool {
-    let item_doc = lookup_item(id, cdata.data());
-    match item_family(item_doc) {
-        Family::DefaultImpl => true,
-        _ => false
-    }
+pub fn is_defaulted_trait<'tcx>(cdata: Cmd, trait_id: ast::NodeId) -> bool {
+    let trait_doc = lookup_item(trait_id, cdata.data());
+    assert!(item_family(trait_doc) == Family::Trait);
+    let defaulted_doc = reader::get_doc(trait_doc, tag_defaulted_trait);
+    reader::doc_as_u8(defaulted_doc) != 0
 }
 
 pub fn get_imported_filemaps(metadata: &[u8]) -> Vec<codemap::FileMap> {
index c4ba2373b9f570cb624d9fe4ed43e40e9045af81..08263eb8e6a03978478147d8ed97b3fd6c4f138a 100644 (file)
@@ -1288,6 +1288,7 @@ fn add_to_index(item: &ast::Item, rbml_w: &mut Encoder,
         let trait_predicates = ty::lookup_predicates(tcx, def_id);
         encode_unsafety(rbml_w, trait_def.unsafety);
         encode_paren_sugar(rbml_w, trait_def.paren_sugar);
+        encode_defaulted(rbml_w, ty::trait_has_default_impl(tcx, def_id));
         encode_associated_type_names(rbml_w, &trait_def.associated_type_names);
         encode_generics(rbml_w, ecx, &trait_def.generics, &trait_predicates, tag_item_generics);
         encode_predicates(rbml_w, ecx, &ty::lookup_super_predicates(tcx, def_id),
@@ -1660,6 +1661,11 @@ fn encode_paren_sugar(rbml_w: &mut Encoder, paren_sugar: bool) {
     rbml_w.wr_tagged_u8(tag_paren_sugar, byte);
 }
 
+fn encode_defaulted(rbml_w: &mut Encoder, is_defaulted: bool) {
+    let byte: u8 = if is_defaulted {1} else {0};
+    rbml_w.wr_tagged_u8(tag_defaulted_trait, byte);
+}
+
 fn encode_associated_type_names(rbml_w: &mut Encoder, names: &[ast::Name]) {
     rbml_w.start_tag(tag_associated_type_names);
     for &name in names {
index 10885359985069eabaed3869240966c63f3e049c..40bba6fb0ac7cde29edb64d4533206971b2971b7 100644 (file)
@@ -276,7 +276,7 @@ fn check_for_static_nan(cx: &MatchCheckCtxt, pat: &Pat) {
                     let subspan = p.span.lo <= err.span.lo && err.span.hi <= p.span.hi;
                     cx.tcx.sess.span_err(err.span,
                                          &format!("constant evaluation error: {}",
-                                                  err.description().as_slice()));
+                                                  err.description()));
                     if !subspan {
                         cx.tcx.sess.span_note(p.span,
                                               "in pattern here")
index 896a0010e7e7f93e5fd789ec571673f34f003b1b..f215b59a6cd0eda1bad552523440ab5c66c31eb6 100644 (file)
@@ -204,7 +204,7 @@ pub fn const_expr_to_pat(tcx: &ty::ctxt, expr: &Expr, span: Span) -> P<ast::Pat>
 pub fn eval_const_expr(tcx: &ty::ctxt, e: &Expr) -> const_val {
     match eval_const_expr_partial(tcx, e, None) {
         Ok(r) => r,
-        Err(s) => tcx.sess.span_fatal(s.span, s.description().as_slice())
+        Err(s) => tcx.sess.span_fatal(s.span, &s.description())
     }
 }
 
@@ -665,14 +665,14 @@ pub fn compare_lit_exprs<'tcx>(tcx: &ty::ctxt<'tcx>,
     let a = match eval_const_expr_partial(tcx, a, ty_hint) {
         Ok(a) => a,
         Err(e) => {
-            tcx.sess.span_err(a.span, e.description().as_slice());
+            tcx.sess.span_err(a.span, &e.description());
             return None;
         }
     };
     let b = match eval_const_expr_partial(tcx, b, ty_hint) {
         Ok(b) => b,
         Err(e) => {
-            tcx.sess.span_err(b.span, e.description().as_slice());
+            tcx.sess.span_err(b.span, &e.description());
             return None;
         }
     };
index add829074c4f0dcc6689d055e87f179580a348aa..4cb4d343de758f3e9cb4b31d40586aa3d57cdbf1 100644 (file)
@@ -757,8 +757,8 @@ pub struct ctxt<'tcx> {
     /// Maps a trait onto a list of impls of that trait.
     pub trait_impls: RefCell<DefIdMap<Rc<RefCell<Vec<ast::DefId>>>>>,
 
-    /// Maps a trait onto a list of *default* trait implementations
-    default_trait_impls: RefCell<DefIdMap<ast::DefId>>,
+    /// A set of traits that have a default impl
+    traits_with_default_impls: RefCell<DefIdMap<()>>,
 
     /// Maps a DefId of a type to a list of its inherent impls.
     /// Contains implementations of methods that are inherent to a type.
@@ -2591,7 +2591,7 @@ pub fn mk_ctxt<'tcx>(s: Session,
         destructor_for_type: RefCell::new(DefIdMap()),
         destructors: RefCell::new(DefIdSet()),
         trait_impls: RefCell::new(DefIdMap()),
-        default_trait_impls: RefCell::new(DefIdMap()),
+        traits_with_default_impls: RefCell::new(DefIdMap()),
         inherent_impls: RefCell::new(DefIdMap()),
         impl_items: RefCell::new(DefIdMap()),
         used_unsafe: RefCell::new(NodeSet()),
@@ -5485,7 +5485,7 @@ pub fn enum_variants<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId)
                                         Err(err) => {
                                             span_err!(cx.sess, err.span, E0305,
                                                       "constant evaluation error: {}",
-                                                      err.description().as_slice());
+                                                      err.description());
                                         }
                                     }
                                 } else {
@@ -5606,8 +5606,7 @@ pub fn predicates<'tcx>(
 pub fn get_attrs<'tcx>(tcx: &'tcx ctxt, did: DefId)
                        -> Cow<'tcx, [ast::Attribute]> {
     if is_local(did) {
-        let item = tcx.map.expect_item(did.node);
-        Cow::Borrowed(&item.attrs)
+        Cow::Borrowed(tcx.map.attrs(did.node))
     } else {
         Cow::Owned(csearch::get_item_attrs(&tcx.sess.cstore, did))
     }
@@ -5975,32 +5974,22 @@ pub fn item_variances(tcx: &ctxt, item_id: ast::DefId) -> Rc<ItemVariances> {
         || Rc::new(csearch::get_item_variances(&tcx.sess.cstore, item_id)))
 }
 
-pub fn trait_default_impl(tcx: &ctxt, trait_def_id: DefId) -> Option<ast::DefId> {
-    match tcx.default_trait_impls.borrow().get(&trait_def_id) {
-        Some(id) => Some(*id),
-        None => None
-    }
-}
-
 pub fn trait_has_default_impl(tcx: &ctxt, trait_def_id: DefId) -> bool {
+    populate_implementations_for_trait_if_necessary(tcx, trait_def_id);
     match tcx.lang_items.to_builtin_kind(trait_def_id) {
         Some(BoundSend) | Some(BoundSync) => true,
-        _ => tcx.default_trait_impls.borrow().contains_key(&trait_def_id)
+        _ => tcx.traits_with_default_impls.borrow().contains_key(&trait_def_id),
     }
 }
 
 /// Records a trait-to-implementation mapping.
-pub fn record_default_trait_implementation(tcx: &ctxt,
-                                           trait_def_id: DefId,
-                                           impl_def_id: DefId) {
-
+pub fn record_trait_has_default_impl(tcx: &ctxt, trait_def_id: DefId) {
     // We're using the latest implementation found as the reference one.
     // Duplicated implementations are caught and reported in the coherence
     // step.
-    tcx.default_trait_impls.borrow_mut().insert(trait_def_id, impl_def_id);
+    tcx.traits_with_default_impls.borrow_mut().insert(trait_def_id, ());
 }
 
-
 /// Records a trait-to-implementation mapping.
 pub fn record_trait_implementation(tcx: &ctxt,
                                    trait_def_id: DefId,
@@ -6031,8 +6020,7 @@ pub fn populate_implementations_for_type_if_necessary(tcx: &ctxt,
     debug!("populate_implementations_for_type_if_necessary: searching for {:?}", type_id);
 
     let mut inherent_impls = Vec::new();
-    csearch::each_implementation_for_type(&tcx.sess.cstore, type_id,
-            |impl_def_id| {
+    csearch::each_implementation_for_type(&tcx.sess.cstore, type_id, |impl_def_id| {
         let impl_items = csearch::get_impl_items(&tcx.sess.cstore, impl_def_id);
 
         // Record the trait->implementation mappings, if applicable.
@@ -6078,27 +6066,20 @@ pub fn populate_implementations_for_trait_if_necessary(
     if trait_id.krate == LOCAL_CRATE {
         return
     }
+
     if tcx.populated_external_traits.borrow().contains(&trait_id) {
         return
     }
 
-    csearch::each_implementation_for_trait(&tcx.sess.cstore, trait_id,
-            |implementation_def_id|{
-        let impl_items = csearch::get_impl_items(&tcx.sess.cstore, implementation_def_id);
+    if csearch::is_defaulted_trait(&tcx.sess.cstore, trait_id) {
+        record_trait_has_default_impl(tcx, trait_id);
+    }
 
-        if csearch::is_default_trait(&tcx.sess.cstore, implementation_def_id) {
-            record_default_trait_implementation(tcx, trait_id,
-                                                implementation_def_id);
-            tcx.populated_external_traits.borrow_mut().insert(trait_id);
+    csearch::each_implementation_for_trait(&tcx.sess.cstore, trait_id, |implementation_def_id| {
+        let impl_items = csearch::get_impl_items(&tcx.sess.cstore, implementation_def_id);
 
-            // Nothing else to do for default trait implementations since
-            // they are not allowed to have type parameters, methods, or any
-            // other item that could be associated to a trait implementation.
-            return;
-        } else {
-            // Record the trait->implementation mapping.
-            record_trait_implementation(tcx, trait_id, implementation_def_id);
-        }
+        // Record the trait->implementation mapping.
+        record_trait_implementation(tcx, trait_id, implementation_def_id);
 
         // For any methods that use a default implementation, add them to
         // the map. This is a bit unfortunate.
@@ -6108,8 +6089,8 @@ pub fn populate_implementations_for_trait_if_necessary(
                 MethodTraitItem(method) => {
                     if let Some(source) = method.provided_source {
                         tcx.provided_method_sources
-                           .borrow_mut()
-                           .insert(method_def_id, source);
+                            .borrow_mut()
+                            .insert(method_def_id, source);
                     }
                 }
                 TypeTraitItem(_) => {}
index 09a122544147704a16436c54460d73e9ef94a341..f41d969c1a271ccf5da0cba4ae20d3003b1f7316 100644 (file)
@@ -115,7 +115,7 @@ pub fn explain_region_and_span(cx: &ctxt, region: ty::Region)
             region::CodeExtent::Misc(_) => tag,
             region::CodeExtent::DestructionScope(_) => {
                 new_string = format!("destruction scope surrounding {}", tag);
-                new_string.as_slice()
+                &*new_string
             }
             region::CodeExtent::Remainder(r) => {
                 new_string = format!("block suffix following statement {}",
index 482c710149c0920a3d5ce7103ff955dbf8504cfd..1a399519296a829ecd782994096376ff890a392b 100644 (file)
@@ -548,7 +548,7 @@ fn test_add_bytes_to_bits_ok() {
 
     // A simple failure case - adding 1 to the max value
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn test_add_bytes_to_bits_overflow() {
         super::add_bytes_to_bits::<u64>(Int::max_value(), 1);
     }
index c15ddf3ae779fbdfc8377433fde482bb117fa377..0367130c1320fe3e65fc8b430a2d34ec69b81f30 100644 (file)
@@ -86,7 +86,7 @@
 ///     let mut flags = FLAG_A | FLAG_B;
 ///     flags.clear();
 ///     assert!(flags.is_empty());
-///     assert_eq!(format!("{:?}", flags).as_slice(), "hi!");
+///     assert_eq!(format!("{:?}", flags), "hi!");
 /// }
 /// ```
 ///
index 42b3555b54edef926dc7d2aadddd436630c4aa9a..b176d8d4118a394cf2186a27c976d9c8ce0d6e99 100644 (file)
@@ -704,9 +704,9 @@ pub fn report_partial_reinitialization_of_uninitialized_structure(
         self.tcx
             .sess
             .span_err(span,
-                      (format!("partial reinitialization of uninitialized \
+                      &format!("partial reinitialization of uninitialized \
                                structure `{}`",
-                               self.loan_path_to_string(lp))).as_slice());
+                               self.loan_path_to_string(lp)));
     }
 
     pub fn report_reassigned_immutable_variable(&self,
index 565782b29e97126041f7d8894437646a42d88698..dc27a30110950454f813cf5ac82003408a379e37 100644 (file)
@@ -927,7 +927,7 @@ pub fn build_output_filenames(input: &Input,
             // We want to toss everything after the final '.'
             let dirpath = match *odir {
                 Some(ref d) => d.clone(),
-                None => PathBuf::new(".")
+                None => PathBuf::new("")
             };
 
             // If a crate name is present, we use it as the link name
@@ -954,8 +954,11 @@ pub fn build_output_filenames(input: &Input,
             if *odir != None {
                 sess.warn("ignoring --out-dir flag due to -o flag.");
             }
+
+            let cur_dir = Path::new("");
+
             OutputFilenames {
-                out_directory: out_file.parent().unwrap().to_path_buf(),
+                out_directory: out_file.parent().unwrap_or(cur_dir).to_path_buf(),
                 out_filestem: out_file.file_stem().unwrap()
                                       .to_str().unwrap().to_string(),
                 single_output_file: ofile,
index c09b018ab634579a4b295a7c9b0e485edc5cbd5c..716b1116a2062aba42f2a9ccbc9a0304398f341d 100644 (file)
@@ -36,7 +36,6 @@
 #![feature(rustc_private)]
 #![feature(unsafe_destructor)]
 #![feature(staged_api)]
-#![feature(unicode)]
 #![feature(exit_status)]
 #![feature(path)]
 #![feature(io)]
@@ -618,8 +617,7 @@ fn sort_lint_groups(lints: Vec<(&'static str, Vec<lint::LintId>, bool)>)
 
     let print_lint_groups = |lints: Vec<(&'static str, Vec<lint::LintId>)>| {
         for (name, to) in lints {
-            let name = name.chars().map(|x| x.to_lowercase())
-                           .collect::<String>().replace("_", "-");
+            let name = name.to_lowercase().replace("_", "-");
             let desc = to.into_iter().map(|x| x.as_str().replace("_", "-"))
                          .collect::<Vec<String>>().connect(", ");
             println!("    {}  {}",
index 1eea52fe1bb205ce05c6b433fd82baecd90bfee4..99febcfe346218290dae18c0b124675e85910dd9 100644 (file)
@@ -810,11 +810,11 @@ fn is_camel_case(ident: ast::Ident) -> bool {
         fn to_camel_case(s: &str) -> String {
             s.split('_').flat_map(|word| word.chars().enumerate().map(|(i, c)|
                 if i == 0 {
-                    c.to_uppercase()
+                    c.to_uppercase().collect::<String>()
                 } else {
-                    c
+                    c.to_string()
                 }
-            )).collect()
+            )).collect::<Vec<_>>().concat()
         }
 
         let s = token::get_ident(ident);
@@ -947,7 +947,7 @@ fn to_snake_case(mut str: &str) -> String {
                     buf = String::new();
                 }
                 last_upper = ch.is_uppercase();
-                buf.push(ch.to_lowercase());
+                buf.extend(ch.to_lowercase());
             }
             words.push(buf);
         }
@@ -1064,8 +1064,7 @@ fn check_upper_case(cx: &Context, sort: &str, ident: ast::Ident, span: Span) {
         let s = token::get_ident(ident);
 
         if s.chars().any(|c| c.is_lowercase()) {
-            let uc: String = NonSnakeCase::to_snake_case(&s).chars()
-                                           .map(|c| c.to_uppercase()).collect();
+            let uc = NonSnakeCase::to_snake_case(&s).to_uppercase();
             if uc != &s[..] {
                 cx.span_lint(NON_UPPER_CASE_GLOBALS, span,
                     &format!("{} `{}` should have an upper case name such as `{}`",
@@ -2080,7 +2079,7 @@ fn check_item(&mut self, cx: &Context, it: &ast::Item) {
                        !cx.exported_items.contains(&it.id) {
                     let msg = format!("static {} is marked #[no_mangle], but not exported",
                                       it.ident);
-                    cx.span_lint(PRIVATE_NO_MANGLE_STATICS, it.span, msg.as_slice());
+                    cx.span_lint(PRIVATE_NO_MANGLE_STATICS, it.span, &msg);
                 }
             },
             ast::ItemConst(..) => {
index 9781e9944f6427dee635f089a4c9a76e1f9324e1..a49c9db07a0e948fa1b5cb0dac286d3d517256e3 100644 (file)
@@ -41,7 +41,6 @@
 #![feature(unsafe_destructor)]
 #![feature(staged_api)]
 #![feature(std_misc)]
-#![feature(unicode)]
 #![cfg_attr(test, feature(test))]
 
 extern crate syntax;
index 96d3e16d253b44707c6f15ba5cb7d536e002b1e1..ecdc7c06bb19dfa8eb629b1a16f17b0d8e763bc8 100644 (file)
@@ -1500,8 +1500,45 @@ pub fn trans_adt<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
     // panic occur before the ADT as a whole is ready.
     let custom_cleanup_scope = fcx.push_custom_cleanup_scope();
 
-    // First we trans the base, if we have one, to the dest
-    if let Some(base) = optbase {
+    if ty::type_is_simd(bcx.tcx(), ty) {
+        // Issue 23112: The original logic appeared vulnerable to same
+        // order-of-eval bug. But, SIMD values are tuple-structs;
+        // i.e. functional record update (FRU) syntax is unavailable.
+        //
+        // To be safe, double-check that we did not get here via FRU.
+        assert!(optbase.is_none());
+
+        // This is the constructor of a SIMD type, such types are
+        // always primitive machine types and so do not have a
+        // destructor or require any clean-up.
+        let llty = type_of::type_of(bcx.ccx(), ty);
+
+        // keep a vector as a register, and running through the field
+        // `insertelement`ing them directly into that register
+        // (i.e. avoid GEPi and `store`s to an alloca) .
+        let mut vec_val = C_undef(llty);
+
+        for &(i, ref e) in fields {
+            let block_datum = trans(bcx, &**e);
+            bcx = block_datum.bcx;
+            let position = C_uint(bcx.ccx(), i);
+            let value = block_datum.datum.to_llscalarish(bcx);
+            vec_val = InsertElement(bcx, vec_val, value, position);
+        }
+        Store(bcx, vec_val, addr);
+    } else if let Some(base) = optbase {
+        // Issue 23112: If there is a base, then order-of-eval
+        // requires field expressions eval'ed before base expression.
+
+        // First, trans field expressions to temporary scratch values.
+        let scratch_vals: Vec<_> = fields.iter().map(|&(i, ref e)| {
+            let datum = unpack_datum!(bcx, trans(bcx, &**e));
+            (i, datum)
+        }).collect();
+
+        debug_location.apply(bcx.fcx);
+
+        // Second, trans the base to the dest.
         assert_eq!(discr, 0);
 
         match ty::expr_kind(bcx.tcx(), &*base.expr) {
@@ -1520,31 +1557,14 @@ pub fn trans_adt<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
                 }
             }
         }
-    }
-
-    debug_location.apply(bcx.fcx);
-
-    if ty::type_is_simd(bcx.tcx(), ty) {
-        // This is the constructor of a SIMD type, such types are
-        // always primitive machine types and so do not have a
-        // destructor or require any clean-up.
-        let llty = type_of::type_of(bcx.ccx(), ty);
-
-        // keep a vector as a register, and running through the field
-        // `insertelement`ing them directly into that register
-        // (i.e. avoid GEPi and `store`s to an alloca) .
-        let mut vec_val = C_undef(llty);
 
-        for &(i, ref e) in fields {
-            let block_datum = trans(bcx, &**e);
-            bcx = block_datum.bcx;
-            let position = C_uint(bcx.ccx(), i);
-            let value = block_datum.datum.to_llscalarish(bcx);
-            vec_val = InsertElement(bcx, vec_val, value, position);
+        // Finally, move scratch field values into actual field locations
+        for (i, datum) in scratch_vals.into_iter() {
+            let dest = adt::trans_field_ptr(bcx, &*repr, addr, discr, i);
+            bcx = datum.store_to(bcx, dest);
         }
-        Store(bcx, vec_val, addr);
     } else {
-        // Now, we just overwrite the fields we've explicitly specified
+        // No base means we can write all fields directly in place.
         for &(i, ref e) in fields {
             let dest = adt::trans_field_ptr(bcx, &*repr, addr, discr, i);
             let e_ty = expr_ty_adjusted(bcx, &**e);
index 00e9e76d81903eb7810c7e389479da0492e61331..2c7a9bf8020c3f324602f7d7089511979b6f1c7a 100644 (file)
@@ -1404,7 +1404,7 @@ pub fn ast_ty_to_ty<'tcx>(this: &AstConv<'tcx>,
                         ast_ty.span.lo <= r.span.lo && r.span.hi <= ast_ty.span.hi;
                     span_err!(tcx.sess, r.span, E0250,
                               "array length constant evaluation error: {}",
-                              r.description().as_slice());
+                              r.description());
                     if !subspan {
                         span_note!(tcx.sess, ast_ty.span, "for array length here")
                     }
index cffd74ccd7218c3da9458131a756bfd3e1578cb6..9c48ac43ee468bb94c38cd3adb65b4766202981b 100644 (file)
@@ -298,8 +298,8 @@ fn iterate_over_potentially_unsafe_regions_in_type<'a, 'tcx>(
                 match rcx.tcx().region_maps.opt_encl_scope(scope) {
                     Some(parent_scope) => ty::ReScope(parent_scope),
                     None => rcx.tcx().sess.span_bug(
-                        span, format!("no enclosing scope found for scope: {:?}",
-                                      scope).as_slice()),
+                        span, &format!("no enclosing scope found for scope: {:?}",
+                                       scope)),
                 };
 
             regionck::type_must_outlive(rcx, origin(), typ, parent_region);
index 595a2295674a12d54f80998d07133e5bfb3349e1..44500ce0bbb7f01aed30d960944d14ac4059c409 100644 (file)
@@ -4620,7 +4620,7 @@ fn do_check<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                         Err(ref err) => {
                             span_err!(ccx.tcx.sess, err.span, E0080,
                                       "constant evaluation error: {}",
-                                      err.description().as_slice());
+                                      err.description());
                         }
                     }
                 },
index a3e98b0c4c6582b9df464e50e649906c148b1069..e1bcad2af37d627f0590fd5cf216d508f39b6df5 100644 (file)
@@ -963,9 +963,9 @@ fn check_safety_of_rvalue_destructor_if_necessary<'a, 'tcx>(rcx: &mut Rcx<'a, 't
                     rcx.tcx()
                        .sess
                        .span_bug(span,
-                                 format!("unexpected rvalue region in rvalue \
-                                          destructor safety checking: `{}`",
-                                         region.repr(rcx.tcx())).as_slice());
+                                 &format!("unexpected rvalue region in rvalue \
+                                           destructor safety checking: `{}`",
+                                          region.repr(rcx.tcx())));
                 }
             }
         }
index 8185f48cb8c7031ed952bdee0b8ac51be794d0c4..32bd40ebda2de26d944e12a4130752af65419405 100644 (file)
@@ -411,9 +411,9 @@ fn report_bivariance(&self,
             Some(def_id) => {
                 self.tcx().sess.fileline_help(
                     span,
-                    format!("consider removing `{}` or using a marker such as `{}`",
-                            param_name.user_string(self.tcx()),
-                            ty::item_path_str(self.tcx(), def_id)).as_slice());
+                    &format!("consider removing `{}` or using a marker such as `{}`",
+                             param_name.user_string(self.tcx()),
+                             ty::item_path_str(self.tcx(), def_id)));
             }
             None => {
                 // no lang items, no help!
diff --git a/src/librustc_typeck/coherence/impls.rs b/src/librustc_typeck/coherence/impls.rs
deleted file mode 100644 (file)
index e89c96b..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2015 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.
-
-//! Implementations checker: builtin traits and default impls are allowed just
-//! for structs and enums.
-
-use middle::ty;
-use syntax::ast::{Item, ItemImpl};
-use syntax::ast;
-use syntax::visit;
-
-pub fn check(tcx: &ty::ctxt) {
-    let mut impls = ImplsChecker { tcx: tcx };
-    visit::walk_crate(&mut impls, tcx.map.krate());
-}
-
-struct ImplsChecker<'cx, 'tcx:'cx> {
-    tcx: &'cx ty::ctxt<'tcx>
-}
-
-impl<'cx, 'tcx,'v> visit::Visitor<'v> for ImplsChecker<'cx, 'tcx> {
-    fn visit_item(&mut self, item: &'v ast::Item) {
-        match item.node {
-            ast::ItemImpl(_, _, _, Some(_), _, _) => {
-                let trait_ref = ty::impl_id_to_trait_ref(self.tcx, item.id);
-                if let Some(_) = self.tcx.lang_items.to_builtin_kind(trait_ref.def_id) {
-                    match trait_ref.self_ty().sty {
-                        ty::ty_struct(..) | ty::ty_enum(..) => {}
-                        _ => {
-                            span_err!(self.tcx.sess, item.span, E0209,
-                                "builtin traits can only be \
-                                          implemented on structs or enums");
-                        }
-                    }
-                }
-            }
-            _ => {}
-        }
-    }
-}
index 9a8545f3dd5159c87a33d06a9bbabf9bdad64afe..a06dcbaf556bdd7ea032914df2b415844c8dfdb1 100644 (file)
@@ -49,7 +49,6 @@
 use util::nodemap::{DefIdMap, FnvHashMap};
 use util::ppaux::Repr;
 
-mod impls;
 mod orphan;
 mod overlap;
 mod unsafety;
@@ -583,7 +582,6 @@ pub fn check_coherence(crate_context: &CrateCtxt) {
         inference_context: new_infer_ctxt(crate_context.tcx),
         inherent_impls: RefCell::new(FnvHashMap()),
     }.check(crate_context.tcx.map.krate());
-    impls::check(crate_context.tcx);
     unsafety::check(crate_context.tcx);
     orphan::check(crate_context.tcx);
     overlap::check(crate_context.tcx);
index 95dafccd866bf3369136c8f936b31edf362e7397..5dfe80cfcb213fd4a441b650af5b3b59802005d4 100644 (file)
@@ -37,10 +37,13 @@ fn check_def_id(&self, item: &ast::Item, def_id: ast::DefId) {
                        a trait or new type instead");
         }
     }
-}
 
-impl<'cx, 'tcx,'v> visit::Visitor<'v> for OrphanChecker<'cx, 'tcx> {
-    fn visit_item(&mut self, item: &ast::Item) {
+    /// Checks exactly one impl for orphan rules and other such
+    /// restrictions.  In this fn, it can happen that multiple errors
+    /// apply to a specific impl, so just return after reporting one
+    /// to prevent inundating the user with a bunch of similar error
+    /// reports.
+    fn check_item(&self, item: &ast::Item) {
         let def_id = ast_util::local_def(item.id);
         match item.node {
             ast::ItemImpl(_, _, _, None, _, _) => {
@@ -63,13 +66,15 @@ fn visit_item(&mut self, item: &ast::Item) {
                         span_err!(self.tcx.sess, item.span, E0118,
                                   "no base type found for inherent implementation; \
                                    implement a trait or new type instead");
+                        return;
                     }
                 }
             }
             ast::ItemImpl(_, _, _, Some(_), _, _) => {
                 // "Trait" impl
                 debug!("coherence2::orphan check: trait impl {}", item.repr(self.tcx));
-                let trait_def_id = ty::impl_trait_ref(self.tcx, def_id).unwrap().def_id;
+                let trait_ref = ty::impl_trait_ref(self.tcx, def_id).unwrap();
+                let trait_def_id = trait_ref.def_id;
                 match traits::orphan_check(self.tcx, def_id) {
                     Ok(()) => { }
                     Err(traits::OrphanCheckErr::NoLocalInputType) => {
@@ -80,6 +85,7 @@ fn visit_item(&mut self, item: &ast::Item) {
                                  types defined in this crate; \
                                  only traits defined in the current crate can be \
                                  implemented for arbitrary types");
+                            return;
                         }
                     }
                     Err(traits::OrphanCheckErr::UncoveredTy(param_ty)) => {
@@ -89,9 +95,100 @@ fn visit_item(&mut self, item: &ast::Item) {
                                      some local type (e.g. `MyStruct<T>`); only traits defined in \
                                      the current crate can be implemented for a type parameter",
                                     param_ty.user_string(self.tcx));
+                            return;
                         }
                     }
                 }
+
+                // In addition to the above rules, we restrict impls of defaulted traits
+                // so that they can only be implemented on structs/enums. To see why this
+                // restriction exists, consider the following example (#22978). Imagine
+                // that crate A defines a defaulted trait `Foo` and a fn that operates
+                // on pairs of types:
+                //
+                // ```
+                // // Crate A
+                // trait Foo { }
+                // impl Foo for .. { }
+                // fn two_foos<A:Foo,B:Foo>(..) {
+                //     one_foo::<(A,B)>(..)
+                // }
+                // fn one_foo<T:Foo>(..) { .. }
+                // ```
+                //
+                // This type-checks fine; in particular the fn
+                // `two_foos` is able to conclude that `(A,B):Foo`
+                // because `A:Foo` and `B:Foo`.
+                //
+                // Now imagine that crate B comes along and does the following:
+                //
+                // ```
+                // struct A { }
+                // struct B { }
+                // impl Foo for A { }
+                // impl Foo for B { }
+                // impl !Send for (A, B) { }
+                // ```
+                //
+                // This final impl is legal according to the orpan
+                // rules, but it invalidates the reasoning from
+                // `two_foos` above.
+                debug!("trait_ref={} trait_def_id={} trait_has_default_impl={}",
+                       trait_ref.repr(self.tcx),
+                       trait_def_id.repr(self.tcx),
+                       ty::trait_has_default_impl(self.tcx, trait_def_id));
+                if
+                    ty::trait_has_default_impl(self.tcx, trait_def_id) &&
+                    trait_def_id.krate != ast::LOCAL_CRATE
+                {
+                    let self_ty = trait_ref.self_ty();
+                    let opt_self_def_id = match self_ty.sty {
+                        ty::ty_struct(self_def_id, _) | ty::ty_enum(self_def_id, _) =>
+                            Some(self_def_id),
+                        ty::ty_uniq(..) =>
+                            self.tcx.lang_items.owned_box(),
+                        _ =>
+                            None
+                    };
+
+                    let msg = match opt_self_def_id {
+                        // We only want to permit structs/enums, but not *all* structs/enums.
+                        // They must be local to the current crate, so that people
+                        // can't do `unsafe impl Send for Rc<SomethingLocal>` or
+                        // `impl !Send for Box<SomethingLocalAndSend>`.
+                        Some(self_def_id) => {
+                            if self_def_id.krate == ast::LOCAL_CRATE {
+                                None
+                            } else {
+                                Some(format!(
+                                    "cross-crate traits with a default impl, like `{}`, \
+                                     can only be implemented for a struct/enum type \
+                                     defined in the current crate",
+                                    ty::item_path_str(self.tcx, trait_def_id)))
+                            }
+                        }
+                        _ => {
+                            Some(format!(
+                                "cross-crate traits with a default impl, like `{}`, \
+                                 can only be implemented for a struct/enum type, \
+                                 not `{}`",
+                                ty::item_path_str(self.tcx, trait_def_id),
+                                self_ty.user_string(self.tcx)))
+                        }
+                    };
+
+                    if let Some(msg) = msg {
+                        span_err!(self.tcx.sess, item.span, E0321, "{}", msg);
+                        return;
+                    }
+                }
+
+                // Disallow *all* explicit impls of `Sized` for now.
+                if Some(trait_def_id) == self.tcx.lang_items.sized_trait() {
+                    span_err!(self.tcx.sess, item.span, E0322,
+                              "explicit impls for the `Sized` trait are not permitted");
+                    return;
+                }
             }
             ast::ItemDefaultImpl(..) => {
                 // "Trait" impl
@@ -100,14 +197,20 @@ fn visit_item(&mut self, item: &ast::Item) {
                 if trait_ref.def_id.krate != ast::LOCAL_CRATE {
                     span_err!(self.tcx.sess, item.span, E0318,
                               "cannot create default implementations for traits outside the \
-                               crate they're defined in; define a new trait instead.");
+                               crate they're defined in; define a new trait instead");
+                    return;
                 }
             }
             _ => {
                 // Not an impl
             }
         }
+    }
+}
 
+impl<'cx, 'tcx,'v> visit::Visitor<'v> for OrphanChecker<'cx, 'tcx> {
+    fn visit_item(&mut self, item: &ast::Item) {
+        self.check_item(item);
         visit::walk_item(self, item);
     }
 }
index a6ecafb6241316382fd516b7236ff6527b80571a..466d00b348b94d33d029c7a34ecbb43b30f71030 100644 (file)
 use syntax::ast_util;
 use syntax::visit;
 use syntax::codemap::Span;
+use util::nodemap::DefIdMap;
 use util::ppaux::Repr;
 
 pub fn check(tcx: &ty::ctxt) {
-    let mut overlap = OverlapChecker { tcx: tcx };
+    let mut overlap = OverlapChecker { tcx: tcx, default_impls: DefIdMap() };
     overlap.check_for_overlapping_impls();
 
     // this secondary walk specifically checks for impls of defaulted
@@ -33,6 +34,9 @@ pub fn check(tcx: &ty::ctxt) {
 
 struct OverlapChecker<'cx, 'tcx:'cx> {
     tcx: &'cx ty::ctxt<'tcx>,
+
+    // maps from a trait def-id to an impl id
+    default_impls: DefIdMap<ast::NodeId>,
 }
 
 impl<'cx, 'tcx> OverlapChecker<'cx, 'tcx> {
@@ -134,24 +138,19 @@ impl<'cx, 'tcx,'v> visit::Visitor<'v> for OverlapChecker<'cx, 'tcx> {
     fn visit_item(&mut self, item: &'v ast::Item) {
         match item.node {
             ast::ItemDefaultImpl(_, _) => {
+                // look for another default impl; note that due to the
+                // general orphan/coherence rules, it must always be
+                // in this crate.
                 let impl_def_id = ast_util::local_def(item.id);
-                match ty::impl_trait_ref(self.tcx, impl_def_id) {
-                    Some(ref trait_ref) => {
-                        match ty::trait_default_impl(self.tcx, trait_ref.def_id) {
-                            Some(other_impl) if other_impl != impl_def_id => {
-                                self.report_overlap_error(trait_ref.def_id,
-                                                          other_impl,
-                                                          impl_def_id);
-                            }
-                            Some(_) => {}
-                            None => {
-                                self.tcx.sess.bug(
-                                          &format!("no default implementation recorded for `{:?}`",
-                                          item));
-                            }
-                        }
+                let trait_ref = ty::impl_trait_ref(self.tcx, impl_def_id).unwrap();
+                let prev_default_impl = self.default_impls.insert(trait_ref.def_id, item.id);
+                match prev_default_impl {
+                    Some(prev_id) => {
+                        self.report_overlap_error(trait_ref.def_id,
+                                                  impl_def_id,
+                                                  ast_util::local_def(prev_id));
                     }
-                    _ => {}
+                    None => { }
                 }
             }
             _ => {}
index 77e3b6ee64bb8f7d834d0861a4c48c3f041d8937..bd68802f262c1a1a532b1a03f8ea30d75b328f04 100644 (file)
@@ -979,7 +979,7 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) {
                                                            None,
                                                            None);
 
-            ty::record_default_trait_implementation(tcx, trait_ref.def_id, local_def(it.id))
+            ty::record_trait_has_default_impl(tcx, trait_ref.def_id);
         }
         ast::ItemImpl(_, _,
                       ref generics,
@@ -1590,8 +1590,8 @@ fn compute_type_scheme_of_item<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
         ast::ItemMac(..) => {
             tcx.sess.span_bug(
                 it.span,
-                format!("compute_type_scheme_of_item: unexpected item type: {:?}",
-                        it.node).as_slice());
+                &format!("compute_type_scheme_of_item: unexpected item type: {:?}",
+                         it.node));
         }
     }
 }
index 3bd15fbc7dbea774fb55ebad140bd1ab85fed0ff..03fa269ccf82908651b7056cbba5ed3f63fa1078 100644 (file)
     E0250, // expected constant expr for array length
     E0318, // can't create default impls for traits outside their crates
     E0319, // trait impls for defaulted traits allowed just for structs/enums
-    E0320  // recursive overflow during dropck
+    E0320, // recursive overflow during dropck
+    E0321, // extended coherence rules for defaulted traits violated
+    E0322  // cannot implement Sized explicitly
 }
 
 __build_diagnostic_array! { DIAGNOSTICS }
index d60f9ad50a16e9865850e31c984f9e1287e4c3f1..46c7a701954859dfdf6691b62bb76fc351fd42f0 100644 (file)
@@ -1264,7 +1264,7 @@ fn build_sidebar_items(&self, m: &clean::Module) -> HashMap<String, Vec<NameDoc>
             let short = short.to_string();
             let v = map.entry(short).get().unwrap_or_else(
                 |vacant_entry| vacant_entry.insert(Vec::with_capacity(1)));
-            v.push((myname, Some(shorter_line(item.doc_value()))));
+            v.push((myname, Some(plain_summary_line(item.doc_value()))));
         }
 
         for (_, items) in &mut map {
@@ -1478,8 +1478,9 @@ fn shorter<'a>(s: Option<&'a str>) -> &'a str {
 }
 
 #[inline]
-fn shorter_line(s: Option<&str>) -> String {
-    shorter(s).replace("\n", " ")
+fn plain_summary_line(s: Option<&str>) -> String {
+    let line = shorter(s).replace("\n", " ");
+    markdown::plain_summary_line(&line[..])
 }
 
 fn document(w: &mut fmt::Formatter, item: &clean::Item) -> fmt::Result {
index 21b7de9ff7c821ab6f68c9439b5c9371a4369d8e..1f075566ad5a280aca775e27fd5398e076b7bf11 100644 (file)
@@ -83,7 +83,7 @@ h2 {
 h3 {
     font-size: 1.3em;
 }
-h1, h2, h3:not(.impl):not(.method):not(.type), h4:not(.method):not(.type) {
+h1, h2, h3:not(.impl):not(.method):not(.type):not(.tymethod), h4:not(.method):not(.type):not(.tymethod) {
     color: black;
     font-weight: 500;
     margin: 20px 0 15px 0;
@@ -93,7 +93,7 @@ h1.fqn {
     border-bottom: 1px dashed #D5D5D5;
     margin-top: 0;
 }
-h2, h3:not(.impl):not(.method):not(.type), h4:not(.method):not(.type) {
+h2, h3:not(.impl):not(.method):not(.type):not(.tymethod), h4:not(.method):not(.type):not(.tymethod) {
     border-bottom: 1px solid #DDDDDD;
 }
 h3.impl, h3.method, h4.method, h3.type, h4.type {
index c785d78dc9303e1247e87298cc9fca6c2adcc899..e7312d6548e9f5798a811923818389ecad43b141 100644 (file)
@@ -114,7 +114,7 @@ pub fn run(input: &str,
 #[allow(deprecated)]
 fn runtest(test: &str, cratename: &str, libs: SearchPaths,
            externs: core::Externs,
-           should_fail: bool, no_run: bool, as_test_harness: bool) {
+           should_panic: bool, no_run: bool, as_test_harness: bool) {
     // the test harness wants its own `main` & top level functions, so
     // never wrap the test in `fn main() { ... }`
     let test = maketest(test, Some(cratename), true, as_test_harness);
@@ -210,9 +210,9 @@ fn runtest(test: &str, cratename: &str, libs: SearchPaths,
                             " - maybe your tempdir is mounted with noexec?"
                         } else { "" }),
         Ok(out) => {
-            if should_fail && out.status.success() {
+            if should_panic && out.status.success() {
                 panic!("test executable succeeded when it should have failed");
-            } else if !should_fail && !out.status.success() {
+            } else if !should_panic && !out.status.success() {
                 panic!("test executable failed:\n{:?}",
                       str::from_utf8(&out.stdout));
             }
@@ -279,7 +279,7 @@ pub fn new(cratename: String, libs: SearchPaths, externs: core::Externs,
     }
 
     pub fn add_test(&mut self, test: String,
-                    should_fail: bool, no_run: bool, should_ignore: bool, as_test_harness: bool) {
+                    should_panic: bool, no_run: bool, should_ignore: bool, as_test_harness: bool) {
         let name = if self.use_headers {
             let s = self.current_header.as_ref().map(|s| &**s).unwrap_or("");
             format!("{}_{}", s, self.cnt)
@@ -295,14 +295,14 @@ pub fn add_test(&mut self, test: String,
             desc: testing::TestDesc {
                 name: testing::DynTestName(name),
                 ignore: should_ignore,
-                should_fail: testing::ShouldFail::No, // compiler failures are test failures
+                should_panic: testing::ShouldPanic::No, // compiler failures are test failures
             },
             testfn: testing::DynTestFn(Thunk::new(move|| {
                 runtest(&test,
                         &cratename,
                         libs,
                         externs,
-                        should_fail,
+                        should_panic,
                         no_run,
                         as_test_harness);
             }))
index 0d445739b397f7d72872d0e65d2f46382eef63ee..6fc56522c6af1dbaa7198a214416b4388535449d 100644 (file)
 //!     let json_str: String = json_obj.to_string();
 //!
 //!     // Deserialize like before
-//!     let decoded: TestStruct = json::decode(json_str.as_slice()).unwrap();
+//!     let decoded: TestStruct = json::decode(json_str)).unwrap();
 //! }
 //! ```
 
index 8eb29a8327a52710c6479f026e35bc4a698b516e..9502302aa53ab8de04827a7af22e91b23bc8d93e 100644 (file)
@@ -2197,7 +2197,7 @@ fn test_index() {
     }
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn test_index_nonexistent() {
         let mut map = HashMap::new();
 
index c052a69bc343a42d0484dfef3934a0004085fd1c..b2ef04a5d632c2e82a3de7f32d2d787ba9e404d3 100644 (file)
@@ -780,8 +780,8 @@ fn test_var_big() {
             i += 1;
         }
         let n = make_rand_name();
-        set_var(&n, s.as_slice());
-        eq(var_os(&n), Some(s.as_slice()));
+        set_var(&n, &s);
+        eq(var_os(&n), Some(&s));
     }
 
     #[test]
@@ -799,7 +799,7 @@ fn test_env_set_get_huge() {
         let n = make_rand_name();
         let s = repeat("x").take(10000).collect::<String>();
         set_var(&n, &s);
-        eq(var_os(&n), Some(s.as_slice()));
+        eq(var_os(&n), Some(&s));
         remove_var(&n);
         eq(var_os(&n), None);
     }
index 80ec9909824bba17d6ac2b0f31c285842c19ecd8..9f9163eb9e69f1fdb5aa1379afe362d9dbdaac9c 100644 (file)
@@ -828,7 +828,7 @@ macro_rules! check { ($e:expr) => (
     macro_rules! error { ($e:expr, $s:expr) => (
         match $e {
             Ok(_) => panic!("Unexpected success. Should've been: {:?}", $s),
-            Err(ref err) => assert!(err.to_string().contains($s.as_slice()),
+            Err(ref err) => assert!(err.to_string().contains($s),
                                     format!("`{}` did not contain `{}`", err, $s))
         }
     ) }
@@ -880,7 +880,7 @@ fn file_test_io_smoke_test() {
                 -1|0 => panic!("shouldn't happen"),
                 n => str::from_utf8(&read_buf[..n]).unwrap().to_string()
             };
-            assert_eq!(read_str.as_slice(), message);
+            assert_eq!(read_str, message);
         }
         check!(fs::remove_file(filename));
     }
@@ -1107,7 +1107,7 @@ fn file_test_directoryinfo_readdir() {
                 check!(check!(File::open(&f)).read(&mut mem));
                 let read_str = str::from_utf8(&mem).unwrap();
                 let expected = format!("{}{}", prefix, n.to_str().unwrap());
-                assert_eq!(expected.as_slice(), read_str);
+                assert_eq!(expected, read_str);
             }
             check!(fs::remove_file(&f));
         }
index 093cde55bbb5fe7c2fd3c4b588998a616fe9318b..969dd35ba228878ea1f90aebd5eb10f397bc9960 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -468,6 +468,11 @@ mod tests {
     use num::*;
     use num::FpCategory as Fp;
 
+    #[test]
+    fn test_num_f32() {
+        test_num(10f32, 2f32);
+    }
+
     #[test]
     fn test_min_nan() {
         assert_eq!(NAN.min(2.0), 2.0);
@@ -481,8 +486,163 @@ fn test_max_nan() {
     }
 
     #[test]
-    fn test_num_f32() {
-        test_num(10f32, 2f32);
+    fn test_nan() {
+        let nan: f32 = Float::nan();
+        assert!(nan.is_nan());
+        assert!(!nan.is_infinite());
+        assert!(!nan.is_finite());
+        assert!(!nan.is_normal());
+        assert!(!nan.is_positive());
+        assert!(!nan.is_negative());
+        assert_eq!(Fp::Nan, nan.classify());
+    }
+
+    #[test]
+    fn test_infinity() {
+        let inf: f32 = Float::infinity();
+        assert!(inf.is_infinite());
+        assert!(!inf.is_finite());
+        assert!(inf.is_positive());
+        assert!(!inf.is_negative());
+        assert!(!inf.is_nan());
+        assert!(!inf.is_normal());
+        assert_eq!(Fp::Infinite, inf.classify());
+    }
+
+    #[test]
+    fn test_neg_infinity() {
+        let neg_inf: f32 = Float::neg_infinity();
+        assert!(neg_inf.is_infinite());
+        assert!(!neg_inf.is_finite());
+        assert!(!neg_inf.is_positive());
+        assert!(neg_inf.is_negative());
+        assert!(!neg_inf.is_nan());
+        assert!(!neg_inf.is_normal());
+        assert_eq!(Fp::Infinite, neg_inf.classify());
+    }
+
+    #[test]
+    fn test_zero() {
+        let zero: f32 = Float::zero();
+        assert_eq!(0.0, zero);
+        assert!(!zero.is_infinite());
+        assert!(zero.is_finite());
+        assert!(zero.is_positive());
+        assert!(!zero.is_negative());
+        assert!(!zero.is_nan());
+        assert!(!zero.is_normal());
+        assert_eq!(Fp::Zero, zero.classify());
+    }
+
+    #[test]
+    fn test_neg_zero() {
+        let neg_zero: f32 = Float::neg_zero();
+        assert_eq!(0.0, neg_zero);
+        assert!(!neg_zero.is_infinite());
+        assert!(neg_zero.is_finite());
+        assert!(!neg_zero.is_positive());
+        assert!(neg_zero.is_negative());
+        assert!(!neg_zero.is_nan());
+        assert!(!neg_zero.is_normal());
+        assert_eq!(Fp::Zero, neg_zero.classify());
+    }
+
+    #[test]
+    fn test_one() {
+        let one: f32 = Float::one();
+        assert_eq!(1.0, one);
+        assert!(!one.is_infinite());
+        assert!(one.is_finite());
+        assert!(one.is_positive());
+        assert!(!one.is_negative());
+        assert!(!one.is_nan());
+        assert!(one.is_normal());
+        assert_eq!(Fp::Normal, one.classify());
+    }
+
+    #[test]
+    fn test_is_nan() {
+        let nan: f32 = Float::nan();
+        let inf: f32 = Float::infinity();
+        let neg_inf: f32 = Float::neg_infinity();
+        assert!(nan.is_nan());
+        assert!(!0.0f32.is_nan());
+        assert!(!5.3f32.is_nan());
+        assert!(!(-10.732f32).is_nan());
+        assert!(!inf.is_nan());
+        assert!(!neg_inf.is_nan());
+    }
+
+    #[test]
+    fn test_is_infinite() {
+        let nan: f32 = Float::nan();
+        let inf: f32 = Float::infinity();
+        let neg_inf: f32 = Float::neg_infinity();
+        assert!(!nan.is_infinite());
+        assert!(inf.is_infinite());
+        assert!(neg_inf.is_infinite());
+        assert!(!0.0f32.is_infinite());
+        assert!(!42.8f32.is_infinite());
+        assert!(!(-109.2f32).is_infinite());
+    }
+
+    #[test]
+    fn test_is_finite() {
+        let nan: f32 = Float::nan();
+        let inf: f32 = Float::infinity();
+        let neg_inf: f32 = Float::neg_infinity();
+        assert!(!nan.is_finite());
+        assert!(!inf.is_finite());
+        assert!(!neg_inf.is_finite());
+        assert!(0.0f32.is_finite());
+        assert!(42.8f32.is_finite());
+        assert!((-109.2f32).is_finite());
+    }
+
+    #[test]
+    fn test_is_normal() {
+        let nan: f32 = Float::nan();
+        let inf: f32 = Float::infinity();
+        let neg_inf: f32 = Float::neg_infinity();
+        let zero: f32 = Float::zero();
+        let neg_zero: f32 = Float::neg_zero();
+        assert!(!nan.is_normal());
+        assert!(!inf.is_normal());
+        assert!(!neg_inf.is_normal());
+        assert!(!zero.is_normal());
+        assert!(!neg_zero.is_normal());
+        assert!(1f32.is_normal());
+        assert!(1e-37f32.is_normal());
+        assert!(!1e-38f32.is_normal());
+    }
+
+    #[test]
+    fn test_classify() {
+        let nan: f32 = Float::nan();
+        let inf: f32 = Float::infinity();
+        let neg_inf: f32 = Float::neg_infinity();
+        let zero: f32 = Float::zero();
+        let neg_zero: f32 = Float::neg_zero();
+        assert_eq!(nan.classify(), Fp::Nan);
+        assert_eq!(inf.classify(), Fp::Infinite);
+        assert_eq!(neg_inf.classify(), Fp::Infinite);
+        assert_eq!(zero.classify(), Fp::Zero);
+        assert_eq!(neg_zero.classify(), Fp::Zero);
+        assert_eq!(1f32.classify(), Fp::Normal);
+        assert_eq!(1e-37f32.classify(), Fp::Normal);
+        assert_eq!(1e-38f32.classify(), Fp::Subnormal);
+    }
+
+    #[test]
+    fn test_integer_decode() {
+        assert_eq!(3.14159265359f32.integer_decode(), (13176795, -22, 1));
+        assert_eq!((-8573.5918555f32).integer_decode(), (8779358, -10, -1));
+        assert_eq!(2f32.powf(100.0).integer_decode(), (8388608, 77, 1));
+        assert_eq!(0f32.integer_decode(), (0, -150, 1));
+        assert_eq!((-0f32).integer_decode(), (0, -150, -1));
+        assert_eq!(INFINITY.integer_decode(), (8388608, 105, 1));
+        assert_eq!(NEG_INFINITY.integer_decode(), (8388608, 105, -1));
+        assert_eq!(NAN.integer_decode(), (12582912, 105, 1));
     }
 
     #[test]
@@ -555,6 +715,140 @@ fn test_fract() {
         assert_approx_eq!((-1.7f32).fract(), -0.7f32);
     }
 
+    #[test]
+    fn test_abs() {
+        assert_eq!(INFINITY.abs(), INFINITY);
+        assert_eq!(1f32.abs(), 1f32);
+        assert_eq!(0f32.abs(), 0f32);
+        assert_eq!((-0f32).abs(), 0f32);
+        assert_eq!((-1f32).abs(), 1f32);
+        assert_eq!(NEG_INFINITY.abs(), INFINITY);
+        assert_eq!((1f32/NEG_INFINITY).abs(), 0f32);
+        assert!(NAN.abs().is_nan());
+    }
+
+    #[test]
+    fn test_signum() {
+        assert_eq!(INFINITY.signum(), 1f32);
+        assert_eq!(1f32.signum(), 1f32);
+        assert_eq!(0f32.signum(), 1f32);
+        assert_eq!((-0f32).signum(), -1f32);
+        assert_eq!((-1f32).signum(), -1f32);
+        assert_eq!(NEG_INFINITY.signum(), -1f32);
+        assert_eq!((1f32/NEG_INFINITY).signum(), -1f32);
+        assert!(NAN.signum().is_nan());
+    }
+
+    #[test]
+    fn test_is_positive() {
+        assert!(INFINITY.is_positive());
+        assert!(1f32.is_positive());
+        assert!(0f32.is_positive());
+        assert!(!(-0f32).is_positive());
+        assert!(!(-1f32).is_positive());
+        assert!(!NEG_INFINITY.is_positive());
+        assert!(!(1f32/NEG_INFINITY).is_positive());
+        assert!(!NAN.is_positive());
+    }
+
+    #[test]
+    fn test_is_negative() {
+        assert!(!INFINITY.is_negative());
+        assert!(!1f32.is_negative());
+        assert!(!0f32.is_negative());
+        assert!((-0f32).is_negative());
+        assert!((-1f32).is_negative());
+        assert!(NEG_INFINITY.is_negative());
+        assert!((1f32/NEG_INFINITY).is_negative());
+        assert!(!NAN.is_negative());
+    }
+
+    #[test]
+    fn test_mul_add() {
+        let nan: f32 = Float::nan();
+        let inf: f32 = Float::infinity();
+        let neg_inf: f32 = Float::neg_infinity();
+        assert_approx_eq!(12.3f32.mul_add(4.5, 6.7), 62.05);
+        assert_approx_eq!((-12.3f32).mul_add(-4.5, -6.7), 48.65);
+        assert_approx_eq!(0.0f32.mul_add(8.9, 1.2), 1.2);
+        assert_approx_eq!(3.4f32.mul_add(-0.0, 5.6), 5.6);
+        assert!(nan.mul_add(7.8, 9.0).is_nan());
+        assert_eq!(inf.mul_add(7.8, 9.0), inf);
+        assert_eq!(neg_inf.mul_add(7.8, 9.0), neg_inf);
+        assert_eq!(8.9f32.mul_add(inf, 3.2), inf);
+        assert_eq!((-3.2f32).mul_add(2.4, neg_inf), neg_inf);
+    }
+
+    #[test]
+    fn test_recip() {
+        let nan: f32 = Float::nan();
+        let inf: f32 = Float::infinity();
+        let neg_inf: f32 = Float::neg_infinity();
+        assert_eq!(1.0f32.recip(), 1.0);
+        assert_eq!(2.0f32.recip(), 0.5);
+        assert_eq!((-0.4f32).recip(), -2.5);
+        assert_eq!(0.0f32.recip(), inf);
+        assert!(nan.recip().is_nan());
+        assert_eq!(inf.recip(), 0.0);
+        assert_eq!(neg_inf.recip(), 0.0);
+    }
+
+    #[test]
+    fn test_powi() {
+        let nan: f32 = Float::nan();
+        let inf: f32 = Float::infinity();
+        let neg_inf: f32 = Float::neg_infinity();
+        assert_eq!(1.0f32.powi(1), 1.0);
+        assert_approx_eq!((-3.1f32).powi(2), 9.61);
+        assert_approx_eq!(5.9f32.powi(-2), 0.028727);
+        assert_eq!(8.3f32.powi(0), 1.0);
+        assert!(nan.powi(2).is_nan());
+        assert_eq!(inf.powi(3), inf);
+        assert_eq!(neg_inf.powi(2), inf);
+    }
+
+    #[test]
+    fn test_powf() {
+        let nan: f32 = Float::nan();
+        let inf: f32 = Float::infinity();
+        let neg_inf: f32 = Float::neg_infinity();
+        assert_eq!(1.0f32.powf(1.0), 1.0);
+        assert_approx_eq!(3.4f32.powf(4.5), 246.408218);
+        assert_approx_eq!(2.7f32.powf(-3.2), 0.041652);
+        assert_approx_eq!((-3.1f32).powf(2.0), 9.61);
+        assert_approx_eq!(5.9f32.powf(-2.0), 0.028727);
+        assert_eq!(8.3f32.powf(0.0), 1.0);
+        assert!(nan.powf(2.0).is_nan());
+        assert_eq!(inf.powf(2.0), inf);
+        assert_eq!(neg_inf.powf(3.0), neg_inf);
+    }
+
+    #[test]
+    fn test_sqrt_domain() {
+        assert!(NAN.sqrt().is_nan());
+        assert!(NEG_INFINITY.sqrt().is_nan());
+        assert!((-1.0f32).sqrt().is_nan());
+        assert_eq!((-0.0f32).sqrt(), -0.0);
+        assert_eq!(0.0f32.sqrt(), 0.0);
+        assert_eq!(1.0f32.sqrt(), 1.0);
+        assert_eq!(INFINITY.sqrt(), INFINITY);
+    }
+
+    #[test]
+    fn test_rsqrt() {
+        let nan: f32 = Float::nan();
+        let inf: f32 = Float::infinity();
+        let neg_inf: f32 = Float::neg_infinity();
+        assert!(nan.rsqrt().is_nan());
+        assert_eq!(inf.rsqrt(), 0.0);
+        assert!(neg_inf.rsqrt().is_nan());
+        assert!((-1.0f32).rsqrt().is_nan());
+        assert_eq!((-0.0f32).rsqrt(), neg_inf);
+        assert_eq!(0.0f32.rsqrt(), inf);
+        assert_eq!(1.0f32.rsqrt(), 1.0);
+        assert_eq!(4.0f32.rsqrt(), 0.5);
+    }
+
     #[test]
     fn test_exp() {
         assert_eq!(1.0, 0.0f32.exp());
@@ -582,6 +876,172 @@ fn test_exp2() {
         assert!(nan.exp2().is_nan());
     }
 
+    #[test]
+    fn test_ln() {
+        let nan: f32 = Float::nan();
+        let inf: f32 = Float::infinity();
+        let neg_inf: f32 = Float::neg_infinity();
+        assert_approx_eq!(1.0f32.exp().ln(), 1.0);
+        assert!(nan.ln().is_nan());
+        assert_eq!(inf.ln(), inf);
+        assert!(neg_inf.ln().is_nan());
+        assert!((-2.3f32).ln().is_nan());
+        assert_eq!((-0.0f32).ln(), neg_inf);
+        assert_eq!(0.0f32.ln(), neg_inf);
+        assert_approx_eq!(4.0f32.ln(), 1.386294);
+    }
+
+    #[test]
+    fn test_log() {
+        let nan: f32 = Float::nan();
+        let inf: f32 = Float::infinity();
+        let neg_inf: f32 = Float::neg_infinity();
+        assert_eq!(10.0f32.log(10.0), 1.0);
+        assert_approx_eq!(2.3f32.log(3.5), 0.664858);
+        assert_eq!(1.0f32.exp().log(1.0.exp()), 1.0);
+        assert!(1.0f32.log(1.0).is_nan());
+        assert!(1.0f32.log(-13.9).is_nan());
+        assert!(nan.log(2.3).is_nan());
+        assert_eq!(inf.log(10.0), inf);
+        assert!(neg_inf.log(8.8).is_nan());
+        assert!((-2.3f32).log(0.1).is_nan());
+        assert_eq!((-0.0f32).log(2.0), neg_inf);
+        assert_eq!(0.0f32.log(7.0), neg_inf);
+    }
+
+    #[test]
+    fn test_log2() {
+        let nan: f32 = Float::nan();
+        let inf: f32 = Float::infinity();
+        let neg_inf: f32 = Float::neg_infinity();
+        assert_approx_eq!(10.0f32.log2(), 3.321928);
+        assert_approx_eq!(2.3f32.log2(), 1.201634);
+        assert_approx_eq!(1.0f32.exp().log2(), 1.442695);
+        assert!(nan.log2().is_nan());
+        assert_eq!(inf.log2(), inf);
+        assert!(neg_inf.log2().is_nan());
+        assert!((-2.3f32).log2().is_nan());
+        assert_eq!((-0.0f32).log2(), neg_inf);
+        assert_eq!(0.0f32.log2(), neg_inf);
+    }
+
+    #[test]
+    fn test_log10() {
+        let nan: f32 = Float::nan();
+        let inf: f32 = Float::infinity();
+        let neg_inf: f32 = Float::neg_infinity();
+        assert_eq!(10.0f32.log10(), 1.0);
+        assert_approx_eq!(2.3f32.log10(), 0.361728);
+        assert_approx_eq!(1.0f32.exp().log10(), 0.434294);
+        assert_eq!(1.0f32.log10(), 0.0);
+        assert!(nan.log10().is_nan());
+        assert_eq!(inf.log10(), inf);
+        assert!(neg_inf.log10().is_nan());
+        assert!((-2.3f32).log10().is_nan());
+        assert_eq!((-0.0f32).log10(), neg_inf);
+        assert_eq!(0.0f32.log10(), neg_inf);
+    }
+
+    #[test]
+    fn test_to_degrees() {
+        let pi: f32 = consts::PI;
+        let nan: f32 = Float::nan();
+        let inf: f32 = Float::infinity();
+        let neg_inf: f32 = Float::neg_infinity();
+        assert_eq!(0.0f32.to_degrees(), 0.0);
+        assert_approx_eq!((-5.8f32).to_degrees(), -332.315521);
+        assert_eq!(pi.to_degrees(), 180.0);
+        assert!(nan.to_degrees().is_nan());
+        assert_eq!(inf.to_degrees(), inf);
+        assert_eq!(neg_inf.to_degrees(), neg_inf);
+    }
+
+    #[test]
+    fn test_to_radians() {
+        let pi: f32 = consts::PI;
+        let nan: f32 = Float::nan();
+        let inf: f32 = Float::infinity();
+        let neg_inf: f32 = Float::neg_infinity();
+        assert_eq!(0.0f32.to_radians(), 0.0);
+        assert_approx_eq!(154.6f32.to_radians(), 2.698279);
+        assert_approx_eq!((-332.31f32).to_radians(), -5.799903);
+        assert_eq!(180.0f32.to_radians(), pi);
+        assert!(nan.to_radians().is_nan());
+        assert_eq!(inf.to_radians(), inf);
+        assert_eq!(neg_inf.to_radians(), neg_inf);
+    }
+
+    #[test]
+    fn test_ldexp() {
+        // We have to use from_str until base-2 exponents
+        // are supported in floating-point literals
+        let f1: f32 = FromStrRadix::from_str_radix("1p-123", 16).unwrap();
+        let f2: f32 = FromStrRadix::from_str_radix("1p-111", 16).unwrap();
+        let f3: f32 = FromStrRadix::from_str_radix("1.Cp-12", 16).unwrap();
+        assert_eq!(Float::ldexp(1f32, -123), f1);
+        assert_eq!(Float::ldexp(1f32, -111), f2);
+        assert_eq!(Float::ldexp(1.75f32, -12), f3);
+
+        assert_eq!(Float::ldexp(0f32, -123), 0f32);
+        assert_eq!(Float::ldexp(-0f32, -123), -0f32);
+
+        let inf: f32 = Float::infinity();
+        let neg_inf: f32 = Float::neg_infinity();
+        let nan: f32 = Float::nan();
+        assert_eq!(Float::ldexp(inf, -123), inf);
+        assert_eq!(Float::ldexp(neg_inf, -123), neg_inf);
+        assert!(Float::ldexp(nan, -123).is_nan());
+    }
+
+    #[test]
+    fn test_frexp() {
+        // We have to use from_str until base-2 exponents
+        // are supported in floating-point literals
+        let f1: f32 = FromStrRadix::from_str_radix("1p-123", 16).unwrap();
+        let f2: f32 = FromStrRadix::from_str_radix("1p-111", 16).unwrap();
+        let f3: f32 = FromStrRadix::from_str_radix("1.Cp-123", 16).unwrap();
+        let (x1, exp1) = f1.frexp();
+        let (x2, exp2) = f2.frexp();
+        let (x3, exp3) = f3.frexp();
+        assert_eq!((x1, exp1), (0.5f32, -122));
+        assert_eq!((x2, exp2), (0.5f32, -110));
+        assert_eq!((x3, exp3), (0.875f32, -122));
+        assert_eq!(Float::ldexp(x1, exp1), f1);
+        assert_eq!(Float::ldexp(x2, exp2), f2);
+        assert_eq!(Float::ldexp(x3, exp3), f3);
+
+        assert_eq!(0f32.frexp(), (0f32, 0));
+        assert_eq!((-0f32).frexp(), (-0f32, 0));
+    }
+
+    #[test] #[cfg_attr(windows, ignore)] // FIXME #8755
+    fn test_frexp_nowin() {
+        let inf: f32 = Float::infinity();
+        let neg_inf: f32 = Float::neg_infinity();
+        let nan: f32 = Float::nan();
+        assert_eq!(match inf.frexp() { (x, _) => x }, inf);
+        assert_eq!(match neg_inf.frexp() { (x, _) => x }, neg_inf);
+        assert!(match nan.frexp() { (x, _) => x.is_nan() })
+    }
+
+    #[test]
+    fn test_abs_sub() {
+        assert_eq!((-1f32).abs_sub(1f32), 0f32);
+        assert_eq!(1f32.abs_sub(1f32), 0f32);
+        assert_eq!(1f32.abs_sub(0f32), 1f32);
+        assert_eq!(1f32.abs_sub(-1f32), 2f32);
+        assert_eq!(NEG_INFINITY.abs_sub(0f32), 0f32);
+        assert_eq!(INFINITY.abs_sub(1f32), INFINITY);
+        assert_eq!(0f32.abs_sub(NEG_INFINITY), INFINITY);
+        assert_eq!(0f32.abs_sub(INFINITY), 0f32);
+    }
+
+    #[test]
+    fn test_abs_sub_nowin() {
+        assert!(NAN.abs_sub(-1f32).is_nan());
+        assert!(1f32.abs_sub(NAN).is_nan());
+    }
+
     #[test]
     fn test_asinh() {
         assert_eq!(0.0f32.asinh(), 0.0f32);
@@ -674,174 +1134,4 @@ fn test_real_consts() {
         assert_approx_eq!(ln_2, 2f32.ln());
         assert_approx_eq!(ln_10, 10f32.ln());
     }
-
-    #[test]
-    pub fn test_abs() {
-        assert_eq!(INFINITY.abs(), INFINITY);
-        assert_eq!(1f32.abs(), 1f32);
-        assert_eq!(0f32.abs(), 0f32);
-        assert_eq!((-0f32).abs(), 0f32);
-        assert_eq!((-1f32).abs(), 1f32);
-        assert_eq!(NEG_INFINITY.abs(), INFINITY);
-        assert_eq!((1f32/NEG_INFINITY).abs(), 0f32);
-        assert!(NAN.abs().is_nan());
-    }
-
-    #[test]
-    fn test_abs_sub() {
-        assert_eq!((-1f32).abs_sub(1f32), 0f32);
-        assert_eq!(1f32.abs_sub(1f32), 0f32);
-        assert_eq!(1f32.abs_sub(0f32), 1f32);
-        assert_eq!(1f32.abs_sub(-1f32), 2f32);
-        assert_eq!(NEG_INFINITY.abs_sub(0f32), 0f32);
-        assert_eq!(INFINITY.abs_sub(1f32), INFINITY);
-        assert_eq!(0f32.abs_sub(NEG_INFINITY), INFINITY);
-        assert_eq!(0f32.abs_sub(INFINITY), 0f32);
-    }
-
-    #[test]
-    fn test_abs_sub_nowin() {
-        assert!(NAN.abs_sub(-1f32).is_nan());
-        assert!(1f32.abs_sub(NAN).is_nan());
-    }
-
-    #[test]
-    fn test_signum() {
-        assert_eq!(INFINITY.signum(), 1f32);
-        assert_eq!(1f32.signum(), 1f32);
-        assert_eq!(0f32.signum(), 1f32);
-        assert_eq!((-0f32).signum(), -1f32);
-        assert_eq!((-1f32).signum(), -1f32);
-        assert_eq!(NEG_INFINITY.signum(), -1f32);
-        assert_eq!((1f32/NEG_INFINITY).signum(), -1f32);
-        assert!(NAN.signum().is_nan());
-    }
-
-    #[test]
-    fn test_is_positive() {
-        assert!(INFINITY.is_positive());
-        assert!(1f32.is_positive());
-        assert!(0f32.is_positive());
-        assert!(!(-0f32).is_positive());
-        assert!(!(-1f32).is_positive());
-        assert!(!NEG_INFINITY.is_positive());
-        assert!(!(1f32/NEG_INFINITY).is_positive());
-        assert!(!NAN.is_positive());
-    }
-
-    #[test]
-    fn test_is_negative() {
-        assert!(!INFINITY.is_negative());
-        assert!(!1f32.is_negative());
-        assert!(!0f32.is_negative());
-        assert!((-0f32).is_negative());
-        assert!((-1f32).is_negative());
-        assert!(NEG_INFINITY.is_negative());
-        assert!((1f32/NEG_INFINITY).is_negative());
-        assert!(!NAN.is_negative());
-    }
-
-    #[test]
-    fn test_is_normal() {
-        let nan: f32 = Float::nan();
-        let inf: f32 = Float::infinity();
-        let neg_inf: f32 = Float::neg_infinity();
-        let zero: f32 = Float::zero();
-        let neg_zero: f32 = Float::neg_zero();
-        assert!(!nan.is_normal());
-        assert!(!inf.is_normal());
-        assert!(!neg_inf.is_normal());
-        assert!(!zero.is_normal());
-        assert!(!neg_zero.is_normal());
-        assert!(1f32.is_normal());
-        assert!(1e-37f32.is_normal());
-        assert!(!1e-38f32.is_normal());
-    }
-
-    #[test]
-    fn test_classify() {
-        let nan: f32 = Float::nan();
-        let inf: f32 = Float::infinity();
-        let neg_inf: f32 = Float::neg_infinity();
-        let zero: f32 = Float::zero();
-        let neg_zero: f32 = Float::neg_zero();
-        assert_eq!(nan.classify(), Fp::Nan);
-        assert_eq!(inf.classify(), Fp::Infinite);
-        assert_eq!(neg_inf.classify(), Fp::Infinite);
-        assert_eq!(zero.classify(), Fp::Zero);
-        assert_eq!(neg_zero.classify(), Fp::Zero);
-        assert_eq!(1f32.classify(), Fp::Normal);
-        assert_eq!(1e-37f32.classify(), Fp::Normal);
-        assert_eq!(1e-38f32.classify(), Fp::Subnormal);
-    }
-
-    #[test]
-    fn test_ldexp() {
-        // We have to use from_str until base-2 exponents
-        // are supported in floating-point literals
-        let f1: f32 = FromStrRadix::from_str_radix("1p-123", 16).unwrap();
-        let f2: f32 = FromStrRadix::from_str_radix("1p-111", 16).unwrap();
-        assert_eq!(Float::ldexp(1f32, -123), f1);
-        assert_eq!(Float::ldexp(1f32, -111), f2);
-
-        assert_eq!(Float::ldexp(0f32, -123), 0f32);
-        assert_eq!(Float::ldexp(-0f32, -123), -0f32);
-
-        let inf: f32 = Float::infinity();
-        let neg_inf: f32 = Float::neg_infinity();
-        let nan: f32 = Float::nan();
-        assert_eq!(Float::ldexp(inf, -123), inf);
-        assert_eq!(Float::ldexp(neg_inf, -123), neg_inf);
-        assert!(Float::ldexp(nan, -123).is_nan());
-    }
-
-    #[test]
-    fn test_frexp() {
-        // We have to use from_str until base-2 exponents
-        // are supported in floating-point literals
-        let f1: f32 = FromStrRadix::from_str_radix("1p-123", 16).unwrap();
-        let f2: f32 = FromStrRadix::from_str_radix("1p-111", 16).unwrap();
-        let (x1, exp1) = f1.frexp();
-        let (x2, exp2) = f2.frexp();
-        assert_eq!((x1, exp1), (0.5f32, -122));
-        assert_eq!((x2, exp2), (0.5f32, -110));
-        assert_eq!(Float::ldexp(x1, exp1), f1);
-        assert_eq!(Float::ldexp(x2, exp2), f2);
-
-        assert_eq!(0f32.frexp(), (0f32, 0));
-        assert_eq!((-0f32).frexp(), (-0f32, 0));
-    }
-
-    #[test] #[cfg_attr(windows, ignore)] // FIXME #8755
-    fn test_frexp_nowin() {
-        let inf: f32 = Float::infinity();
-        let neg_inf: f32 = Float::neg_infinity();
-        let nan: f32 = Float::nan();
-        assert_eq!(match inf.frexp() { (x, _) => x }, inf);
-        assert_eq!(match neg_inf.frexp() { (x, _) => x }, neg_inf);
-        assert!(match nan.frexp() { (x, _) => x.is_nan() })
-    }
-
-    #[test]
-    fn test_integer_decode() {
-        assert_eq!(3.14159265359f32.integer_decode(), (13176795, -22, 1));
-        assert_eq!((-8573.5918555f32).integer_decode(), (8779358, -10, -1));
-        assert_eq!(2f32.powf(100.0).integer_decode(), (8388608, 77, 1));
-        assert_eq!(0f32.integer_decode(), (0, -150, 1));
-        assert_eq!((-0f32).integer_decode(), (0, -150, -1));
-        assert_eq!(INFINITY.integer_decode(), (8388608, 105, 1));
-        assert_eq!(NEG_INFINITY.integer_decode(), (8388608, 105, -1));
-        assert_eq!(NAN.integer_decode(), (12582912, 105, 1));
-    }
-
-    #[test]
-    fn test_sqrt_domain() {
-        assert!(NAN.sqrt().is_nan());
-        assert!(NEG_INFINITY.sqrt().is_nan());
-        assert!((-1.0f32).sqrt().is_nan());
-        assert_eq!((-0.0f32).sqrt(), -0.0);
-        assert_eq!(0.0f32.sqrt(), 0.0);
-        assert_eq!(1.0f32.sqrt(), 1.0);
-        assert_eq!(INFINITY.sqrt(), INFINITY);
-    }
 }
index a7bdad70a362b8cf16ddddd95cec057a18c586c4..95065b59678c951052eef175475ebab3ff75c39f 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -477,6 +477,11 @@ mod tests {
     use num::*;
     use num::FpCategory as Fp;
 
+    #[test]
+    fn test_num_f64() {
+        test_num(10f64, 2f64);
+    }
+
     #[test]
     fn test_min_nan() {
         assert_eq!(NAN.min(2.0), 2.0);
@@ -490,8 +495,162 @@ fn test_max_nan() {
     }
 
     #[test]
-    fn test_num_f64() {
-        test_num(10f64, 2f64);
+    fn test_nan() {
+        let nan: f64 = Float::nan();
+        assert!(nan.is_nan());
+        assert!(!nan.is_infinite());
+        assert!(!nan.is_finite());
+        assert!(!nan.is_normal());
+        assert!(!nan.is_positive());
+        assert!(!nan.is_negative());
+        assert_eq!(Fp::Nan, nan.classify());
+    }
+
+    #[test]
+    fn test_infinity() {
+        let inf: f64 = Float::infinity();
+        assert!(inf.is_infinite());
+        assert!(!inf.is_finite());
+        assert!(inf.is_positive());
+        assert!(!inf.is_negative());
+        assert!(!inf.is_nan());
+        assert!(!inf.is_normal());
+        assert_eq!(Fp::Infinite, inf.classify());
+    }
+
+    #[test]
+    fn test_neg_infinity() {
+        let neg_inf: f64 = Float::neg_infinity();
+        assert!(neg_inf.is_infinite());
+        assert!(!neg_inf.is_finite());
+        assert!(!neg_inf.is_positive());
+        assert!(neg_inf.is_negative());
+        assert!(!neg_inf.is_nan());
+        assert!(!neg_inf.is_normal());
+        assert_eq!(Fp::Infinite, neg_inf.classify());
+    }
+
+    #[test]
+    fn test_zero() {
+        let zero: f64 = Float::zero();
+        assert_eq!(0.0, zero);
+        assert!(!zero.is_infinite());
+        assert!(zero.is_finite());
+        assert!(zero.is_positive());
+        assert!(!zero.is_negative());
+        assert!(!zero.is_nan());
+        assert!(!zero.is_normal());
+        assert_eq!(Fp::Zero, zero.classify());
+    }
+
+    #[test]
+    fn test_neg_zero() {
+        let neg_zero: f64 = Float::neg_zero();
+        assert_eq!(0.0, neg_zero);
+        assert!(!neg_zero.is_infinite());
+        assert!(neg_zero.is_finite());
+        assert!(!neg_zero.is_positive());
+        assert!(neg_zero.is_negative());
+        assert!(!neg_zero.is_nan());
+        assert!(!neg_zero.is_normal());
+        assert_eq!(Fp::Zero, neg_zero.classify());
+    }
+
+    #[test]
+    fn test_one() {
+        let one: f64 = Float::one();
+        assert_eq!(1.0, one);
+        assert!(!one.is_infinite());
+        assert!(one.is_finite());
+        assert!(one.is_positive());
+        assert!(!one.is_negative());
+        assert!(!one.is_nan());
+        assert!(one.is_normal());
+        assert_eq!(Fp::Normal, one.classify());
+    }
+
+    #[test]
+    fn test_is_nan() {
+        let nan: f64 = Float::nan();
+        let inf: f64 = Float::infinity();
+        let neg_inf: f64 = Float::neg_infinity();
+        assert!(nan.is_nan());
+        assert!(!0.0f64.is_nan());
+        assert!(!5.3f64.is_nan());
+        assert!(!(-10.732f64).is_nan());
+        assert!(!inf.is_nan());
+        assert!(!neg_inf.is_nan());
+    }
+
+    #[test]
+    fn test_is_infinite() {
+        let nan: f64 = Float::nan();
+        let inf: f64 = Float::infinity();
+        let neg_inf: f64 = Float::neg_infinity();
+        assert!(!nan.is_infinite());
+        assert!(inf.is_infinite());
+        assert!(neg_inf.is_infinite());
+        assert!(!0.0f64.is_infinite());
+        assert!(!42.8f64.is_infinite());
+        assert!(!(-109.2f64).is_infinite());
+    }
+
+    #[test]
+    fn test_is_finite() {
+        let nan: f64 = Float::nan();
+        let inf: f64 = Float::infinity();
+        let neg_inf: f64 = Float::neg_infinity();
+        assert!(!nan.is_finite());
+        assert!(!inf.is_finite());
+        assert!(!neg_inf.is_finite());
+        assert!(0.0f64.is_finite());
+        assert!(42.8f64.is_finite());
+        assert!((-109.2f64).is_finite());
+    }
+
+    #[test]
+    fn test_is_normal() {
+        let nan: f64 = Float::nan();
+        let inf: f64 = Float::infinity();
+        let neg_inf: f64 = Float::neg_infinity();
+        let zero: f64 = Float::zero();
+        let neg_zero: f64 = Float::neg_zero();
+        assert!(!nan.is_normal());
+        assert!(!inf.is_normal());
+        assert!(!neg_inf.is_normal());
+        assert!(!zero.is_normal());
+        assert!(!neg_zero.is_normal());
+        assert!(1f64.is_normal());
+        assert!(1e-307f64.is_normal());
+        assert!(!1e-308f64.is_normal());
+    }
+
+    #[test]
+    fn test_classify() {
+        let nan: f64 = Float::nan();
+        let inf: f64 = Float::infinity();
+        let neg_inf: f64 = Float::neg_infinity();
+        let zero: f64 = Float::zero();
+        let neg_zero: f64 = Float::neg_zero();
+        assert_eq!(nan.classify(), Fp::Nan);
+        assert_eq!(inf.classify(), Fp::Infinite);
+        assert_eq!(neg_inf.classify(), Fp::Infinite);
+        assert_eq!(zero.classify(), Fp::Zero);
+        assert_eq!(neg_zero.classify(), Fp::Zero);
+        assert_eq!(1e-307f64.classify(), Fp::Normal);
+        assert_eq!(1e-308f64.classify(), Fp::Subnormal);
+    }
+
+    #[test]
+    fn test_integer_decode() {
+        assert_eq!(3.14159265359f64.integer_decode(), (7074237752028906, -51, 1));
+        assert_eq!((-8573.5918555f64).integer_decode(), (4713381968463931, -39, -1));
+        assert_eq!(2f64.powf(100.0).integer_decode(), (4503599627370496, 48, 1));
+        assert_eq!(0f64.integer_decode(), (0, -1075, 1));
+        assert_eq!((-0f64).integer_decode(), (0, -1075, -1));
+        assert_eq!(INFINITY.integer_decode(), (4503599627370496, 972, 1));
+        assert_eq!(NEG_INFINITY.integer_decode(), (4503599627370496, 972, -1));
+        assert_eq!(NAN.integer_decode(), (6755399441055744, 972, 1));
     }
 
     #[test]
@@ -564,6 +723,140 @@ fn test_fract() {
         assert_approx_eq!((-1.7f64).fract(), -0.7f64);
     }
 
+    #[test]
+    fn test_abs() {
+        assert_eq!(INFINITY.abs(), INFINITY);
+        assert_eq!(1f64.abs(), 1f64);
+        assert_eq!(0f64.abs(), 0f64);
+        assert_eq!((-0f64).abs(), 0f64);
+        assert_eq!((-1f64).abs(), 1f64);
+        assert_eq!(NEG_INFINITY.abs(), INFINITY);
+        assert_eq!((1f64/NEG_INFINITY).abs(), 0f64);
+        assert!(NAN.abs().is_nan());
+    }
+
+    #[test]
+    fn test_signum() {
+        assert_eq!(INFINITY.signum(), 1f64);
+        assert_eq!(1f64.signum(), 1f64);
+        assert_eq!(0f64.signum(), 1f64);
+        assert_eq!((-0f64).signum(), -1f64);
+        assert_eq!((-1f64).signum(), -1f64);
+        assert_eq!(NEG_INFINITY.signum(), -1f64);
+        assert_eq!((1f64/NEG_INFINITY).signum(), -1f64);
+        assert!(NAN.signum().is_nan());
+    }
+
+    #[test]
+    fn test_is_positive() {
+        assert!(INFINITY.is_positive());
+        assert!(1f64.is_positive());
+        assert!(0f64.is_positive());
+        assert!(!(-0f64).is_positive());
+        assert!(!(-1f64).is_positive());
+        assert!(!NEG_INFINITY.is_positive());
+        assert!(!(1f64/NEG_INFINITY).is_positive());
+        assert!(!NAN.is_positive());
+    }
+
+    #[test]
+    fn test_is_negative() {
+        assert!(!INFINITY.is_negative());
+        assert!(!1f64.is_negative());
+        assert!(!0f64.is_negative());
+        assert!((-0f64).is_negative());
+        assert!((-1f64).is_negative());
+        assert!(NEG_INFINITY.is_negative());
+        assert!((1f64/NEG_INFINITY).is_negative());
+        assert!(!NAN.is_negative());
+    }
+
+    #[test]
+    fn test_mul_add() {
+        let nan: f64 = Float::nan();
+        let inf: f64 = Float::infinity();
+        let neg_inf: f64 = Float::neg_infinity();
+        assert_approx_eq!(12.3f64.mul_add(4.5, 6.7), 62.05);
+        assert_approx_eq!((-12.3f64).mul_add(-4.5, -6.7), 48.65);
+        assert_approx_eq!(0.0f64.mul_add(8.9, 1.2), 1.2);
+        assert_approx_eq!(3.4f64.mul_add(-0.0, 5.6), 5.6);
+        assert!(nan.mul_add(7.8, 9.0).is_nan());
+        assert_eq!(inf.mul_add(7.8, 9.0), inf);
+        assert_eq!(neg_inf.mul_add(7.8, 9.0), neg_inf);
+        assert_eq!(8.9f64.mul_add(inf, 3.2), inf);
+        assert_eq!((-3.2f64).mul_add(2.4, neg_inf), neg_inf);
+    }
+
+    #[test]
+    fn test_recip() {
+        let nan: f64 = Float::nan();
+        let inf: f64 = Float::infinity();
+        let neg_inf: f64 = Float::neg_infinity();
+        assert_eq!(1.0f64.recip(), 1.0);
+        assert_eq!(2.0f64.recip(), 0.5);
+        assert_eq!((-0.4f64).recip(), -2.5);
+        assert_eq!(0.0f64.recip(), inf);
+        assert!(nan.recip().is_nan());
+        assert_eq!(inf.recip(), 0.0);
+        assert_eq!(neg_inf.recip(), 0.0);
+    }
+
+    #[test]
+    fn test_powi() {
+        let nan: f64 = Float::nan();
+        let inf: f64 = Float::infinity();
+        let neg_inf: f64 = Float::neg_infinity();
+        assert_eq!(1.0f64.powi(1), 1.0);
+        assert_approx_eq!((-3.1f64).powi(2), 9.61);
+        assert_approx_eq!(5.9f64.powi(-2), 0.028727);
+        assert_eq!(8.3f64.powi(0), 1.0);
+        assert!(nan.powi(2).is_nan());
+        assert_eq!(inf.powi(3), inf);
+        assert_eq!(neg_inf.powi(2), inf);
+    }
+
+    #[test]
+    fn test_powf() {
+        let nan: f64 = Float::nan();
+        let inf: f64 = Float::infinity();
+        let neg_inf: f64 = Float::neg_infinity();
+        assert_eq!(1.0f64.powf(1.0), 1.0);
+        assert_approx_eq!(3.4f64.powf(4.5), 246.408183);
+        assert_approx_eq!(2.7f64.powf(-3.2), 0.041652);
+        assert_approx_eq!((-3.1f64).powf(2.0), 9.61);
+        assert_approx_eq!(5.9f64.powf(-2.0), 0.028727);
+        assert_eq!(8.3f64.powf(0.0), 1.0);
+        assert!(nan.powf(2.0).is_nan());
+        assert_eq!(inf.powf(2.0), inf);
+        assert_eq!(neg_inf.powf(3.0), neg_inf);
+    }
+
+    #[test]
+    fn test_sqrt_domain() {
+        assert!(NAN.sqrt().is_nan());
+        assert!(NEG_INFINITY.sqrt().is_nan());
+        assert!((-1.0f64).sqrt().is_nan());
+        assert_eq!((-0.0f64).sqrt(), -0.0);
+        assert_eq!(0.0f64.sqrt(), 0.0);
+        assert_eq!(1.0f64.sqrt(), 1.0);
+        assert_eq!(INFINITY.sqrt(), INFINITY);
+    }
+
+    #[test]
+    fn test_rsqrt() {
+        let nan: f64 = Float::nan();
+        let inf: f64 = Float::infinity();
+        let neg_inf: f64 = Float::neg_infinity();
+        assert!(nan.rsqrt().is_nan());
+        assert_eq!(inf.rsqrt(), 0.0);
+        assert!(neg_inf.rsqrt().is_nan());
+        assert!((-1.0f64).rsqrt().is_nan());
+        assert_eq!((-0.0f64).rsqrt(), neg_inf);
+        assert_eq!(0.0f64.rsqrt(), inf);
+        assert_eq!(1.0f64.rsqrt(), 1.0);
+        assert_eq!(4.0f64.rsqrt(), 0.5);
+    }
+
     #[test]
     fn test_exp() {
         assert_eq!(1.0, 0.0f64.exp());
@@ -591,6 +884,172 @@ fn test_exp2() {
         assert!(nan.exp2().is_nan());
     }
 
+    #[test]
+    fn test_ln() {
+        let nan: f64 = Float::nan();
+        let inf: f64 = Float::infinity();
+        let neg_inf: f64 = Float::neg_infinity();
+        assert_approx_eq!(1.0f64.exp().ln(), 1.0);
+        assert!(nan.ln().is_nan());
+        assert_eq!(inf.ln(), inf);
+        assert!(neg_inf.ln().is_nan());
+        assert!((-2.3f64).ln().is_nan());
+        assert_eq!((-0.0f64).ln(), neg_inf);
+        assert_eq!(0.0f64.ln(), neg_inf);
+        assert_approx_eq!(4.0f64.ln(), 1.386294);
+    }
+
+    #[test]
+    fn test_log() {
+        let nan: f64 = Float::nan();
+        let inf: f64 = Float::infinity();
+        let neg_inf: f64 = Float::neg_infinity();
+        assert_eq!(10.0f64.log(10.0), 1.0);
+        assert_approx_eq!(2.3f64.log(3.5), 0.664858);
+        assert_eq!(1.0f64.exp().log(1.0.exp()), 1.0);
+        assert!(1.0f64.log(1.0).is_nan());
+        assert!(1.0f64.log(-13.9).is_nan());
+        assert!(nan.log(2.3).is_nan());
+        assert_eq!(inf.log(10.0), inf);
+        assert!(neg_inf.log(8.8).is_nan());
+        assert!((-2.3f64).log(0.1).is_nan());
+        assert_eq!((-0.0f64).log(2.0), neg_inf);
+        assert_eq!(0.0f64.log(7.0), neg_inf);
+    }
+
+    #[test]
+    fn test_log2() {
+        let nan: f64 = Float::nan();
+        let inf: f64 = Float::infinity();
+        let neg_inf: f64 = Float::neg_infinity();
+        assert_approx_eq!(10.0f64.log2(), 3.321928);
+        assert_approx_eq!(2.3f64.log2(), 1.201634);
+        assert_approx_eq!(1.0f64.exp().log2(), 1.442695);
+        assert!(nan.log2().is_nan());
+        assert_eq!(inf.log2(), inf);
+        assert!(neg_inf.log2().is_nan());
+        assert!((-2.3f64).log2().is_nan());
+        assert_eq!((-0.0f64).log2(), neg_inf);
+        assert_eq!(0.0f64.log2(), neg_inf);
+    }
+
+    #[test]
+    fn test_log10() {
+        let nan: f64 = Float::nan();
+        let inf: f64 = Float::infinity();
+        let neg_inf: f64 = Float::neg_infinity();
+        assert_eq!(10.0f64.log10(), 1.0);
+        assert_approx_eq!(2.3f64.log10(), 0.361728);
+        assert_approx_eq!(1.0f64.exp().log10(), 0.434294);
+        assert_eq!(1.0f64.log10(), 0.0);
+        assert!(nan.log10().is_nan());
+        assert_eq!(inf.log10(), inf);
+        assert!(neg_inf.log10().is_nan());
+        assert!((-2.3f64).log10().is_nan());
+        assert_eq!((-0.0f64).log10(), neg_inf);
+        assert_eq!(0.0f64.log10(), neg_inf);
+    }
+
+    #[test]
+    fn test_to_degrees() {
+        let pi: f64 = consts::PI;
+        let nan: f64 = Float::nan();
+        let inf: f64 = Float::infinity();
+        let neg_inf: f64 = Float::neg_infinity();
+        assert_eq!(0.0f64.to_degrees(), 0.0);
+        assert_approx_eq!((-5.8f64).to_degrees(), -332.315521);
+        assert_eq!(pi.to_degrees(), 180.0);
+        assert!(nan.to_degrees().is_nan());
+        assert_eq!(inf.to_degrees(), inf);
+        assert_eq!(neg_inf.to_degrees(), neg_inf);
+    }
+
+    #[test]
+    fn test_to_radians() {
+        let pi: f64 = consts::PI;
+        let nan: f64 = Float::nan();
+        let inf: f64 = Float::infinity();
+        let neg_inf: f64 = Float::neg_infinity();
+        assert_eq!(0.0f64.to_radians(), 0.0);
+        assert_approx_eq!(154.6f64.to_radians(), 2.698279);
+        assert_approx_eq!((-332.31f64).to_radians(), -5.799903);
+        assert_eq!(180.0f64.to_radians(), pi);
+        assert!(nan.to_radians().is_nan());
+        assert_eq!(inf.to_radians(), inf);
+        assert_eq!(neg_inf.to_radians(), neg_inf);
+    }
+
+    #[test]
+    fn test_ldexp() {
+        // We have to use from_str until base-2 exponents
+        // are supported in floating-point literals
+        let f1: f64 = FromStrRadix::from_str_radix("1p-123", 16).unwrap();
+        let f2: f64 = FromStrRadix::from_str_radix("1p-111", 16).unwrap();
+        let f3: f64 = FromStrRadix::from_str_radix("1.Cp-12", 16).unwrap();
+        assert_eq!(Float::ldexp(1f64, -123), f1);
+        assert_eq!(Float::ldexp(1f64, -111), f2);
+        assert_eq!(Float::ldexp(1.75f64, -12), f3);
+
+        assert_eq!(Float::ldexp(0f64, -123), 0f64);
+        assert_eq!(Float::ldexp(-0f64, -123), -0f64);
+
+        let inf: f64 = Float::infinity();
+        let neg_inf: f64 = Float::neg_infinity();
+        let nan: f64 = Float::nan();
+        assert_eq!(Float::ldexp(inf, -123), inf);
+        assert_eq!(Float::ldexp(neg_inf, -123), neg_inf);
+        assert!(Float::ldexp(nan, -123).is_nan());
+    }
+
+    #[test]
+    fn test_frexp() {
+        // We have to use from_str until base-2 exponents
+        // are supported in floating-point literals
+        let f1: f64 = FromStrRadix::from_str_radix("1p-123", 16).unwrap();
+        let f2: f64 = FromStrRadix::from_str_radix("1p-111", 16).unwrap();
+        let f3: f64 = FromStrRadix::from_str_radix("1.Cp-123", 16).unwrap();
+        let (x1, exp1) = f1.frexp();
+        let (x2, exp2) = f2.frexp();
+        let (x3, exp3) = f3.frexp();
+        assert_eq!((x1, exp1), (0.5f64, -122));
+        assert_eq!((x2, exp2), (0.5f64, -110));
+        assert_eq!((x3, exp3), (0.875f64, -122));
+        assert_eq!(Float::ldexp(x1, exp1), f1);
+        assert_eq!(Float::ldexp(x2, exp2), f2);
+        assert_eq!(Float::ldexp(x3, exp3), f3);
+
+        assert_eq!(0f64.frexp(), (0f64, 0));
+        assert_eq!((-0f64).frexp(), (-0f64, 0));
+    }
+
+    #[test] #[cfg_attr(windows, ignore)] // FIXME #8755
+    fn test_frexp_nowin() {
+        let inf: f64 = Float::infinity();
+        let neg_inf: f64 = Float::neg_infinity();
+        let nan: f64 = Float::nan();
+        assert_eq!(match inf.frexp() { (x, _) => x }, inf);
+        assert_eq!(match neg_inf.frexp() { (x, _) => x }, neg_inf);
+        assert!(match nan.frexp() { (x, _) => x.is_nan() })
+    }
+
+    #[test]
+    fn test_abs_sub() {
+        assert_eq!((-1f64).abs_sub(1f64), 0f64);
+        assert_eq!(1f64.abs_sub(1f64), 0f64);
+        assert_eq!(1f64.abs_sub(0f64), 1f64);
+        assert_eq!(1f64.abs_sub(-1f64), 2f64);
+        assert_eq!(NEG_INFINITY.abs_sub(0f64), 0f64);
+        assert_eq!(INFINITY.abs_sub(1f64), INFINITY);
+        assert_eq!(0f64.abs_sub(NEG_INFINITY), INFINITY);
+        assert_eq!(0f64.abs_sub(INFINITY), 0f64);
+    }
+
+    #[test]
+    fn test_abs_sub_nowin() {
+        assert!(NAN.abs_sub(-1f64).is_nan());
+        assert!(1f64.abs_sub(NAN).is_nan());
+    }
+
     #[test]
     fn test_asinh() {
         assert_eq!(0.0f64.asinh(), 0.0f64);
@@ -677,173 +1136,4 @@ fn test_real_consts() {
         assert_approx_eq!(ln_2, 2f64.ln());
         assert_approx_eq!(ln_10, 10f64.ln());
     }
-
-    #[test]
-    pub fn test_abs() {
-        assert_eq!(INFINITY.abs(), INFINITY);
-        assert_eq!(1f64.abs(), 1f64);
-        assert_eq!(0f64.abs(), 0f64);
-        assert_eq!((-0f64).abs(), 0f64);
-        assert_eq!((-1f64).abs(), 1f64);
-        assert_eq!(NEG_INFINITY.abs(), INFINITY);
-        assert_eq!((1f64/NEG_INFINITY).abs(), 0f64);
-        assert!(NAN.abs().is_nan());
-    }
-
-    #[test]
-    fn test_abs_sub() {
-        assert_eq!((-1f64).abs_sub(1f64), 0f64);
-        assert_eq!(1f64.abs_sub(1f64), 0f64);
-        assert_eq!(1f64.abs_sub(0f64), 1f64);
-        assert_eq!(1f64.abs_sub(-1f64), 2f64);
-        assert_eq!(NEG_INFINITY.abs_sub(0f64), 0f64);
-        assert_eq!(INFINITY.abs_sub(1f64), INFINITY);
-        assert_eq!(0f64.abs_sub(NEG_INFINITY), INFINITY);
-        assert_eq!(0f64.abs_sub(INFINITY), 0f64);
-    }
-
-    #[test]
-    fn test_abs_sub_nowin() {
-        assert!(NAN.abs_sub(-1f64).is_nan());
-        assert!(1f64.abs_sub(NAN).is_nan());
-    }
-
-    #[test]
-    fn test_signum() {
-        assert_eq!(INFINITY.signum(), 1f64);
-        assert_eq!(1f64.signum(), 1f64);
-        assert_eq!(0f64.signum(), 1f64);
-        assert_eq!((-0f64).signum(), -1f64);
-        assert_eq!((-1f64).signum(), -1f64);
-        assert_eq!(NEG_INFINITY.signum(), -1f64);
-        assert_eq!((1f64/NEG_INFINITY).signum(), -1f64);
-        assert!(NAN.signum().is_nan());
-    }
-
-    #[test]
-    fn test_is_positive() {
-        assert!(INFINITY.is_positive());
-        assert!(1f64.is_positive());
-        assert!(0f64.is_positive());
-        assert!(!(-0f64).is_positive());
-        assert!(!(-1f64).is_positive());
-        assert!(!NEG_INFINITY.is_positive());
-        assert!(!(1f64/NEG_INFINITY).is_positive());
-        assert!(!NAN.is_positive());
-    }
-
-    #[test]
-    fn test_is_negative() {
-        assert!(!INFINITY.is_negative());
-        assert!(!1f64.is_negative());
-        assert!(!0f64.is_negative());
-        assert!((-0f64).is_negative());
-        assert!((-1f64).is_negative());
-        assert!(NEG_INFINITY.is_negative());
-        assert!((1f64/NEG_INFINITY).is_negative());
-        assert!(!NAN.is_negative());
-    }
-
-    #[test]
-    fn test_is_normal() {
-        let nan: f64 = Float::nan();
-        let inf: f64 = Float::infinity();
-        let neg_inf: f64 = Float::neg_infinity();
-        let zero: f64 = Float::zero();
-        let neg_zero: f64 = Float::neg_zero();
-        assert!(!nan.is_normal());
-        assert!(!inf.is_normal());
-        assert!(!neg_inf.is_normal());
-        assert!(!zero.is_normal());
-        assert!(!neg_zero.is_normal());
-        assert!(1f64.is_normal());
-        assert!(1e-307f64.is_normal());
-        assert!(!1e-308f64.is_normal());
-    }
-
-    #[test]
-    fn test_classify() {
-        let nan: f64 = Float::nan();
-        let inf: f64 = Float::infinity();
-        let neg_inf: f64 = Float::neg_infinity();
-        let zero: f64 = Float::zero();
-        let neg_zero: f64 = Float::neg_zero();
-        assert_eq!(nan.classify(), Fp::Nan);
-        assert_eq!(inf.classify(), Fp::Infinite);
-        assert_eq!(neg_inf.classify(), Fp::Infinite);
-        assert_eq!(zero.classify(), Fp::Zero);
-        assert_eq!(neg_zero.classify(), Fp::Zero);
-        assert_eq!(1e-307f64.classify(), Fp::Normal);
-        assert_eq!(1e-308f64.classify(), Fp::Subnormal);
-    }
-
-    #[test]
-    fn test_ldexp() {
-        // We have to use from_str until base-2 exponents
-        // are supported in floating-point literals
-        let f1: f64 = FromStrRadix::from_str_radix("1p-123", 16).unwrap();
-        let f2: f64 = FromStrRadix::from_str_radix("1p-111", 16).unwrap();
-        assert_eq!(Float::ldexp(1f64, -123), f1);
-        assert_eq!(Float::ldexp(1f64, -111), f2);
-
-        assert_eq!(Float::ldexp(0f64, -123), 0f64);
-        assert_eq!(Float::ldexp(-0f64, -123), -0f64);
-
-        let inf: f64 = Float::infinity();
-        let neg_inf: f64 = Float::neg_infinity();
-        let nan: f64 = Float::nan();
-        assert_eq!(Float::ldexp(inf, -123), inf);
-        assert_eq!(Float::ldexp(neg_inf, -123), neg_inf);
-        assert!(Float::ldexp(nan, -123).is_nan());
-    }
-
-    #[test]
-    fn test_frexp() {
-        // We have to use from_str until base-2 exponents
-        // are supported in floating-point literals
-        let f1: f64 = FromStrRadix::from_str_radix("1p-123", 16).unwrap();
-        let f2: f64 = FromStrRadix::from_str_radix("1p-111", 16).unwrap();
-        let (x1, exp1) = f1.frexp();
-        let (x2, exp2) = f2.frexp();
-        assert_eq!((x1, exp1), (0.5f64, -122));
-        assert_eq!((x2, exp2), (0.5f64, -110));
-        assert_eq!(Float::ldexp(x1, exp1), f1);
-        assert_eq!(Float::ldexp(x2, exp2), f2);
-
-        assert_eq!(0f64.frexp(), (0f64, 0));
-        assert_eq!((-0f64).frexp(), (-0f64, 0));
-    }
-
-    #[test] #[cfg_attr(windows, ignore)] // FIXME #8755
-    fn test_frexp_nowin() {
-        let inf: f64 = Float::infinity();
-        let neg_inf: f64 = Float::neg_infinity();
-        let nan: f64 = Float::nan();
-        assert_eq!(match inf.frexp() { (x, _) => x }, inf);
-        assert_eq!(match neg_inf.frexp() { (x, _) => x }, neg_inf);
-        assert!(match nan.frexp() { (x, _) => x.is_nan() })
-    }
-
-    #[test]
-    fn test_integer_decode() {
-        assert_eq!(3.14159265359f64.integer_decode(), (7074237752028906, -51, 1));
-        assert_eq!((-8573.5918555f64).integer_decode(), (4713381968463931, -39, -1));
-        assert_eq!(2f64.powf(100.0).integer_decode(), (4503599627370496, 48, 1));
-        assert_eq!(0f64.integer_decode(), (0, -1075, 1));
-        assert_eq!((-0f64).integer_decode(), (0, -1075, -1));
-        assert_eq!(INFINITY.integer_decode(), (4503599627370496, 972, 1));
-        assert_eq!(NEG_INFINITY.integer_decode(), (4503599627370496, 972, -1));
-        assert_eq!(NAN.integer_decode(), (6755399441055744, 972, 1));
-    }
-
-    #[test]
-    fn test_sqrt_domain() {
-        assert!(NAN.sqrt().is_nan());
-        assert!(NEG_INFINITY.sqrt().is_nan());
-        assert!((-1.0f64).sqrt().is_nan());
-        assert_eq!((-0.0f64).sqrt(), -0.0);
-        assert_eq!(0.0f64.sqrt(), 0.0);
-        assert_eq!(1.0f64.sqrt(), 1.0);
-        assert_eq!(INFINITY.sqrt(), INFINITY);
-    }
 }
index fe2510b668f9278e6376734a13804e90ab082b68..cbb7bf043274506cee50a88ae535ac30f79711e2 100644 (file)
@@ -658,7 +658,7 @@ fn test_chars() {
     }
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn dont_panic_in_drop_on_panicked_flush() {
         struct FailFlushWriter;
 
index a2bc28962c39a9ad6b7c38619940c8b49c4445d9..ec30121d78db807afbab0b9495dccd6ce7f4b204 100644 (file)
@@ -396,7 +396,7 @@ fn read_to_end() {
     }
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn read_to_end_error() {
         let mut reader = ThreeChunkReader {
             count: 0,
index 9ce888efcebed3baef9c0ae75f199b67a1b220aa..f2042b384ceea3cce97d5f0ea877e87a5eab6e8f 100644 (file)
@@ -343,8 +343,7 @@ impl IoError {
     pub fn from_errno(errno: i32, detail: bool) -> IoError {
         let mut err = sys::decode_error(errno as i32);
         if detail && err.kind == OtherIoError {
-            err.detail = Some(os::error_string(errno).chars()
-                                 .map(|c| c.to_lowercase()).collect())
+            err.detail = Some(os::error_string(errno).to_lowercase());
         }
         err
     }
index e02e863516ab1ebdddcea006f24af713076c48ae..a30dcd9d9f0ab72ce9a8f927b58d5847564d9d3a 100644 (file)
@@ -110,10 +110,11 @@ pub struct Process {
 #[cfg(windows)]
 impl hash::Hash for EnvKey {
     fn hash<H: hash::Hasher>(&self, state: &mut H) {
+        use ascii::AsciiExt;
         let &EnvKey(ref x) = self;
         match str::from_utf8(x.as_bytes()) {
             Ok(s) => for ch in s.chars() {
-                (ch as u8 as char).to_lowercase().hash(state);
+                ch.to_ascii_lowercase().hash(state);
             },
             Err(..) => x.hash(state)
         }
@@ -123,6 +124,7 @@ fn hash<H: hash::Hasher>(&self, state: &mut H) {
 #[cfg(windows)]
 impl PartialEq for EnvKey {
     fn eq(&self, other: &EnvKey) -> bool {
+        use ascii::AsciiExt;
         let &EnvKey(ref x) = self;
         let &EnvKey(ref y) = other;
         match (str::from_utf8(x.as_bytes()), str::from_utf8(y.as_bytes())) {
@@ -131,7 +133,7 @@ fn eq(&self, other: &EnvKey) -> bool {
                     return false
                 } else {
                     for (xch, ych) in xs.chars().zip(ys.chars()) {
-                        if xch.to_lowercase() != ych.to_lowercase() {
+                        if xch.to_ascii_lowercase() != ych.to_ascii_lowercase() {
                             return false;
                         }
                     }
index de5f2141095f30705e99a467f9c5b16e746a04d6..375fe6ce483aae520dbb3236ce0bbf75c0af3d15 100644 (file)
@@ -333,7 +333,7 @@ fn sleep() {
     }
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn oneshot_fail() {
         let mut timer = Timer::new().unwrap();
         let _rx = timer.oneshot(Duration::milliseconds(1));
@@ -341,7 +341,7 @@ fn oneshot_fail() {
     }
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn period_fail() {
         let mut timer = Timer::new().unwrap();
         let _rx = timer.periodic(Duration::milliseconds(1));
@@ -349,7 +349,7 @@ fn period_fail() {
     }
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn normal_fail() {
         let _timer = Timer::new().unwrap();
         panic!();
index 31a8cbe572a0318d60d8c0afb8f2c710d205cd11..5f2f1728be1a6317a65792f4be1f1351f89ec58c 100644 (file)
@@ -1324,7 +1324,7 @@ fn test_null_byte() {
     }
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn test_not_utf8_panics() {
         Path::new(b"hello\x80.txt");
     }
index 79028f49e68bfa17efcc7009500550d02a9a865d..ec4fcec5556223d98fc73eef43e3ef90d3b2ef29 100644 (file)
@@ -264,7 +264,7 @@ pub fn spawn(&mut self) -> io::Result<Child> {
     /// By default, stdin, stdout and stderr are captured (and used to
     /// provide the resulting output).
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
     /// # #![feature(process)]
@@ -275,8 +275,8 @@ pub fn spawn(&mut self) -> io::Result<Child> {
     /// });
     ///
     /// println!("status: {}", output.status);
-    /// println!("stdout: {}", String::from_utf8_lossy(output.stdout.as_slice()));
-    /// println!("stderr: {}", String::from_utf8_lossy(output.stderr.as_slice()));
+    /// println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
+    /// println!("stderr: {}", String::from_utf8_lossy(&output.stderr));
     /// ```
     #[stable(feature = "process", since = "1.0.0")]
     pub fn output(&mut self) -> io::Result<Output> {
@@ -812,7 +812,7 @@ fn test_inherit_env() {
         for (ref k, ref v) in env::vars() {
             // don't check windows magical empty-named variables
             assert!(k.is_empty() ||
-                    output.contains(format!("{}={}", *k, *v).as_slice()),
+                    output.contains(&format!("{}={}", *k, *v)),
                     "output doesn't contain `{}={}`\n{}",
                     k, v, output);
         }
@@ -830,12 +830,12 @@ fn test_inherit_env() {
         for &(ref k, ref v) in &r {
             // don't check android RANDOM variables
             if *k != "RANDOM".to_string() {
-                assert!(output.contains(format!("{}={}",
-                                                *k,
-                                                *v).as_slice()) ||
-                        output.contains(format!("{}=\'{}\'",
-                                                *k,
-                                                *v).as_slice()));
+                assert!(output.contains(&format!("{}={}",
+                                                 *k,
+                                                 *v)) ||
+                        output.contains(&format!("{}=\'{}\'",
+                                                 *k,
+                                                 *v)));
             }
         }
     }
index 4ed1520ed03f60181a2651d83287e4a3baf46ebe..7382cc6e2eb33cd1f19fb15e21593ac01247ca11 100644 (file)
@@ -500,14 +500,14 @@ fn test_gen_range() {
     }
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn test_gen_range_panic_int() {
         let mut r = thread_rng();
         r.gen_range(5, -2);
     }
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn test_gen_range_panic_uint() {
         let mut r = thread_rng();
         r.gen_range(5, 2);
index ba1ebc2ab227556ce7eb023ae972c85aff5b93ee..c56dc387b7fe6773fa0c69ad0188242c729e3974 100644 (file)
@@ -114,7 +114,7 @@ fn test_reader_rng_fill_bytes() {
     }
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn test_reader_rng_insufficient_bytes() {
         let mut rng = ReaderRng::new(MemReader::new(vec!()));
         let mut v = [0; 3];
index e7ee9bd2066514f4e47a04b3bf2eb102de874fc6..3499675f5422d81c508f37c405ae3ecbc4c5c05b 100644 (file)
@@ -479,7 +479,7 @@ fn wait_timeout_with() {
     }
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn two_mutexes() {
         static M1: StaticMutex = MUTEX_INIT;
         static M2: StaticMutex = MUTEX_INIT;
index d60e27388086444a4323c8f53525a8046b28ecec..ee9bcd3dd89bf630d28886e8357f62ea41297def 100644 (file)
@@ -204,7 +204,7 @@ fn test_spawn() {
     }
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn test_future_panic() {
         let mut f = Future::spawn(move|| panic!());
         let _x: String = f.get();
index 1a1e9e69e71122eabe6254036f1e174fcb1a8aaa..2ae1d4a9d50bc42f7adc9b130052740c45cbdcc6 100644 (file)
 use prelude::v1::*;
 
 use sync::Arc;
+use error;
 use fmt;
 use mem;
 use cell::UnsafeCell;
@@ -975,6 +976,18 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T> error::Error for SendError<T> {
+
+    fn description(&self) -> &str {
+        "sending on a closed channel"
+    }
+
+    fn cause(&self) -> Option<&error::Error> {
+        None
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> fmt::Debug for TrySendError<T> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@@ -999,6 +1012,25 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T> error::Error for TrySendError<T> {
+
+    fn description(&self) -> &str {
+        match *self {
+            TrySendError::Full(..) => {
+                "sending on a full channel"
+            }
+            TrySendError::Disconnected(..) => {
+                "sending on a closed channel"
+            }
+        }
+    }
+
+    fn cause(&self) -> Option<&error::Error> {
+        None
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl fmt::Display for RecvError {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@@ -1006,6 +1038,18 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
+impl error::Error for RecvError {
+
+    fn description(&self) -> &str {
+        "receiving on a closed channel"
+    }
+
+    fn cause(&self) -> Option<&error::Error> {
+        None
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl fmt::Display for TryRecvError {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@@ -1020,6 +1064,25 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
+impl error::Error for TryRecvError {
+
+    fn description(&self) -> &str {
+        match *self {
+            TryRecvError::Empty => {
+                "receiving on an empty channel"
+            }
+            TryRecvError::Disconnected => {
+                "receiving on a closed channel"
+            }
+        }
+    }
+
+    fn cause(&self) -> Option<&error::Error> {
+        None
+    }
+}
+
 #[cfg(test)]
 mod test {
     use prelude::v1::*;
index efb6689e7855a40da3f9d374ead25439b9bee138..e41bc6d8683abb14a32df9de279ace42423ad01b 100644 (file)
@@ -164,7 +164,7 @@ fn test_works() {
     }
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn test_zero_tasks_panic() {
         TaskPool::new(0);
     }
index 719c74179ac23690bc360f5bf59e4a7e6c7784c0..7a02df23b19c5659a287d06dceab3c16a7b23a6d 100644 (file)
@@ -1030,14 +1030,14 @@ fn wtf8buf_truncate() {
     }
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn wtf8buf_truncate_fail_code_point_boundary() {
         let mut string = Wtf8Buf::from_str("aé");
         string.truncate(2);
     }
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn wtf8buf_truncate_fail_longer() {
         let mut string = Wtf8Buf::from_str("aé");
         string.truncate(4);
@@ -1133,7 +1133,7 @@ fn wtf8_slice() {
     }
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn wtf8_slice_not_code_point_boundary() {
         &Wtf8::from_str("aé 💩")[2.. 4];
     }
@@ -1144,7 +1144,7 @@ fn wtf8_slice_from() {
     }
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn wtf8_slice_from_not_code_point_boundary() {
         &Wtf8::from_str("aé 💩")[2..];
     }
@@ -1155,7 +1155,7 @@ fn wtf8_slice_to() {
     }
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn wtf8_slice_to_not_code_point_boundary() {
         &Wtf8::from_str("aé 💩")[5..];
     }
index 0ce3ca1f97ac8896abf350a06c1eef61ce972e6d..7d0df679591079e8fa6d149973c0a58de5e30eba 100644 (file)
@@ -284,7 +284,7 @@ fn spawn_inner<T: Send>(self, f: Thunk<(), T>) -> io::Result<JoinInner<T>> {
                 stack::record_os_managed_stack_bounds(my_stack_bottom, my_stack_top);
             }
             match their_thread.name() {
-                Some(name) => unsafe { imp::set_name(name.as_slice()); },
+                Some(name) => unsafe { imp::set_name(name); },
                 None => {}
             }
             thread_info::set(
index b41eb05ded695041108291b4d5b63935bb6c96d7..550ce3bb8c8734fe05a5cf27d0acfe5b1a7193dd 100644 (file)
@@ -1264,7 +1264,7 @@ pub struct BareFnTy {
 /// The different kinds of types recognized by the compiler
 pub enum Ty_ {
     TyVec(P<Ty>),
-    /// A fixed length array (`[T, ..n]`)
+    /// A fixed length array (`[Tn]`)
     TyFixedLengthVec(P<Ty>, P<Expr>),
     /// A raw pointer (`*const T` or `*mut T`)
     TyPtr(MutTy),
index faa681c0255285ccab0a12e1f49f05d5d7e3cf34..b96d735d92dbdd1e6ed59d3681f92bb6ecae9bcd 100644 (file)
@@ -457,35 +457,32 @@ fn with_path_next<T, F>(&self, id: NodeId, next: LinkedPath, f: F) -> T where
         }
     }
 
-    /// Given a node ID and a closure, apply the closure to the array
-    /// of attributes associated with the AST corresponding to the Node ID
-    pub fn with_attrs<T, F>(&self, id: NodeId, f: F) -> T where
-        F: FnOnce(Option<&[Attribute]>) -> T,
-    {
-        let attrs = match self.get(id) {
-            NodeItem(i) => Some(&i.attrs[..]),
-            NodeForeignItem(fi) => Some(&fi.attrs[..]),
-            NodeTraitItem(ref tm) => match **tm {
+    /// Given a node ID, get a list of of attributes associated with the AST
+    /// corresponding to the Node ID
+    pub fn attrs(&self, id: NodeId) -> &[Attribute] {
+        let attrs = match self.find(id) {
+            Some(NodeItem(i)) => Some(&i.attrs[..]),
+            Some(NodeForeignItem(fi)) => Some(&fi.attrs[..]),
+            Some(NodeTraitItem(ref tm)) => match **tm {
                 RequiredMethod(ref type_m) => Some(&type_m.attrs[..]),
                 ProvidedMethod(ref m) => Some(&m.attrs[..]),
                 TypeTraitItem(ref typ) => Some(&typ.attrs[..]),
             },
-            NodeImplItem(ref ii) => {
+            Some(NodeImplItem(ref ii)) => {
                 match **ii {
                     MethodImplItem(ref m) => Some(&m.attrs[..]),
                     TypeImplItem(ref t) => Some(&t.attrs[..]),
                 }
             }
-            NodeVariant(ref v) => Some(&v.node.attrs[..]),
+            Some(NodeVariant(ref v)) => Some(&v.node.attrs[..]),
             // unit/tuple structs take the attributes straight from
             // the struct definition.
-            // FIXME(eddyb) make this work again (requires access to the map).
-            NodeStructCtor(_) => {
-                return self.with_attrs(self.get_parent(id), f);
+            Some(NodeStructCtor(_)) => {
+                return self.attrs(self.get_parent(id));
             }
             _ => None
         };
-        f(attrs)
+        attrs.unwrap_or(&[])
     }
 
     /// Returns an iterator that yields the node id's with paths that
index 44df8a6d3daec74139a3b91e3aa234ebf4da2a1d..7d2d4e53fe9fd43002db11920e775e60bfa7b06a 100644 (file)
@@ -922,7 +922,7 @@ fn t1 () {
     }
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn t2 () {
         let cm = CodeMap::new();
         let fm = cm.new_filemap("blork.rs".to_string(),
index db8819ef82c2e3f011384141a3a858fbce8d870c..98c7aefcd8ad3275f68122308e65b87d790b441e 100644 (file)
@@ -1656,7 +1656,7 @@ fn test_ecfg() -> ExpansionConfig<'static> {
     }
 
     // make sure that macros can't escape fns
-    #[should_fail]
+    #[should_panic]
     #[test] fn macros_cant_escape_fns_test () {
         let src = "fn bogus() {macro_rules! z (() => (3+4));}\
                    fn inty() -> i32 { z!() }".to_string();
@@ -1670,7 +1670,7 @@ fn test_ecfg() -> ExpansionConfig<'static> {
     }
 
     // make sure that macros can't escape modules
-    #[should_fail]
+    #[should_panic]
     #[test] fn macros_cant_escape_mods_test () {
         let src = "mod foo {macro_rules! z (() => (3+4));}\
                    fn inty() -> i32 { z!() }".to_string();
index 425c517cb29fddcbeba06798d335387626ef1af8..c3bac0cf57c758cb8921f9f5185462db8b9a7b63 100644 (file)
@@ -403,11 +403,11 @@ fn check_attribute(&self, attr: &ast::Attribute) {
                                for the compiler");
         } else {
             self.gate_feature("custom_attribute", attr.span,
-                       format!("The attribute `{}` is currently \
+                       &format!("The attribute `{}` is currently \
                                 unknown to the the compiler and \
                                 may have meaning \
                                 added to it in the future",
-                                name).as_slice());
+                                name));
         }
     }
 }
index 58d58551df363715365f717735e0770acbe13284..fae305f955174241d46b018609fbfd5a521c50f2 100644 (file)
@@ -813,7 +813,7 @@ fn sp(a: u32, b: u32) -> Span {
                    }))
     }
 
-    #[should_fail]
+    #[should_panic]
     #[test] fn bad_path_expr_1() {
         string_to_expr("::abc::def::return".to_string());
     }
index d889453a5f977127708805124cf273979392a68c..5e858d8a79f766b3750fa6b1b4eaee7176d3c8d4 100644 (file)
@@ -37,7 +37,7 @@
 use ptr::P;
 use util::small_vector::SmallVector;
 
-enum ShouldFail {
+enum ShouldPanic {
     No,
     Yes(Option<InternedString>),
 }
@@ -47,7 +47,7 @@ struct Test {
     path: Vec<ast::Ident> ,
     bench: bool,
     ignore: bool,
-    should_fail: ShouldFail
+    should_panic: ShouldPanic
 }
 
 struct TestCtxt<'a> {
@@ -136,7 +136,7 @@ fn fold_item(&mut self, i: P<ast::Item>) -> SmallVector<P<ast::Item>> {
                         path: self.cx.path.clone(),
                         bench: is_bench_fn(&self.cx, &*i),
                         ignore: is_ignored(&*i),
-                        should_fail: should_fail(&*i)
+                        should_panic: should_panic(&*i, self.cx.span_diagnostic)
                     };
                     self.cx.testfns.push(test);
                     self.tests.push(i.ident);
@@ -378,15 +378,23 @@ fn is_ignored(i: &ast::Item) -> bool {
     i.attrs.iter().any(|attr| attr.check_name("ignore"))
 }
 
-fn should_fail(i: &ast::Item) -> ShouldFail {
-    match i.attrs.iter().find(|attr| attr.check_name("should_fail")) {
+fn should_panic(i: &ast::Item, diag: &diagnostic::SpanHandler) -> ShouldPanic {
+    match i.attrs.iter().find(|attr| {
+        if attr.check_name("should_panic") { return true; }
+        if attr.check_name("should_fail") {
+            diag.span_warn(attr.span, "`#[should_fail]` is deprecated. Use `#[should_panic]` \
+                                       instead");
+            return true;
+        }
+        false
+    }) {
         Some(attr) => {
             let msg = attr.meta_item_list()
                 .and_then(|list| list.iter().find(|mi| mi.check_name("expected")))
                 .and_then(|mi| mi.value_str());
-            ShouldFail::Yes(msg)
+            ShouldPanic::Yes(msg)
         }
-        None => ShouldFail::No,
+        None => ShouldPanic::No,
     }
 }
 
@@ -617,13 +625,13 @@ fn mk_test_desc_and_fn_rec(cx: &TestCtxt, test: &Test) -> P<ast::Expr> {
                                   vec![name_expr]);
 
     let ignore_expr = ecx.expr_bool(span, test.ignore);
-    let should_fail_path = |name| {
-        ecx.path(span, vec![self_id, test_id, ecx.ident_of("ShouldFail"), ecx.ident_of(name)])
+    let should_panic_path = |name| {
+        ecx.path(span, vec![self_id, test_id, ecx.ident_of("ShouldPanic"), ecx.ident_of(name)])
     };
-    let fail_expr = match test.should_fail {
-        ShouldFail::No => ecx.expr_path(should_fail_path("No")),
-        ShouldFail::Yes(ref msg) => {
-            let path = should_fail_path("Yes");
+    let fail_expr = match test.should_panic {
+        ShouldPanic::No => ecx.expr_path(should_panic_path("No")),
+        ShouldPanic::Yes(ref msg) => {
+            let path = should_panic_path("Yes");
             let arg = match *msg {
                 Some(ref msg) => ecx.expr_some(span, ecx.expr_str(span, msg.clone())),
                 None => ecx.expr_none(span),
@@ -638,7 +646,7 @@ fn mk_test_desc_and_fn_rec(cx: &TestCtxt, test: &Test) -> P<ast::Expr> {
         test_path("TestDesc"),
         vec![field("name", name_expr),
              field("ignore", ignore_expr),
-             field("should_fail", fail_expr)]);
+             field("should_panic", fail_expr)]);
 
 
     let mut visible_path = match cx.toplevel_reexport {
index 5be45a2698f40ae34c295c3e2e892994d465fc2a..7ae9e4646e516b32bee9972485f904b3f974d2d6 100644 (file)
@@ -234,7 +234,7 @@ mod tests {
     use ast::Name;
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn i1 () {
         let i : Interner<RcStr> = Interner::new();
         i.get(Name(13));
index 90df23882a1d4bf53c790a36ed40dae5ac899696..5bd6591cfb097c770cf1aa658e8e495ad91f4e97 100644 (file)
@@ -236,13 +236,13 @@ fn test_move_iter() {
     }
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn test_expect_one_zero() {
         let _: isize = SmallVector::zero().expect_one("");
     }
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn test_expect_one_many() {
         SmallVector::many(vec!(1, 2)).expect_one("");
     }
index 1dad5d0909263885ca6d3302a7a151ce9205e93a..d3be5b5683063aa7957124f34e5bf58edb8d3699 100644 (file)
@@ -61,7 +61,6 @@
 #![feature(rustc_private)]
 #![feature(staged_api)]
 #![feature(std_misc)]
-#![feature(unicode)]
 #![feature(path_ext)]
 #![cfg_attr(windows, feature(libc))]
 
index 44aaeec6145e5bc31a25ac7eadaf1540d6879ca8..1590291c88c16336a492d4a00341f77511f90231 100644 (file)
@@ -90,7 +90,7 @@ pub mod test {
              Metric, MetricMap,
              StaticTestFn, StaticTestName, DynTestName, DynTestFn,
              run_test, test_main, test_main_static, filter_tests,
-             parse_opts, StaticBenchFn, ShouldFail};
+             parse_opts, StaticBenchFn, ShouldPanic};
 }
 
 pub mod stats;
@@ -202,7 +202,7 @@ pub struct Bencher {
 }
 
 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
-pub enum ShouldFail {
+pub enum ShouldPanic {
     No,
     Yes(Option<&'static str>)
 }
@@ -213,7 +213,7 @@ pub enum ShouldFail {
 pub struct TestDesc {
     pub name: TestName,
     pub ignore: bool,
-    pub should_fail: ShouldFail,
+    pub should_panic: ShouldPanic,
 }
 
 unsafe impl Send for TestDesc {}
@@ -351,10 +351,10 @@ fn usage(binary: &str) {
                      takes no arguments.
     #[bench]       - Indicates a function is a benchmark to be run. This
                      function takes one argument (test::Bencher).
-    #[should_fail] - This function (also labeled with #[test]) will only pass if
-                     the code causes a failure (an assertion failure or panic!)
+    #[should_panic] - This function (also labeled with #[test]) will only pass if
+                     the code causes a panic (an assertion failure or panic!)
                      A message may be provided, which the failure string must
-                     contain: #[should_fail(expected = "foo")].
+                     contain: #[should_panic(expected = "foo")].
     #[ignore]      - When applied to a function which is already attributed as a
                      test, then the test runner will ignore these tests during
                      normal test runs. Running with --ignored will run these
@@ -717,13 +717,13 @@ fn should_sort_failures_before_printing_them() {
     let test_a = TestDesc {
         name: StaticTestName("a"),
         ignore: false,
-        should_fail: ShouldFail::No
+        should_panic: ShouldPanic::No
     };
 
     let test_b = TestDesc {
         name: StaticTestName("b"),
         ignore: false,
-        should_fail: ShouldFail::No
+        should_panic: ShouldPanic::No
     };
 
     let mut st = ConsoleTestState {
@@ -953,10 +953,10 @@ fn run_test_inner(desc: TestDesc,
 }
 
 fn calc_result(desc: &TestDesc, task_result: Result<(), Box<Any+Send>>) -> TestResult {
-    match (&desc.should_fail, task_result) {
-        (&ShouldFail::No, Ok(())) |
-        (&ShouldFail::Yes(None), Err(_)) => TrOk,
-        (&ShouldFail::Yes(Some(msg)), Err(ref err))
+    match (&desc.should_panic, task_result) {
+        (&ShouldPanic::No, Ok(())) |
+        (&ShouldPanic::Yes(None), Err(_)) => TrOk,
+        (&ShouldPanic::Yes(Some(msg)), Err(ref err))
             if err.downcast_ref::<String>()
                 .map(|e| &**e)
                 .or_else(|| err.downcast_ref::<&'static str>().map(|e| *e))
@@ -1109,7 +1109,14 @@ pub fn auto_bench<F>(&mut self, mut f: F) -> stats::Summary<f64> where F: FnMut(
                 return summ5;
             }
 
-            n *= 2;
+            // If we overflow here just return the results so far. We check a
+            // multiplier of 10 because we're about to multiply by 2 and the
+            // next iteration of the loop will also multiply by 5 (to calculate
+            // the summ5 result)
+            n = match n.checked_mul(10) {
+                Some(_) => n * 2,
+                None => return summ5,
+            };
         }
     }
 }
@@ -1144,7 +1151,7 @@ mod tests {
     use test::{TrFailed, TrIgnored, TrOk, filter_tests, parse_opts,
                TestDesc, TestDescAndFn, TestOpts, run_test,
                MetricMap,
-               StaticTestName, DynTestName, DynTestFn, ShouldFail};
+               StaticTestName, DynTestName, DynTestFn, ShouldPanic};
     use std::thunk::Thunk;
     use std::sync::mpsc::channel;
 
@@ -1155,7 +1162,7 @@ pub fn do_not_run_ignored_tests() {
             desc: TestDesc {
                 name: StaticTestName("whatever"),
                 ignore: true,
-                should_fail: ShouldFail::No,
+                should_panic: ShouldPanic::No,
             },
             testfn: DynTestFn(Thunk::new(move|| f())),
         };
@@ -1172,7 +1179,7 @@ fn f() { }
             desc: TestDesc {
                 name: StaticTestName("whatever"),
                 ignore: true,
-                should_fail: ShouldFail::No,
+                should_panic: ShouldPanic::No,
             },
             testfn: DynTestFn(Thunk::new(move|| f())),
         };
@@ -1183,13 +1190,13 @@ fn f() { }
     }
 
     #[test]
-    fn test_should_fail() {
+    fn test_should_panic() {
         fn f() { panic!(); }
         let desc = TestDescAndFn {
             desc: TestDesc {
                 name: StaticTestName("whatever"),
                 ignore: false,
-                should_fail: ShouldFail::Yes(None)
+                should_panic: ShouldPanic::Yes(None)
             },
             testfn: DynTestFn(Thunk::new(move|| f())),
         };
@@ -1200,13 +1207,13 @@ fn test_should_fail() {
     }
 
     #[test]
-    fn test_should_fail_good_message() {
+    fn test_should_panic_good_message() {
         fn f() { panic!("an error message"); }
         let desc = TestDescAndFn {
             desc: TestDesc {
                 name: StaticTestName("whatever"),
                 ignore: false,
-                should_fail: ShouldFail::Yes(Some("error message"))
+                should_panic: ShouldPanic::Yes(Some("error message"))
             },
             testfn: DynTestFn(Thunk::new(move|| f())),
         };
@@ -1217,13 +1224,13 @@ fn test_should_fail_good_message() {
     }
 
     #[test]
-    fn test_should_fail_bad_message() {
+    fn test_should_panic_bad_message() {
         fn f() { panic!("an error message"); }
         let desc = TestDescAndFn {
             desc: TestDesc {
                 name: StaticTestName("whatever"),
                 ignore: false,
-                should_fail: ShouldFail::Yes(Some("foobar"))
+                should_panic: ShouldPanic::Yes(Some("foobar"))
             },
             testfn: DynTestFn(Thunk::new(move|| f())),
         };
@@ -1234,13 +1241,13 @@ fn test_should_fail_bad_message() {
     }
 
     #[test]
-    fn test_should_fail_but_succeeds() {
+    fn test_should_panic_but_succeeds() {
         fn f() { }
         let desc = TestDescAndFn {
             desc: TestDesc {
                 name: StaticTestName("whatever"),
                 ignore: false,
-                should_fail: ShouldFail::Yes(None)
+                should_panic: ShouldPanic::Yes(None)
             },
             testfn: DynTestFn(Thunk::new(move|| f())),
         };
@@ -1276,7 +1283,7 @@ pub fn filter_for_ignored_option() {
                 desc: TestDesc {
                     name: StaticTestName("1"),
                     ignore: true,
-                    should_fail: ShouldFail::No,
+                    should_panic: ShouldPanic::No,
                 },
                 testfn: DynTestFn(Thunk::new(move|| {})),
             },
@@ -1284,7 +1291,7 @@ pub fn filter_for_ignored_option() {
                 desc: TestDesc {
                     name: StaticTestName("2"),
                     ignore: false,
-                    should_fail: ShouldFail::No,
+                    should_panic: ShouldPanic::No,
                 },
                 testfn: DynTestFn(Thunk::new(move|| {})),
             });
@@ -1320,7 +1327,7 @@ fn testfn() { }
                     desc: TestDesc {
                         name: DynTestName((*name).clone()),
                         ignore: false,
-                        should_fail: ShouldFail::No,
+                        should_panic: ShouldPanic::No,
                     },
                     testfn: DynTestFn(Thunk::new(testfn)),
                 };
diff --git a/src/libunicode/char.rs b/src/libunicode/char.rs
new file mode 100644 (file)
index 0000000..bcc2820
--- /dev/null
@@ -0,0 +1,469 @@
+// Copyright 2012-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 <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.
+
+//! Character manipulation (`char` type, Unicode Scalar Value)
+//!
+//! This module provides the `CharExt` trait, as well as its
+//! implementation for the primitive `char` type, in order to allow
+//! basic character manipulation.
+//!
+//! A `char` actually represents a
+//! *[Unicode Scalar
+//! Value](http://www.unicode.org/glossary/#unicode_scalar_value)*, as it can
+//! contain any Unicode code point except high-surrogate and low-surrogate code
+//! points.
+//!
+//! As such, only values in the ranges \[0x0,0xD7FF\] and \[0xE000,0x10FFFF\]
+//! (inclusive) are allowed. A `char` can always be safely cast to a `u32`;
+//! however the converse is not always true due to the above range limits
+//! and, as such, should be performed via the `from_u32` function.
+
+#![stable(feature = "rust1", since = "1.0.0")]
+#![doc(primitive = "char")]
+
+use core::char::CharExt as C;
+use core::option::Option::{self, Some};
+use core::iter::Iterator;
+use tables::{derived_property, property, general_category, conversions, charwidth};
+
+// stable reexports
+pub use core::char::{MAX, from_u32, from_digit, EscapeUnicode, EscapeDefault};
+
+// unstable reexports
+pub use normalize::{decompose_canonical, decompose_compatible, compose};
+pub use tables::normalization::canonical_combining_class;
+pub use tables::UNICODE_VERSION;
+
+/// Functionality for manipulating `char`.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub trait CharExt {
+    /// Checks if a `char` parses as a numeric digit in the given radix.
+    ///
+    /// Compared to `is_numeric()`, this function only recognizes the characters
+    /// `0-9`, `a-z` and `A-Z`.
+    ///
+    /// # Return value
+    ///
+    /// Returns `true` if `c` is a valid digit under `radix`, and `false`
+    /// otherwise.
+    ///
+    /// # Panics
+    ///
+    /// Panics if given a radix > 36.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let c = '1';
+    ///
+    /// assert!(c.is_digit(10));
+    ///
+    /// assert!('f'.is_digit(16));
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn is_digit(self, radix: u32) -> bool;
+
+    /// Converts a character to the corresponding digit.
+    ///
+    /// # Return value
+    ///
+    /// If `c` is between '0' and '9', the corresponding value between 0 and
+    /// 9. If `c` is 'a' or 'A', 10. If `c` is 'b' or 'B', 11, etc. Returns
+    /// none if the character does not refer to a digit in the given radix.
+    ///
+    /// # Panics
+    ///
+    /// Panics if given a radix outside the range [0..36].
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let c = '1';
+    ///
+    /// assert_eq!(c.to_digit(10), Some(1));
+    ///
+    /// assert_eq!('f'.to_digit(16), Some(15));
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn to_digit(self, radix: u32) -> Option<u32>;
+
+    /// Returns an iterator that yields the hexadecimal Unicode escape of a
+    /// character, as `char`s.
+    ///
+    /// All characters are escaped with Rust syntax of the form `\\u{NNNN}`
+    /// where `NNNN` is the shortest hexadecimal representation of the code
+    /// point.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// for i in '❤'.escape_unicode() {
+    ///     println!("{}", i);
+    /// }
+    /// ```
+    ///
+    /// This prints:
+    ///
+    /// ```text
+    /// \
+    /// u
+    /// {
+    /// 2
+    /// 7
+    /// 6
+    /// 4
+    /// }
+    /// ```
+    ///
+    /// Collecting into a `String`:
+    ///
+    /// ```
+    /// let heart: String = '❤'.escape_unicode().collect();
+    ///
+    /// assert_eq!(heart, r"\u{2764}");
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn escape_unicode(self) -> EscapeUnicode;
+
+    /// Returns an iterator that yields the 'default' ASCII and
+    /// C++11-like literal escape of a character, as `char`s.
+    ///
+    /// The default is chosen with a bias toward producing literals that are
+    /// legal in a variety of languages, including C++11 and similar C-family
+    /// languages. The exact rules are:
+    ///
+    /// * Tab, CR and LF are escaped as '\t', '\r' and '\n' respectively.
+    /// * Single-quote, double-quote and backslash chars are backslash-
+    ///   escaped.
+    /// * Any other chars in the range [0x20,0x7e] are not escaped.
+    /// * Any other chars are given hex Unicode escapes; see `escape_unicode`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// for i in '"'.escape_default() {
+    ///     println!("{}", i);
+    /// }
+    /// ```
+    ///
+    /// This prints:
+    ///
+    /// ```text
+    /// \
+    /// "
+    /// ```
+    ///
+    /// Collecting into a `String`:
+    ///
+    /// ```
+    /// let quote: String = '"'.escape_default().collect();
+    ///
+    /// assert_eq!(quote, "\\\"");
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn escape_default(self) -> EscapeDefault;
+
+    /// Returns the number of bytes this character would need if encoded in
+    /// UTF-8.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let n = 'ß'.len_utf8();
+    ///
+    /// assert_eq!(n, 2);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn len_utf8(self) -> usize;
+
+    /// Returns the number of 16-bit code units this character would need if
+    /// encoded in UTF-16.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let n = 'ß'.len_utf16();
+    ///
+    /// assert_eq!(n, 1);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn len_utf16(self) -> usize;
+
+    /// Encodes this character as UTF-8 into the provided byte buffer, and then
+    /// returns the number of bytes written.
+    ///
+    /// If the buffer is not large enough, nothing will be written into it and a
+    /// `None` will be returned. A buffer of length four is large enough to
+    /// encode any `char`.
+    ///
+    /// # Examples
+    ///
+    /// In both of these examples, 'ß' takes two bytes to encode.
+    ///
+    /// ```
+    /// let mut b = [0; 2];
+    ///
+    /// let result = 'ß'.encode_utf8(&mut b);
+    ///
+    /// assert_eq!(result, Some(2));
+    /// ```
+    ///
+    /// A buffer that's too small:
+    ///
+    /// ```
+    /// let mut b = [0; 1];
+    ///
+    /// let result = 'ß'.encode_utf8(&mut b);
+    ///
+    /// assert_eq!(result, None);
+    /// ```
+    #[unstable(feature = "unicode",
+               reason = "pending decision about Iterator/Writer/Reader")]
+    fn encode_utf8(self, dst: &mut [u8]) -> Option<usize>;
+
+    /// Encodes this character as UTF-16 into the provided `u16` buffer, and
+    /// then returns the number of `u16`s written.
+    ///
+    /// If the buffer is not large enough, nothing will be written into it and a
+    /// `None` will be returned. A buffer of length 2 is large enough to encode
+    /// any `char`.
+    ///
+    /// # Examples
+    ///
+    /// In both of these examples, 'ß' takes one `u16` to encode.
+    ///
+    /// ```
+    /// let mut b = [0; 1];
+    ///
+    /// let result = 'ß'.encode_utf16(&mut b);
+    ///
+    /// assert_eq!(result, Some(1));
+    /// ```
+    ///
+    /// A buffer that's too small:
+    ///
+    /// ```
+    /// let mut b = [0; 0];
+    ///
+    /// let result = 'ß'.encode_utf8(&mut b);
+    ///
+    /// assert_eq!(result, None);
+    /// ```
+    #[unstable(feature = "unicode",
+               reason = "pending decision about Iterator/Writer/Reader")]
+    fn encode_utf16(self, dst: &mut [u16]) -> Option<usize>;
+
+    /// Returns whether the specified character is considered a Unicode
+    /// alphabetic code point.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn is_alphabetic(self) -> bool;
+
+    /// Returns whether the specified character satisfies the 'XID_Start'
+    /// Unicode property.
+    ///
+    /// 'XID_Start' is a Unicode Derived Property specified in
+    /// [UAX #31](http://unicode.org/reports/tr31/#NFKC_Modifications),
+    /// mostly similar to ID_Start but modified for closure under NFKx.
+    #[unstable(feature = "unicode",
+               reason = "mainly needed for compiler internals")]
+    fn is_xid_start(self) -> bool;
+
+    /// Returns whether the specified `char` satisfies the 'XID_Continue'
+    /// Unicode property.
+    ///
+    /// 'XID_Continue' is a Unicode Derived Property specified in
+    /// [UAX #31](http://unicode.org/reports/tr31/#NFKC_Modifications),
+    /// mostly similar to 'ID_Continue' but modified for closure under NFKx.
+    #[unstable(feature = "unicode",
+               reason = "mainly needed for compiler internals")]
+    fn is_xid_continue(self) -> bool;
+
+    /// Indicates whether a character is in lowercase.
+    ///
+    /// This is defined according to the terms of the Unicode Derived Core
+    /// Property `Lowercase`.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn is_lowercase(self) -> bool;
+
+    /// Indicates whether a character is in uppercase.
+    ///
+    /// This is defined according to the terms of the Unicode Derived Core
+    /// Property `Uppercase`.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn is_uppercase(self) -> bool;
+
+    /// Indicates whether a character is whitespace.
+    ///
+    /// Whitespace is defined in terms of the Unicode Property `White_Space`.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn is_whitespace(self) -> bool;
+
+    /// Indicates whether a character is alphanumeric.
+    ///
+    /// Alphanumericness is defined in terms of the Unicode General Categories
+    /// 'Nd', 'Nl', 'No' and the Derived Core Property 'Alphabetic'.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn is_alphanumeric(self) -> bool;
+
+    /// Indicates whether a character is a control code point.
+    ///
+    /// Control code points are defined in terms of the Unicode General
+    /// Category `Cc`.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn is_control(self) -> bool;
+
+    /// Indicates whether the character is numeric (Nd, Nl, or No).
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn is_numeric(self) -> bool;
+
+    /// Converts a character to its lowercase equivalent.
+    ///
+    /// The case-folding performed is the common or simple mapping. See
+    /// `to_uppercase()` for references and more information.
+    ///
+    /// # Return value
+    ///
+    /// Returns an iterator which yields the characters corresponding to the
+    /// lowercase equivalent of the character. If no conversion is possible then
+    /// the input character is returned.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn to_lowercase(self) -> ToLowercase;
+
+    /// Converts a character to its uppercase equivalent.
+    ///
+    /// The case-folding performed is the common or simple mapping: it maps
+    /// one Unicode codepoint to its uppercase equivalent according to the
+    /// Unicode database [1]. The additional [`SpecialCasing.txt`] is not yet
+    /// considered here, but the iterator returned will soon support this form
+    /// of case folding.
+    ///
+    /// A full reference can be found here [2].
+    ///
+    /// # Return value
+    ///
+    /// Returns an iterator which yields the characters corresponding to the
+    /// uppercase equivalent of the character. If no conversion is possible then
+    /// the input character is returned.
+    ///
+    /// [1]: ftp://ftp.unicode.org/Public/UNIDATA/UnicodeData.txt
+    ///
+    /// [`SpecialCasing`.txt`]: ftp://ftp.unicode.org/Public/UNIDATA/SpecialCasing.txt
+    ///
+    /// [2]: http://www.unicode.org/versions/Unicode4.0.0/ch03.pdf#G33992
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn to_uppercase(self) -> ToUppercase;
+
+    /// Returns this character's displayed width in columns, or `None` if it is a
+    /// control character other than `'\x00'`.
+    ///
+    /// `is_cjk` determines behavior for characters in the Ambiguous category:
+    /// if `is_cjk` is `true`, these are 2 columns wide; otherwise, they are 1.
+    /// In CJK contexts, `is_cjk` should be `true`, else it should be `false`.
+    /// [Unicode Standard Annex #11](http://www.unicode.org/reports/tr11/)
+    /// recommends that these characters be treated as 1 column (i.e.,
+    /// `is_cjk` = `false`) if the context cannot be reliably determined.
+    #[unstable(feature = "unicode",
+               reason = "needs expert opinion. is_cjk flag stands out as ugly")]
+    fn width(self, is_cjk: bool) -> Option<usize>;
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl CharExt for char {
+    fn is_digit(self, radix: u32) -> bool { C::is_digit(self, radix) }
+    fn to_digit(self, radix: u32) -> Option<u32> { C::to_digit(self, radix) }
+    fn escape_unicode(self) -> EscapeUnicode { C::escape_unicode(self) }
+    fn escape_default(self) -> EscapeDefault { C::escape_default(self) }
+    fn len_utf8(self) -> usize { C::len_utf8(self) }
+    fn len_utf16(self) -> usize { C::len_utf16(self) }
+    fn encode_utf8(self, dst: &mut [u8]) -> Option<usize> { C::encode_utf8(self, dst) }
+    fn encode_utf16(self, dst: &mut [u16]) -> Option<usize> { C::encode_utf16(self, dst) }
+
+    fn is_alphabetic(self) -> bool {
+        match self {
+            'a' ... 'z' | 'A' ... 'Z' => true,
+            c if c > '\x7f' => derived_property::Alphabetic(c),
+            _ => false
+        }
+    }
+
+    fn is_xid_start(self) -> bool { derived_property::XID_Start(self) }
+
+    fn is_xid_continue(self) -> bool { derived_property::XID_Continue(self) }
+
+    fn is_lowercase(self) -> bool {
+        match self {
+            'a' ... 'z' => true,
+            c if c > '\x7f' => derived_property::Lowercase(c),
+            _ => false
+        }
+    }
+
+    fn is_uppercase(self) -> bool {
+        match self {
+            'A' ... 'Z' => true,
+            c if c > '\x7f' => derived_property::Uppercase(c),
+            _ => false
+        }
+    }
+
+    fn is_whitespace(self) -> bool {
+        match self {
+            ' ' | '\x09' ... '\x0d' => true,
+            c if c > '\x7f' => property::White_Space(c),
+            _ => false
+        }
+    }
+
+    fn is_alphanumeric(self) -> bool {
+        self.is_alphabetic() || self.is_numeric()
+    }
+
+    fn is_control(self) -> bool { general_category::Cc(self) }
+
+    fn is_numeric(self) -> bool {
+        match self {
+            '0' ... '9' => true,
+            c if c > '\x7f' => general_category::N(c),
+            _ => false
+        }
+    }
+
+    fn to_lowercase(self) -> ToLowercase {
+        ToLowercase(Some(conversions::to_lower(self)))
+    }
+
+    fn to_uppercase(self) -> ToUppercase {
+        ToUppercase(Some(conversions::to_upper(self)))
+    }
+
+    fn width(self, is_cjk: bool) -> Option<usize> { charwidth::width(self, is_cjk) }
+}
+
+/// An iterator over the lowercase mapping of a given character, returned from
+/// the `lowercase` method on characters.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct ToLowercase(Option<char>);
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl Iterator for ToLowercase {
+    type Item = char;
+    fn next(&mut self) -> Option<char> { self.0.take() }
+}
+
+/// An iterator over the uppercase mapping of a given character, returned from
+/// the `uppercase` method on characters.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct ToUppercase(Option<char>);
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl Iterator for ToUppercase {
+    type Item = char;
+    fn next(&mut self) -> Option<char> { self.0.take() }
+}
index 2095b6921c840a437dd428727942e7d01c0dd507..fadf91f33bce83a3a6d667b3266ddb08ddfb27c0 100644 (file)
 
 mod normalize;
 mod tables;
-mod u_char;
 mod u_str;
-
-// re-export char so that std et al see it correctly
-/// Character manipulation (`char` type, Unicode Scalar Value)
-///
-/// This module provides the `CharExt` trait, as well as its
-/// implementation for the primitive `char` type, in order to allow
-/// basic character manipulation.
-///
-/// A `char` actually represents a
-/// *[Unicode Scalar Value](http://www.unicode.org/glossary/#unicode_scalar_value)*,
-/// as it can contain any Unicode code point except high-surrogate and
-/// low-surrogate code points.
-///
-/// As such, only values in the ranges \[0x0,0xD7FF\] and \[0xE000,0x10FFFF\]
-/// (inclusive) are allowed. A `char` can always be safely cast to a `u32`;
-/// however the converse is not always true due to the above range limits
-/// and, as such, should be performed via the `from_u32` function.
-#[stable(feature = "rust1", since = "1.0.0")]
-#[doc(primitive = "char")]
-pub mod char {
-    pub use core::char::{MAX, from_u32, from_digit};
-
-    pub use normalize::{decompose_canonical, decompose_compatible, compose};
-
-    pub use tables::normalization::canonical_combining_class;
-    pub use tables::UNICODE_VERSION;
-
-    pub use u_char::CharExt;
-}
+pub mod char;
 
 pub mod str {
     pub use u_str::{UnicodeStr, Words, Graphemes, GraphemeIndices};
diff --git a/src/libunicode/u_char.rs b/src/libunicode/u_char.rs
deleted file mode 100644 (file)
index c0f45ca..0000000
+++ /dev/null
@@ -1,317 +0,0 @@
-// Copyright 2012-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 <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.
-
-//! Unicode-intensive `char` methods along with the `core` methods.
-//!
-//! These methods implement functionality for `char` that requires knowledge of
-//! Unicode definitions, including normalization, categorization, and display information.
-
-use core::char;
-use core::char::CharExt as C;
-use core::option::Option;
-use tables::{derived_property, property, general_category, conversions, charwidth};
-
-/// Functionality for manipulating `char`.
-#[stable(feature = "rust1", since = "1.0.0")]
-pub trait CharExt {
-    /// Checks if a `char` parses as a numeric digit in the given radix.
-    ///
-    /// Compared to `is_numeric()`, this function only recognizes the characters
-    /// `0-9`, `a-z` and `A-Z`.
-    ///
-    /// # Return value
-    ///
-    /// Returns `true` if `c` is a valid digit under `radix`, and `false`
-    /// otherwise.
-    ///
-    /// # Panics
-    ///
-    /// Panics if given a radix > 36.
-    #[unstable(feature = "unicode",
-               reason = "pending integer conventions")]
-    fn is_digit(self, radix: u32) -> bool;
-
-    /// Converts a character to the corresponding digit.
-    ///
-    /// # Return value
-    ///
-    /// If `c` is between '0' and '9', the corresponding value between 0 and
-    /// 9. If `c` is 'a' or 'A', 10. If `c` is 'b' or 'B', 11, etc. Returns
-    /// none if the character does not refer to a digit in the given radix.
-    ///
-    /// # Panics
-    ///
-    /// Panics if given a radix outside the range [0..36].
-    #[unstable(feature = "unicode",
-               reason = "pending integer conventions")]
-    fn to_digit(self, radix: u32) -> Option<u32>;
-
-    /// Returns an iterator that yields the hexadecimal Unicode escape
-    /// of a character, as `char`s.
-    ///
-    /// All characters are escaped with Rust syntax of the form `\\u{NNNN}`
-    /// where `NNNN` is the shortest hexadecimal representation of the code
-    /// point.
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn escape_unicode(self) -> char::EscapeUnicode;
-
-    /// Returns an iterator that yields the 'default' ASCII and
-    /// C++11-like literal escape of a character, as `char`s.
-    ///
-    /// The default is chosen with a bias toward producing literals that are
-    /// legal in a variety of languages, including C++11 and similar C-family
-    /// languages. The exact rules are:
-    ///
-    /// * Tab, CR and LF are escaped as '\t', '\r' and '\n' respectively.
-    /// * Single-quote, double-quote and backslash chars are backslash-
-    ///   escaped.
-    /// * Any other chars in the range [0x20,0x7e] are not escaped.
-    /// * Any other chars are given hex Unicode escapes; see `escape_unicode`.
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn escape_default(self) -> char::EscapeDefault;
-
-    /// Returns the amount of bytes this character would need if encoded in
-    /// UTF-8.
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn len_utf8(self) -> usize;
-
-    /// Returns the amount of bytes this character would need if encoded in
-    /// UTF-16.
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn len_utf16(self) -> usize;
-
-    /// Encodes this character as UTF-8 into the provided byte buffer,
-    /// and then returns the number of bytes written.
-    ///
-    /// If the buffer is not large enough, nothing will be written into it
-    /// and a `None` will be returned.
-    #[unstable(feature = "unicode",
-               reason = "pending decision about Iterator/Writer/Reader")]
-    fn encode_utf8(self, dst: &mut [u8]) -> Option<usize>;
-
-    /// Encodes this character as UTF-16 into the provided `u16` buffer,
-    /// and then returns the number of `u16`s written.
-    ///
-    /// If the buffer is not large enough, nothing will be written into it
-    /// and a `None` will be returned.
-    #[unstable(feature = "unicode",
-               reason = "pending decision about Iterator/Writer/Reader")]
-    fn encode_utf16(self, dst: &mut [u16]) -> Option<usize>;
-
-    /// Returns whether the specified character is considered a Unicode
-    /// alphabetic code point.
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn is_alphabetic(self) -> bool;
-
-    /// Returns whether the specified character satisfies the 'XID_Start'
-    /// Unicode property.
-    ///
-    /// 'XID_Start' is a Unicode Derived Property specified in
-    /// [UAX #31](http://unicode.org/reports/tr31/#NFKC_Modifications),
-    /// mostly similar to ID_Start but modified for closure under NFKx.
-    #[unstable(feature = "unicode",
-               reason = "mainly needed for compiler internals")]
-    fn is_xid_start(self) -> bool;
-
-    /// Returns whether the specified `char` satisfies the 'XID_Continue'
-    /// Unicode property.
-    ///
-    /// 'XID_Continue' is a Unicode Derived Property specified in
-    /// [UAX #31](http://unicode.org/reports/tr31/#NFKC_Modifications),
-    /// mostly similar to 'ID_Continue' but modified for closure under NFKx.
-    #[unstable(feature = "unicode",
-               reason = "mainly needed for compiler internals")]
-    fn is_xid_continue(self) -> bool;
-
-    /// Indicates whether a character is in lowercase.
-    ///
-    /// This is defined according to the terms of the Unicode Derived Core
-    /// Property `Lowercase`.
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn is_lowercase(self) -> bool;
-
-    /// Indicates whether a character is in uppercase.
-    ///
-    /// This is defined according to the terms of the Unicode Derived Core
-    /// Property `Uppercase`.
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn is_uppercase(self) -> bool;
-
-    /// Indicates whether a character is whitespace.
-    ///
-    /// Whitespace is defined in terms of the Unicode Property `White_Space`.
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn is_whitespace(self) -> bool;
-
-    /// Indicates whether a character is alphanumeric.
-    ///
-    /// Alphanumericness is defined in terms of the Unicode General Categories
-    /// 'Nd', 'Nl', 'No' and the Derived Core Property 'Alphabetic'.
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn is_alphanumeric(self) -> bool;
-
-    /// Indicates whether a character is a control code point.
-    ///
-    /// Control code points are defined in terms of the Unicode General
-    /// Category `Cc`.
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn is_control(self) -> bool;
-
-    /// Indicates whether the character is numeric (Nd, Nl, or No).
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn is_numeric(self) -> bool;
-
-    /// Converts a character to its lowercase equivalent.
-    ///
-    /// The case-folding performed is the common or simple mapping. See
-    /// `to_uppercase()` for references and more information.
-    ///
-    /// # Return value
-    ///
-    /// Returns the lowercase equivalent of the character, or the character
-    /// itself if no conversion is possible.
-    #[unstable(feature = "unicode",
-               reason = "pending case transformation decisions")]
-    fn to_lowercase(self) -> char;
-
-    /// Converts a character to its uppercase equivalent.
-    ///
-    /// The case-folding performed is the common or simple mapping: it maps
-    /// one Unicode codepoint (one character in Rust) to its uppercase
-    /// equivalent according to the Unicode database [1]. The additional
-    /// [`SpecialCasing.txt`] is not considered here, as it expands to multiple
-    /// codepoints in some cases.
-    ///
-    /// A full reference can be found here [2].
-    ///
-    /// # Return value
-    ///
-    /// Returns the uppercase equivalent of the character, or the character
-    /// itself if no conversion was made.
-    ///
-    /// [1]: ftp://ftp.unicode.org/Public/UNIDATA/UnicodeData.txt
-    ///
-    /// [`SpecialCasing`.txt`]: ftp://ftp.unicode.org/Public/UNIDATA/SpecialCasing.txt
-    ///
-    /// [2]: http://www.unicode.org/versions/Unicode4.0.0/ch03.pdf#G33992
-    #[unstable(feature = "unicode",
-               reason = "pending case transformation decisions")]
-    fn to_uppercase(self) -> char;
-
-    /// Returns this character's displayed width in columns, or `None` if it is a
-    /// control character other than `'\x00'`.
-    ///
-    /// `is_cjk` determines behavior for characters in the Ambiguous category:
-    /// if `is_cjk` is `true`, these are 2 columns wide; otherwise, they are 1.
-    /// In CJK contexts, `is_cjk` should be `true`, else it should be `false`.
-    /// [Unicode Standard Annex #11](http://www.unicode.org/reports/tr11/)
-    /// recommends that these characters be treated as 1 column (i.e.,
-    /// `is_cjk` = `false`) if the context cannot be reliably determined.
-    #[unstable(feature = "unicode",
-               reason = "needs expert opinion. is_cjk flag stands out as ugly")]
-    fn width(self, is_cjk: bool) -> Option<usize>;
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl CharExt for char {
-    #[unstable(feature = "unicode",
-               reason = "pending integer conventions")]
-    fn is_digit(self, radix: u32) -> bool { C::is_digit(self, radix) }
-    #[unstable(feature = "unicode",
-               reason = "pending integer conventions")]
-    fn to_digit(self, radix: u32) -> Option<u32> { C::to_digit(self, radix) }
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn escape_unicode(self) -> char::EscapeUnicode { C::escape_unicode(self) }
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn escape_default(self) -> char::EscapeDefault { C::escape_default(self) }
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn len_utf8(self) -> usize { C::len_utf8(self) }
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn len_utf16(self) -> usize { C::len_utf16(self) }
-    #[unstable(feature = "unicode",
-               reason = "pending decision about Iterator/Writer/Reader")]
-    fn encode_utf8(self, dst: &mut [u8]) -> Option<usize> { C::encode_utf8(self, dst) }
-    #[unstable(feature = "unicode",
-               reason = "pending decision about Iterator/Writer/Reader")]
-    fn encode_utf16(self, dst: &mut [u16]) -> Option<usize> { C::encode_utf16(self, dst) }
-
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn is_alphabetic(self) -> bool {
-        match self {
-            'a' ... 'z' | 'A' ... 'Z' => true,
-            c if c > '\x7f' => derived_property::Alphabetic(c),
-            _ => false
-        }
-    }
-
-    #[unstable(feature = "unicode",
-               reason = "mainly needed for compiler internals")]
-    fn is_xid_start(self) -> bool { derived_property::XID_Start(self) }
-
-    #[unstable(feature = "unicode",
-               reason = "mainly needed for compiler internals")]
-    fn is_xid_continue(self) -> bool { derived_property::XID_Continue(self) }
-
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn is_lowercase(self) -> bool {
-        match self {
-            'a' ... 'z' => true,
-            c if c > '\x7f' => derived_property::Lowercase(c),
-            _ => false
-        }
-    }
-
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn is_uppercase(self) -> bool {
-        match self {
-            'A' ... 'Z' => true,
-            c if c > '\x7f' => derived_property::Uppercase(c),
-            _ => false
-        }
-    }
-
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn is_whitespace(self) -> bool {
-        match self {
-            ' ' | '\x09' ... '\x0d' => true,
-            c if c > '\x7f' => property::White_Space(c),
-            _ => false
-        }
-    }
-
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn is_alphanumeric(self) -> bool {
-        self.is_alphabetic() || self.is_numeric()
-    }
-
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn is_control(self) -> bool { general_category::Cc(self) }
-
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn is_numeric(self) -> bool {
-        match self {
-            '0' ... '9' => true,
-            c if c > '\x7f' => general_category::N(c),
-            _ => false
-        }
-    }
-
-    #[unstable(feature = "unicode",
-               reason = "pending case transformation decisions")]
-    fn to_lowercase(self) -> char { conversions::to_lower(self) }
-
-    #[unstable(feature = "unicode",
-               reason = "pending case transformation decisions")]
-    fn to_uppercase(self) -> char { conversions::to_upper(self) }
-
-    #[unstable(feature = "unicode",
-               reason = "needs expert opinion. is_cjk flag stands out as ugly")]
-    fn width(self, is_cjk: bool) -> Option<usize> { charwidth::width(self, is_cjk) }
-}
index 57439addeaa1a85b1acb596fd36ca3d6cad76045..9b3f4b0521da3fadfe986078e80523368514ff46 100644 (file)
@@ -26,7 +26,7 @@
 use core::slice;
 use core::str::Split;
 
-use u_char::CharExt as UCharExt; // conflicts with core::prelude::CharExt
+use char::CharExt as UCharExt; // conflicts with core::prelude::CharExt
 use tables::grapheme::GraphemeCat;
 
 /// An iterator over the words of a string, separated by a sequence of whitespace
index 5e85e3dff6afacfd51d8b3b5f055d718be3f21b9..35f46ca6d3299a68f4e5b9cc33c8160864a01e20 100644 (file)
@@ -1,3 +1,12 @@
+S 2015-03-07 270a677
+  freebsd-x86_64 3c147d8e4cfdcb02c2569f5aca689a1d8920d17b
+  linux-i386 50a47ef247610fb089d2c4f24e4b641eb0ba4afb
+  linux-x86_64 ccb20709b3c984f960ddde996451be8ce2268d7c
+  macos-i386 ad263bdeadcf9bf1889426e0c1391a7cf277364e
+  macos-x86_64 01c8275828042264206b7acd8e86dc719a2f27aa
+  winnt-i386 cb73ac7a9bf408e8b5cdb92d595082a537a90794
+  winnt-x86_64 b9b47e80101f726ae4f5919373ea20b92d827f3c
+
 S 2015-02-25 880fb89
   bitrig-x86_64 8cdc4ca0a80103100f46cbf8caa9fe497df048c5
   freebsd-x86_64 f4cbe4227739de986444211f8ee8d74745ab8f7f
diff --git a/src/test/auxiliary/typeck-default-trait-impl-cross-crate-coherence-lib.rs b/src/test/auxiliary/typeck-default-trait-impl-cross-crate-coherence-lib.rs
new file mode 100644 (file)
index 0000000..506e7a0
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright 2015 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.
+
+#![feature(optin_builtin_traits)]
+#![crate_type = "rlib"]
+
+use std::marker::MarkerTrait;
+
+pub trait DefaultedTrait : MarkerTrait { }
+impl DefaultedTrait for .. { }
+
+pub struct Something<T> { t: T }
diff --git a/src/test/compile-fail-fulldeps/gated-quote.rs b/src/test/compile-fail-fulldeps/gated-quote.rs
new file mode 100644 (file)
index 0000000..6a5cd88
--- /dev/null
@@ -0,0 +1,50 @@
+// Copyright 2015 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.
+
+// Test that `quote`-related macro are gated by `quote` feature gate.
+
+// (To sanity-check the code, uncomment this.)
+// #![feature(quote)]
+
+// FIXME the error message that is current emitted seems pretty bad.
+
+#![feature(rustc_private)]
+#![allow(dead_code, unused_imports, unused_variables)]
+
+#[macro_use]
+extern crate syntax;
+
+use syntax::ast;
+use syntax::codemap::Span;
+use syntax::parse;
+
+struct ParseSess;
+
+impl ParseSess {
+    fn cfg(&self) -> ast::CrateConfig { loop { } }
+    fn parse_sess<'a>(&'a self) -> &'a parse::ParseSess { loop { } }
+    fn call_site(&self) -> Span { loop { } }
+    fn ident_of(&self, st: &str) -> ast::Ident { loop { } }
+    fn name_of(&self, st: &str) -> ast::Name { loop { } }
+}
+
+pub fn main() {
+    let ecx = &ParseSess;
+    let x = quote_tokens!(ecx, 3);   //~ ERROR macro undefined: 'quote_tokens!'
+    let x = quote_expr!(ecx, 3);     //~ ERROR macro undefined: 'quote_expr!'
+    let x = quote_ty!(ecx, 3);       //~ ERROR macro undefined: 'quote_ty!'
+    let x = quote_method!(ecx, 3);   //~ ERROR macro undefined: 'quote_method!'
+    let x = quote_item!(ecx, 3);     //~ ERROR macro undefined: 'quote_item!'
+    let x = quote_pat!(ecx, 3);      //~ ERROR macro undefined: 'quote_pat!'
+    let x = quote_arm!(ecx, 3);      //~ ERROR macro undefined: 'quote_arm!'
+    let x = quote_stmt!(ecx, 3);     //~ ERROR macro undefined: 'quote_stmt!'
+    let x = quote_matcher!(ecx, 3);  //~ ERROR macro undefined: 'quote_matcher!'
+    let x = quote_attr!(ecx, 3);     //~ ERROR macro undefined: 'quote_attr!'
+}
diff --git a/src/test/compile-fail/coherence-impls-builtin.rs b/src/test/compile-fail/coherence-impls-builtin.rs
deleted file mode 100644 (file)
index 3e132dc..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2015 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.
-
-#![feature(optin_builtin_traits)]
-
-use std::marker::Send;
-
-enum TestE {
-  A
-}
-
-struct MyType;
-
-struct NotSync;
-impl !Sync for NotSync {}
-
-unsafe impl Send for TestE {}
-unsafe impl Send for MyType {}
-unsafe impl Send for (MyType, MyType) {}
-//~^ ERROR builtin traits can only be implemented on structs or enums
-
-unsafe impl Send for &'static NotSync {}
-//~^ ERROR builtin traits can only be implemented on structs or enums
-
-unsafe impl Send for [MyType] {}
-//~^ ERROR builtin traits can only be implemented on structs or enums
-
-unsafe impl Send for &'static [NotSync] {}
-//~^ ERROR builtin traits can only be implemented on structs or enums
-//~^^ ERROR conflicting implementations for trait `core::marker::Send`
-
-fn is_send<T: Send>() {}
-
-fn main() {
-    is_send::<(MyType, TestE)>();
-}
diff --git a/src/test/compile-fail/coherence-impls-copy.rs b/src/test/compile-fail/coherence-impls-copy.rs
new file mode 100644 (file)
index 0000000..3034be1
--- /dev/null
@@ -0,0 +1,39 @@
+// Copyright 2015 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.
+
+#![feature(optin_builtin_traits)]
+
+use std::marker::Copy;
+
+enum TestE {
+  A
+}
+
+struct MyType;
+
+struct NotSync;
+impl !Sync for NotSync {}
+
+impl Copy for TestE {}
+impl Copy for MyType {}
+impl Copy for (MyType, MyType) {}
+//~^ ERROR E0206
+
+impl Copy for &'static NotSync {}
+//~^ ERROR E0206
+
+impl Copy for [MyType] {}
+//~^ ERROR E0206
+
+impl Copy for &'static [NotSync] {}
+//~^ ERROR E0206
+
+fn main() {
+}
diff --git a/src/test/compile-fail/coherence-impls-send.rs b/src/test/compile-fail/coherence-impls-send.rs
new file mode 100644 (file)
index 0000000..b05c1ff
--- /dev/null
@@ -0,0 +1,40 @@
+// Copyright 2015 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.
+
+#![feature(optin_builtin_traits)]
+
+use std::marker::Copy;
+
+enum TestE {
+  A
+}
+
+struct MyType;
+
+struct NotSync;
+impl !Sync for NotSync {}
+
+unsafe impl Send for TestE {}
+unsafe impl Send for MyType {}
+unsafe impl Send for (MyType, MyType) {}
+//~^ ERROR E0321
+
+unsafe impl Send for &'static NotSync {}
+//~^ ERROR E0321
+
+unsafe impl Send for [MyType] {}
+//~^ ERROR E0321
+
+unsafe impl Send for &'static [NotSync] {}
+//~^ ERROR E0321
+//~| ERROR conflicting implementations
+
+fn main() {
+}
diff --git a/src/test/compile-fail/coherence-impls-sized.rs b/src/test/compile-fail/coherence-impls-sized.rs
new file mode 100644 (file)
index 0000000..a9a3eba
--- /dev/null
@@ -0,0 +1,33 @@
+// Copyright 2015 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.
+
+#![feature(optin_builtin_traits)]
+
+use std::marker::Copy;
+
+enum TestE {
+  A
+}
+
+struct MyType;
+
+struct NotSync;
+impl !Sync for NotSync {}
+
+impl Sized for TestE {} //~ ERROR E0322
+impl Sized for MyType {} //~ ERROR E0322
+impl Sized for (MyType, MyType) {} //~ ERROR E0322
+impl Sized for &'static NotSync {} //~ ERROR E0322
+impl Sized for [MyType] {} //~ ERROR E0322
+//~^ ERROR E0277
+impl Sized for &'static [NotSync] {} //~ ERROR E0322
+
+fn main() {
+}
index d7cd68e73c3498acc75b0557ceca6224e450e455..97dffec2dd9bd4758db4a11f9f89107d00581b72 100644 (file)
 
 struct TheType;
 
-impl TheTrait<usize> for isize { } //~ ERROR E0117
+impl TheTrait<usize> for isize { }
+//~^ ERROR E0117
 
 impl TheTrait<TheType> for isize { }
 
 impl TheTrait<isize> for TheType { }
 
-impl !Send for Vec<isize> { } //~ ERROR E0117
-//~^ ERROR conflicting
+impl !Send for Vec<isize> { }
+//~^ ERROR E0117
+//~| ERROR E0119
 
 fn main() { }
diff --git a/src/test/compile-fail/gated-link-args.rs b/src/test/compile-fail/gated-link-args.rs
new file mode 100644 (file)
index 0000000..c8845ce
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright 2015 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.
+
+// Test that `#[link_args]` attribute is gated by `link_args`
+// feature gate.
+
+#[link_args = "aFdEfSeVEEE"]
+extern {}
+//~^ ERROR the `link_args` attribute is not portable across platforms
+//~| HELP add #![feature(link_args)] to the crate attributes to enable
+
+fn main() { }
diff --git a/src/test/compile-fail/gated-link-llvm-intrinsics.rs b/src/test/compile-fail/gated-link-llvm-intrinsics.rs
new file mode 100644 (file)
index 0000000..716ea9f
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright 2015 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.
+
+extern {
+    #[link_name = "llvm.sqrt.f32"]
+    fn sqrt(x: f32) -> f32;
+    //~^ ERROR linking to LLVM intrinsics is experimental
+    //~| HELP add #![feature(link_llvm_intrinsics)] to the crate attributes
+}
+
+fn main(){
+}
index f6e11ffd9e5239c92f732a01c6cbd0969afd6726..d716c53e1d18ce68c4db2f1a79f42b7c9802cae4 100644 (file)
@@ -8,8 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// Test that `#[plugin_registrar]` attribute is gated by `plugin_registrar`
+// feature gate.
+
 // the registration function isn't typechecked yet
 #[plugin_registrar]
-pub fn registrar() {} //~ ERROR compiler plugins are experimental
-
+pub fn registrar() {}
+//~^ ERROR compiler plugins are experimental
+//~| HELP add #![feature(plugin_registrar)] to the crate attributes to enable
 fn main() {}
diff --git a/src/test/compile-fail/gated-thread-local.rs b/src/test/compile-fail/gated-thread-local.rs
new file mode 100644 (file)
index 0000000..f355c65
--- /dev/null
@@ -0,0 +1,25 @@
+// Copyright 2015 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.
+
+// Test that `#[thread_local]` attribute is gated by `thread_local`
+// feature gate.
+//
+// (Note that the `thread_local!` macro is explicitly *not* gated; it
+// is given permission to expand into this unstable attribute even
+// when the surrounding context does not have permission to use it.)
+
+#[thread_local] //~ ERROR `#[thread_local]` is an experimental feature
+static FOO: i32 = 3;
+
+pub fn main() {
+    FOO.with(|x| {
+        println!("x: {}", x);
+    });
+}
diff --git a/src/test/compile-fail/gated-unsafe-destructor.rs b/src/test/compile-fail/gated-unsafe-destructor.rs
new file mode 100644 (file)
index 0000000..6024fef
--- /dev/null
@@ -0,0 +1,23 @@
+// Copyright 2015 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.
+
+// Test that `#[unsafe_destructor]` attribute is gated by `unsafe_destructor`
+// feature gate.
+
+struct D<'a>(&'a u32);
+
+#[unsafe_destructor]
+impl<'a> Drop for D<'a> {
+    //~^ ERROR `#[unsafe_destructor]` allows too many unsafe patterns
+    fn drop(&mut self) { }
+}
+//~^ HELP: add #![feature(unsafe_destructor)] to the crate attributes to enable
+
+pub fn main() { }
diff --git a/src/test/compile-fail/typeck-default-trait-impl-cross-crate-coherence.rs b/src/test/compile-fail/typeck-default-trait-impl-cross-crate-coherence.rs
new file mode 100644 (file)
index 0000000..3a29bb9
--- /dev/null
@@ -0,0 +1,34 @@
+// Copyright 2015 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.
+
+// aux-build:typeck-default-trait-impl-cross-crate-coherence-lib.rs
+
+// Test that we do not consider associated types to be sendable without
+// some applicable trait bound (and we don't ICE).
+
+#![feature(optin_builtin_traits)]
+
+extern crate "typeck-default-trait-impl-cross-crate-coherence-lib" as lib;
+
+use lib::DefaultedTrait;
+
+struct A;
+impl DefaultedTrait for (A,) { } //~ ERROR E0321
+
+struct B;
+impl !DefaultedTrait for (B,) { } //~ ERROR E0321
+
+struct C;
+struct D<T>(T);
+impl DefaultedTrait for Box<C> { } //~ ERROR E0321
+impl DefaultedTrait for lib::Something<C> { } //~ ERROR E0321
+impl DefaultedTrait for D<C> { } // OK
+
+fn main() { }
index 10ba8c74164830efeed897659da41a04faa5e99b..a345bd1b65c0ea1f1f7c83ac410dd066e7dfb78c 100644 (file)
@@ -13,6 +13,6 @@
 #![feature(optin_builtin_traits)]
 
 impl Copy for .. {}
-//~^ ERROR cannot create default implementations for traits outside the crate they're defined in; define a new trait instead.
+//~^ ERROR E0318
 
 fn main() {}
index 5a5bb53a33a209f12f25f928a01fb662e034e7ff..e18c5d9631a702358a6964b918fe8b2db3bb3267 100644 (file)
@@ -14,7 +14,7 @@
 // ignore-pretty: does not work well with `--test`
 
 #[test]
-#[should_fail(expected = "foobar")]
+#[should_panic(expected = "foobar")]
 fn test_foo() {
     panic!("blah")
 }
diff --git a/src/test/run-make/bare-outfile/Makefile b/src/test/run-make/bare-outfile/Makefile
new file mode 100644 (file)
index 0000000..97d09c8
--- /dev/null
@@ -0,0 +1,4 @@
+-include ../tools.mk
+
+all:
+       $(rustc) -o foo foo.rs
diff --git a/src/test/run-make/bare-outfile/foo.rs b/src/test/run-make/bare-outfile/foo.rs
new file mode 100644 (file)
index 0000000..63e7479
--- /dev/null
@@ -0,0 +1,12 @@
+// Copyright 2015 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.
+
+fn main() {
+}
index ef6c799336bd4e5171878fe7ccf1b9339c32fded..a6cb9fe0324d7d7c5cde512aa9ce39506a04a46e 100644 (file)
@@ -80,7 +80,7 @@ fn main() {
                          .arg(format!("{} {}",
                                       rustc,
                                       main_file.as_str()
-                                               .unwrap()).as_slice())
+                                               .unwrap()))
                          .output().unwrap();
 
     let err = String::from_utf8_lossy(result.error.as_slice());
index ce2f488b90c7b6adf7bde9917ce62b05cdc1b26a..a565460c42e28333fad057b931ed6d27ecc14fc0 100644 (file)
@@ -7,9 +7,7 @@
 // <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.
-//
-// ignore-lexer-test FIXME #15877
 
 trait U { fn f(self); }
-impl U for int { fn f(self) {} }
+impl U for isize { fn f(self) {} }
 pub fn main() { 4.f(); }
index 6cebd17496a52b07d9aa4d0e389842f5af2caf64..a64477242c08fb43eb7b2fadbc81c5e866c95b50 100644 (file)
@@ -12,11 +12,12 @@ struct S { f0: String, f1: int }
 
 pub fn main() {
     let s = "Hello, world!".to_string();
-    let _s = S {
+    let s = S {
         f0: s.to_string(),
         ..S {
             f0: s,
             f1: 23
         }
     };
+    assert_eq!(s.f0, "Hello, world!");
 }
index 786f080bb9ee3c6350fe6244fdbcfdacdd9b1edf..359ecdab630eccc56fefe0bd811ac916dbc81bd4 100644 (file)
@@ -15,8 +15,9 @@ struct S {
 
 pub fn main() {
     let s = "Hello, world!".to_string();
-    let _s = S {
+    let s = S {
         f1: s.to_string(),
         f0: s
     };
+    assert_eq!(s.f0, "Hello, world!");
 }
diff --git a/src/test/run-pass/struct-order-of-eval-3.rs b/src/test/run-pass/struct-order-of-eval-3.rs
new file mode 100644 (file)
index 0000000..856ed7c
--- /dev/null
@@ -0,0 +1,46 @@
+// Copyright 2015 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.
+
+// Checks that functional-record-update order-of-eval is as expected
+// even when no Drop-implementations are involved.
+
+use std::sync::atomic::{Ordering, AtomicUsize, ATOMIC_USIZE_INIT};
+
+struct W { wrapped: u32 }
+struct S { f0: W, _f1: i32 }
+
+pub fn main() {
+    const VAL: u32 = 0x89AB_CDEF;
+    let w = W { wrapped: VAL };
+    let s = S {
+        f0: { event(0x01); W { wrapped: w.wrapped + 1 } },
+        ..S {
+            f0: { event(0x02); w},
+            _f1: 23
+        }
+    };
+    assert_eq!(s.f0.wrapped, VAL + 1);
+    let actual = event_log();
+    let expect = 0x01_02;
+    assert!(expect == actual,
+            "expect: 0x{:x} actual: 0x{:x}", expect, actual);
+}
+
+static LOG: AtomicUsize = ATOMIC_USIZE_INIT;
+
+fn event_log() -> usize {
+    LOG.load(Ordering::SeqCst)
+}
+
+fn event(tag: u8) {
+    let old_log = LOG.load(Ordering::SeqCst);
+    let new_log = (old_log << 8) + tag as usize;
+    LOG.store(new_log, Ordering::SeqCst);
+}
diff --git a/src/test/run-pass/struct-order-of-eval-4.rs b/src/test/run-pass/struct-order-of-eval-4.rs
new file mode 100644 (file)
index 0000000..25923be
--- /dev/null
@@ -0,0 +1,43 @@
+// Copyright 2015 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.
+
+// Checks that struct-literal expression order-of-eval is as expected
+// even when no Drop-implementations are involved.
+
+use std::sync::atomic::{Ordering, AtomicUsize, ATOMIC_USIZE_INIT};
+
+struct W { wrapped: u32 }
+struct S { f0: W, _f1: i32 }
+
+pub fn main() {
+    const VAL: u32 = 0x89AB_CDEF;
+    let w = W { wrapped: VAL };
+    let s = S {
+        _f1: { event(0x01); 23 },
+        f0: { event(0x02); w },
+    };
+    assert_eq!(s.f0.wrapped, VAL);
+    let actual = event_log();
+    let expect = 0x01_02;
+    assert!(expect == actual,
+            "expect: 0x{:x} actual: 0x{:x}", expect, actual);
+}
+
+static LOG: AtomicUsize = ATOMIC_USIZE_INIT;
+
+fn event_log() -> usize {
+    LOG.load(Ordering::SeqCst)
+}
+
+fn event(tag: u8) {
+    let old_log = LOG.load(Ordering::SeqCst);
+    let new_log = (old_log << 8) + tag as usize;
+    LOG.store(new_log, Ordering::SeqCst);
+}
index dcb2fe6dfc07660a78be9646655e93b5df4bf3c8..b8e05b4d35ab78da407efe8174b2d383a2bac5ca 100644 (file)
 // ignore-pretty: does not work well with `--test`
 
 #[test]
-#[should_fail(expected = "foo")]
+#[should_panic(expected = "foo")]
 fn test_foo() {
     panic!("foo bar")
 }
 
 #[test]
-#[should_fail(expected = "foo")]
+#[should_panic(expected = "foo")]
 fn test_foo_dynamic() {
     panic!("{} bar", "foo")
 }
index ae175d27b0a4ea09b08f9ae0bdbd75e7de00032a..1a479d05d50936ff52b8902d2bbdef06f7866528 100644 (file)
@@ -7,8 +7,6 @@
 // <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.
-//
-// ignore-lexer-test FIXME #15879
 
 // Test syntax checks for `?Sized` syntax.
 
index 10b2f2fb7092423c2a2e77c772baf71b68abed31..e0d37ff40de59b4b62b475f31a1eefd9e61a6af5 100644 (file)
@@ -7,8 +7,6 @@
 // <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.
-//
-// ignore-lexer-test FIXME #15879
 
 #![allow(unknown_features)]
 #![feature(box_syntax)]