diff options
677 files changed, 9753 insertions, 5560 deletions
diff --git a/README.md b/README.md index c88c237cbee..93f0daa7141 100644 --- 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. diff --git a/configure b/configure index e5333b45525..b0d0c3f29b8 100755 --- a/configure +++ b/configure @@ -430,6 +430,10 @@ case $CFG_OSTYPE in CFG_CPUTYPE=x86_64 ;; +# Win 8 # uname -s on 64-bit cygwin does not contain WOW64, so simply use uname -m to detect arch (works in my install) + CYGWIN_NT-6.3) + CFG_OSTYPE=pc-windows-gnu + ;; # We do not detect other OS such as XP/2003 using 64 bit using uname. # If we want to in the future, we will need to use Cygwin - Chuck's csih helper in /usr/lib/csih/winProductName.exe or alternative. *) @@ -697,15 +701,17 @@ probe CFG_ADB adb if [ ! -z "$CFG_PANDOC" ] then - PV_MAJOR_MINOR=$(pandoc --version | grep '^pandoc\(.exe\)\? ' | - # extract the first 2 version fields, ignore everything else - sed 's/pandoc\(.exe\)\? \([0-9]*\)\.\([0-9]*\).*/\2 \3/') + # Extract "MAJOR MINOR" from Pandoc's version number + PV_MAJOR_MINOR=$(pandoc --version | grep '^pandoc' | + sed -E 's/pandoc(.exe)? ([0-9]+)\.([0-9]+).*/\2 \3/') MIN_PV_MAJOR="1" MIN_PV_MINOR="9" + # these patterns are shell globs, *not* regexps PV_MAJOR=${PV_MAJOR_MINOR% *} PV_MINOR=${PV_MAJOR_MINOR#* } + if [ "$PV_MAJOR" -lt "$MIN_PV_MAJOR" ] || [ "$PV_MINOR" -lt "$MIN_PV_MINOR" ] then step_msg "pandoc $PV_MAJOR.$PV_MINOR is too old. Need at least $MIN_PV_MAJOR.$MIN_PV_MINOR. Disabling" diff --git a/man/rustc.1 b/man/rustc.1 index 49056afa045..f37e6600190 100644 --- a/man/rustc.1 +++ b/man/rustc.1 @@ -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. diff --git a/man/rustdoc.1 b/man/rustdoc.1 index 830884b19bd..1738354fb43 100644 --- a/man/rustdoc.1 +++ b/man/rustdoc.1 @@ -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. diff --git a/mk/docs.mk b/mk/docs.mk index 743032f676d..f7ab86d3a29 100644 --- a/mk/docs.mk +++ b/mk/docs.mk @@ -273,11 +273,13 @@ compiler-docs: $(COMPILER_DOC_TARGETS) trpl: doc/book/index.html doc/book/index.html: $(RUSTBOOK_EXE) $(wildcard $(S)/src/doc/trpl/*.md) | doc/ + @$(call E, rustbook: $@) $(Q)rm -rf doc/book $(Q)$(RUSTBOOK) build $(S)src/doc/trpl doc/book style: doc/style/index.html doc/style/index.html: $(RUSTBOOK_EXE) $(wildcard $(S)/src/doc/style/*.md) | doc/ + @$(call E, rustbook: $@) $(Q)rm -rf doc/style $(Q)$(RUSTBOOK) build $(S)src/doc/style doc/style diff --git a/mk/main.mk b/mk/main.mk index 9752ee233b6..c00494be47c 100644 --- a/mk/main.mk +++ b/mk/main.mk @@ -18,7 +18,7 @@ CFG_RELEASE_NUM=1.0.0 # An optional number to put after the label, e.g. '.2' -> '-beta.2' # NB Make sure it starts with a dot to conform to semver pre-release # versions (section 9) -CFG_PRERELEASE_VERSION=.2 +CFG_PRERELEASE_VERSION= CFG_FILENAME_EXTRA=4e7c5e5c @@ -30,8 +30,8 @@ CFG_PACKAGE_VERS=$(CFG_RELEASE_NUM) CFG_DISABLE_UNSTABLE_FEATURES=1 endif ifeq ($(CFG_RELEASE_CHANNEL),beta) -CFG_RELEASE=$(CFG_RELEASE_NUM)-alpha$(CFG_PRERELEASE_VERSION) -CFG_PACKAGE_VERS=$(CFG_RELEASE_NUM)-alpha$(CFG_PRERELEASE_VERSION) +CFG_RELEASE=$(CFG_RELEASE_NUM)-beta(CFG_PRERELEASE_VERSION) +CFG_PACKAGE_VERS=$(CFG_RELEASE_NUM)-beta(CFG_PRERELEASE_VERSION) CFG_DISABLE_UNSTABLE_FEATURES=1 endif ifeq ($(CFG_RELEASE_CHANNEL),nightly) diff --git a/mk/tests.mk b/mk/tests.mk index 838ed0dccfc..ef38abcab65 100644 --- a/mk/tests.mk +++ b/mk/tests.mk @@ -590,7 +590,7 @@ TEST_SREQ$(1)_T_$(2)_H_$(3) = \ # The tests select when to use debug configuration on their own; # remove directive, if present, from CFG_RUSTC_FLAGS (issue #7898). -CTEST_RUSTC_FLAGS := $$(subst --cfg ndebug,,$$(CFG_RUSTC_FLAGS)) +CTEST_RUSTC_FLAGS := $$(subst -C debug-assertions,,$$(CFG_RUSTC_FLAGS)) # The tests cannot be optimized while the rest of the compiler is optimized, so # filter out the optimization (if any) from rustc and then figure out if we need diff --git a/src/compiletest/common.rs b/src/compiletest/common.rs index 2c046d25279..fe556cecef6 100644 --- a/src/compiletest/common.rs +++ b/src/compiletest/common.rs @@ -11,6 +11,7 @@ pub use self::Mode::*; use std::fmt; use std::str::FromStr; +use std::path::PathBuf; #[derive(Clone, Copy, PartialEq, Debug)] pub enum Mode { @@ -68,13 +69,13 @@ pub struct Config { pub run_lib_path: String, // The rustc executable - pub rustc_path: Path, + pub rustc_path: PathBuf, // The clang executable - pub clang_path: Option<Path>, + pub clang_path: Option<PathBuf>, // The llvm binaries path - pub llvm_bin_path: Option<Path>, + pub llvm_bin_path: Option<PathBuf>, // The valgrind path pub valgrind_path: Option<String>, @@ -84,13 +85,13 @@ pub struct Config { pub force_valgrind: bool, // The directory containing the tests to run - pub src_base: Path, + pub src_base: PathBuf, // The directory where programs should be built - pub build_base: Path, + pub build_base: PathBuf, // Directory for auxiliary libraries - pub aux_base: Path, + pub aux_base: PathBuf, // The name of the stage being built (stage1, etc) pub stage_id: String, @@ -105,7 +106,7 @@ pub struct Config { pub filter: Option<String>, // Write out a parseable log of tests that were run - pub logfile: Option<Path>, + pub logfile: Option<PathBuf>, // A command line to prefix program execution with, // for running under valgrind @@ -133,7 +134,7 @@ pub struct Config { pub lldb_version: Option<String>, // Path to the android tools - pub android_cross_path: Path, + pub android_cross_path: PathBuf, // Extra parameter to run adb on arm-linux-androideabi pub adb_path: String, diff --git a/src/compiletest/compiletest.rs b/src/compiletest/compiletest.rs index 4993dd140d3..2837c923b3d 100644 --- a/src/compiletest/compiletest.rs +++ b/src/compiletest/compiletest.rs @@ -21,6 +21,10 @@ #![feature(test)] #![feature(unicode)] #![feature(core)] +#![feature(path)] +#![feature(io)] +#![feature(net)] +#![feature(path_ext)] #![deny(warnings)] @@ -31,8 +35,9 @@ extern crate getopts; extern crate log; use std::env; +use std::fs; use std::old_io; -use std::old_io::fs; +use std::path::{Path, PathBuf}; use std::thunk::Thunk; use getopts::{optopt, optflag, reqopt}; use common::Config; @@ -114,9 +119,9 @@ pub fn parse_config(args: Vec<String> ) -> Config { panic!() } - fn opt_path(m: &getopts::Matches, nm: &str) -> Path { + fn opt_path(m: &getopts::Matches, nm: &str) -> PathBuf { match m.opt_str(nm) { - Some(s) => Path::new(s), + Some(s) => PathBuf::new(&s), None => panic!("no option (=path) found for {}", nm), } } @@ -131,10 +136,10 @@ pub fn parse_config(args: Vec<String> ) -> Config { compile_lib_path: matches.opt_str("compile-lib-path").unwrap(), run_lib_path: matches.opt_str("run-lib-path").unwrap(), rustc_path: opt_path(matches, "rustc-path"), - clang_path: matches.opt_str("clang-path").map(|s| Path::new(s)), + clang_path: matches.opt_str("clang-path").map(|s| PathBuf::new(&s)), valgrind_path: matches.opt_str("valgrind-path"), force_valgrind: matches.opt_present("force-valgrind"), - llvm_bin_path: matches.opt_str("llvm-bin-path").map(|s| Path::new(s)), + llvm_bin_path: matches.opt_str("llvm-bin-path").map(|s| PathBuf::new(&s)), src_base: opt_path(matches, "src-base"), build_base: opt_path(matches, "build-base"), aux_base: opt_path(matches, "aux-base"), @@ -142,7 +147,7 @@ pub fn parse_config(args: Vec<String> ) -> Config { mode: matches.opt_str("mode").unwrap().parse().ok().expect("invalid mode"), run_ignored: matches.opt_present("ignored"), filter: filter, - logfile: matches.opt_str("logfile").map(|s| Path::new(s)), + logfile: matches.opt_str("logfile").map(|s| PathBuf::new(&s)), runtool: matches.opt_str("runtool"), host_rustcflags: matches.opt_str("host-rustcflags"), target_rustcflags: matches.opt_str("target-rustcflags"), @@ -276,9 +281,9 @@ pub fn make_tests(config: &Config) -> Vec<test::TestDescAndFn> { debug!("making tests from {:?}", config.src_base.display()); let mut tests = Vec::new(); - let dirs = fs::readdir(&config.src_base).unwrap(); - for file in &dirs { - let file = file.clone(); + let dirs = fs::read_dir(&config.src_base).unwrap(); + for file in dirs { + let file = file.unwrap().path(); debug!("inspecting file {:?}", file.display()); if is_test(config, &file) { let t = make_test(config, &file, || { @@ -301,7 +306,7 @@ pub fn is_test(config: &Config, testfile: &Path) -> bool { _ => vec!(".rc".to_string(), ".rs".to_string()) }; let invalid_prefixes = vec!(".".to_string(), "#".to_string(), "~".to_string()); - let name = testfile.filename_str().unwrap(); + let name = testfile.file_name().unwrap().to_str().unwrap(); let mut valid = false; @@ -327,7 +332,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(), } @@ -337,9 +342,9 @@ pub fn make_test_name(config: &Config, testfile: &Path) -> test::TestName { // Try to elide redundant long paths fn shorten(path: &Path) -> String { - let filename = path.filename_str(); - let p = path.dir_path(); - let dir = p.filename_str(); + let filename = path.file_name().unwrap().to_str(); + let p = path.parent().unwrap(); + let dir = p.file_name().unwrap().to_str(); format!("{}/{}", dir.unwrap_or(""), filename.unwrap_or("")) } @@ -348,19 +353,17 @@ pub fn make_test_name(config: &Config, testfile: &Path) -> test::TestName { pub fn make_test_closure(config: &Config, testfile: &Path) -> test::TestFn { let config = (*config).clone(); - // FIXME (#9639): This needs to handle non-utf8 paths - let testfile = testfile.as_str().unwrap().to_string(); + let testfile = testfile.to_path_buf(); test::DynTestFn(Thunk::new(move || { - runtest::run(config, testfile) + runtest::run(config, &testfile) })) } pub fn make_metrics_test_closure(config: &Config, testfile: &Path) -> test::TestFn { let config = (*config).clone(); - // FIXME (#9639): This needs to handle non-utf8 paths - let testfile = testfile.as_str().unwrap().to_string(); + let testfile = testfile.to_path_buf(); test::DynMetricFn(box move |mm: &mut test::MetricMap| { - runtest::run_metrics(config, testfile, mm) + runtest::run_metrics(config, &testfile, mm) }) } diff --git a/src/compiletest/errors.rs b/src/compiletest/errors.rs index 7411a9b48d4..25f962c5785 100644 --- a/src/compiletest/errors.rs +++ b/src/compiletest/errors.rs @@ -9,7 +9,10 @@ // except according to those terms. use self::WhichLine::*; -use std::old_io::{BufferedReader, File}; +use std::fs::File; +use std::io::BufReader; +use std::io::prelude::*; +use std::path::Path; pub struct ExpectedError { pub line: uint, @@ -29,7 +32,7 @@ enum WhichLine { ThisLine, FollowPrevious(uint), AdjustBackward(uint) } /// //~| ERROR message two for that same line. // Load any test directives embedded in the file pub fn load_errors(testfile: &Path) -> Vec<ExpectedError> { - let mut rdr = BufferedReader::new(File::open(testfile).unwrap()); + let rdr = BufReader::new(File::open(testfile).unwrap()); // `last_nonfollow_error` tracks the most recently seen // line with an error template that did not use the diff --git a/src/compiletest/header.rs b/src/compiletest/header.rs index e5570fe0b8f..21cebc61b3a 100644 --- a/src/compiletest/header.rs +++ b/src/compiletest/header.rs @@ -9,6 +9,10 @@ // except according to those terms. use std::env; +use std::fs::File; +use std::io::BufReader; +use std::io::prelude::*; +use std::path::{Path, PathBuf}; use common::Config; use common; @@ -23,7 +27,7 @@ pub struct TestProps { pub run_flags: Option<String>, // If present, the name of a file that this test should match when // pretty-printed - pub pp_exact: Option<Path>, + pub pp_exact: Option<PathBuf>, // Modules from aux directory that should be compiled pub aux_builds: Vec<String> , // Environment settings to use during execution @@ -62,7 +66,7 @@ pub fn load_props(testfile: &Path) -> TestProps { let mut pretty_mode = None; let mut pretty_compare_only = false; let mut forbid_output = Vec::new(); - iter_header(testfile, |ln| { + iter_header(testfile, &mut |ln| { match parse_error_pattern(ln) { Some(ep) => error_patterns.push(ep), None => () @@ -219,7 +223,7 @@ pub fn is_test_ignored(config: &Config, testfile: &Path) -> bool { } } - let val = iter_header(testfile, |ln| { + let val = iter_header(testfile, &mut |ln| { !parse_name_directive(ln, "ignore-test") && !parse_name_directive(ln, &ignore_target(config)) && !parse_name_directive(ln, &ignore_stage(config)) && @@ -232,12 +236,8 @@ pub fn is_test_ignored(config: &Config, testfile: &Path) -> bool { !val } -fn iter_header<F>(testfile: &Path, mut it: F) -> bool where - F: FnMut(&str) -> bool, -{ - use std::old_io::{BufferedReader, File}; - - let mut rdr = BufferedReader::new(File::open(testfile).unwrap()); +fn iter_header(testfile: &Path, it: &mut FnMut(&str) -> bool) -> bool { + let rdr = BufReader::new(File::open(testfile).unwrap()); for ln in rdr.lines() { // Assume that any directives will be found before the first // module or function. This doesn't seem to be an optimization @@ -322,12 +322,12 @@ fn parse_exec_env(line: &str) -> Option<(String, String)> { }) } -fn parse_pp_exact(line: &str, testfile: &Path) -> Option<Path> { +fn parse_pp_exact(line: &str, testfile: &Path) -> Option<PathBuf> { match parse_name_value_directive(line, "pp-exact") { - Some(s) => Some(Path::new(s)), + Some(s) => Some(PathBuf::new(&s)), None => { if parse_name_directive(line, "pp-exact") { - testfile.filename().map(|s| Path::new(s)) + testfile.file_name().map(|s| PathBuf::new(s)) } else { None } diff --git a/src/compiletest/procsrv.rs b/src/compiletest/procsrv.rs index 148a43e6c78..b684dbcface 100644 --- a/src/compiletest/procsrv.rs +++ b/src/compiletest/procsrv.rs @@ -8,7 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::old_io::process::{ProcessExit, Command, Process, ProcessOutput}; +use std::process::{ExitStatus, Command, Child, Output, Stdio}; +use std::io::prelude::*; use std::dynamic_lib::DynamicLibrary; fn add_target_env(cmd: &mut Command, lib_path: &str, aux_path: Option<&str>) { @@ -25,10 +26,10 @@ fn add_target_env(cmd: &mut Command, lib_path: &str, aux_path: Option<&str>) { let var = DynamicLibrary::envvar(); let newpath = DynamicLibrary::create_path(&path); let newpath = String::from_utf8(newpath).unwrap(); - cmd.env(var.to_string(), newpath); + cmd.env(var, &newpath); } -pub struct Result {pub status: ProcessExit, pub out: String, pub err: String} +pub struct Result {pub status: ExitStatus, pub out: String, pub err: String} pub fn run(lib_path: &str, prog: &str, @@ -38,10 +39,13 @@ pub fn run(lib_path: &str, input: Option<String>) -> Option<Result> { let mut cmd = Command::new(prog); - cmd.args(args); + cmd.args(args) + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .stderr(Stdio::piped()); add_target_env(&mut cmd, lib_path, aux_path); for (key, val) in env { - cmd.env(key, val); + cmd.env(&key, &val); } match cmd.spawn() { @@ -49,13 +53,13 @@ pub fn run(lib_path: &str, if let Some(input) = input { process.stdin.as_mut().unwrap().write_all(input.as_bytes()).unwrap(); } - let ProcessOutput { status, output, error } = + let Output { status, stdout, stderr } = process.wait_with_output().unwrap(); Some(Result { status: status, - out: String::from_utf8(output).unwrap(), - err: String::from_utf8(error).unwrap() + out: String::from_utf8(stdout).unwrap(), + err: String::from_utf8(stderr).unwrap() }) }, Err(..) => None @@ -67,13 +71,16 @@ pub fn run_background(lib_path: &str, aux_path: Option<&str>, args: &[String], env: Vec<(String, String)> , - input: Option<String>) -> Option<Process> { + input: Option<String>) -> Option<Child> { let mut cmd = Command::new(prog); - cmd.args(args); + cmd.args(args) + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .stderr(Stdio::piped()); add_target_env(&mut cmd, lib_path, aux_path); for (key, val) in env { - cmd.env(key, val); + cmd.env(&key, &val); } match cmd.spawn() { diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs index 7ac8a9b041c..04714b50fc0 100644 --- a/src/compiletest/runtest.rs +++ b/src/compiletest/runtest.rs @@ -11,35 +11,29 @@ use self::TargetLocation::*; use common::Config; -use common::{CompileFail, ParseFail, Pretty, RunFail, RunPass, RunPassValgrind, DebugInfoGdb}; -use common::{Codegen, DebugInfoLldb}; +use common::{CompileFail, ParseFail, Pretty, RunFail, RunPass, RunPassValgrind}; +use common::{Codegen, DebugInfoLldb, DebugInfoGdb}; use errors; use header::TestProps; use header; use procsrv; use util::logv; -#[cfg(target_os = "windows")] -use util; - -#[cfg(target_os = "windows")] -use std::ascii::AsciiExt; -use std::old_io::File; -use std::old_io::fs::PathExtensions; -use std::old_io::fs; -use std::old_io::net::tcp; -use std::old_io::process::ProcessExit; -use std::old_io::process; -use std::old_io::timer; -use std::old_io; + use std::env; +use std::fmt; +use std::fs::{self, File}; +use std::io::BufReader; +use std::io::prelude::*; use std::iter::repeat; +use std::net::TcpStream; +use std::old_io::timer; +use std::path::{Path, PathBuf}; +use std::process::{Command, Output, ExitStatus}; use std::str; -use std::string::String; -use std::thread; use std::time::Duration; use test::MetricMap; -pub fn run(config: Config, testfile: String) { +pub fn run(config: Config, testfile: &Path) { match &*config.target { "arm-linux-androideabi" | "aarch64-linux-android" => { @@ -55,12 +49,11 @@ pub fn run(config: Config, testfile: String) { run_metrics(config, testfile, &mut _mm); } -pub fn run_metrics(config: Config, testfile: String, mm: &mut MetricMap) { +pub fn run_metrics(config: Config, testfile: &Path, mm: &mut MetricMap) { if config.verbose { // We're going to be dumping a lot of info. Start on a new line. print!("\n\n"); } - let testfile = Path::new(testfile); debug!("running {:?}", testfile.display()); let props = header::load_props(&testfile); debug!("loaded props"); @@ -127,8 +120,8 @@ fn run_rfail_test(config: &Config, props: &TestProps, testfile: &Path) { }; // The value our Makefile configures valgrind to return on failure - const VALGRIND_ERR: int = 100; - if proc_res.status.matches_exit_status(VALGRIND_ERR) { + const VALGRIND_ERR: i32 = 100; + if proc_res.status.code() == Some(VALGRIND_ERR) { fatal_proc_rec("run-fail test isn't valgrind-clean!", &proc_res); } @@ -139,10 +132,10 @@ fn run_rfail_test(config: &Config, props: &TestProps, testfile: &Path) { fn check_correct_failure_status(proc_res: &ProcRes) { // The value the rust runtime returns on failure - const RUST_ERR: int = 101; - if !proc_res.status.matches_exit_status(RUST_ERR) { + const RUST_ERR: i32 = 101; + if proc_res.status.code() != Some(RUST_ERR) { fatal_proc_rec( - &format!("failure produced the wrong error: {:?}", + &format!("failure produced the wrong error: {}", proc_res.status), proc_res); } @@ -201,8 +194,8 @@ fn run_pretty_test(config: &Config, props: &TestProps, testfile: &Path) { let rounds = match props.pp_exact { Some(_) => 1, None => 2 }; - let src = File::open(testfile).read_to_end().unwrap(); - let src = String::from_utf8(src.clone()).unwrap(); + let mut src = String::new(); + File::open(testfile).unwrap().read_to_string(&mut src).unwrap(); let mut srcs = vec!(src); let mut round = 0; @@ -226,9 +219,10 @@ fn run_pretty_test(config: &Config, props: &TestProps, testfile: &Path) { let mut expected = match props.pp_exact { Some(ref file) => { - let filepath = testfile.dir_path().join(file); - let s = File::open(&filepath).read_to_end().unwrap(); - String::from_utf8(s).unwrap() + let filepath = testfile.parent().unwrap().join(file); + let mut s = String::new(); + File::open(&filepath).unwrap().read_to_string(&mut s).unwrap(); + s } None => { srcs[srcs.len() - 2].clone() } }; @@ -283,7 +277,7 @@ fn run_pretty_test(config: &Config, props: &TestProps, testfile: &Path) { pretty_type.to_string()), props.exec_env.clone(), &config.compile_lib_path, - Some(aux_dir.as_str().unwrap()), + Some(aux_dir.to_str().unwrap()), Some(src)) } @@ -299,11 +293,11 @@ fn run_pretty_test(config: &Config, props: &TestProps, testfile: &Path) { pretty_type, format!("--target={}", config.target), "-L".to_string(), - aux_dir.as_str().unwrap().to_string()); + aux_dir.to_str().unwrap().to_string()); args.extend(split_maybe_args(&config.target_rustcflags).into_iter()); args.extend(split_maybe_args(&props.compile_flags).into_iter()); return ProcArgs { - prog: config.rustc_path.as_str().unwrap().to_string(), + prog: config.rustc_path.to_str().unwrap().to_string(), args: args, }; } @@ -345,14 +339,14 @@ actual:\n\ "--crate-type=lib".to_string(), format!("--target={}", target), "-L".to_string(), - config.build_base.as_str().unwrap().to_string(), + config.build_base.to_str().unwrap().to_string(), "-L".to_string(), - aux_dir.as_str().unwrap().to_string()); + aux_dir.to_str().unwrap().to_string()); args.extend(split_maybe_args(&config.target_rustcflags).into_iter()); args.extend(split_maybe_args(&props.compile_flags).into_iter()); // FIXME (#9639): This needs to handle non-utf8 paths return ProcArgs { - prog: config.rustc_path.as_str().unwrap().to_string(), + prog: config.rustc_path.to_str().unwrap().to_string(), args: args, }; } @@ -390,18 +384,19 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) { // write debugger script let mut script_str = String::with_capacity(2048); script_str.push_str("set charset UTF-8\n"); - script_str.push_str(&format!("file {}\n", exe_file.as_str().unwrap())); + script_str.push_str(&format!("file {}\n", exe_file.to_str().unwrap())); script_str.push_str("target remote :5039\n"); script_str.push_str(&format!("set solib-search-path \ ./{}/stage2/lib/rustlib/{}/lib/\n", config.host, config.target)); for line in breakpoint_lines.iter() { script_str.push_str(&format!("break {:?}:{}\n", - testfile.filename_display(), + testfile.file_name().unwrap() + .to_string_lossy(), *line)[..]); } script_str.push_str(&cmds); - script_str.push_str("quit\n"); + script_str.push_str("\nquit\n"); debug!("script_str = {}", script_str); dump_output_file(config, @@ -415,7 +410,7 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) { None, &[ "push".to_string(), - exe_file.as_str().unwrap().to_string(), + exe_file.to_str().unwrap().to_string(), config.adb_test_dir.clone() ], vec!(("".to_string(), "".to_string())), @@ -440,9 +435,8 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) { if config.target.contains("aarch64") {"64"} else {""}, config.adb_test_dir.clone(), - str::from_utf8( - exe_file.filename() - .unwrap()).unwrap()); + exe_file.file_name().unwrap().to_str() + .unwrap()); let mut process = procsrv::run_background("", &config.adb_path @@ -459,16 +453,12 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) { loop { //waiting 1 second for gdbserver start timer::sleep(Duration::milliseconds(1000)); - let result = thread::spawn(move || { - tcp::TcpStream::connect("127.0.0.1:5039").unwrap(); - }).join(); - if result.is_err() { - continue; + if TcpStream::connect("127.0.0.1:5039").is_ok() { + break } - break; } - let tool_path = match config.android_cross_path.as_str() { + let tool_path = match config.android_cross_path.to_str() { Some(x) => x.to_string(), None => fatal("cannot find android cross path") }; @@ -479,7 +469,7 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) { vec!("-quiet".to_string(), "-batch".to_string(), "-nx".to_string(), - format!("-command={}", debugger_script.as_str().unwrap())); + format!("-command={}", debugger_script.to_str().unwrap())); let mut gdb_path = tool_path; gdb_path.push_str(&format!("/bin/{}-gdb", config.target)); @@ -503,12 +493,12 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) { }; debugger_run_result = ProcRes { - status: status, + status: Status::Normal(status), stdout: out, stderr: err, cmdline: cmdline }; - if process.signal_kill().is_err() { + if process.kill().is_err() { println!("Adb process is already finished."); } } @@ -518,7 +508,7 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) { .expect("Could not find Rust source root"); let rust_pp_module_rel_path = Path::new("./src/etc"); let rust_pp_module_abs_path = rust_src_root.join(rust_pp_module_rel_path) - .as_str() + .to_str() .unwrap() .to_string(); // write debugger script @@ -538,7 +528,7 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) { // GDB's script auto loading safe path script_str.push_str( &format!("add-auto-load-safe-path {}\n", - rust_pp_module_abs_path.replace("\\", "\\\\")) + rust_pp_module_abs_path.replace(r"\", r"\\")) ); } } @@ -553,21 +543,24 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) { script_str.push_str("set print pretty off\n"); // Add the pretty printer directory to GDB's source-file search path - script_str.push_str(&format!("directory {}\n", rust_pp_module_abs_path)[..]); + script_str.push_str(&format!("directory {}\n", + rust_pp_module_abs_path)); // Load the target executable script_str.push_str(&format!("file {}\n", - exe_file.as_str().unwrap().replace("\\", "\\\\"))[..]); + exe_file.to_str().unwrap() + .replace(r"\", r"\\"))); // Add line breakpoints for line in &breakpoint_lines { script_str.push_str(&format!("break '{}':{}\n", - testfile.filename_display(), - *line)[..]); + testfile.file_name().unwrap() + .to_string_lossy(), + *line)); } script_str.push_str(&cmds); - script_str.push_str("quit\n"); + script_str.push_str("\nquit\n"); debug!("script_str = {}", script_str); dump_output_file(config, @@ -576,13 +569,8 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) { "debugger.script"); // run debugger script with gdb - #[cfg(windows)] - fn debugger() -> String { - "gdb.exe".to_string() - } - #[cfg(unix)] - fn debugger() -> String { - "gdb".to_string() + fn debugger() -> &'static str { + if cfg!(windows) {"gdb.exe"} else {"gdb"} } let debugger_script = make_out_name(config, testfile, "debugger.script"); @@ -592,10 +580,10 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) { vec!("-quiet".to_string(), "-batch".to_string(), "-nx".to_string(), - format!("-command={}", debugger_script.as_str().unwrap())); + format!("-command={}", debugger_script.to_str().unwrap())); let proc_args = ProcArgs { - prog: debugger(), + prog: debugger().to_string(), args: debugger_opts, }; @@ -618,7 +606,7 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) { check_debugger_output(&debugger_run_result, &check_lines); } -fn find_rust_src_root(config: &Config) -> Option<Path> { +fn find_rust_src_root(config: &Config) -> Option<PathBuf> { let mut path = config.src_base.clone(); let path_postfix = Path::new("src/etc/lldb_batchmode.py"); @@ -632,8 +620,6 @@ fn find_rust_src_root(config: &Config) -> Option<Path> { } fn run_debuginfo_lldb_test(config: &Config, props: &TestProps, testfile: &Path) { - use std::old_io::process::{Command, ProcessOutput}; - if config.lldb_python_dir.is_none() { fatal("Can't run LLDB test because LLDB's python path is not set."); } @@ -685,11 +671,12 @@ fn run_debuginfo_lldb_test(config: &Config, props: &TestProps, testfile: &Path) .expect("Could not find Rust source root"); let rust_pp_module_rel_path = Path::new("./src/etc/lldb_rust_formatters.py"); let rust_pp_module_abs_path = rust_src_root.join(rust_pp_module_rel_path) - .as_str() + .to_str() .unwrap() .to_string(); - script_str.push_str(&format!("command script import {}\n", &rust_pp_module_abs_path[..])[..]); + script_str.push_str(&format!("command script import {}\n", + &rust_pp_module_abs_path[..])[..]); script_str.push_str("type summary add --no-value "); script_str.push_str("--python-function lldb_rust_formatters.print_val "); script_str.push_str("-x \".*\" --category Rust\n"); @@ -707,7 +694,7 @@ fn run_debuginfo_lldb_test(config: &Config, props: &TestProps, testfile: &Path) } // Finally, quit the debugger - script_str.push_str("quit\n"); + script_str.push_str("\nquit\n"); // Write the script into a file debug!("script_str = {}", script_str); @@ -735,22 +722,19 @@ fn run_debuginfo_lldb_test(config: &Config, props: &TestProps, testfile: &Path) rust_src_root: &Path) -> ProcRes { // Prepare the lldb_batchmode which executes the debugger script - let lldb_script_path = rust_src_root.join(Path::new("./src/etc/lldb_batchmode.py")); + let lldb_script_path = rust_src_root.join("src/etc/lldb_batchmode.py"); let mut cmd = Command::new("python"); - cmd.arg(lldb_script_path) + cmd.arg(&lldb_script_path) .arg(test_executable) .arg(debugger_script) - .env_set_all(&[("PYTHONPATH", config.lldb_python_dir.clone().unwrap())]); - - let (status, out, err) = match cmd.spawn() { - Ok(process) => { - let ProcessOutput { status, output, error } = - process.wait_with_output().unwrap(); + .env("PYTHONPATH", config.lldb_python_dir.as_ref().unwrap()); + let (status, out, err) = match cmd.output() { + Ok(Output { status, stdout, stderr }) => { (status, - String::from_utf8(output).unwrap(), - String::from_utf8(error).unwrap()) + String::from_utf8(stdout).unwrap(), + String::from_utf8(stderr).unwrap()) }, Err(e) => { fatal(&format!("Failed to setup Python process for \ @@ -760,7 +744,7 @@ fn run_debuginfo_lldb_test(config: &Config, props: &TestProps, testfile: &Path) dump_output(config, test_executable, &out, &err); return ProcRes { - status: status, + status: Status::Normal(status), stdout: out, stderr: err, cmdline: format!("{:?}", cmd) @@ -776,8 +760,6 @@ struct DebuggerCommands { fn parse_debugger_commands(file_path: &Path, debugger_prefix: &str) -> DebuggerCommands { - use std::old_io::{BufferedReader, File}; - let command_directive = format!("{}-command", debugger_prefix); let check_directive = format!("{}-check", debugger_prefix); @@ -785,7 +767,7 @@ fn parse_debugger_commands(file_path: &Path, debugger_prefix: &str) let mut commands = vec!(); let mut check_lines = vec!(); let mut counter = 1; - let mut reader = BufferedReader::new(File::open(file_path).unwrap()); + let reader = BufReader::new(File::open(file_path).unwrap()); for line in reader.lines() { match line { Ok(line) => { @@ -963,16 +945,17 @@ fn check_expected_errors(expected_errors: Vec<errors::ExpectedError> , let prefixes = expected_errors.iter().map(|ee| { format!("{}:{}:", testfile.display(), ee.line) - }).collect::<Vec<String> >(); - - #[cfg(windows)] - fn prefix_matches( line : &str, prefix : &str ) -> bool { - line.to_ascii_lowercase().starts_with(&prefix.to_ascii_lowercase()) - } - - #[cfg(unix)] - fn prefix_matches( line : &str, prefix : &str ) -> bool { - line.starts_with( prefix ) + }).collect::<Vec<String>>(); + + fn prefix_matches(line: &str, prefix: &str) -> bool { + use std::ascii::AsciiExt; + // On windows just translate all '\' path separators to '/' + let line = line.replace(r"\", "/"); + if cfg!(windows) { + line.to_ascii_lowercase().starts_with(&prefix.to_ascii_lowercase()) + } else { + line.starts_with(prefix) + } } // A multi-line error will have followup lines which will always @@ -1113,12 +1096,42 @@ struct ProcArgs { } struct ProcRes { - status: ProcessExit, + status: Status, stdout: String, stderr: String, cmdline: String, } +enum Status { + Parsed(i32), + Normal(ExitStatus), +} + +impl Status { + fn code(&self) -> Option<i32> { + match *self { + Status::Parsed(i) => Some(i), + Status::Normal(ref e) => e.code(), + } + } + + fn success(&self) -> bool { + match *self { + Status::Parsed(i) => i == 0, + Status::Normal(ref e) => e.success(), + } + } +} + +impl fmt::Display for Status { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + Status::Parsed(i) => write!(f, "exit code: {}", i), + Status::Normal(ref e) => e.fmt(f), + } + } +} + fn compile_test(config: &Config, props: &TestProps, testfile: &Path) -> ProcRes { compile_test_(config, props, testfile, &[]) @@ -1133,7 +1146,7 @@ fn compile_test_(config: &Config, props: &TestProps, let aux_dir = aux_output_dir_name(config, testfile); // FIXME (#9639): This needs to handle non-utf8 paths let mut link_args = vec!("-L".to_string(), - aux_dir.as_str().unwrap().to_string()); + aux_dir.to_str().unwrap().to_string()); link_args.extend(extra_args.iter().cloned()); let args = make_compile_args(config, props, @@ -1160,7 +1173,7 @@ fn exec_compiled_test(config: &Config, props: &TestProps, make_run_args(config, props, testfile), env, &config.run_lib_path, - Some(aux_dir.as_str().unwrap()), + Some(aux_dir.to_str().unwrap()), None) } } @@ -1179,7 +1192,7 @@ fn compose_and_run_compiler( let aux_dir = aux_output_dir_name(config, testfile); // FIXME (#9639): This needs to handle non-utf8 paths - let extra_link_args = vec!("-L".to_string(), aux_dir.as_str().unwrap().to_string()); + let extra_link_args = vec!("-L".to_string(), aux_dir.to_str().unwrap().to_string()); for rel_ab in &props.aux_builds { let abs_ab = config.aux_base.join(rel_ab); @@ -1196,7 +1209,8 @@ fn compose_and_run_compiler( crate_type, |a,b| { let f = make_lib_name(a, b, testfile); - TargetLocation::ThisDirectory(f.dir_path()) + let parent = f.parent().unwrap(); + TargetLocation::ThisDirectory(parent.to_path_buf()) }, &abs_ab); let auxres = compose_and_run(config, @@ -1204,7 +1218,7 @@ fn compose_and_run_compiler( aux_args, Vec::new(), &config.compile_lib_path, - Some(aux_dir.as_str().unwrap()), + Some(aux_dir.to_str().unwrap()), None); if !auxres.status.success() { fatal_proc_rec( @@ -1226,13 +1240,13 @@ fn compose_and_run_compiler( args, Vec::new(), &config.compile_lib_path, - Some(aux_dir.as_str().unwrap()), + Some(aux_dir.to_str().unwrap()), input) } fn ensure_dir(path: &Path) { if path.is_dir() { return; } - fs::mkdir(path, old_io::USER_RWX).unwrap(); + fs::create_dir(path).unwrap(); } fn compose_and_run(config: &Config, testfile: &Path, @@ -1246,8 +1260,8 @@ fn compose_and_run(config: &Config, testfile: &Path, } enum TargetLocation { - ThisFile(Path), - ThisDirectory(Path), + ThisFile(PathBuf), + ThisDirectory(PathBuf), } fn make_compile_args<F>(config: &Config, @@ -1265,9 +1279,9 @@ fn make_compile_args<F>(config: &Config, &*config.target }; // FIXME (#9639): This needs to handle non-utf8 paths - let mut args = vec!(testfile.as_str().unwrap().to_string(), + let mut args = vec!(testfile.to_str().unwrap().to_string(), "-L".to_string(), - config.build_base.as_str().unwrap().to_string(), + config.build_base.to_str().unwrap().to_string(), format!("--target={}", target)); args.push_all(&extras); if !props.no_prefer_dynamic { @@ -1284,7 +1298,7 @@ fn make_compile_args<F>(config: &Config, path } }; - args.push(path.as_str().unwrap().to_string()); + args.push(path.to_str().unwrap().to_string()); if props.force_host { args.extend(split_maybe_args(&config.host_rustcflags).into_iter()); } else { @@ -1292,24 +1306,24 @@ fn make_compile_args<F>(config: &Config, } args.extend(split_maybe_args(&props.compile_flags).into_iter()); return ProcArgs { - prog: config.rustc_path.as_str().unwrap().to_string(), + prog: config.rustc_path.to_str().unwrap().to_string(), args: args, }; } -fn make_lib_name(config: &Config, auxfile: &Path, testfile: &Path) -> Path { +fn make_lib_name(config: &Config, auxfile: &Path, testfile: &Path) -> PathBuf { // what we return here is not particularly important, as it // happens; rustc ignores everything except for the directory. let auxname = output_testname(auxfile); aux_output_dir_name(config, testfile).join(&auxname) } -fn make_exe_name(config: &Config, testfile: &Path) -> Path { +fn make_exe_name(config: &Config, testfile: &Path) -> PathBuf { let mut f = output_base_name(config, testfile); if !env::consts::EXE_SUFFIX.is_empty() { - let mut fname = f.filename().unwrap().to_vec(); - fname.extend(env::consts::EXE_SUFFIX.bytes()); - f.set_filename(fname); + let mut fname = f.file_name().unwrap().to_os_string(); + fname.push(env::consts::EXE_SUFFIX); + f.set_file_name(&fname); } f } @@ -1322,7 +1336,7 @@ fn make_run_args(config: &Config, props: &TestProps, testfile: &Path) -> let exe_file = make_exe_name(config, testfile); // FIXME (#9639): This needs to handle non-utf8 paths - args.push(exe_file.as_str().unwrap().to_string()); + args.push(exe_file.to_str().unwrap().to_string()); // Add the arguments in the run_flags directive args.extend(split_maybe_args(&props.run_flags).into_iter()); @@ -1375,29 +1389,28 @@ fn program_output(config: &Config, testfile: &Path, lib_path: &str, prog: String input).expect(&format!("failed to exec `{}`", prog)); dump_output(config, testfile, &out, &err); return ProcRes { - status: status, + status: Status::Normal(status), stdout: out, stderr: err, cmdline: cmdline, }; } -// Linux and mac don't require adjusting the library search path -#[cfg(unix)] -fn make_cmdline(_libpath: &str, prog: &str, args: &[String]) -> String { - format!("{} {}", prog, args.connect(" ")) -} - -#[cfg(windows)] fn make_cmdline(libpath: &str, prog: &str, args: &[String]) -> String { + use util; - // Build the LD_LIBRARY_PATH variable as it would be seen on the command line - // for diagnostic purposes - fn lib_path_cmd_prefix(path: &str) -> String { - format!("{}=\"{}\"", util::lib_path_env_var(), util::make_new_path(path)) - } + // Linux and mac don't require adjusting the library search path + if cfg!(unix) { + format!("{} {}", prog, args.connect(" ")) + } else { + // Build the LD_LIBRARY_PATH variable as it would be seen on the command line + // for diagnostic purposes + fn lib_path_cmd_prefix(path: &str) -> String { + format!("{}=\"{}\"", util::lib_path_env_var(), util::make_new_path(path)) + } - format!("{} {} {}", lib_path_cmd_prefix(libpath), prog, args.connect(" ")) + format!("{} {} {}", lib_path_cmd_prefix(libpath), prog, args.connect(" ")) + } } fn dump_output(config: &Config, testfile: &Path, out: &str, err: &str) { @@ -1409,25 +1422,25 @@ fn dump_output(config: &Config, testfile: &Path, out: &str, err: &str) { fn dump_output_file(config: &Config, testfile: &Path, out: &str, extension: &str) { let outfile = make_out_name(config, testfile, extension); - File::create(&outfile).write_all(out.as_bytes()).unwrap(); + File::create(&outfile).unwrap().write_all(out.as_bytes()).unwrap(); } -fn make_out_name(config: &Config, testfile: &Path, extension: &str) -> Path { +fn make_out_name(config: &Config, testfile: &Path, extension: &str) -> PathBuf { output_base_name(config, testfile).with_extension(extension) } -fn aux_output_dir_name(config: &Config, testfile: &Path) -> Path { +fn aux_output_dir_name(config: &Config, testfile: &Path) -> PathBuf { let f = output_base_name(config, testfile); - let mut fname = f.filename().unwrap().to_vec(); - fname.extend("libaux".bytes()); - f.with_filename(fname) + let mut fname = f.file_name().unwrap().to_os_string(); + fname.push("libaux"); + f.with_file_name(&fname) } -fn output_testname(testfile: &Path) -> Path { - Path::new(testfile.filestem().unwrap()) +fn output_testname(testfile: &Path) -> PathBuf { + PathBuf::new(testfile.file_stem().unwrap()) } -fn output_base_name(config: &Config, testfile: &Path) -> Path { +fn output_base_name(config: &Config, testfile: &Path) -> PathBuf { config.build_base .join(&output_testname(testfile)) .with_extension(&config.stage_id) @@ -1542,11 +1555,11 @@ fn _arm_exec_compiled_test(config: &Config, Some("".to_string())) .expect(&format!("failed to exec `{}`", config.adb_path)); - let mut exitcode: int = 0; + let mut exitcode: i32 = 0; for c in exitcode_out.chars() { if !c.is_numeric() { break; } exitcode = exitcode * 10 + match c { - '0' ... '9' => c as int - ('0' as int), + '0' ... '9' => c as i32 - ('0' as i32), _ => 101, } } @@ -1587,7 +1600,7 @@ fn _arm_exec_compiled_test(config: &Config, &stderr_out); ProcRes { - status: process::ProcessExit::ExitStatus(exitcode), + status: Status::Parsed(exitcode), stdout: stdout_out, stderr: stderr_out, cmdline: cmdline @@ -1597,16 +1610,17 @@ fn _arm_exec_compiled_test(config: &Config, fn _arm_push_aux_shared_library(config: &Config, testfile: &Path) { let tdir = aux_output_dir_name(config, testfile); - let dirs = fs::readdir(&tdir).unwrap(); - for file in &dirs { - if file.extension_str() == Some("so") { + let dirs = fs::read_dir(&tdir).unwrap(); + for file in dirs { + let file = file.unwrap().path(); + if file.extension().and_then(|s| s.to_str()) == Some("so") { // FIXME (#9639): This needs to handle non-utf8 paths let copy_result = procsrv::run("", &config.adb_path, None, &[ "push".to_string(), - file.as_str() + file.to_str() .unwrap() .to_string(), config.adb_test_dir.to_string(), @@ -1627,14 +1641,14 @@ fn _arm_push_aux_shared_library(config: &Config, testfile: &Path) { // codegen tests (vs. clang) -fn append_suffix_to_stem(p: &Path, suffix: &str) -> Path { +fn append_suffix_to_stem(p: &Path, suffix: &str) -> PathBuf { if suffix.len() == 0 { - (*p).clone() + p.to_path_buf() } else { - let mut stem = p.filestem().unwrap().to_vec(); - stem.extend("-".bytes()); - stem.extend(suffix.bytes()); - p.with_filename(stem) + let mut stem = p.file_stem().unwrap().to_os_string(); + stem.push("-"); + stem.push(suffix); + p.with_file_name(&stem) } } @@ -1643,7 +1657,7 @@ fn compile_test_and_save_bitcode(config: &Config, props: &TestProps, let aux_dir = aux_output_dir_name(config, testfile); // FIXME (#9639): This needs to handle non-utf8 paths let mut link_args = vec!("-L".to_string(), - aux_dir.as_str().unwrap().to_string()); + aux_dir.to_str().unwrap().to_string()); let llvm_args = vec!("--emit=llvm-bc,obj".to_string(), "--crate-type=lib".to_string()); link_args.extend(llvm_args.into_iter()); @@ -1651,7 +1665,8 @@ fn compile_test_and_save_bitcode(config: &Config, props: &TestProps, props, link_args, |a, b| TargetLocation::ThisDirectory( - output_base_name(a, b).dir_path()), + output_base_name(a, b).parent() + .unwrap().to_path_buf()), testfile); compose_and_run_compiler(config, props, testfile, args, None) } @@ -1663,12 +1678,12 @@ fn compile_cc_with_clang_and_save_bitcode(config: &Config, _props: &TestProps, let testcc = testfile.with_extension("cc"); let proc_args = ProcArgs { // FIXME (#9639): This needs to handle non-utf8 paths - prog: config.clang_path.as_ref().unwrap().as_str().unwrap().to_string(), + prog: config.clang_path.as_ref().unwrap().to_str().unwrap().to_string(), args: vec!("-c".to_string(), "-emit-llvm".to_string(), "-o".to_string(), - bitcodefile.as_str().unwrap().to_string(), - testcc.as_str().unwrap().to_string()) + bitcodefile.to_str().unwrap().to_string(), + testcc.to_str().unwrap().to_string()) }; compose_and_run(config, testfile, proc_args, Vec::new(), "", None, None) } @@ -1682,10 +1697,10 @@ fn extract_function_from_bitcode(config: &Config, _props: &TestProps, let prog = config.llvm_bin_path.as_ref().unwrap().join("llvm-extract"); let proc_args = ProcArgs { // FIXME (#9639): This needs to handle non-utf8 paths - prog: prog.as_str().unwrap().to_string(), + prog: prog.to_str().unwrap().to_string(), args: vec!(format!("-func={}", fname), - format!("-o={}", extracted_bc.as_str().unwrap()), - bitcodefile.as_str().unwrap().to_string()) + format!("-o={}", extracted_bc.to_str().unwrap()), + bitcodefile.to_str().unwrap().to_string()) }; compose_and_run(config, testfile, proc_args, Vec::new(), "", None, None) } @@ -1699,16 +1714,17 @@ fn disassemble_extract(config: &Config, _props: &TestProps, let prog = config.llvm_bin_path.as_ref().unwrap().join("llvm-dis"); let proc_args = ProcArgs { // FIXME (#9639): This needs to handle non-utf8 paths - prog: prog.as_str().unwrap().to_string(), - args: vec!(format!("-o={}", extracted_ll.as_str().unwrap()), - extracted_bc.as_str().unwrap().to_string()) + prog: prog.to_str().unwrap().to_string(), + args: vec!(format!("-o={}", extracted_ll.to_str().unwrap()), + extracted_bc.to_str().unwrap().to_string()) }; compose_and_run(config, testfile, proc_args, Vec::new(), "", None, None) } fn count_extracted_lines(p: &Path) -> uint { - let x = File::open(&p.with_extension("ll")).read_to_end().unwrap(); + let mut x = Vec::new(); + File::open(&p.with_extension("ll")).unwrap().read_to_end(&mut x).unwrap(); let x = str::from_utf8(&x).unwrap(); x.lines().count() } diff --git a/src/compiletest/util.rs b/src/compiletest/util.rs index c0d7c59ef6a..16e2806f72c 100644 --- a/src/compiletest/util.rs +++ b/src/compiletest/util.rs @@ -8,10 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use common::Config; - -#[cfg(target_os = "windows")] use std::env; +use common::Config; /// Conversion table from triple OS name to Rust SYSNAME const OS_TABLE: &'static [(&'static str, &'static str)] = &[ @@ -36,24 +34,20 @@ pub fn get_os(triple: &str) -> &'static str { panic!("Cannot determine OS from triple"); } -#[cfg(target_os = "windows")] pub fn make_new_path(path: &str) -> String { - + assert!(cfg!(windows)); // Windows just uses PATH as the library search path, so we have to // maintain the current value while adding our own match env::var(lib_path_env_var()) { - Ok(curr) => { - format!("{}{}{}", path, path_div(), curr) - } - Err(..) => path.to_string() + Ok(curr) => { + format!("{}{}{}", path, path_div(), curr) + } + Err(..) => path.to_string() } } -#[cfg(target_os = "windows")] pub fn lib_path_env_var() -> &'static str { "PATH" } - -#[cfg(target_os = "windows")] -pub fn path_div() -> &'static str { ";" } +fn path_div() -> &'static str { ";" } pub fn logv(config: &Config, s: String) { debug!("{}", s); diff --git a/src/doc/complement-design-faq.md b/src/doc/complement-design-faq.md index e57953db3a2..3edbcbe62c5 100644 --- a/src/doc/complement-design-faq.md +++ b/src/doc/complement-design-faq.md @@ -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. diff --git a/src/doc/grammar.md b/src/doc/grammar.md index d7a29ea5309..68ca1cb7217 100644 --- a/src/doc/grammar.md +++ b/src/doc/grammar.md @@ -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] ; ``` diff --git a/src/doc/guide-tasks.md b/src/doc/guide-tasks.md index 197559bef04..21217bf54d7 100644 --- a/src/doc/guide-tasks.md +++ b/src/doc/guide-tasks.md @@ -1,4 +1,4 @@ % The (old) Rust Threads and Communication Guide This content has moved into -[the Rust Programming Language book](book/tasks.html). +[the Rust Programming Language book](book/concurrency.html). diff --git a/src/doc/intro.md b/src/doc/intro.md index d145eaada2b..9e575abeee2 100644 --- a/src/doc/intro.md +++ b/src/doc/intro.md @@ -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,15 +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 || { - for j in 0..3 { numbers[j] += 1 } - }); + thread::scoped(move || { + numbers[i] += 1; + println!("numbers[{}] is {}", i, numbers[i]); + }) }).collect(); } ``` @@ -437,10 +438,12 @@ fn main() { It gives us this error: ```text -7:29: 9:10 error: cannot move out of captured outer variable in an `FnMut` closure -7 Thread::scoped(move || { -8 for j in 0..3 { numbers[j] += 1 } -9 }); +7:25: 10:6 error: cannot move out of captured outer variable in an `FnMut` closure +7 thread::scoped(move || { +8 numbers[i] += 1; +9 println!("numbers[{}] is {}", i, numbers[i]); +10 }) +error: aborting due to previous error ``` It mentions that "captured outer variable in an `FnMut` closure". @@ -468,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() { @@ -476,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(); } ``` @@ -532,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(); } ``` diff --git a/src/doc/reference.md b/src/doc/reference.md index 333d6fddbbd..4f5f2a631ad 100644 --- a/src/doc/reference.md +++ b/src/doc/reference.md @@ -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 @@ -764,7 +764,15 @@ usually in [procedural macros](book/plugins.html#syntax-extensions): * `quote_pat!` * `quote_stmt!` * `quote_tokens!` +* `quote_matcher!` * `quote_ty!` +* `quote_attr!` + +Keep in mind that when `$name : ident` appears in the input to +`quote_tokens!`, the result contains unquoted `name` followed by two tokens. +However, input of the same form passed to `quote_matcher!` becomes a +quasiquoted MBE-matcher of a nonterminal. No unquotation happens. Otherwise +the result of `quote_matcher!` is identical to that of `quote_tokens!`. Documentation is very limited at the moment. @@ -2421,6 +2429,10 @@ The currently implemented features of the reference compiler are: so that new attributes can be added in a bacwards compatible manner (RFC 572). +* `custom_derive` - Allows the use of `#[derive(Foo,Bar)]` as sugar for + `#[derive_Foo] #[derive_Bar]`, which can be user-defined syntax + extensions. + * `intrinsics` - Allows use of the "rust-intrinsics" ABI. Compiler intrinsics are inherently unstable and no promise about them is made. @@ -2547,6 +2559,14 @@ The currently implemented features of the reference compiler are: types, e.g. as the return type of a public function. This capability may be removed in the future. +* `allow_internal_unstable` - Allows `macro_rules!` macros to be tagged with the + `#[allow_internal_unstable]` attribute, designed + to allow `std` macros to call + `#[unstable]`/feature-gated functionality + internally without imposing on callers + (i.e. making them behave like function calls in + terms of encapsulation). + If a feature is promoted to a language feature, then all existing programs will start to receive compilation warnings about #[feature] directives which enabled the new feature (because the directive is no longer necessary). However, if a @@ -2827,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] ; ``` @@ -2987,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: ``` diff --git a/src/doc/style/errors/ergonomics.md b/src/doc/style/errors/ergonomics.md index 33f1e82b187..d2fcf27e93c 100644 --- a/src/doc/style/errors/ergonomics.md +++ b/src/doc/style/errors/ergonomics.md @@ -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)); } ``` diff --git a/src/doc/trpl/SUMMARY.md b/src/doc/trpl/SUMMARY.md index d57aff7f4f4..c65389287fb 100644 --- a/src/doc/trpl/SUMMARY.md +++ b/src/doc/trpl/SUMMARY.md @@ -16,11 +16,11 @@ * [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) diff --git a/src/doc/trpl/arrays-vectors-and-slices.md b/src/doc/trpl/arrays-vectors-and-slices.md index d4e2ad5cd5f..f1b5ecf4ff0 100644 --- a/src/doc/trpl/arrays-vectors-and-slices.md +++ b/src/doc/trpl/arrays-vectors-and-slices.md @@ -60,6 +60,12 @@ let v = vec![1, 2, 3]; // v: Vec<i32> brackets `[]` with `vec!`. Rust allows you to use either in either situation, this is just convention.) +There's an alternate form of `vec!` for repeating an initial value: + +``` +let v = vec![0; 10]; // ten zeroes +``` + You can get the length of, iterate over, and subscript vectors just like arrays. In addition, (mutable) vectors can grow automatically: diff --git a/src/doc/trpl/compound-data-types.md b/src/doc/trpl/compound-data-types.md index 85d67262c40..e09922fd390 100644 --- a/src/doc/trpl/compound-data-types.md +++ b/src/doc/trpl/compound-data-types.md @@ -6,8 +6,8 @@ strings, but next, let's talk about some more complicated ways of storing data. ## Tuples -The first compound data type we're going to talk about are called *tuples*. -Tuples are an ordered list of a fixed size. Like this: +The first compound data type we're going to talk about is called the *tuple*. +A tuple is an ordered list of fixed size. Like this: ```rust let x = (1, "hello"); @@ -229,7 +229,7 @@ enum Character { ``` An `enum` variant can be defined as most normal types. Below are some example -types have been listed which also would be allowed in an `enum`. +types which also would be allowed in an `enum`. ```rust struct Empty; diff --git a/src/doc/trpl/concurrency.md b/src/doc/trpl/concurrency.md index 842957bd601..9b6d6ca67f6 100644 --- a/src/doc/trpl/concurrency.md +++ b/src/doc/trpl/concurrency.md @@ -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: diff --git a/src/doc/trpl/crates-and-modules.md b/src/doc/trpl/crates-and-modules.md index f3c0195855c..8eaad5067f0 100644 --- a/src/doc/trpl/crates-and-modules.md +++ b/src/doc/trpl/crates-and-modules.md @@ -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. diff --git a/src/doc/trpl/documentation.md b/src/doc/trpl/documentation.md index ded30063eba..0553fe3280c 100644 --- a/src/doc/trpl/documentation.md +++ b/src/doc/trpl/documentation.md @@ -1,224 +1,223 @@ % Documentation -`rustdoc` is the built-in tool for generating documentation. It integrates -with the compiler to provide accurate hyperlinking between usage of types and -their documentation. Furthermore, by not using a separate parser, it will -never reject your valid Rust code. +Documentation is an important part of any software project, and it's +first-class in Rust. Let's talk about the tooling Rust gives you to +document your project. -# Creating Documentation +## About `rustdoc` -Documenting Rust APIs is quite simple. To document a given item, we have "doc -comments": +The Rust distribution includes a tool, `rustdoc`, that generates documentation. +`rustdoc` is also used by Cargo through `cargo doc`. -~~~ -# #![allow(unused_attribute)] -// the "link" crate attribute is currently required for rustdoc, but normally -// isn't needed. -#![crate_id = "universe"] -#![crate_type= "lib"] - -//! Tools for dealing with universes (this is a doc comment, and is shown on -//! the crate index page. The ! makes it apply to the parent of the comment, -//! rather than what follows). - -# mod workaround_the_outer_function_rustdoc_inserts { -/// Widgets are very common (this is a doc comment, and will show up on -/// Widget's documentation). -pub struct Widget { - /// All widgets have a purpose (this is a doc comment, and will show up - /// the field's documentation). - purpose: String, - /// Humans are not allowed to understand some widgets - understandable: bool -} +Documentation can be generated in two ways: from source code, and from +standalone Markdown files. -pub fn recalibrate() { - //! Recalibrate a pesky universe (this is also a doc comment, like above, - //! the documentation will be applied to the *parent* item, so - //! `recalibrate`). - /* ... */ -} -# } -~~~ +## Documenting source code -Documentation can also be controlled via the `doc` attribute on items. This is -implicitly done by the compiler when using the above form of doc comments -(converting the slash-based comments to `#[doc]` attributes). +The primary way of documenting a Rust project is through annotating the source +code. You can use documentation comments for this purpose: -~~~ -#[doc = " -Calculates the factorial of a number. +```rust,ignore +/// Constructs a new `Rc<T>`. +/// +/// # Examples +/// +/// ``` +/// use std::rc::Rc; +/// +/// let five = Rc::new(5); +/// ``` +pub fn new(value: T) -> Rc<T> { + // implementation goes here +} +``` -Given the input integer `n`, this function will calculate `n!` and return it. -"] -pub fn factorial(n: int) -> int { if n < 2 {1} else {n * factorial(n - 1)} } -# fn main() {} -~~~ +This code generates documentation that looks [like this][rc-new]. I've left the +implementation out, with a regular comment in its place. That's the first thing +to notice about this annotation: it uses `///`, instead of `//`. The triple slash +indicates a documentation comment. -The `doc` attribute can also be used to control how rustdoc emits documentation -in some cases. +Documentation comments are written in Markdown. + +Rust keeps track of these comments, and uses them when generating +documentation. This is important when documenting things like enums: ``` -// Rustdoc will inline documentation of a `pub use` into this crate when the -// `pub use` reaches across crates, but this behavior can also be disabled. -#[doc(no_inline)] -pub use std::option::Option; -# fn main() {} +/// The `Option` type. See [the module level documentation](../) for more. +enum Option<T> { + /// No value + None, + /// Some value `T` + Some(T), +} ``` -Doc comments are markdown, and are currently parsed with the -[hoedown][hoedown] library. rustdoc does not yet do any fanciness such as -referencing other items inline, like javadoc's `@see`. One exception to this -is that the first paragraph will be used as the "summary" of an item in the -generated documentation: +The above works, but this does not: -~~~ -/// A whizbang. Does stuff. (this line is the summary) -/// -/// Whizbangs are ... -struct Whizbang; -~~~ - -To generate the docs, run `rustdoc universe.rs`. By default, it generates a -directory called `doc`, with the documentation for `universe` being in -`doc/universe/index.html`. If you are using other crates with `extern crate`, -rustdoc will even link to them when you use their types, as long as their -documentation has already been generated by a previous run of rustdoc, or the -crate advertises that its documentation is hosted at a given URL. +```rust,ignore +/// The `Option` type. See [the module level documentation](../) for more. +enum Option<T> { + None, /// No value + Some(T), /// Some value `T` +} +``` -The generated output can be controlled with the `doc` crate attribute, which -is how the above advertisement works. An example from the `libstd` -documentation: +You'll get an error: -~~~ -#[doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", - html_favicon_url = "http://www.rust-lang.org/favicon.ico", - html_root_url = "http://doc.rust-lang.org/")]; -~~~ +```text +hello.rs:4:1: 4:2 error: expected ident, found `}` +hello.rs:4 } + ^ +``` -The `html_root_url` is the prefix that rustdoc will apply to any references to -that crate's types etc. +This [unfortunate error](https://github.com/rust-lang/rust/issues/22547) is +correct: documentation comments apply to the thing after them, and there's no +thing after that last comment. -rustdoc can also generate JSON, for consumption by other tools, with -`rustdoc --output-format json`, and also consume already-generated JSON with -`rustdoc --input-format json`. +[rc-new]: http://doc.rust-lang.org/nightly/std/rc/struct.Rc.html#method.new -rustdoc also supports personalizing the output from crates' documentation, -similar to markdown options. +### Writing documentation comments -- `--html-in-header FILE`: includes the contents of `FILE` at the - end of the `<head>...</head>` section. -- `--html-before-content FILE`: includes the contents of `FILE` - directly after `<body>`, before the rendered content (including the - search bar). -- `--html-after-content FILE`: includes the contents of `FILE` - after all the rendered content. +Anyway, let's cover each part of this comment in detail: -# Using the Documentation +``` +/// Constructs a new `Rc<T>`. +# fn foo() {} +``` -The web pages generated by rustdoc present the same logical hierarchy that one -writes a library with. Every kind of item (function, struct, etc) has its own -color, and one can always click on a colored type to jump to its -documentation. There is a search bar at the top, which is powered by some -JavaScript and a statically-generated search index. No special web server is -required for the search. +The first line of a documentation comment should be a short summary of its +functionality. One sentence. Just the basics. High level. -[hoedown]: https://github.com/hoedown/hoedown +``` +/// +/// Other details about constructing `Rc<T>`s, maybe describing complicated +/// semantics, maybe additional options, all kinds of stuff. +/// +# fn foo() {} +``` -# Testing the Documentation +Our original example had just a summary line, but if we had more things to say, +we could have added more explanation in a new paragraph. -`rustdoc` has support for testing code examples which appear in the -documentation. This is helpful for keeping code examples up to date with the -source code. +#### Special sections -To test documentation, the `--test` argument is passed to rustdoc: +``` +/// # Examples +# fn foo() {} +``` -~~~ {.sh} -rustdoc --test crate.rs -~~~ +Next, are special sections. These are indicated with a header, `#`. There +are three kinds of headers that are commonly used. They aren't special syntax, +just convention, for now. -## Defining tests +``` +/// # Panics +# fn foo() {} +``` -Rust documentation currently uses the markdown format, and rustdoc treats all -code blocks as testable-by-default unless they carry a language tag of another -language. In order to not run a test over a block of code, the `ignore` string -can be added to the three-backtick form of markdown code block. +Unrecoverable misuses of a function (i.e. programming errors) in Rust are +usually indicated by panics, which kill the whole current thread at the very +least. If your function has a non-trivial contract like this, that is +detected/enforced by panics, documenting it is very important. -~~~md ``` -// This is a testable code block +/// # Failures +# fn foo() {} ``` -```rust{.example} -// This is rust and also testable -``` +If your function or method returns a `Result<T, E>`, then describing the +conditions under which it returns `Err(E)` is a nice thing to do. This is +slightly less important than `Panics`, because failure is encoded into the type +system, but it's still a good thing to do. -```ignore -// This is not a testable code block +``` +/// # Safety +# fn foo() {} ``` - // This is a testable code block (4-space indent) +If your function is `unsafe`, you should explain which invariants the caller is +responsible for upholding. -```sh -# this is shell code and not tested ``` -~~~ +/// # Examples +/// +/// ``` +/// use std::rc::Rc; +/// +/// let five = Rc::new(5); +/// ``` +# fn foo() {} +``` -You can specify that the test's execution should fail with the `should_fail` -directive. +Third, `Examples`. Include one or more examples of using your function or +method, and your users will love you for it. These examples go inside of +code block annotations, which we'll talk about in a moment, and can have +more than one section: -~~~md -```should_fail -// This code block is expected to generate a panic when run ``` -~~~ +/// # Examples +/// +/// Simple `&str` patterns: +/// +/// ``` +/// let v: Vec<&str> = "Mary had a little lamb".split(' ').collect(); +/// assert_eq!(v, vec!["Mary", "had", "a", "little", "lamb"]); +/// ``` +/// +/// More complex patterns with a lambda: +/// +/// ``` +/// let v: Vec<&str> = "abc1def2ghi".split(|c: char| c.is_numeric()).collect(); +/// assert_eq!(v, vec!["abc", "def", "ghi"]); +/// ``` +# fn foo() {} +``` -You can specify that the code block should be compiled but not run with the -`no_run` directive. +Let's discuss the details of these code blocks. -~~~md -```no_run -// This code will be compiled but not executed -``` -~~~ +#### Code block annotations -Lastly, you can specify that a code block be compiled as if `--test` -were passed to the compiler using the `test_harness` directive. +To write some Rust code in a comment, use the triple graves: -~~~md -```test_harness -#[test] -fn foo() { - panic!("oops! (will run & register as a failed test)") -} ``` -~~~ +/// ``` +/// println!("Hello, world"); +/// ``` +# fn foo() {} +``` -Rustdoc also supplies some extra sugar for helping with some tedious -documentation examples. If a line is prefixed with `# `, then the line -will not show up in the HTML documentation, but it will be used when -testing the code block (NB. the space after the `#` is required, so -that one can still write things like `#[derive(Eq)]`). +If you want something that's not Rust code, you can add an annotation: -~~~md ``` -# /!\ The three following lines are comments, which are usually stripped off by -# the doc-generating tool. In order to display them anyway in this particular -# case, the character following the leading '#' is not a usual space like in -# these first five lines but a non breakable one. -# // showing 'fib' in this documentation would just be tedious and detracts from -# // what's actually being documented. -# fn fib(n: int) { n + 2 } - -spawn(move || { fib(200); }) +/// ```c +/// printf("Hello, world\n"); +/// ``` +# fn foo() {} ``` -~~~ -The documentation online would look like `spawn(move || { fib(200); })`, but when -testing this code, the `fib` function will be included (so it can compile). +This will highlight according to whatever language you're showing off. +If you're just showing plain text, choose `text`. + +It's important to choose the correct annotation here, because `rustdoc` uses it +in an interesting way: It can be used to actually test your examples, so that +they don't get out of date. If you have some C code but `rustdoc` thinks it's +Rust because you left off the annotation, `rustdoc` will complain when trying to +generate the documentation. -Rustdoc will automatically add a `main()` wrapper around your code, and in the right -place. For example: +## Documentation as tests + +Let's discuss our sample example documentation: + +``` +/// ``` +/// println!("Hello, world"); +/// ``` +# fn foo() {} +``` + +You'll notice that you don't need a `fn main()` or anything here. `rustdoc` will +automatically add a main() wrapper around your code, and in the right place. +For example: ``` /// ``` @@ -240,80 +239,286 @@ fn main() { Here's the full algorithm: -1. Given a code block, if it does not contain `fn main`, it is wrapped in `fn main() { your_code }` +1. Given a code block, if it does not contain `fn main()`, it is wrapped in + `fn main() { your_code }` 2. Given that result, if it contains no `extern crate` directives but it also contains the name of the crate being tested, then `extern crate <name>` is injected at the top. -3. Some common `allow` attributes are added for documentation examples at the top. +3. Some common allow attributes are added for documentation examples at the top. + +Sometimes, this isn't enough, though. For example, all of these code samples +with `///` we've been talking about? The raw text: + +```text +/// Some documentation. +# fn foo() {} +``` + +looks different than the output: + +``` +/// Some documentation. +# fn foo() {} +``` + +Yes, that's right: you can add lines that start with `# `, and they will +be hidden from the output, but will be used when compiling your code. You +can use this to your advantage. In this case, documentation comments need +to apply to some kind of function, so if I want to show you just a +documentation comment, I need to add a little function definition below +it. At the same time, it's just there to satisfy the compiler, so hiding +it makes the example more clear. You can use this technique to explain +longer examples in detail, while still preserving the testability of your +documentation. For example, this code: + +``` +let x = 5; +let y = 6; +println!("{}", x + y); +``` + +Here's an explanation, rendered: + +First, we set `x` to five: + +``` +let x = 5; +# let y = 6; +# println!("{}", x + y); +``` + +Next, we set `y` to six: + +``` +# let x = 5; +let y = 6; +# println!("{}", x + y); +``` + +Finally, we print the sum of `x` and `y`: + +``` +# let x = 5; +# let y = 6; +println!("{}", x + y); +``` + +Here's the same explanation, in raw text: + +> First, we set `x` to five: +> +> ```text +> let x = 5; +> # let y = 6; +> # println!("{}", x + y); +> ``` +> +> Next, we set `y` to six: +> +> ```text +> # let x = 5; +> let y = 6; +> # println!("{}", x + y); +> ``` +> +> Finally, we print the sum of `x` and `y`: +> +> ```text +> # let x = 5; +> # let y = 6; +> println!("{}", x + y); +> ``` + +By repeating all parts of the example, you can ensure that your example still +compiles, while only showing the parts that are relevant to that part of your +explanation. + +To run the tests, either + +```bash +$ rustdoc --test path/to/my/crate/root.rs +# or +$ cargo test +``` + +That's right, `cargo test` tests embedded documentation too. + +There are a few more annotations that are useful to help `rustdoc` do the right +thing when testing your code: + +``` +/// ```ignore +/// fn foo() { +/// ``` +# fn foo() {} +``` + +The `ignore` directive tells Rust to ignore your code. This is almost never +what you want, as it's the most generic. Instead, consider annotating it +with `text` if it's not code, or using `#`s to get a working example that +only shows the part you care about. + +``` +/// ```should_panic +/// assert!(false); +/// ``` +# fn foo() {} +``` + +`should_panic` tells `rustdoc` that the code should compile correctly, but +not actually pass as a test. + +``` +/// ```no_run +/// loop { +/// println!("Hello, world"); +/// } +/// ``` +# fn foo() {} +``` + +The `no_run` attribute will compile your code, but not run it. This is +important for examples such as "Here's how to start up a network service," +which you would want to make sure compile, but might run in an infinite loop! + +### Documenting modules + +Rust has another kind of doc comment, `//!`. This comment doesn't document the next item, but the enclosing item. In other words: + +``` +mod foo { + //! This is documentation for the `foo` module. + //! + //! # Examples + + // ... +} +``` + +This is where you'll see `//!` used most often: for module documentation. If +you have a module in `foo.rs`, you'll often open its code and see this: + +``` +//! A module for using `foo`s. +//! +//! The `foo` module contains a lot of useful functionality blah blah blah +``` + +### Documentation comment style + +Check out [RFC 505][rfc505] for full conventions around the style and format of +documentation. + +[rfc505]: https://github.com/rust-lang/rfcs/blob/master/text/0505-api-comment-conventions.md + +## Other documentation + +All of this behavior works in non-Rust source files too. Because comments +are written in Markdown, they're often `.md` files. + +When you write documentation in Markdown files, you don't need to prefix +the documentation with comments. For example: -## Running tests (advanced) +``` +/// # Examples +/// +/// ``` +/// use std::rc::Rc; +/// +/// let five = Rc::new(5); +/// ``` +# fn foo() {} +``` -Running tests often requires some special configuration to filter tests, find -libraries, or try running ignored examples. The testing framework that rustdoc -uses is built on crate `test`, which is also used when you compile crates with -rustc's `--test` flag. Extra arguments can be passed to rustdoc's test harness -with the `--test-args` flag. +is just -~~~console -# Only run tests containing 'foo' in their name -$ rustdoc --test lib.rs --test-args 'foo' +~~~markdown +# Examples -# See what's possible when running tests -$ rustdoc --test lib.rs --test-args '--help' +``` +use std::rc::Rc; + +let five = Rc::new(5); +``` ~~~ -When testing a library, code examples will often show how functions are used, -and this code often requires `use`-ing paths from the crate. To accommodate this, -rustdoc will implicitly add `extern crate <crate>;` where `<crate>` is the name of -the crate being tested to the top of each code example. This means that rustdoc -must be able to find a compiled version of the library crate being tested. Extra -search paths may be added via the `-L` flag to `rustdoc`. +when it's in a Markdown file. There is one wrinkle though: Markdown files need +to have a title like this: -# Standalone Markdown files +```markdown +% The title -As well as Rust crates, rustdoc supports rendering pure Markdown files -into HTML and testing the code snippets from them. A Markdown file is -detected by a `.md` or `.markdown` extension. +This is the example documentation. +``` + +This `%` line needs to be the very first line of the file. + +## `doc` attributes + +At a deeper level, documentation comments are sugar for documentation attributes: + +``` +/// this +# fn foo() {} + +#[doc="this"] +# fn bar() {} +``` -There are 4 options to modify the output that Rustdoc creates. +are the same, as are these: -- `--markdown-css PATH`: adds a `<link rel="stylesheet">` tag pointing to `PATH`. -- `--html-in-header FILE`: includes the contents of `FILE` at the - end of the `<head>...</head>` section. -- `--html-before-content FILE`: includes the contents of `FILE` - directly after `<body>`, before the rendered content (including the - title). -- `--html-after-content FILE`: includes the contents of `FILE` - directly before `</body>`, after all the rendered content. +``` +//! this -All of these can be specified multiple times, and they are output in -the order in which they are specified. The first line of the file being rendered must -be the title, prefixed with `%` (e.g. this page has `% Rust -Documentation` on the first line). +#![doc="/// this"] +``` -Like with a Rust crate, the `--test` argument will run the code -examples to check they compile, and obeys any `--test-args` flags. The -tests are named after the last `#` heading. +You won't often see this attribute used for writing documentation, but it +can be useful when changing some options, or when writing a macro. -# Re-exports +### Re-exports -Rustdoc will show the documentation for a publc re-export in both places: +`rustdoc` will show the documentation for a publc re-export in both places: -```{rust,ignore} +```ignore extern crate foo; pub use foo::bar; ``` -This will create documentation for `bar` both inside the documentation for -the crate `foo`, as well as the documentation for your crate. It will use -the same documentation in both places. +This will create documentation for bar both inside the documentation for the +crate `foo`, as well as the documentation for your crate. It will use the same +documentation in both places. This behavior can be supressed with `no_inline`: -```{rust,ignore} +```ignore extern crate foo; #[doc(no_inline)] pub use foo::bar; ``` + +### Controlling HTML + +You can control a few aspects of the HTML that `rustdoc` generates through the +`#![doc]` version of the attribute: + +``` +#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", + html_favicon_url = "http://www.rust-lang.org/favicon.ico", + html_root_url = "http://doc.rust-lang.org/")]; +``` + +This sets a few different options, with a logo, favicon, and a root URL. + +## Generation options + +`rustdoc` also contains a few other options on the command line, for further customiziation: + +- `--html-in-header FILE`: includes the contents of FILE at the end of the + `<head>...</head>` section. +- `--html-before-content FILE`: includes the contents of FILE directly after + `<body>`, before the rendered content (including the search bar). +- `--html-after-content FILE`: includes the contents of FILE after all the rendered content. + diff --git a/src/doc/trpl/method-syntax.md b/src/doc/trpl/method-syntax.md index 64d540582a3..0625d649e30 100644 --- a/src/doc/trpl/method-syntax.md +++ b/src/doc/trpl/method-syntax.md @@ -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 diff --git a/src/doc/trpl/more-strings.md b/src/doc/trpl/more-strings.md index a2a558094e1..6567cd448f9 100644 --- a/src/doc/trpl/more-strings.md +++ b/src/doc/trpl/more-strings.md @@ -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); +``` diff --git a/src/doc/trpl/plugins.md b/src/doc/trpl/plugins.md index a093b97eefb..33f0893466d 100644 --- a/src/doc/trpl/plugins.md +++ b/src/doc/trpl/plugins.md @@ -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] diff --git a/src/doc/trpl/pointers.md b/src/doc/trpl/pointers.md index e56706500a0..930a40c5050 100644 --- a/src/doc/trpl/pointers.md +++ b/src/doc/trpl/pointers.md @@ -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. diff --git a/src/doc/trpl/traits.md b/src/doc/trpl/traits.md index abd9af1af33..676f1cc425a 100644 --- a/src/doc/trpl/traits.md +++ b/src/doc/trpl/traits.md @@ -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!" +``` diff --git a/src/etc/tidy.py b/src/etc/tidy.py index fd3309dce12..c524fae7f0a 100644 --- a/src/etc/tidy.py +++ b/src/etc/tidy.py @@ -13,7 +13,7 @@ import fileinput import subprocess import re import os -from licenseck import * +from licenseck import check_license import snapshot err = 0 @@ -22,13 +22,8 @@ cr_flag = "ignore-tidy-cr" tab_flag = "ignore-tidy-tab" linelength_flag = "ignore-tidy-linelength" -# Be careful to support Python 2.4, 2.6, and 3.x here! -config_proc = subprocess.Popen(["git", "config", "core.autocrlf"], - stdout=subprocess.PIPE) -result = config_proc.communicate()[0] - -true = "true".encode('utf8') -autocrlf = result.strip() == true if result is not None else False +interesting_files = ['.rs', '.py', '.js', '.sh', '.c', '.h'] +uninteresting_files = ['miniz.c', 'jquery', 'rust_android_dummy'] def report_error_name_no(name, no, s): @@ -51,6 +46,34 @@ def do_license_check(name, contents): if not check_license(name, contents): report_error_name_no(name, 1, "incorrect license") + +def update_counts(current_name): + global file_counts + global count_other_linted_files + + _, ext = os.path.splitext(current_name) + + if ext in interesting_files: + file_counts[ext] += 1 + else: + count_other_linted_files += 1 + + +def interesting_file(f): + if any(x in f for x in uninteresting_files): + return False + + return any(os.path.splitext(f)[1] == ext for ext in interesting_files) + + +# Be careful to support Python 2.4, 2.6, and 3.x here! +config_proc = subprocess.Popen(["git", "config", "core.autocrlf"], + stdout=subprocess.PIPE) +result = config_proc.communicate()[0] + +true = "true".encode('utf8') +autocrlf = result.strip() == true if result is not None else False + current_name = "" current_contents = "" check_tab = True @@ -63,28 +86,16 @@ if len(sys.argv) < 2: src_dir = sys.argv[1] -try: - count_lines = 0 - count_non_blank_lines = 0 +count_lines = 0 +count_non_blank_lines = 0 +count_other_linted_files = 0 - interesting_files = ['.rs', '.py', '.js', '.sh', '.c', '.h'] +file_counts = {ext: 0 for ext in interesting_files} - file_counts = {ext: 0 for ext in interesting_files} - file_counts['other'] = 0 - - def update_counts(current_name): - global file_counts - _, ext = os.path.splitext(current_name) - - if ext in file_counts: - file_counts[ext] += 1 - else: - file_counts['other'] += 1 - - all_paths = set() +all_paths = set() +try: for (dirpath, dirnames, filenames) in os.walk(src_dir): - # Skip some third-party directories skippable_dirs = { 'src/jemalloc', @@ -103,14 +114,6 @@ try: if any(d in dirpath for d in skippable_dirs): continue - def interesting_file(f): - if "miniz.c" in f \ - or "jquery" in f \ - or "rust_android_dummy" in f: - return False - - return any(os.path.splitext(f)[1] == ext for ext in interesting_files) - file_names = [os.path.join(dirpath, f) for f in filenames if interesting_file(f) and not f.endswith("_gen.rs") @@ -196,10 +199,11 @@ except UnicodeDecodeError as e: report_err("UTF-8 decoding error " + str(e)) print -for ext in file_counts: - print "* linted " + str(file_counts[ext]) + " " + ext + " files" -print "* total lines of code: " + str(count_lines) -print "* total non-blank lines of code: " + str(count_non_blank_lines) +for ext in sorted(file_counts, key=file_counts.get, reverse=True): + print "* linted {} {} files".format(file_counts[ext], ext) +print "* linted {} other files".format(count_other_linted_files) +print "* total lines of code: {}".format(count_lines) +print "* total non-blank lines of code: {}".format(count_non_blank_lines) print sys.exit(err) diff --git a/src/etc/unicode.py b/src/etc/unicode.py index 5472ba3c7ed..312076b1b13 100755 --- a/src/etc/unicode.py +++ b/src/etc/unicode.py @@ -84,8 +84,8 @@ def fetch(f): sys.stderr.write("cannot load %s" % f) exit(1) -def is_valid_unicode(n): - return 0 <= n <= 0xD7FF or 0xE000 <= n <= 0x10FFFF +def is_surrogate(n): + return 0xD800 <= n <= 0xDFFF def load_unicode_data(f): fetch(f) @@ -96,19 +96,28 @@ def load_unicode_data(f): canon_decomp = {} compat_decomp = {} + udict = {}; + range_start = -1; for line in fileinput.input(f): - fields = line.split(";") - if len(fields) != 15: + data = line.split(';'); + if len(data) != 15: continue - [code, name, gencat, combine, bidi, - decomp, deci, digit, num, mirror, - old, iso, upcase, lowcase, titlecase ] = fields - - code_org = code - code = int(code, 16) - - if not is_valid_unicode(code): + cp = int(data[0], 16); + if is_surrogate(cp): continue + if range_start >= 0: + for i in xrange(range_start, cp): + udict[i] = data; + range_start = -1; + if data[1].endswith(", First>"): + range_start = cp; + continue; + udict[cp] = data; + + for code in udict: + [code_org, name, gencat, combine, bidi, + decomp, deci, digit, num, mirror, + old, iso, upcase, lowcase, titlecase ] = udict[code]; # generate char to char direct common and simple conversions # uppercase to lowercase diff --git a/src/grammar/parser-lalr.y b/src/grammar/parser-lalr.y index 6a6f7e0e9f9..6c3fd186cd4 100644 --- a/src/grammar/parser-lalr.y +++ b/src/grammar/parser-lalr.y @@ -152,6 +152,12 @@ extern char *yytext; %precedence MOD_SEP %precedence RARROW ':' +// In where clauses, "for" should have greater precedence when used as +// a higher ranked constraint than when used as the beginning of a +// for_in_type (which is a ty) +%precedence FORTYPE +%precedence FOR + // Binops & unops, and their precedences %precedence BOX %precedence BOXPLACE @@ -582,6 +588,14 @@ item_impl { $$ = mk_node("ItemImplNeg", 7, $1, $3, $5, $7, $8, $10, $11); } +| maybe_unsafe IMPL generic_params trait_ref FOR DOTDOT '{' '}' +{ + $$ = mk_node("ItemImplDefault", 3, $1, $3, $4); +} +| maybe_unsafe IMPL generic_params '!' trait_ref FOR DOTDOT '{' '}' +{ + $$ = mk_node("ItemImplDefaultNeg", 3, $1, $3, $4); +} ; maybe_impl_items @@ -769,10 +783,14 @@ where_predicates ; where_predicate -: lifetime ':' bounds { $$ = mk_node("WherePredicate", 2, $1, $3); } -| ty ':' ty_param_bounds { $$ = mk_node("WherePredicate", 2, $1, $3); } +: maybe_for_lifetimes lifetime ':' bounds { $$ = mk_node("WherePredicate", 3, $1, $2, $4); } +| maybe_for_lifetimes ty ':' ty_param_bounds { $$ = mk_node("WherePredicate", 3, $1, $2, $4); } ; +maybe_for_lifetimes +: FOR '<' lifetimes '>' { $$ = mk_none(); } +| %prec FORTYPE %empty { $$ = mk_none(); } + ty_params : ty_param { $$ = mk_node("TyParams", 1, $1); } | ty_params ',' ty_param { $$ = ext_node($1, 1, $3); } @@ -1024,7 +1042,8 @@ ty_qualified_path_and_generic_values } | ty_qualified_path ',' ty_sums maybe_bindings { - $$ = mk_node("GenericValues", 3, mk_none(), ext_node(mk_node("TySums", 1, $1), 1, $3), $4); } + $$ = mk_node("GenericValues", 3, mk_none(), mk_node("TySums", 2, $1, $3), $4); +} ; ty_qualified_path @@ -1513,31 +1532,35 @@ nonblock_prefix_expr ; expr_qualified_path -: '<' ty_sum AS trait_ref '>' MOD_SEP ident +: '<' ty_sum maybe_as_trait_ref '>' MOD_SEP ident { - $$ = mk_node("ExprQualifiedPath", 3, $2, $4, $7); + $$ = mk_node("ExprQualifiedPath", 3, $2, $3, $6); } -| '<' ty_sum AS trait_ref '>' MOD_SEP ident generic_args +| '<' ty_sum maybe_as_trait_ref '>' MOD_SEP ident generic_args { - $$ = mk_node("ExprQualifiedPath", 4, $2, $4, $7, $8); + $$ = mk_node("ExprQualifiedPath", 4, $2, $3, $6, $7); } -| SHL ty_sum AS trait_ref '>' MOD_SEP ident AS trait_ref '>' MOD_SEP ident +| SHL ty_sum maybe_as_trait_ref '>' MOD_SEP ident maybe_as_trait_ref '>' MOD_SEP ident { - $$ = mk_node("ExprQualifiedPath", 3, mk_node("ExprQualifiedPath", 3, $2, $4, $7), $9, $12); + $$ = mk_node("ExprQualifiedPath", 3, mk_node("ExprQualifiedPath", 3, $2, $3, $6), $7, $10); } -| SHL ty_sum AS trait_ref '>' MOD_SEP ident generic_args AS trait_ref '>' MOD_SEP ident +| SHL ty_sum maybe_as_trait_ref '>' MOD_SEP ident generic_args maybe_as_trait_ref '>' MOD_SEP ident { - $$ = mk_node("ExprQualifiedPath", 3, mk_node("ExprQualifiedPath", 4, $2, $4, $7, $8), $10, $13); + $$ = mk_node("ExprQualifiedPath", 3, mk_node("ExprQualifiedPath", 4, $2, $3, $6, $7), $8, $11); } -| SHL ty_sum AS trait_ref '>' MOD_SEP ident AS trait_ref '>' MOD_SEP ident generic_args +| SHL ty_sum maybe_as_trait_ref '>' MOD_SEP ident maybe_as_trait_ref '>' MOD_SEP ident generic_args { - $$ = mk_node("ExprQualifiedPath", 4, mk_node("ExprQualifiedPath", 3, $2, $4, $7), $9, $12, $13); + $$ = mk_node("ExprQualifiedPath", 4, mk_node("ExprQualifiedPath", 3, $2, $3, $6), $7, $10, $11); } -| SHL ty_sum AS trait_ref '>' MOD_SEP ident generic_args AS trait_ref '>' MOD_SEP ident generic_args +| SHL ty_sum maybe_as_trait_ref '>' MOD_SEP ident generic_args maybe_as_trait_ref '>' MOD_SEP ident generic_args { - $$ = mk_node("ExprQualifiedPath", 4, mk_node("ExprQualifiedPath", 4, $2, $4, $7, $8), $10, $13, $14); + $$ = mk_node("ExprQualifiedPath", 4, mk_node("ExprQualifiedPath", 4, $2, $3, $6, $7), $8, $11, $12); } +maybe_as_trait_ref +: AS trait_ref { $$ = $2; } +| %empty { $$ = mk_none(); } +; lambda_expr : %prec LAMBDA diff --git a/src/jemalloc b/src/jemalloc -Subproject b001609960ca33047e5cbc5a231c1e24b6041d4 +Subproject e24a1a025a1f214e40eedafe3b9c7b1d6993792 diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 630ca837daa..9351b110100 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -42,7 +42,7 @@ //! } //! ``` //! -//! This will print `Cons(1i32, Box(Cons(2i32, Box(Nil))))`. +//! This will print `Cons(1, Box(Cons(2, Box(Nil))))`. #![stable(feature = "rust1", since = "1.0.0")] diff --git a/src/liballoc/boxed_test.rs b/src/liballoc/boxed_test.rs index b7bacaa0cae..bb1ff9428a7 100644 --- a/src/liballoc/boxed_test.rs +++ b/src/liballoc/boxed_test.rs @@ -72,13 +72,13 @@ fn test_show() { #[test] fn deref() { fn homura<T: Deref<Target=i32>>(_: T) { } - homura(Box::new(765i32)); + homura(Box::new(765)); } #[test] fn raw_sized() { unsafe { - let x = Box::new(17i32); + let x = Box::new(17); let p = boxed::into_raw(x); assert_eq!(17, *p); *p = 19; diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index b1fdf139b0c..5c9a42a8a71 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -56,6 +56,8 @@ //! The [`heap`](heap/index.html) module defines the low-level interface to the //! default global allocator. It is not compatible with the libc allocator API. +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "alloc"] #![unstable(feature = "alloc")] #![feature(staged_api)] diff --git a/src/libarena/lib.rs b/src/libarena/lib.rs index 4678fe15c8b..d08c9b3257a 100644 --- a/src/libarena/lib.rs +++ b/src/libarena/lib.rs @@ -19,6 +19,8 @@ //! arena but can only hold objects of a single type, and `Arena`, which is a //! more complex, slower arena which can hold objects of any type. +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "arena"] #![unstable(feature = "rustc_private")] #![staged_api] @@ -321,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. diff --git a/src/libcollections/bit.rs b/src/libcollections/bit.rs index b0490b287ad..7524fb6cf18 100644 --- a/src/libcollections/bit.rs +++ b/src/libcollections/bit.rs @@ -118,11 +118,11 @@ fn match_words <'a,'b>(a: &'a BitVec, b: &'b BitVec) -> (MatchWords<'a>, MatchWo // have to uselessly pretend to pad the longer one for type matching if a_len < b_len { - (a.blocks().enumerate().chain(iter::repeat(0u32).enumerate().take(b_len).skip(a_len)), - b.blocks().enumerate().chain(iter::repeat(0u32).enumerate().take(0).skip(0))) + (a.blocks().enumerate().chain(iter::repeat(0).enumerate().take(b_len).skip(a_len)), + b.blocks().enumerate().chain(iter::repeat(0).enumerate().take(0).skip(0))) } else { - (a.blocks().enumerate().chain(iter::repeat(0u32).enumerate().take(0).skip(0)), - b.blocks().enumerate().chain(iter::repeat(0u32).enumerate().take(a_len).skip(b_len))) + (a.blocks().enumerate().chain(iter::repeat(0).enumerate().take(0).skip(0)), + b.blocks().enumerate().chain(iter::repeat(0).enumerate().take(a_len).skip(b_len))) } } @@ -199,7 +199,7 @@ fn blocks_for_bits(bits: usize) -> usize { /// Computes the bitmask for the final word of the vector fn mask_for_bits(bits: usize) -> u32 { // Note especially that a perfect multiple of u32::BITS should mask all 1s. - !0u32 >> (u32::BITS as usize - bits % u32::BITS as usize) % u32::BITS as usize + !0 >> (u32::BITS as usize - bits % u32::BITS as usize) % u32::BITS as usize } impl BitVec { @@ -275,7 +275,7 @@ impl BitVec { pub fn from_elem(nbits: usize, bit: bool) -> BitVec { let nblocks = blocks_for_bits(nbits); let mut bit_vec = BitVec { - storage: repeat(if bit { !0u32 } else { 0u32 }).take(nblocks).collect(), + storage: repeat(if bit { !0 } else { 0 }).take(nblocks).collect(), nbits: nbits }; bit_vec.fix_last_block(); @@ -330,7 +330,7 @@ impl BitVec { } if extra_bytes > 0 { - let mut last_word = 0u32; + let mut last_word = 0; for (i, &byte) in bytes[complete_words*4..].iter().enumerate() { last_word |= (reverse_bits(byte) as u32) << (i * 8); } @@ -431,7 +431,7 @@ impl BitVec { /// ``` #[inline] pub fn set_all(&mut self) { - for w in &mut self.storage { *w = !0u32; } + for w in &mut self.storage { *w = !0; } self.fix_last_block(); } @@ -566,12 +566,12 @@ impl BitVec { /// assert_eq!(bv.all(), false); /// ``` pub fn all(&self) -> bool { - let mut last_word = !0u32; + let mut last_word = !0; // Check that every block but the last is all-ones... self.blocks().all(|elem| { let tmp = last_word; last_word = elem; - tmp == !0u32 + tmp == !0 // and then check the last one has enough ones }) && (last_word == mask_for_bits(self.nbits)) } @@ -912,7 +912,7 @@ impl BitVec { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn clear(&mut self) { - for w in &mut self.storage { *w = 0u32; } + for w in &mut self.storage { *w = 0; } } } @@ -2313,7 +2313,7 @@ mod tests { assert_eq!(bit_vec.iter().collect::<Vec<bool>>(), bools); - let long: Vec<_> = (0i32..10000).map(|i| i % 2 == 0).collect(); + let long: Vec<_> = (0..10000).map(|i| i % 2 == 0).collect(); let bit_vec: BitVec = long.iter().map(|n| *n).collect(); assert_eq!(bit_vec.iter().collect::<Vec<bool>>(), long) } diff --git a/src/libcollections/enum_set.rs b/src/libcollections/enum_set.rs index 4c966c0d44b..68ff94cfbfb 100644 --- a/src/libcollections/enum_set.rs +++ b/src/libcollections/enum_set.rs @@ -490,7 +490,7 @@ mod test { } #[test] - #[should_fail] + #[should_panic] fn test_overflow() { #[allow(dead_code)] #[derive(Copy)] diff --git a/src/libcollections/fmt.rs b/src/libcollections/fmt.rs index 5a20ba4b49f..15a66bd80d0 100644 --- a/src/libcollections/fmt.rs +++ b/src/libcollections/fmt.rs @@ -198,7 +198,7 @@ //! // 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) //! } //! } //! @@ -226,7 +226,7 @@ //! Some examples of the output from both traits: //! //! ``` -//! assert_eq!(format!("{} {:?}", 3i32, 4i32), "3 4"); +//! assert_eq!(format!("{} {:?}", 3, 4), "3 4"); //! assert_eq!(format!("{} {:?}", 'a', 'b'), "a 'b'"); //! assert_eq!(format!("{} {:?}", "foo\n", "bar\n"), "foo\n \"bar\\n\""); //! ``` diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs index 7b66bfee34f..9c1c2cc5906 100644 --- a/src/libcollections/lib.rs +++ b/src/libcollections/lib.rs @@ -12,7 +12,8 @@ //! //! See [std::collections](../std/collections) for a detailed discussion of collections in Rust. - +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "collections"] #![unstable(feature = "collections")] #![staged_api] diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs index ecff2c7cc4b..cffa4bbfbf4 100644 --- a/src/libcollections/slice.rs +++ b/src/libcollections/slice.rs @@ -1647,14 +1647,14 @@ mod tests { } #[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 @@ mod tests { } #[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 @@ mod tests { } #[test] - #[should_fail] + #[should_panic] fn test_swap_remove_fail() { let mut v = vec![1]; let _ = v.swap_remove(0); @@ -2176,8 +2176,8 @@ mod tests { fn test_connect() { let v: [Vec<i32>; 0] = []; assert_eq!(v.connect(&0), []); - assert_eq!([vec![1i], vec![2, 3]].connect(&0), [1, 0, 2, 3]); - assert_eq!([vec![1i], vec![2], vec![3]].connect(&0), [1, 0, 2, 0, 3]); + assert_eq!([vec![1], vec![2, 3]].connect(&0), [1, 0, 2, 3]); + assert_eq!([vec![1], vec![2], vec![3]].connect(&0), [1, 0, 2, 0, 3]); let v: [&[_]; 2] = [&[1], &[2, 3]]; assert_eq!(v.connect(&0), [1, 0, 2, 3]); @@ -2205,7 +2205,7 @@ mod tests { } #[test] - #[should_fail] + #[should_panic] fn test_insert_oob() { let mut a = vec![1, 2, 3]; a.insert(4, 5); @@ -2229,7 +2229,7 @@ mod tests { } #[test] - #[should_fail] + #[should_panic] fn test_remove_fail() { let mut a = vec![1]; let _ = a.remove(0); @@ -2253,7 +2253,7 @@ mod tests { } #[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 @@ mod tests { } #[test] - #[should_fail] + #[should_panic] fn test_windowsator_0() { let v = &[1,2,3,4]; let _it = v.windows(0); @@ -2564,7 +2564,7 @@ mod tests { } #[test] - #[should_fail] + #[should_panic] fn test_chunksator_0() { let v = &[1,2,3,4]; let _it = v.chunks(0); @@ -2639,7 +2639,7 @@ mod tests { #[test] fn test_bytes_set_memory() { use slice::bytes::MutableByteVector; - let mut values = [1u8,2,3,4,5]; + let mut values = [1,2,3,4,5]; values[0..5].set_memory(0xAB); assert!(values == [0xAB, 0xAB, 0xAB, 0xAB, 0xAB]); values[2..4].set_memory(0xFF); @@ -2647,7 +2647,7 @@ mod tests { } #[test] - #[should_fail] + #[should_panic] fn test_overflow_does_not_cause_segfault() { let mut v = vec![]; v.reserve_exact(-1); @@ -2656,7 +2656,7 @@ mod tests { } #[test] - #[should_fail] + #[should_panic] fn test_overflow_does_not_cause_segfault_managed() { let mut v = vec![Rc::new(1)]; v.reserve_exact(-1); @@ -2809,31 +2809,31 @@ mod tests { fn test_mut_chunks() { use core::iter::ExactSizeIterator; - let mut v = [0u8, 1, 2, 3, 4, 5, 6]; + let mut v = [0, 1, 2, 3, 4, 5, 6]; assert_eq!(v.chunks_mut(2).len(), 4); for (i, chunk) in v.chunks_mut(3).enumerate() { for x in chunk { *x = i as u8; } } - let result = [0u8, 0, 0, 1, 1, 1, 2]; + let result = [0, 0, 0, 1, 1, 1, 2]; assert!(v == result); } #[test] fn test_mut_chunks_rev() { - let mut v = [0u8, 1, 2, 3, 4, 5, 6]; + let mut v = [0, 1, 2, 3, 4, 5, 6]; for (i, chunk) in v.chunks_mut(3).rev().enumerate() { for x in chunk { *x = i as u8; } } - let result = [2u8, 2, 2, 1, 1, 1, 0]; + let result = [2, 2, 2, 1, 1, 1, 0]; assert!(v == result); } #[test] - #[should_fail] + #[should_panic] fn test_mut_chunks_0() { let mut v = [1, 2, 3, 4]; let _it = v.chunks_mut(0); diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs index 599b92d05dd..49317a7f0ce 100644 --- a/src/libcollections/str.rs +++ b/src/libcollections/str.rs @@ -10,12 +10,15 @@ // // ignore-lexer-test FIXME #15679 -//! Unicode string manipulation (the `str` type). +//! Unicode string manipulation (the [`str`](../primitive.str.html) type). //! -//! Rust's `str` 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 -//! string (see below). As the word "borrowed" implies, this type of string is owned elsewhere, and -//! this string cannot be moved out of. +//! 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. //! //! # Examples //! @@ -383,7 +386,7 @@ macro_rules! utf8_first_byte { // return the value of $ch updated with continuation byte $byte macro_rules! utf8_acc_cont_byte { - ($ch:expr, $byte:expr) => (($ch << 6) | ($byte & 63u8) as u32) + ($ch:expr, $byte:expr) => (($ch << 6) | ($byte & 63) as u32) } #[stable(feature = "rust1", since = "1.0.0")] @@ -1083,7 +1086,7 @@ pub trait StrExt: Index<RangeFull, Output = str> { /// /// let s = "中华Việt Nam"; /// let mut i = s.len(); - /// while i < 0 { + /// while i > 0 { /// let CharRange {ch, next} = s.char_range_at_reverse(i); /// println!("{}: {}", i, ch); /// i = next; @@ -1874,7 +1877,7 @@ mod tests { } #[test] - #[should_fail] + #[should_panic] fn test_slice_fail() { "中华Việt Nam".slice(0, 2); } @@ -2092,7 +2095,7 @@ mod tests { } #[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.) @@ -2129,7 +2132,7 @@ mod tests { } #[test] - #[should_fail] + #[should_panic] fn test_subslice_offset_2() { let a = "alchemiter"; let b = "cruxtruder"; @@ -2300,8 +2303,8 @@ mod tests { #[test] fn test_chars_decoding() { - let mut bytes = [0u8; 4]; - for c in (0u32..0x110000).filter_map(|c| ::core::char::from_u32(c)) { + let mut bytes = [0; 4]; + for c in (0..0x110000).filter_map(|c| ::core::char::from_u32(c)) { let len = c.encode_utf8(&mut bytes).unwrap_or(0); let s = ::core::str::from_utf8(&bytes[..len]).unwrap(); if Some(c) != s.chars().next() { @@ -2312,8 +2315,8 @@ mod tests { #[test] fn test_chars_rev_decoding() { - let mut bytes = [0u8; 4]; - for c in (0u32..0x110000).filter_map(|c| ::core::char::from_u32(c)) { + let mut bytes = [0; 4]; + for c in (0..0x110000).filter_map(|c| ::core::char::from_u32(c)) { let len = c.encode_utf8(&mut bytes).unwrap_or(0); let s = ::core::str::from_utf8(&bytes[..len]).unwrap(); if Some(c) != s.chars().rev().next() { diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs index 33189bd68bd..83c63e47e50 100644 --- a/src/libcollections/string.rs +++ b/src/libcollections/string.rs @@ -139,7 +139,7 @@ impl String { /// ```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> { @@ -153,7 +153,7 @@ impl String { } } - const TAG_CONT_U8: u8 = 128u8; + const TAG_CONT_U8: u8 = 128; const REPLACEMENT: &'static [u8] = b"\xEF\xBF\xBD"; // U+FFFD in UTF-8 let total = v.len(); fn unsafe_get(xs: &[u8], i: usize) -> u8 { @@ -195,14 +195,14 @@ impl String { } })} - if byte < 128u8 { + if byte < 128 { // subseqidx handles this } else { let w = unicode_str::utf8_char_width(byte); match w { 2 => { - if safe_get(v, i, total) & 192u8 != TAG_CONT_U8 { + if safe_get(v, i, total) & 192 != TAG_CONT_U8 { error!(); continue; } @@ -220,7 +220,7 @@ impl String { } } i += 1; - if safe_get(v, i, total) & 192u8 != TAG_CONT_U8 { + if safe_get(v, i, total) & 192 != TAG_CONT_U8 { error!(); continue; } @@ -237,12 +237,12 @@ impl String { } } i += 1; - if safe_get(v, i, total) & 192u8 != TAG_CONT_U8 { + if safe_get(v, i, total) & 192 != TAG_CONT_U8 { error!(); continue; } i += 1; - if safe_get(v, i, total) & 192u8 != TAG_CONT_U8 { + if safe_get(v, i, total) & 192 != TAG_CONT_U8 { error!(); continue; } @@ -355,7 +355,7 @@ impl String { /// ``` /// 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 @@ impl String { /// 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 @@ impl String { /// ``` /// 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 @@ impl String { /// 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")] @@ -1084,40 +1084,40 @@ mod tests { fn test_from_utf16() { let pairs = [(String::from_str("𐍅𐌿𐌻𐍆𐌹𐌻𐌰\n"), - vec![0xd800_u16, 0xdf45_u16, 0xd800_u16, 0xdf3f_u16, - 0xd800_u16, 0xdf3b_u16, 0xd800_u16, 0xdf46_u16, - 0xd800_u16, 0xdf39_u16, 0xd800_u16, 0xdf3b_u16, - 0xd800_u16, 0xdf30_u16, 0x000a_u16]), + vec![0xd800, 0xdf45, 0xd800, 0xdf3f, + 0xd800, 0xdf3b, 0xd800, 0xdf46, + 0xd800, 0xdf39, 0xd800, 0xdf3b, + 0xd800, 0xdf30, 0x000a]), (String::from_str("𐐒𐑉𐐮𐑀𐐲𐑋 𐐏𐐲𐑍\n"), - vec![0xd801_u16, 0xdc12_u16, 0xd801_u16, - 0xdc49_u16, 0xd801_u16, 0xdc2e_u16, 0xd801_u16, - 0xdc40_u16, 0xd801_u16, 0xdc32_u16, 0xd801_u16, - 0xdc4b_u16, 0x0020_u16, 0xd801_u16, 0xdc0f_u16, - 0xd801_u16, 0xdc32_u16, 0xd801_u16, 0xdc4d_u16, - 0x000a_u16]), + vec![0xd801, 0xdc12, 0xd801, + 0xdc49, 0xd801, 0xdc2e, 0xd801, + 0xdc40, 0xd801, 0xdc32, 0xd801, + 0xdc4b, 0x0020, 0xd801, 0xdc0f, + 0xd801, 0xdc32, 0xd801, 0xdc4d, + 0x000a]), (String::from_str("𐌀𐌖𐌋𐌄𐌑𐌉·𐌌𐌄𐌕𐌄𐌋𐌉𐌑\n"), - vec![0xd800_u16, 0xdf00_u16, 0xd800_u16, 0xdf16_u16, - 0xd800_u16, 0xdf0b_u16, 0xd800_u16, 0xdf04_u16, - 0xd800_u16, 0xdf11_u16, 0xd800_u16, 0xdf09_u16, - 0x00b7_u16, 0xd800_u16, 0xdf0c_u16, 0xd800_u16, - 0xdf04_u16, 0xd800_u16, 0xdf15_u16, 0xd800_u16, - 0xdf04_u16, 0xd800_u16, 0xdf0b_u16, 0xd800_u16, - 0xdf09_u16, 0xd800_u16, 0xdf11_u16, 0x000a_u16 ]), + vec![0xd800, 0xdf00, 0xd800, 0xdf16, + 0xd800, 0xdf0b, 0xd800, 0xdf04, + 0xd800, 0xdf11, 0xd800, 0xdf09, + 0x00b7, 0xd800, 0xdf0c, 0xd800, + 0xdf04, 0xd800, 0xdf15, 0xd800, + 0xdf04, 0xd800, 0xdf0b, 0xd800, + 0xdf09, 0xd800, 0xdf11, 0x000a ]), (String::from_str("𐒋𐒘𐒈𐒑𐒛𐒒 𐒕𐒓 𐒈𐒚𐒍 𐒏𐒜𐒒𐒖𐒆 𐒕𐒆\n"), - vec![0xd801_u16, 0xdc8b_u16, 0xd801_u16, 0xdc98_u16, - 0xd801_u16, 0xdc88_u16, 0xd801_u16, 0xdc91_u16, - 0xd801_u16, 0xdc9b_u16, 0xd801_u16, 0xdc92_u16, - 0x0020_u16, 0xd801_u16, 0xdc95_u16, 0xd801_u16, - 0xdc93_u16, 0x0020_u16, 0xd801_u16, 0xdc88_u16, - 0xd801_u16, 0xdc9a_u16, 0xd801_u16, 0xdc8d_u16, - 0x0020_u16, 0xd801_u16, 0xdc8f_u16, 0xd801_u16, - 0xdc9c_u16, 0xd801_u16, 0xdc92_u16, 0xd801_u16, - 0xdc96_u16, 0xd801_u16, 0xdc86_u16, 0x0020_u16, - 0xd801_u16, 0xdc95_u16, 0xd801_u16, 0xdc86_u16, - 0x000a_u16 ]), + vec![0xd801, 0xdc8b, 0xd801, 0xdc98, + 0xd801, 0xdc88, 0xd801, 0xdc91, + 0xd801, 0xdc9b, 0xd801, 0xdc92, + 0x0020, 0xd801, 0xdc95, 0xd801, + 0xdc93, 0x0020, 0xd801, 0xdc88, + 0xd801, 0xdc9a, 0xd801, 0xdc8d, + 0x0020, 0xd801, 0xdc8f, 0xd801, + 0xdc9c, 0xd801, 0xdc92, 0xd801, + 0xdc96, 0xd801, 0xdc86, 0x0020, + 0xd801, 0xdc95, 0xd801, 0xdc86, + 0x000a ]), // Issue #12318, even-numbered non-BMP planes (String::from_str("\u{20000}"), vec![0xD840, 0xDC00])]; @@ -1232,14 +1232,14 @@ mod tests { } #[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 @@ mod tests { assert_eq!(s, "ไทย中华Vit Nam; foobar"); } - #[test] #[should_fail] + #[test] #[should_panic] fn remove_bad() { "ศ".to_string().remove(1); } @@ -1286,8 +1286,8 @@ mod tests { 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() { @@ -1303,7 +1303,7 @@ mod tests { assert_eq!(1.to_string(), "1"); assert_eq!((-1).to_string(), "-1"); assert_eq!(200.to_string(), "200"); - assert_eq!(2u8.to_string(), "2"); + assert_eq!(2.to_string(), "2"); assert_eq!(true.to_string(), "true"); assert_eq!(false.to_string(), "false"); assert_eq!(("hi".to_string()).to_string(), "hi"); @@ -1421,7 +1421,7 @@ mod tests { #[bench] fn from_utf8_lossy_100_invalid(b: &mut Bencher) { - let s = repeat(0xf5u8).take(100).collect::<Vec<_>>(); + let s = repeat(0xf5).take(100).collect::<Vec<_>>(); b.iter(|| { let _ = String::from_utf8_lossy(&s); }); diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index 2e947ea2460..ca0092a6e66 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -2242,7 +2242,7 @@ mod tests { } #[test] - #[should_fail] + #[should_panic] fn test_vec_truncate_fail() { struct BadElem(i32); impl Drop for BadElem { @@ -2265,49 +2265,49 @@ mod tests { } #[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 @@ mod tests { } #[test] - #[should_fail] + #[should_panic] fn test_map_in_place_incompatible_types_fail() { let v = vec![0, 1, 2]; v.map_in_place(|_| ()); diff --git a/src/libcollections/vec_deque.rs b/src/libcollections/vec_deque.rs index 551d28b91b4..cab589d55be 100644 --- a/src/libcollections/vec_deque.rs +++ b/src/libcollections/vec_deque.rs @@ -1884,7 +1884,7 @@ mod tests { } #[test] - #[should_fail] + #[should_panic] fn test_index_out_of_bounds() { let mut deq = VecDeque::new(); for i in 1..4 { diff --git a/src/libcollections/vec_map.rs b/src/libcollections/vec_map.rs index 515de74e340..431c8d5df8c 100644 --- a/src/libcollections/vec_map.rs +++ b/src/libcollections/vec_map.rs @@ -1432,7 +1432,7 @@ mod test_map { } #[test] - #[should_fail] + #[should_panic] fn test_index_nonexistent() { let mut map = VecMap::new(); diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index b8a22c30f9e..4f77a20c7ca 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -631,9 +631,6 @@ impl<'b, T> DerefMut for RefMut<'b, 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 /// /// ``` diff --git a/src/libcore/char.rs b/src/libcore/char.rs index 8e27ae1cea9..973070677d8 100644 --- a/src/libcore/char.rs +++ b/src/libcore/char.rs @@ -22,13 +22,13 @@ use option::Option; use slice::SliceExt; // UTF-8 ranges and tags for encoding characters -const TAG_CONT: u8 = 0b1000_0000u8; -const TAG_TWO_B: u8 = 0b1100_0000u8; -const TAG_THREE_B: u8 = 0b1110_0000u8; -const TAG_FOUR_B: u8 = 0b1111_0000u8; -const MAX_ONE_B: u32 = 0x80u32; -const MAX_TWO_B: u32 = 0x800u32; -const MAX_THREE_B: u32 = 0x10000u32; +const TAG_CONT: u8 = 0b1000_0000; +const TAG_TWO_B: u8 = 0b1100_0000; +const TAG_THREE_B: u8 = 0b1110_0000; +const TAG_FOUR_B: u8 = 0b1111_0000; +const MAX_ONE_B: u32 = 0x80; +const MAX_TWO_B: u32 = 0x800; +const MAX_THREE_B: u32 = 0x10000; /* Lu Uppercase_Letter an uppercase letter @@ -413,7 +413,7 @@ impl CharExt for char { #[stable(feature = "rust1", since = "1.0.0")] fn len_utf16(self) -> usize { let ch = self as u32; - if (ch & 0xFFFF_u32) == ch { 1 } else { 2 } + if (ch & 0xFFFF) == ch { 1 } else { 2 } } #[inline] @@ -444,19 +444,19 @@ pub fn encode_utf8_raw(code: u32, dst: &mut [u8]) -> Option<usize> { dst[0] = code as u8; Some(1) } else if code < MAX_TWO_B && dst.len() >= 2 { - dst[0] = (code >> 6 & 0x1F_u32) as u8 | TAG_TWO_B; - dst[1] = (code & 0x3F_u32) as u8 | TAG_CONT; + dst[0] = (code >> 6 & 0x1F) as u8 | TAG_TWO_B; + dst[1] = (code & 0x3F) as u8 | TAG_CONT; Some(2) } else if code < MAX_THREE_B && dst.len() >= 3 { - dst[0] = (code >> 12 & 0x0F_u32) as u8 | TAG_THREE_B; - dst[1] = (code >> 6 & 0x3F_u32) as u8 | TAG_CONT; - dst[2] = (code & 0x3F_u32) as u8 | TAG_CONT; + dst[0] = (code >> 12 & 0x0F) as u8 | TAG_THREE_B; + dst[1] = (code >> 6 & 0x3F) as u8 | TAG_CONT; + dst[2] = (code & 0x3F) as u8 | TAG_CONT; Some(3) } else if dst.len() >= 4 { - dst[0] = (code >> 18 & 0x07_u32) as u8 | TAG_FOUR_B; - dst[1] = (code >> 12 & 0x3F_u32) as u8 | TAG_CONT; - dst[2] = (code >> 6 & 0x3F_u32) as u8 | TAG_CONT; - dst[3] = (code & 0x3F_u32) as u8 | TAG_CONT; + dst[0] = (code >> 18 & 0x07) as u8 | TAG_FOUR_B; + dst[1] = (code >> 12 & 0x3F) as u8 | TAG_CONT; + dst[2] = (code >> 6 & 0x3F) as u8 | TAG_CONT; + dst[3] = (code & 0x3F) as u8 | TAG_CONT; Some(4) } else { None @@ -472,15 +472,15 @@ pub fn encode_utf8_raw(code: u32, dst: &mut [u8]) -> Option<usize> { #[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_u32) == ch && dst.len() >= 1 { + if (ch & 0xFFFF) == ch && dst.len() >= 1 { // The BMP falls through (assuming non-surrogate, as it should) dst[0] = ch as u16; Some(1) } else if dst.len() >= 2 { // Supplementary planes break into surrogates. - ch -= 0x1_0000_u32; - dst[0] = 0xD800_u16 | ((ch >> 10) as u16); - dst[1] = 0xDC00_u16 | ((ch as u16) & 0x3FF_u16); + ch -= 0x1_0000; + dst[0] = 0xD800 | ((ch >> 10) as u16); + dst[1] = 0xDC00 | ((ch as u16) & 0x3FF); Some(2) } else { None diff --git a/src/libcore/fmt/float.rs b/src/libcore/fmt/float.rs index 2eeb564859c..0df04c296c8 100644 --- a/src/libcore/fmt/float.rs +++ b/src/libcore/fmt/float.rs @@ -123,13 +123,13 @@ pub fn float_to_str_bytes_common<T: Float, U, F>( // For an f64 the exponent is in the range of [-1022, 1023] for base 2, so // we may have up to that many digits. Give ourselves some extra wiggle room // otherwise as well. - let mut buf = [0u8; 1536]; + let mut buf = [0; 1536]; let mut end = 0; let radix_gen: T = cast(radix as int).unwrap(); let (num, exp) = match exp_format { - ExpNone => (num, 0i32), - ExpDec if num == _0 => (num, 0i32), + ExpNone => (num, 0), + ExpDec if num == _0 => (num, 0), ExpDec => { let (exp, exp_base) = match exp_format { ExpDec => (num.abs().log10().floor(), cast::<f64, T>(10.0f64).unwrap()), diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index 9544fbaa55b..e640bf02f5a 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -565,7 +565,7 @@ impl<'a> Formatter<'a> { Alignment::Center => (padding / 2, (padding + 1) / 2), }; - let mut fill = [0u8; 4]; + let mut fill = [0; 4]; let len = self.fill.encode_utf8(&mut fill).unwrap_or(0); let fill = unsafe { str::from_utf8_unchecked(&fill[..len]) }; @@ -689,7 +689,7 @@ impl Debug for char { #[stable(feature = "rust1", since = "1.0.0")] impl Display for char { fn fmt(&self, f: &mut Formatter) -> Result { - let mut utf8 = [0u8; 4]; + let mut utf8 = [0; 4]; let amt = self.encode_utf8(&mut utf8).unwrap_or(0); let s: &str = unsafe { mem::transmute(&utf8[..amt]) }; Display::fmt(s, f) diff --git a/src/libcore/fmt/num.rs b/src/libcore/fmt/num.rs index 045442e28ac..b3f2302bb3e 100644 --- a/src/libcore/fmt/num.rs +++ b/src/libcore/fmt/num.rs @@ -38,7 +38,7 @@ trait GenericRadix { // characters for a base 2 number. let zero = Int::zero(); let is_positive = x >= zero; - let mut buf = [0u8; 64]; + let mut buf = [0; 64]; let mut curr = buf.len(); let base = cast(self.base()).unwrap(); if is_positive { diff --git a/src/libcore/hash/sip.rs b/src/libcore/hash/sip.rs index df0008c500b..bd1516e0cfc 100644 --- a/src/libcore/hash/sip.rs +++ b/src/libcore/hash/sip.rs @@ -60,7 +60,7 @@ macro_rules! u8to64_le { ($buf:expr, $i:expr, $len:expr) => ({ let mut t = 0; - let mut out = 0u64; + let mut out = 0; while t < $len { out |= ($buf[t+$i] as u64) << t*8; t += 1; diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs index ed129136091..7fccb93f2a0 100644 --- a/src/libcore/intrinsics.rs +++ b/src/libcore/intrinsics.rs @@ -230,7 +230,7 @@ extern "rust-intrinsic" { /// use std::mem; /// /// let v: &[u8] = unsafe { mem::transmute("L") }; - /// assert!(v == [76u8]); + /// assert!(v == [76]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn transmute<T,U>(e: T) -> U; @@ -545,11 +545,7 @@ extern "rust-intrinsic" { 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. diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index 767828408be..d5e891a156e 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -611,7 +611,7 @@ pub trait IteratorExt: Iterator + Sized { /// /// ``` /// 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")] @@ -1149,7 +1149,7 @@ pub trait AdditiveIterator<A> { /// ``` /// use std::iter::AdditiveIterator; /// - /// let a = [1i32, 2, 3, 4, 5]; + /// let a = [1, 2, 3, 4, 5]; /// let mut it = a.iter().cloned(); /// assert!(it.sum() == 15); /// ``` @@ -1279,14 +1279,14 @@ pub struct Cloned<I> { } #[stable(feature = "rust1", since = "1.0.0")] -impl<T, D, I> Iterator for Cloned<I> where - T: Clone, - D: Deref<Target=T>, - I: Iterator<Item=D>, +impl<I> Iterator for Cloned<I> where + I: Iterator, + I::Item: Deref, + <I::Item as Deref>::Target: Clone { - type Item = T; + type Item = <I::Item as Deref>::Target; - fn next(&mut self) -> Option<T> { + fn next(&mut self) -> Option<<Self as Iterator>::Item> { self.it.next().cloned() } @@ -1296,28 +1296,28 @@ impl<T, D, I> Iterator for Cloned<I> where } #[stable(feature = "rust1", since = "1.0.0")] -impl<T, D, I> DoubleEndedIterator for Cloned<I> where - T: Clone, - D: Deref<Target=T>, - I: DoubleEndedIterator<Item=D>, +impl<I> DoubleEndedIterator for Cloned<I> where + I: DoubleEndedIterator, + I::Item: Deref, + <I::Item as Deref>::Target: Clone { - fn next_back(&mut self) -> Option<T> { + fn next_back(&mut self) -> Option<<Self as Iterator>::Item> { self.it.next_back().cloned() } } #[stable(feature = "rust1", since = "1.0.0")] -impl<T, D, I> ExactSizeIterator for Cloned<I> where - T: Clone, - D: Deref<Target=T>, - I: ExactSizeIterator<Item=D>, +impl<I> ExactSizeIterator for Cloned<I> where + I: ExactSizeIterator, + I::Item: Deref, + <I::Item as Deref>::Target: Clone {} #[unstable(feature = "core", reason = "trait is experimental")] -impl<T, D, I> RandomAccessIterator for Cloned<I> where - T: Clone, - D: Deref<Target=T>, - I: RandomAccessIterator<Item=D> +impl<I> RandomAccessIterator for Cloned<I> where + I: RandomAccessIterator, + I::Item: Deref, + <I::Item as Deref>::Target: Clone { #[inline] fn indexable(&self) -> usize { @@ -1325,7 +1325,7 @@ impl<T, D, I> RandomAccessIterator for Cloned<I> where } #[inline] - fn idx(&mut self, index: usize) -> Option<T> { + fn idx(&mut self, index: usize) -> Option<<Self as Iterator>::Item> { self.it.idx(index).cloned() } } @@ -1400,11 +1400,14 @@ pub struct Chain<A, B> { } #[stable(feature = "rust1", since = "1.0.0")] -impl<T, A, B> Iterator for Chain<A, B> where A: Iterator<Item=T>, B: Iterator<Item=T> { - type Item = T; +impl<A, B> Iterator for Chain<A, B> where + A: Iterator, + B: Iterator<Item = A::Item> +{ + type Item = A::Item; #[inline] - fn next(&mut self) -> Option<T> { + fn next(&mut self) -> Option<A::Item> { if self.flag { self.b.next() } else { @@ -1434,12 +1437,12 @@ impl<T, A, B> Iterator for Chain<A, B> where A: Iterator<Item=T>, B: Iterator<It } #[stable(feature = "rust1", since = "1.0.0")] -impl<T, A, B> DoubleEndedIterator for Chain<A, B> where - A: DoubleEndedIterator<Item=T>, - B: DoubleEndedIterator<Item=T>, +impl<A, B> DoubleEndedIterator for Chain<A, B> where + A: DoubleEndedIterator, + B: DoubleEndedIterator<Item=A::Item>, { #[inline] - fn next_back(&mut self) -> Option<T> { + fn next_back(&mut self) -> Option<A::Item> { match self.b.next_back() { Some(x) => Some(x), None => self.a.next_back() @@ -1448,9 +1451,9 @@ impl<T, A, B> DoubleEndedIterator for Chain<A, B> where } #[unstable(feature = "core", reason = "trait is experimental")] -impl<T, A, B> RandomAccessIterator for Chain<A, B> where - A: RandomAccessIterator<Item=T>, - B: RandomAccessIterator<Item=T>, +impl<A, B> RandomAccessIterator for Chain<A, B> where + A: RandomAccessIterator, + B: RandomAccessIterator<Item = A::Item>, { #[inline] fn indexable(&self) -> usize { @@ -1459,7 +1462,7 @@ impl<T, A, B> RandomAccessIterator for Chain<A, B> where } #[inline] - fn idx(&mut self, index: usize) -> Option<T> { + fn idx(&mut self, index: usize) -> Option<A::Item> { let len = self.a.indexable(); if index < len { self.a.idx(index) @@ -1479,14 +1482,12 @@ pub struct Zip<A, B> { } #[stable(feature = "rust1", since = "1.0.0")] -impl<T, U, A, B> Iterator for Zip<A, B> where - A: Iterator<Item = T>, - B: Iterator<Item = U>, +impl<A, B> Iterator for Zip<A, B> where A: Iterator, B: Iterator { - type Item = (T, U); + type Item = (A::Item, B::Item); #[inline] - fn next(&mut self) -> Option<(T, U)> { + fn next(&mut self) -> Option<(A::Item, B::Item)> { match self.a.next() { None => None, Some(x) => match self.b.next() { @@ -1515,12 +1516,12 @@ impl<T, U, A, B> Iterator for Zip<A, B> where } #[stable(feature = "rust1", since = "1.0.0")] -impl<T, U, A, B> DoubleEndedIterator for Zip<A, B> where - A: DoubleEndedIterator + ExactSizeIterator<Item=T>, - B: DoubleEndedIterator + ExactSizeIterator<Item=U>, +impl<A, B> DoubleEndedIterator for Zip<A, B> where + A: DoubleEndedIterator + ExactSizeIterator, + B: DoubleEndedIterator + ExactSizeIterator, { #[inline] - fn next_back(&mut self) -> Option<(T, U)> { + fn next_back(&mut self) -> Option<(A::Item, B::Item)> { let a_sz = self.a.len(); let b_sz = self.b.len(); if a_sz != b_sz { @@ -1540,9 +1541,9 @@ impl<T, U, A, B> DoubleEndedIterator for Zip<A, B> where } #[unstable(feature = "core", reason = "trait is experimental")] -impl<T, U, A, B> RandomAccessIterator for Zip<A, B> where - A: RandomAccessIterator<Item=T>, - B: RandomAccessIterator<Item=U>, +impl<A, B> RandomAccessIterator for Zip<A, B> where + A: RandomAccessIterator, + B: RandomAccessIterator { #[inline] fn indexable(&self) -> usize { @@ -1550,7 +1551,7 @@ impl<T, U, A, B> RandomAccessIterator for Zip<A, B> where } #[inline] - fn idx(&mut self, index: usize) -> Option<(T, U)> { + fn idx(&mut self, index: usize) -> Option<(A::Item, B::Item)> { match self.a.idx(index) { None => None, Some(x) => match self.b.idx(index) { @@ -2058,8 +2059,9 @@ pub struct Scan<I, St, F> { } #[stable(feature = "rust1", since = "1.0.0")] -impl<A, B, I: Iterator<Item=A>, St, F> Iterator for Scan<I, St, F> where - F: FnMut(&mut St, A) -> Option<B>, +impl<B, I, St, F> Iterator for Scan<I, St, F> where + I: Iterator, + F: FnMut(&mut St, I::Item) -> Option<B>, { type Item = B; diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 94d37cee5b3..45a5563ceeb 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -35,8 +35,7 @@ //! often generated by LLVM. Additionally, this library can make explicit //! calls to these functions. Their signatures are the same as found in C. //! These functions are often provided by the system libc, but can also be -//! provided by `librlibc` which is distributed with the standard rust -//! distribution. +//! provided by the [rlibc crate](https://crates.io/crates/rlibc). //! //! * `rust_begin_unwind` - This function takes three arguments, a //! `fmt::Arguments`, a `&str`, and a `usize`. These three arguments dictate @@ -47,6 +46,8 @@ // Since libcore defines many fundamental lang items, all tests live in a // separate crate, libcoretest, to avoid bizarre issues. +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "core"] #![unstable(feature = "core")] #![staged_api] diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs index 94ca9ec37b4..c2860d43511 100644 --- a/src/libcore/macros.rs +++ b/src/libcore/macros.rs @@ -100,10 +100,12 @@ macro_rules! assert_eq { /// This will invoke the `panic!` macro if the provided expression cannot be /// evaluated to `true` at runtime. /// -/// Unlike `assert!`, `debug_assert!` statements can be disabled by passing -/// `--cfg ndebug` to the compiler. This makes `debug_assert!` useful for -/// checks that are too expensive to be present in a release build but may be -/// helpful during development. +/// Unlike `assert!`, `debug_assert!` statements are only enabled in non +/// optimized builds by default. An optimized build will omit all +/// `debug_assert!` statements unless `-C debug-assertions` is passed to the +/// compiler. This makes `debug_assert!` useful for checks that are too +/// expensive to be present in a release build but may be helpful during +/// development. /// /// # Example /// @@ -125,7 +127,7 @@ macro_rules! assert_eq { #[macro_export] #[stable(feature = "rust1", since = "1.0.0")] macro_rules! debug_assert { - ($($arg:tt)*) => (if cfg!(not(ndebug)) { assert!($($arg)*); }) + ($($arg:tt)*) => (if cfg!(debug_assertions) { assert!($($arg)*); }) } /// Asserts that two expressions are equal to each other, testing equality in @@ -133,10 +135,12 @@ macro_rules! debug_assert { /// /// On panic, this macro will print the values of the expressions. /// -/// Unlike `assert_eq!`, `debug_assert_eq!` statements can be disabled by -/// passing `--cfg ndebug` to the compiler. This makes `debug_assert_eq!` -/// useful for checks that are too expensive to be present in a release build -/// but may be helpful during development. +/// Unlike `assert_eq!`, `debug_assert_eq!` statements are only enabled in non +/// optimized builds by default. An optimized build will omit all +/// `debug_assert_eq!` statements unless `-C debug-assertions` is passed to the +/// compiler. This makes `debug_assert_eq!` useful for checks that are too +/// expensive to be present in a release build but may be helpful during +/// development. /// /// # Example /// @@ -147,7 +151,7 @@ macro_rules! debug_assert { /// ``` #[macro_export] macro_rules! debug_assert_eq { - ($($arg:tt)*) => (if cfg!(not(ndebug)) { assert_eq!($($arg)*); }) + ($($arg:tt)*) => (if cfg!(debug_assertions) { assert_eq!($($arg)*); }) } /// Short circuiting evaluation on Err @@ -227,7 +231,7 @@ macro_rules! writeln { /// /// ```rust /// fn divide_by_three(x: u32) -> u32 { // one of the poorest implementations of x/3 -/// for i in std::iter::count(0_u32, 1) { +/// for i in std::iter::count(0, 1) { /// if 3*i < i { panic!("u32 overflow"); } /// if x < 3*i { return i-1; } /// } diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs index 868a671b956..fe53ea1f0af 100644 --- a/src/libcore/marker.rs +++ b/src/libcore/marker.rs @@ -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 diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 92cdd84160b..752eca797bd 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -1238,6 +1238,7 @@ pub fn from_f64<A: FromPrimitive>(n: f64) -> Option<A> { macro_rules! impl_from_primitive { ($T:ty, $to_ty:ident) => ( + #[allow(deprecated)] impl FromPrimitive for $T { #[inline] fn from_int(n: int) -> Option<$T> { n.$to_ty() } #[inline] fn from_i8(n: i8) -> Option<$T> { n.$to_ty() } @@ -1299,6 +1300,7 @@ macro_rules! impl_num_cast { ($T:ty, $conv:ident) => ( impl NumCast for $T { #[inline] + #[allow(deprecated)] fn from<N: ToPrimitive>(n: N) -> Option<$T> { // `$conv` could be generated using `concat_idents!`, but that // macro seems to be broken at the moment @@ -1515,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> { diff --git a/src/libcore/num/wrapping.rs b/src/libcore/num/wrapping.rs index 707e41a948b..f8fc4ef27a1 100644 --- a/src/libcore/num/wrapping.rs +++ b/src/libcore/num/wrapping.rs @@ -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 @@ macro_rules! wrapping_impl { )*) } -#[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")] diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs index c382ac46d5d..4116d8be9fb 100644 --- a/src/libcore/ops.rs +++ b/src/libcore/ops.rs @@ -913,6 +913,7 @@ shr_impl_all! { u8 u16 u32 u64 usize i8 i16 i32 i64 isize } #[stable(feature = "rust1", since = "1.0.0")] pub trait Index<Idx: ?Sized> { /// The returned type after indexing + #[stable(feature = "rust1", since = "1.0.0")] type Output: ?Sized; /// The method for the indexing (`Foo[Bar]`) operation diff --git a/src/libcore/option.rs b/src/libcore/option.rs index 1ecbd8fae8c..5343cdaaf08 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -385,7 +385,7 @@ impl<T> Option<T> { /// # Example /// /// ``` - /// let k = 10i32; + /// let k = 10; /// assert_eq!(Some(4).unwrap_or_else(|| 2 * k), 4); /// assert_eq!(None.unwrap_or_else(|| 2 * k), 20); /// ``` diff --git a/src/libcore/result.rs b/src/libcore/result.rs index b8271562d2e..6c3afdf8849 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -178,13 +178,13 @@ //! 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)); //! } //! ``` //! @@ -202,9 +202,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(()); //! } //! ``` diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index 4f4164f673b..1d4b81512dd 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -1119,9 +1119,9 @@ pub struct CharRange { } /// Mask of the value bits of a continuation byte -const CONT_MASK: u8 = 0b0011_1111u8; +const CONT_MASK: u8 = 0b0011_1111; /// Value of the tag bits (tag mask is !CONT_MASK) of a continuation byte -const TAG_CONT_U8: u8 = 0b1000_0000u8; +const TAG_CONT_U8: u8 = 0b1000_0000; /* Section: Trait implementations @@ -1568,7 +1568,7 @@ impl StrExt for str { if index == self.len() { return true; } match self.as_bytes().get(index) { None => false, - Some(&b) => b < 128u8 || b >= 192u8, + Some(&b) => b < 128 || b >= 192, } } @@ -1680,7 +1680,7 @@ impl StrExt for str { #[inline] #[unstable(feature = "core")] pub fn char_range_at_raw(bytes: &[u8], i: usize) -> (u32, usize) { - if bytes[i] < 128u8 { + if bytes[i] < 128 { return (bytes[i] as u32, i + 1); } diff --git a/src/libcoretest/cell.rs b/src/libcoretest/cell.rs index 317ef3a5701..3397cbb18fa 100644 --- a/src/libcoretest/cell.rs +++ b/src/libcoretest/cell.rs @@ -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(); diff --git a/src/libcoretest/char.rs b/src/libcoretest/char.rs index 32dc6440b13..46d1f7ff3ae 100644 --- a/src/libcoretest/char.rs +++ b/src/libcoretest/char.rs @@ -165,7 +165,7 @@ fn test_escape_unicode() { #[test] fn test_encode_utf8() { fn check(input: char, expect: &[u8]) { - let mut buf = [0u8; 4]; + let mut buf = [0; 4]; let n = input.encode_utf8(&mut buf).unwrap_or(0); assert_eq!(&buf[..n], expect); } @@ -179,7 +179,7 @@ fn test_encode_utf8() { #[test] fn test_encode_utf16() { fn check(input: char, expect: &[u16]) { - let mut buf = [0u16; 2]; + let mut buf = [0; 2]; let n = input.encode_utf16(&mut buf).unwrap_or(0); assert_eq!(&buf[..n], expect); } diff --git a/src/libcoretest/finally.rs b/src/libcoretest/finally.rs index 55fcb849851..2a48395271d 100644 --- a/src/libcoretest/finally.rs +++ b/src/libcoretest/finally.rs @@ -30,7 +30,7 @@ fn test_success() { } #[test] -#[should_fail] +#[should_panic] fn test_fail() { let mut i = 0; try_finally( diff --git a/src/libcoretest/fmt/num.rs b/src/libcoretest/fmt/num.rs index bc3995439a0..7db8db444ff 100644 --- a/src/libcoretest/fmt/num.rs +++ b/src/libcoretest/fmt/num.rs @@ -161,7 +161,7 @@ fn test_format_radix() { } #[test] -#[should_fail] +#[should_panic] fn test_radix_base_too_large() { let _ = radix(55, 37); } diff --git a/src/libcoretest/hash/mod.rs b/src/libcoretest/hash/mod.rs index da96680d84b..5c11f0196ae 100644 --- a/src/libcoretest/hash/mod.rs +++ b/src/libcoretest/hash/mod.rs @@ -62,10 +62,10 @@ fn test_writer_hasher() { // FIXME (#18283) Enable test //let s: Box<str> = box "a"; //assert_eq!(hasher.hash(& s), 97 + 0xFF); - let cs: &[u8] = &[1u8, 2u8, 3u8]; + let cs: &[u8] = &[1, 2, 3]; assert_eq!(hash(& cs), 9); // FIXME (#22405): Replace `Box::new` with `box` here when/if possible. - let cs: Box<[u8]> = Box::new([1u8, 2u8, 3u8]); + let cs: Box<[u8]> = Box::new([1, 2, 3]); assert_eq!(hash(& cs), 9); // FIXME (#18248) Add tests for hashing Rc<str> and Rc<[T]> @@ -86,7 +86,7 @@ struct CustomHasher { output: u64 } impl Hasher for CustomHasher { fn finish(&self) -> u64 { self.output } - fn write(&mut self, data: &[u8]) { panic!() } + fn write(&mut self, _: &[u8]) { panic!() } fn write_u64(&mut self, data: u64) { self.output = data; } } diff --git a/src/libcoretest/hash/sip.rs b/src/libcoretest/hash/sip.rs index 248cad32ef4..8289d06d04c 100644 --- a/src/libcoretest/hash/sip.rs +++ b/src/libcoretest/hash/sip.rs @@ -100,8 +100,8 @@ fn test_siphash() { [ 0x72, 0x45, 0x06, 0xeb, 0x4c, 0x32, 0x8a, 0x95, ] ]; - let k0 = 0x_07_06_05_04_03_02_01_00_u64; - let k1 = 0x_0f_0e_0d_0c_0b_0a_09_08_u64; + let k0 = 0x_07_06_05_04_03_02_01_00; + let k1 = 0x_0f_0e_0d_0c_0b_0a_09_08; let mut buf = Vec::new(); let mut t = 0; let mut state_inc = SipState::new_with_keys(k0, k1); @@ -230,8 +230,8 @@ fn test_hash_no_concat_alias() { assert!(s != t && t != u); assert!(hash(&s) != hash(&t) && hash(&s) != hash(&u)); - let v: (&[u8], &[u8], &[u8]) = (&[1u8], &[0u8, 0], &[0u8]); - let w: (&[u8], &[u8], &[u8]) = (&[1u8, 0, 0, 0], &[], &[]); + let v: (&[u8], &[u8], &[u8]) = (&[1], &[0, 0], &[0]); + let w: (&[u8], &[u8], &[u8]) = (&[1, 0, 0, 0], &[], &[]); assert!(v != w); assert!(hash(&v) != hash(&w)); diff --git a/src/libcoretest/iter.rs b/src/libcoretest/iter.rs index b1b10b582e5..0f4e7fcdda5 100644 --- a/src/libcoretest/iter.rs +++ b/src/libcoretest/iter.rs @@ -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), @@ -778,9 +778,9 @@ fn test_range_step() { assert_eq!(range_step(0, 20, 5).collect::<Vec<int>>(), [0, 5, 10, 15]); assert_eq!(range_step(20, 0, -5).collect::<Vec<int>>(), [20, 15, 10, 5]); assert_eq!(range_step(20, 0, -6).collect::<Vec<int>>(), [20, 14, 8, 2]); - assert_eq!(range_step(200u8, 255, 50).collect::<Vec<u8>>(), [200u8, 250]); - assert_eq!(range_step(200i, -5, 1).collect::<Vec<int>>(), []); - assert_eq!(range_step(200i, 200, 1).collect::<Vec<int>>(), []); + assert_eq!(range_step(200, 255, 50).collect::<Vec<u8>>(), [200, 250]); + assert_eq!(range_step(200, -5, 1).collect::<Vec<int>>(), []); + assert_eq!(range_step(200, 200, 1).collect::<Vec<int>>(), []); } #[test] @@ -788,7 +788,7 @@ fn test_range_step_inclusive() { assert_eq!(range_step_inclusive(0, 20, 5).collect::<Vec<int>>(), [0, 5, 10, 15, 20]); assert_eq!(range_step_inclusive(20, 0, -5).collect::<Vec<int>>(), [20, 15, 10, 5, 0]); assert_eq!(range_step_inclusive(20, 0, -6).collect::<Vec<int>>(), [20, 14, 8, 2]); - assert_eq!(range_step_inclusive(200u8, 255, 50).collect::<Vec<u8>>(), [200u8, 250]); + assert_eq!(range_step_inclusive(200, 255, 50).collect::<Vec<u8>>(), [200, 250]); assert_eq!(range_step_inclusive(200, -5, 1).collect::<Vec<int>>(), []); assert_eq!(range_step_inclusive(200, 200, 1).collect::<Vec<int>>(), [200]); } diff --git a/src/libcoretest/lib.rs b/src/libcoretest/lib.rs index 03924910e04..1dbbb845d46 100644 --- a/src/libcoretest/lib.rs +++ b/src/libcoretest/lib.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![feature(box_syntax)] #![feature(int_uint)] #![feature(unboxed_closures)] diff --git a/src/libcoretest/mem.rs b/src/libcoretest/mem.rs index 73000670c61..bf3e1cf03cb 100644 --- a/src/libcoretest/mem.rs +++ b/src/libcoretest/mem.rs @@ -103,7 +103,7 @@ fn test_transmute() { } unsafe { - assert_eq!([76u8], transmute::<_, Vec<u8>>("L".to_string())); + assert_eq!([76], transmute::<_, Vec<u8>>("L".to_string())); } } diff --git a/src/libcoretest/num/mod.rs b/src/libcoretest/num/mod.rs index 721354b6a44..9087b87f640 100644 --- a/src/libcoretest/num/mod.rs +++ b/src/libcoretest/num/mod.rs @@ -88,7 +88,7 @@ mod test { #[test] fn test_int_from_str_overflow() { - let mut i8_val: i8 = 127_i8; + let mut i8_val: i8 = 127; assert_eq!("127".parse::<i8>().ok(), Some(i8_val)); assert_eq!("128".parse::<i8>().ok(), None); @@ -96,7 +96,7 @@ mod test { assert_eq!("-128".parse::<i8>().ok(), Some(i8_val)); assert_eq!("-129".parse::<i8>().ok(), None); - let mut i16_val: i16 = 32_767_i16; + let mut i16_val: i16 = 32_767; assert_eq!("32767".parse::<i16>().ok(), Some(i16_val)); assert_eq!("32768".parse::<i16>().ok(), None); @@ -104,7 +104,7 @@ mod test { assert_eq!("-32768".parse::<i16>().ok(), Some(i16_val)); assert_eq!("-32769".parse::<i16>().ok(), None); - let mut i32_val: i32 = 2_147_483_647_i32; + let mut i32_val: i32 = 2_147_483_647; assert_eq!("2147483647".parse::<i32>().ok(), Some(i32_val)); assert_eq!("2147483648".parse::<i32>().ok(), None); @@ -112,7 +112,7 @@ mod test { assert_eq!("-2147483648".parse::<i32>().ok(), Some(i32_val)); assert_eq!("-2147483649".parse::<i32>().ok(), None); - let mut i64_val: i64 = 9_223_372_036_854_775_807_i64; + let mut i64_val: i64 = 9_223_372_036_854_775_807; assert_eq!("9223372036854775807".parse::<i64>().ok(), Some(i64_val)); assert_eq!("9223372036854775808".parse::<i64>().ok(), None); diff --git a/src/libcoretest/option.rs b/src/libcoretest/option.rs index 59116f23d44..fe0b10e9119 100644 --- a/src/libcoretest/option.rs +++ b/src/libcoretest/option.rs @@ -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(); diff --git a/src/libcoretest/ptr.rs b/src/libcoretest/ptr.rs index c8a54ef59ab..6a25c8be14e 100644 --- a/src/libcoretest/ptr.rs +++ b/src/libcoretest/ptr.rs @@ -139,12 +139,12 @@ fn test_ptr_addition() { fn test_ptr_subtraction() { unsafe { let xs = vec![0,1,2,3,4,5,6,7,8,9]; - let mut idx = 9i8; + let mut idx = 9; let ptr = xs.as_ptr(); - while idx >= 0i8 { + while idx >= 0 { assert_eq!(*(ptr.offset(idx as int)), idx as int); - idx = idx - 1i8; + idx = idx - 1; } let mut xs_mut = xs; diff --git a/src/libcoretest/result.rs b/src/libcoretest/result.rs index 10cc3ad6424..1c175ba99f7 100644 --- a/src/libcoretest/result.rs +++ b/src/libcoretest/result.rs @@ -126,7 +126,7 @@ pub fn test_unwrap_or_else() { } #[test] -#[should_fail] +#[should_panic] pub fn test_unwrap_or_else_panic() { fn handler(msg: &'static str) -> int { if msg == "I got this." { diff --git a/src/libcoretest/str.rs b/src/libcoretest/str.rs index 019f935911f..a89d3380707 100644 --- a/src/libcoretest/str.rs +++ b/src/libcoretest/str.rs @@ -188,15 +188,13 @@ fn trim_ws() { mod pattern { use std::str::Pattern; - use std::str::{Searcher, ReverseSearcher, DoubleEndedSearcher}; + use std::str::{Searcher, ReverseSearcher}; use std::str::SearchStep::{self, Match, Reject, Done}; macro_rules! make_test { ($name:ident, $p:expr, $h:expr, [$($e:expr,)*]) => { mod $name { - use std::str::Pattern; - use std::str::{Searcher, ReverseSearcher, DoubleEndedSearcher}; - use std::str::SearchStep::{self, Match, Reject, Done}; + use std::str::SearchStep::{Match, Reject}; use super::{cmp_search_to_vec}; #[test] fn fwd() { diff --git a/src/libflate/lib.rs b/src/libflate/lib.rs index 58531830043..a5cfe908aa8 100644 --- a/src/libflate/lib.rs +++ b/src/libflate/lib.rs @@ -14,6 +14,8 @@ //! [def]: https://en.wikipedia.org/wiki/DEFLATE //! [mz]: https://code.google.com/p/miniz/ +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "flate"] #![unstable(feature = "rustc_private")] #![staged_api] diff --git a/src/libfmt_macros/lib.rs b/src/libfmt_macros/lib.rs index 4e25e51e9a4..9b220409ef5 100644 --- a/src/libfmt_macros/lib.rs +++ b/src/libfmt_macros/lib.rs @@ -14,6 +14,8 @@ //! Parsing does not happen at runtime: structures of `std::fmt::rt` are //! generated instead. +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "fmt_macros"] #![unstable(feature = "rustc_private")] #![staged_api] diff --git a/src/libgetopts/lib.rs b/src/libgetopts/lib.rs index 6240b0e6afd..38abf3881bd 100644 --- a/src/libgetopts/lib.rs +++ b/src/libgetopts/lib.rs @@ -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() { @@ -63,20 +63,23 @@ //! 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); //! } //! ``` + +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "getopts"] #![unstable(feature = "rustc_private", reason = "use the crates.io `getopts` library instead")] @@ -92,6 +95,7 @@ #![feature(collections)] #![feature(int_uint)] #![feature(staged_api)] +#![feature(core)] #![feature(str_words)] #![cfg_attr(test, feature(rustc_private))] diff --git a/src/libgraphviz/lib.rs b/src/libgraphviz/lib.rs index 2f60a9e2cca..5f6bfd196f0 100644 --- a/src/libgraphviz/lib.rs +++ b/src/libgraphviz/lib.rs @@ -264,6 +264,8 @@ //! //! * [DOT language](http://www.graphviz.org/doc/info/lang.html) +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "graphviz"] #![unstable(feature = "rustc_private")] #![feature(staged_api)] diff --git a/src/liblibc/lib.rs b/src/liblibc/lib.rs index 42143b06ca0..11aba40afad 100644 --- a/src/liblibc/lib.rs +++ b/src/liblibc/lib.rs @@ -8,15 +8,14 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "libc"] #![crate_type = "rlib"] -#![cfg_attr(not(feature = "cargo-build"), - unstable(feature = "libc"))] -#![cfg_attr(not(feature = "cargo-build"), feature(staged_api))] +#![cfg_attr(not(feature = "cargo-build"), unstable(feature = "libc"))] +#![cfg_attr(not(feature = "cargo-build"), feature(staged_api, core, no_std))] #![cfg_attr(not(feature = "cargo-build"), staged_api)] -#![cfg_attr(not(feature = "cargo-build"), feature(core))] -#![feature(no_std)] -#![no_std] +#![cfg_attr(not(feature = "cargo-build"), no_std)] #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", html_favicon_url = "http://www.rust-lang.org/favicon.ico", html_root_url = "http://doc.rust-lang.org/nightly/", @@ -386,7 +385,8 @@ pub mod types { target_arch = "mips", target_arch = "mipsel", target_arch = "powerpc", - target_arch = "le32"))] + target_arch = "le32", + all(target_arch = "arm", not(target_os = "android"))))] pub mod posix88 { pub type off_t = i32; pub type dev_t = u64; @@ -398,7 +398,7 @@ pub mod types { pub type mode_t = u32; pub type ssize_t = i32; } - #[cfg(target_arch = "arm")] + #[cfg(all(target_arch = "arm", target_os = "android"))] pub mod posix88 { pub type off_t = i32; pub type dev_t = u32; @@ -412,7 +412,8 @@ pub mod types { } #[cfg(any(target_arch = "x86", target_arch = "le32", - target_arch = "powerpc"))] + target_arch = "powerpc", + all(target_arch = "arm", not(target_os = "android"))))] pub mod posix01 { use types::os::arch::c95::{c_short, c_long, time_t}; use types::os::arch::posix88::{dev_t, gid_t, ino_t}; @@ -458,7 +459,7 @@ pub mod types { pub __size: [u32; 9] } } - #[cfg(target_arch = "arm")] + #[cfg(all(target_arch = "arm", target_os = "android"))] pub mod posix01 { use types::os::arch::c95::{c_uchar, c_uint, c_ulong, time_t}; use types::os::arch::c99::{c_longlong, c_ulonglong}; @@ -2203,11 +2204,11 @@ pub mod consts { pub const _IOFBF : c_int = 0; pub const _IONBF : c_int = 4; pub const _IOLBF : c_int = 64; - pub const BUFSIZ : c_uint = 512_u32; - pub const FOPEN_MAX : c_uint = 20_u32; - pub const FILENAME_MAX : c_uint = 260_u32; - pub const L_tmpnam : c_uint = 16_u32; - pub const TMP_MAX : c_uint = 32767_u32; + pub const BUFSIZ : c_uint = 512; + pub const FOPEN_MAX : c_uint = 20; + pub const FILENAME_MAX : c_uint = 260; + pub const L_tmpnam : c_uint = 16; + pub const TMP_MAX : c_uint = 32767; pub const WSAEINTR: c_int = 10004; pub const WSAEBADF: c_int = 10009; @@ -2584,11 +2585,11 @@ pub mod consts { pub const _IOFBF : c_int = 0; pub const _IONBF : c_int = 2; pub const _IOLBF : c_int = 1; - pub const BUFSIZ : c_uint = 8192_u32; - pub const FOPEN_MAX : c_uint = 16_u32; - pub const FILENAME_MAX : c_uint = 4096_u32; - pub const L_tmpnam : c_uint = 20_u32; - pub const TMP_MAX : c_uint = 238328_u32; + pub const BUFSIZ : c_uint = 8192; + pub const FOPEN_MAX : c_uint = 16; + pub const FILENAME_MAX : c_uint = 4096; + pub const L_tmpnam : c_uint = 20; + pub const TMP_MAX : c_uint = 238328; } pub mod c99 { } @@ -3450,11 +3451,11 @@ pub mod consts { pub const _IOFBF : c_int = 0; pub const _IONBF : c_int = 2; pub const _IOLBF : c_int = 1; - pub const BUFSIZ : c_uint = 1024_u32; - pub const FOPEN_MAX : c_uint = 20_u32; - pub const FILENAME_MAX : c_uint = 1024_u32; - pub const L_tmpnam : c_uint = 1024_u32; - pub const TMP_MAX : c_uint = 308915776_u32; + pub const BUFSIZ : c_uint = 1024; + pub const FOPEN_MAX : c_uint = 20; + pub const FILENAME_MAX : c_uint = 1024; + pub const L_tmpnam : c_uint = 1024; + pub const TMP_MAX : c_uint = 308915776; } pub mod c99 { } @@ -3858,11 +3859,11 @@ pub mod consts { pub const _IOFBF : c_int = 0; pub const _IONBF : c_int = 2; pub const _IOLBF : c_int = 1; - pub const BUFSIZ : c_uint = 1024_u32; - pub const FOPEN_MAX : c_uint = 20_u32; - pub const FILENAME_MAX : c_uint = 1024_u32; - pub const L_tmpnam : c_uint = 1024_u32; - pub const TMP_MAX : c_uint = 308915776_u32; + pub const BUFSIZ : c_uint = 1024; + pub const FOPEN_MAX : c_uint = 20; + pub const FILENAME_MAX : c_uint = 1024; + pub const L_tmpnam : c_uint = 1024; + pub const TMP_MAX : c_uint = 308915776; } pub mod c99 { } @@ -4236,11 +4237,11 @@ pub mod consts { pub const _IOFBF : c_int = 0; pub const _IONBF : c_int = 2; pub const _IOLBF : c_int = 1; - pub const BUFSIZ : c_uint = 1024_u32; - pub const FOPEN_MAX : c_uint = 20_u32; - pub const FILENAME_MAX : c_uint = 1024_u32; - pub const L_tmpnam : c_uint = 1024_u32; - pub const TMP_MAX : c_uint = 308915776_u32; + pub const BUFSIZ : c_uint = 1024; + pub const FOPEN_MAX : c_uint = 20; + pub const FILENAME_MAX : c_uint = 1024; + pub const L_tmpnam : c_uint = 1024; + pub const TMP_MAX : c_uint = 308915776; } pub mod c99 { } @@ -5002,9 +5003,36 @@ pub mod funcs { use types::os::arch::c95::{c_char, c_int}; use types::os::arch::posix88::mode_t; + mod open_shim { + extern { + #[cfg(any(target_os = "macos", + target_os = "ios"))] + pub fn open(path: *const ::c_char, oflag: ::c_int, ...) + -> ::c_int; + + #[cfg(not(any(target_os = "macos", + target_os = "ios")))] + pub fn open(path: *const ::c_char, oflag: ::c_int, mode: ::mode_t) + -> ::c_int; + } + } + + #[cfg(any(target_os = "macos", + target_os = "ios"))] + #[inline] + pub unsafe extern fn open(path: *const c_char, oflag: c_int, mode: mode_t) -> c_int { + use types::os::arch::c95::c_uint; + open_shim::open(path, oflag, mode as c_uint) + } + + #[cfg(not(any(target_os = "macos", + target_os = "ios")))] + #[inline] + pub unsafe extern fn open(path: *const c_char, oflag: c_int, mode: mode_t) -> c_int { + open_shim::open(path, oflag, mode) + } + extern { - pub fn open(path: *const c_char, oflag: c_int, mode: mode_t) - -> c_int; pub fn creat(path: *const c_char, mode: mode_t) -> c_int; pub fn fcntl(fd: c_int, cmd: c_int, ...) -> c_int; } diff --git a/src/liblog/lib.rs b/src/liblog/lib.rs index d0105bb6577..3b6e1d04691 100644 --- a/src/liblog/lib.rs +++ b/src/liblog/lib.rs @@ -155,6 +155,8 @@ //! they're turned off (just a load and an integer comparison). This also means that //! if logging is disabled, none of the components of the log will be executed. +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "log"] #![unstable(feature = "rustc_private", reason = "use the crates.io `log` library instead")] diff --git a/src/liblog/macros.rs b/src/liblog/macros.rs index 4a9a9bd4060..f0f861a3831 100644 --- a/src/liblog/macros.rs +++ b/src/liblog/macros.rs @@ -157,7 +157,7 @@ macro_rules! info { /// ``` #[macro_export] macro_rules! debug { - ($($arg:tt)*) => (if cfg!(not(ndebug)) { log!(::log::DEBUG, $($arg)*) }) + ($($arg:tt)*) => (if cfg!(debug_assertions) { log!(::log::DEBUG, $($arg)*) }) } /// A macro to test whether a log level is enabled for the current module. @@ -192,7 +192,7 @@ macro_rules! debug { macro_rules! log_enabled { ($lvl:expr) => ({ let lvl = $lvl; - (lvl != ::log::DEBUG || cfg!(not(ndebug))) && + (lvl != ::log::DEBUG || cfg!(debug_assertions)) && lvl <= ::log::log_level() && ::log::mod_enabled(lvl, module_path!()) }) diff --git a/src/librand/chacha.rs b/src/librand/chacha.rs index 71ace016d6b..d54f1837074 100644 --- a/src/librand/chacha.rs +++ b/src/librand/chacha.rs @@ -173,7 +173,7 @@ impl<'a> SeedableRng<&'a [u32]> for ChaChaRng { fn reseed(&mut self, seed: &'a [u32]) { // reset state - self.init(&[0u32; KEY_WORDS]); + self.init(&[0; KEY_WORDS]); // set key in place let key = &mut self.state[4 .. 4+KEY_WORDS]; for (k, s) in key.iter_mut().zip(seed.iter()) { @@ -245,7 +245,7 @@ mod test { fn test_rng_true_values() { // Test vectors 1 and 2 from // http://tools.ietf.org/html/draft-nir-cfrg-chacha20-poly1305-04 - let seed : &[_] = &[0u32; 8]; + let seed : &[_] = &[0; 8]; let mut ra: ChaChaRng = SeedableRng::from_seed(seed); let v = (0..16).map(|_| ra.next_u32()).collect::<Vec<_>>(); @@ -285,7 +285,7 @@ mod test { #[test] fn test_rng_clone() { - let seed : &[_] = &[0u32; 8]; + let seed : &[_] = &[0; 8]; let mut rng: ChaChaRng = SeedableRng::from_seed(seed); let mut clone = rng.clone(); for _ in 0..16 { diff --git a/src/librand/distributions/exponential.rs b/src/librand/distributions/exponential.rs index e4927902cb3..bf9d334e8a4 100644 --- a/src/librand/distributions/exponential.rs +++ b/src/librand/distributions/exponential.rs @@ -109,12 +109,12 @@ mod test { } } #[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); } diff --git a/src/librand/distributions/gamma.rs b/src/librand/distributions/gamma.rs index 38eba0cfc71..ae3724a2b43 100644 --- a/src/librand/distributions/gamma.rs +++ b/src/librand/distributions/gamma.rs @@ -356,7 +356,7 @@ mod test { } } #[test] - #[should_fail] + #[should_panic] fn test_chi_squared_invalid_dof() { ChiSquared::new(-1.0); } diff --git a/src/librand/distributions/mod.rs b/src/librand/distributions/mod.rs index 12794ed69be..9775507b3cd 100644 --- a/src/librand/distributions/mod.rs +++ b/src/librand/distributions/mod.rs @@ -351,16 +351,16 @@ mod tests { [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 }, diff --git a/src/librand/distributions/normal.rs b/src/librand/distributions/normal.rs index 83f202742d3..ab5d03ad825 100644 --- a/src/librand/distributions/normal.rs +++ b/src/librand/distributions/normal.rs @@ -175,7 +175,7 @@ mod tests { } } #[test] - #[should_fail] + #[should_panic] fn test_normal_invalid_sd() { Normal::new(10.0, -1.0); } @@ -191,7 +191,7 @@ mod tests { } } #[test] - #[should_fail] + #[should_panic] fn test_log_normal_invalid_sd() { LogNormal::new(10.0, -1.0); } diff --git a/src/librand/distributions/range.rs b/src/librand/distributions/range.rs index fb73a44c2b9..c5a260346e0 100644 --- a/src/librand/distributions/range.rs +++ b/src/librand/distributions/range.rs @@ -23,8 +23,8 @@ use distributions::{Sample, IndependentSample}; /// /// This gives a uniform distribution (assuming the RNG used to sample /// it is itself uniform & the `SampleRange` implementation for the -/// given type is correct), even for edge cases like `low = 0u8`, -/// `high = 170u8`, for which a naive modulo operation would return +/// given type is correct), even for edge cases like `low = 0`, +/// `high = 170`, for which a naive modulo operation would return /// numbers less than 85 with double the probability to those greater /// than 85. /// @@ -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); diff --git a/src/librand/isaac.rs b/src/librand/isaac.rs index 28f1ea872d7..7ea62b7fd3f 100644 --- a/src/librand/isaac.rs +++ b/src/librand/isaac.rs @@ -10,16 +10,21 @@ //! 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]. /// @@ -33,18 +38,18 @@ const RAND_SIZE_UINT: uint = 1 << (RAND_SIZE_LEN as uint); #[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 @@ impl 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 @@ impl IsaacRng { 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 @@ impl IsaacRng { 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 @@ impl IsaacRng { #[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 @@ impl IsaacRng { 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 @@ impl Rng for IsaacRng { // (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 } } @@ -217,15 +221,15 @@ impl<'a> SeedableRng<&'a [u32]> for IsaacRng { fn reseed(&mut self, seed: &'a [u32]) { // make the seed into [seed[0], seed[1], ..., seed[seed.len() // - 1], 0, 0, ...], to fill rng.rsl. - let seed_iter = seed.iter().cloned().chain(repeat(0u32)); + 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 @@ impl Rand for 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 @@ const RAND_SIZE_64: uint = 1 << RAND_SIZE_64_LEN; /// 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 @@ impl 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 @@ impl Isaac64Rng { 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 @@ impl Isaac64Rng { 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 @@ impl Isaac64Rng { } 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 @@ impl Isaac64Rng { /// 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 @@ impl Isaac64Rng { 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 @@ impl Isaac64Rng { } } - self.a = a.0; - self.b = b.0; + self.a = a; + self.b = b; self.cnt = RAND_SIZE_64; } } @@ -452,7 +456,7 @@ impl Rng for Isaac64Rng { // 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 } } @@ -460,15 +464,15 @@ impl<'a> SeedableRng<&'a [u64]> for Isaac64Rng { fn reseed(&mut self, seed: &'a [u64]) { // make the seed into [seed[0], seed[1], ..., seed[seed.len() // - 1], 0, 0, ...], to fill rng.rsl. - let seed_iter = seed.iter().cloned().chain(repeat(0u64)); + 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 @@ impl Rand for 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 @@ mod test { #[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 @@ mod test { #[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); diff --git a/src/librand/lib.rs b/src/librand/lib.rs index 3458d519af5..6bc56ce9084 100644 --- a/src/librand/lib.rs +++ b/src/librand/lib.rs @@ -16,6 +16,8 @@ //! is not recommended to use this library directly, but rather the official //! interface through `std::rand`. +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "rand"] #![crate_type = "rlib"] #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk.png", @@ -149,7 +151,7 @@ pub trait Rng : Sized { /// ```rust /// use std::rand::{thread_rng, Rng}; /// - /// let mut v = [0u8; 13579]; + /// let mut v = [0; 13579]; /// thread_rng().fill_bytes(&mut v); /// println!("{:?}", v.as_slice()); /// ``` diff --git a/src/librand/rand_impls.rs b/src/librand/rand_impls.rs index c8a757079c3..e2a5276cc78 100644 --- a/src/librand/rand_impls.rs +++ b/src/librand/rand_impls.rs @@ -214,7 +214,6 @@ impl<T:Rand> Rand for Option<T> { #[cfg(test)] mod tests { - use std::prelude::v1::*; use std::rand::{Rng, thread_rng, Open01, Closed01}; struct ConstantRng(u64); diff --git a/src/librand/reseeding.rs b/src/librand/reseeding.rs index 0072c555d14..22b77a75931 100644 --- a/src/librand/reseeding.rs +++ b/src/librand/reseeding.rs @@ -215,7 +215,7 @@ mod test { const FILL_BYTES_V_LEN: uint = 13579; #[test] fn test_rng_fill_bytes() { - let mut v = repeat(0u8).take(FILL_BYTES_V_LEN).collect::<Vec<_>>(); + let mut v = repeat(0).take(FILL_BYTES_V_LEN).collect::<Vec<_>>(); ::test::rng().fill_bytes(&mut v); // Sanity test: if we've gotten here, `fill_bytes` has not infinitely diff --git a/src/librbml/io.rs b/src/librbml/io.rs index 4ef3c5bc206..fc0a9d29ed6 100644 --- a/src/librbml/io.rs +++ b/src/librbml/io.rs @@ -140,32 +140,32 @@ mod tests { fn test_seekable_mem_writer() { let mut writer = SeekableMemWriter::new(); assert_eq!(writer.tell(), Ok(0)); - writer.write(&[0]).unwrap(); + writer.write_all(&[0]).unwrap(); assert_eq!(writer.tell(), Ok(1)); - writer.write(&[1, 2, 3]).unwrap(); - writer.write(&[4, 5, 6, 7]).unwrap(); + writer.write_all(&[1, 2, 3]).unwrap(); + writer.write_all(&[4, 5, 6, 7]).unwrap(); assert_eq!(writer.tell(), Ok(8)); let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7]; assert_eq!(writer.get_ref(), b); writer.seek(0, old_io::SeekSet).unwrap(); assert_eq!(writer.tell(), Ok(0)); - writer.write(&[3, 4]).unwrap(); + writer.write_all(&[3, 4]).unwrap(); let b: &[_] = &[3, 4, 2, 3, 4, 5, 6, 7]; assert_eq!(writer.get_ref(), b); writer.seek(1, old_io::SeekCur).unwrap(); - writer.write(&[0, 1]).unwrap(); + writer.write_all(&[0, 1]).unwrap(); let b: &[_] = &[3, 4, 2, 0, 1, 5, 6, 7]; assert_eq!(writer.get_ref(), b); writer.seek(-1, old_io::SeekEnd).unwrap(); - writer.write(&[1, 2]).unwrap(); + writer.write_all(&[1, 2]).unwrap(); let b: &[_] = &[3, 4, 2, 0, 1, 5, 6, 1, 2]; assert_eq!(writer.get_ref(), b); writer.seek(1, old_io::SeekEnd).unwrap(); - writer.write(&[1]).unwrap(); + writer.write_all(&[1]).unwrap(); let b: &[_] = &[3, 4, 2, 0, 1, 5, 6, 1, 2, 0, 1]; assert_eq!(writer.get_ref(), b); } @@ -174,7 +174,7 @@ mod tests { fn seek_past_end() { let mut r = SeekableMemWriter::new(); r.seek(10, old_io::SeekSet).unwrap(); - assert!(r.write(&[3]).is_ok()); + assert!(r.write_all(&[3]).is_ok()); } #[test] @@ -190,7 +190,7 @@ mod tests { b.iter(|| { let mut wr = SeekableMemWriter::new(); for _ in 0..times { - wr.write(&src).unwrap(); + wr.write_all(&src).unwrap(); } let v = wr.unwrap(); diff --git a/src/librbml/lib.rs b/src/librbml/lib.rs index 844d097bdaf..d71bcdf2924 100644 --- a/src/librbml/lib.rs +++ b/src/librbml/lib.rs @@ -111,6 +111,8 @@ //! //! First 0x20 tags are reserved by RBML; custom tags start at 0x20. +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "rbml"] #![unstable(feature = "rustc_private")] #![staged_api] @@ -290,22 +292,22 @@ pub mod reader { #[inline(never)] fn vuint_at_slow(data: &[u8], start: uint) -> DecodeResult<Res> { let a = data[start]; - if a & 0x80u8 != 0u8 { - return Ok(Res {val: (a & 0x7fu8) as uint, next: start + 1}); + if a & 0x80 != 0 { + return Ok(Res {val: (a & 0x7f) as uint, next: start + 1}); } - if a & 0x40u8 != 0u8 { - return Ok(Res {val: ((a & 0x3fu8) as uint) << 8 | + if a & 0x40 != 0 { + return Ok(Res {val: ((a & 0x3f) as uint) << 8 | (data[start + 1] as uint), next: start + 2}); } - if a & 0x20u8 != 0u8 { - return Ok(Res {val: ((a & 0x1fu8) as uint) << 16 | + if a & 0x20 != 0 { + return Ok(Res {val: ((a & 0x1f) as uint) << 16 | (data[start + 1] as uint) << 8 | (data[start + 2] as uint), next: start + 3}); } - if a & 0x10u8 != 0u8 { - return Ok(Res {val: ((a & 0x0fu8) as uint) << 24 | + if a & 0x10 != 0 { + return Ok(Res {val: ((a & 0x0f) as uint) << 24 | (data[start + 1] as uint) << 16 | (data[start + 2] as uint) << 8 | (data[start + 3] as uint), @@ -877,11 +879,11 @@ pub mod writer { fn write_sized_vuint<W: Writer>(w: &mut W, n: uint, size: uint) -> EncodeResult { match size { - 1 => w.write_all(&[0x80u8 | (n as u8)]), - 2 => w.write_all(&[0x40u8 | ((n >> 8) as u8), n as u8]), - 3 => w.write_all(&[0x20u8 | ((n >> 16) as u8), (n >> 8) as u8, + 1 => w.write_all(&[0x80 | (n as u8)]), + 2 => w.write_all(&[0x40 | ((n >> 8) as u8), n as u8]), + 3 => w.write_all(&[0x20 | ((n >> 16) as u8), (n >> 8) as u8, n as u8]), - 4 => w.write_all(&[0x10u8 | ((n >> 24) as u8), (n >> 16) as u8, + 4 => w.write_all(&[0x10 | ((n >> 24) as u8), (n >> 16) as u8, (n >> 8) as u8, n as u8]), _ => Err(old_io::IoError { kind: old_io::OtherIoError, @@ -930,7 +932,7 @@ pub mod writer { // Write a placeholder four-byte size. self.size_positions.push(try!(self.writer.tell()) as uint); - let zeroes: &[u8] = &[0u8, 0u8, 0u8, 0u8]; + let zeroes: &[u8] = &[0, 0, 0, 0]; self.writer.write_all(zeroes) } @@ -1422,9 +1424,9 @@ mod bench { #[bench] pub fn vuint_at_A_aligned(b: &mut Bencher) { - let data = (0i32..4*100).map(|i| { + let data = (0..4*100).map(|i| { match i % 2 { - 0 => 0x80u8, + 0 => 0x80, _ => i as u8, } }).collect::<Vec<_>>(); @@ -1440,9 +1442,9 @@ mod bench { #[bench] pub fn vuint_at_A_unaligned(b: &mut Bencher) { - let data = (0i32..4*100+1).map(|i| { + let data = (0..4*100+1).map(|i| { match i % 2 { - 1 => 0x80u8, + 1 => 0x80, _ => i as u8 } }).collect::<Vec<_>>(); @@ -1458,11 +1460,11 @@ mod bench { #[bench] pub fn vuint_at_D_aligned(b: &mut Bencher) { - let data = (0i32..4*100).map(|i| { + let data = (0..4*100).map(|i| { match i % 4 { - 0 => 0x10u8, + 0 => 0x10, 3 => i as u8, - _ => 0u8 + _ => 0 } }).collect::<Vec<_>>(); let mut sum = 0; @@ -1477,11 +1479,11 @@ mod bench { #[bench] pub fn vuint_at_D_unaligned(b: &mut Bencher) { - let data = (0i32..4*100+1).map(|i| { + let data = (0..4*100+1).map(|i| { match i % 4 { - 1 => 0x10u8, + 1 => 0x10, 0 => i as u8, - _ => 0u8 + _ => 0 } }).collect::<Vec<_>>(); let mut sum = 0; diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index aa51320ee7f..f424ac0cda2 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -14,6 +14,8 @@ //! //! This API is completely unstable and subject to change. +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "rustc"] #![unstable(feature = "rustc_private")] #![staged_api] @@ -38,7 +40,10 @@ #![feature(unsafe_destructor)] #![feature(staged_api)] #![feature(std_misc)] -#![feature(os)] +#![feature(path)] +#![feature(io)] +#![feature(path_ext)] +#![feature(str_words)] #![cfg_attr(test, feature(test))] extern crate arena; diff --git a/src/librustc/metadata/common.rs b/src/librustc/metadata/common.rs index a58ef53de9a..081c64ecae8 100644 --- a/src/librustc/metadata/common.rs +++ b/src/librustc/metadata/common.rs @@ -84,7 +84,6 @@ pub const tag_mod_impl: uint = 0x38; pub const tag_item_trait_item: uint = 0x39; pub const tag_item_trait_ref: uint = 0x3a; -pub const tag_item_super_trait_ref: uint = 0x3b; // discriminator value for variants pub const tag_disr_val: uint = 0x3c; @@ -221,8 +220,6 @@ pub const tag_struct_field_id: uint = 0x8b; pub const tag_attribute_is_sugared_doc: uint = 0x8c; -pub const tag_trait_def_bounds: uint = 0x8d; - pub const tag_items_data_region: uint = 0x8e; pub const tag_region_param_def: uint = 0x8f; @@ -252,3 +249,10 @@ pub const tag_macro_def: uint = 0x9e; pub const tag_macro_def_body: uint = 0x9f; pub const tag_paren_sugar: uint = 0xa0; + +pub const tag_codemap: uint = 0xa1; +pub const tag_codemap_filemap: uint = 0xa2; + +pub const tag_item_super_predicates: uint = 0xa3; + +pub const tag_defaulted_trait: uint = 0xa4; diff --git a/src/librustc/metadata/creader.rs b/src/librustc/metadata/creader.rs index 46155925b3c..00a47ce17da 100644 --- a/src/librustc/metadata/creader.rs +++ b/src/librustc/metadata/creader.rs @@ -21,12 +21,13 @@ use metadata::decoder; use metadata::loader; use metadata::loader::CratePaths; +use std::path::{Path, PathBuf}; use std::rc::Rc; use syntax::ast; use syntax::abi; use syntax::attr; use syntax::attr::AttrMetaMethods; -use syntax::codemap::{Span, mk_sp}; +use syntax::codemap::{self, Span, mk_sp, Pos}; use syntax::parse; use syntax::parse::token::InternedString; use syntax::parse::token; @@ -126,7 +127,7 @@ fn register_native_lib(sess: &Session, // Extra info about a crate loaded for plugins or exported macros. struct ExtensionCrate { metadata: PMDSource, - dylib: Option<Path>, + dylib: Option<PathBuf>, target_only: bool, } @@ -373,15 +374,17 @@ impl<'a> CrateReader<'a> { // Maintain a reference to the top most crate. let root = if root.is_some() { root } else { &crate_paths }; - let cnum_map = self.resolve_crate_deps(root, lib.metadata.as_slice(), span); + let loader::Library { dylib, rlib, metadata } = lib; - let loader::Library{ dylib, rlib, metadata } = lib; + let cnum_map = self.resolve_crate_deps(root, metadata.as_slice(), span); + let codemap_import_info = import_codemap(self.sess.codemap(), &metadata); let cmeta = Rc::new( cstore::crate_metadata { name: name.to_string(), data: metadata, cnum_map: cnum_map, cnum: cnum, + codemap_import_info: codemap_import_info, span: span, }); @@ -490,7 +493,7 @@ impl<'a> CrateReader<'a> { }; 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 { @@ -539,6 +542,7 @@ impl<'a> CrateReader<'a> { // overridden in plugin/load.rs export: false, use_locally: false, + allow_internal_unstable: false, body: body, }); @@ -549,7 +553,8 @@ impl<'a> CrateReader<'a> { } /// Look for a plugin registrar. Returns library path and symbol name. - pub fn find_plugin_registrar(&mut self, span: Span, name: &str) -> Option<(Path, String)> { + pub fn find_plugin_registrar(&mut self, span: Span, name: &str) + -> Option<(PathBuf, String)> { let ekrate = self.read_extension_crate(span, &CrateInfo { name: name.to_string(), ident: name.to_string(), @@ -572,7 +577,7 @@ impl<'a> CrateReader<'a> { .map(|id| decoder::get_symbol(ekrate.metadata.as_slice(), id)); match (ekrate.dylib.as_ref(), registrar) { - (Some(dylib), Some(reg)) => Some((dylib.clone(), reg)), + (Some(dylib), Some(reg)) => Some((dylib.to_path_buf(), reg)), (None, Some(_)) => { let message = format!("plugin `{}` only found in rlib format, \ but must be available in dylib format", @@ -586,3 +591,131 @@ impl<'a> CrateReader<'a> { } } } + +/// Imports the codemap from an external crate into the codemap of the crate +/// currently being compiled (the "local crate"). +/// +/// The import algorithm works analogous to how AST items are inlined from an +/// external crate's metadata: +/// For every FileMap in the external codemap an 'inline' copy is created in the +/// local codemap. The correspondence relation between external and local +/// FileMaps is recorded in the `ImportedFileMap` objects returned from this +/// function. When an item from an external crate is later inlined into this +/// crate, this correspondence information is used to translate the span +/// information of the inlined item so that it refers the correct positions in +/// the local codemap (see `astencode::DecodeContext::tr_span()`). +/// +/// The import algorithm in the function below will reuse FileMaps already +/// existing in the local codemap. For example, even if the FileMap of some +/// source file of libstd gets imported many times, there will only ever be +/// one FileMap object for the corresponding file in the local codemap. +/// +/// Note that imported FileMaps do not actually contain the source code of the +/// file they represent, just information about length, line breaks, and +/// multibyte characters. This information is enough to generate valid debuginfo +/// for items inlined from other crates. +fn import_codemap(local_codemap: &codemap::CodeMap, + metadata: &MetadataBlob) + -> Vec<cstore::ImportedFileMap> { + let external_codemap = decoder::get_imported_filemaps(metadata.as_slice()); + + let imported_filemaps = external_codemap.into_iter().map(|filemap_to_import| { + // Try to find an existing FileMap that can be reused for the filemap to + // be imported. A FileMap is reusable if it is exactly the same, just + // positioned at a different offset within the codemap. + let reusable_filemap = { + local_codemap.files + .borrow() + .iter() + .find(|fm| are_equal_modulo_startpos(&fm, &filemap_to_import)) + .map(|rc| rc.clone()) + }; + + match reusable_filemap { + Some(fm) => { + cstore::ImportedFileMap { + original_start_pos: filemap_to_import.start_pos, + original_end_pos: filemap_to_import.end_pos, + translated_filemap: fm + } + } + None => { + // We can't reuse an existing FileMap, so allocate a new one + // containing the information we need. + let codemap::FileMap { + name, + start_pos, + end_pos, + lines, + multibyte_chars, + .. + } = filemap_to_import; + + let source_length = (end_pos - start_pos).to_usize(); + + // Translate line-start positions and multibyte character + // position into frame of reference local to file. + // `CodeMap::new_imported_filemap()` will then translate those + // coordinates to their new global frame of reference when the + // offset of the FileMap is known. + let lines = lines.into_inner().map_in_place(|pos| pos - start_pos); + let multibyte_chars = multibyte_chars + .into_inner() + .map_in_place(|mbc| + codemap::MultiByteChar { + pos: mbc.pos + start_pos, + bytes: mbc.bytes + }); + + let local_version = local_codemap.new_imported_filemap(name, + source_length, + lines, + multibyte_chars); + cstore::ImportedFileMap { + original_start_pos: start_pos, + original_end_pos: end_pos, + translated_filemap: local_version + } + } + } + }).collect(); + + return imported_filemaps; + + fn are_equal_modulo_startpos(fm1: &codemap::FileMap, + fm2: &codemap::FileMap) + -> bool { + if fm1.name != fm2.name { + return false; + } + + let lines1 = fm1.lines.borrow(); + let lines2 = fm2.lines.borrow(); + + if lines1.len() != lines2.len() { + return false; + } + + for (&line1, &line2) in lines1.iter().zip(lines2.iter()) { + if (line1 - fm1.start_pos) != (line2 - fm2.start_pos) { + return false; + } + } + + let multibytes1 = fm1.multibyte_chars.borrow(); + let multibytes2 = fm2.multibyte_chars.borrow(); + + if multibytes1.len() != multibytes2.len() { + return false; + } + + for (mb1, mb2) in multibytes1.iter().zip(multibytes2.iter()) { + if (mb1.bytes != mb2.bytes) || + ((mb1.pos - fm1.start_pos) != (mb2.pos - fm2.start_pos)) { + return false; + } + } + + true + } +} diff --git a/src/librustc/metadata/csearch.rs b/src/librustc/metadata/csearch.rs index f5c4cce0659..ed5783c8dba 100644 --- a/src/librustc/metadata/csearch.rs +++ b/src/librustc/metadata/csearch.rs @@ -175,14 +175,6 @@ pub fn get_provided_trait_methods<'tcx>(tcx: &ty::ctxt<'tcx>, decoder::get_provided_trait_methods(cstore.intr.clone(), &*cdata, def.node, tcx) } -pub fn get_supertraits<'tcx>(tcx: &ty::ctxt<'tcx>, - def: ast::DefId) - -> Vec<Rc<ty::TraitRef<'tcx>>> { - let cstore = &tcx.sess.cstore; - let cdata = cstore.get_crate_data(def.krate); - decoder::get_supertraits(&*cdata, def.node, tcx) -} - pub fn get_type_name_if_impl(cstore: &cstore::CStore, def: ast::DefId) -> Option<ast::Name> { let cdata = cstore.get_crate_data(def.krate); @@ -238,6 +230,14 @@ pub fn get_predicates<'tcx>(tcx: &ty::ctxt<'tcx>, def: ast::DefId) decoder::get_predicates(&*cdata, def.node, tcx) } +pub fn get_super_predicates<'tcx>(tcx: &ty::ctxt<'tcx>, def: ast::DefId) + -> ty::GenericPredicates<'tcx> +{ + let cstore = &tcx.sess.cstore; + let cdata = cstore.get_crate_data(def.krate); + decoder::get_super_predicates(&*cdata, def.node, tcx) +} + pub fn get_field_type<'tcx>(tcx: &ty::ctxt<'tcx>, class_id: ast::DefId, def: ast::DefId) -> ty::TypeScheme<'tcx> { let cstore = &tcx.sess.cstore; @@ -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) } diff --git a/src/librustc/metadata/cstore.rs b/src/librustc/metadata/cstore.rs index a3f7d57da67..47ec31c0f1a 100644 --- a/src/librustc/metadata/cstore.rs +++ b/src/librustc/metadata/cstore.rs @@ -25,9 +25,10 @@ use util::nodemap::{FnvHashMap, NodeMap}; use std::cell::RefCell; use std::rc::Rc; +use std::path::PathBuf; use flate::Bytes; use syntax::ast; -use syntax::codemap::Span; +use syntax::codemap; use syntax::parse::token::IdentInterner; // A map from external crate numbers (as decoded from some crate file) to @@ -41,12 +42,24 @@ pub enum MetadataBlob { MetadataArchive(loader::ArchiveMetadata), } +/// Holds information about a codemap::FileMap imported from another crate. +/// See creader::import_codemap() for more information. +pub struct ImportedFileMap { + /// This FileMap's byte-offset within the codemap of its original crate + pub original_start_pos: codemap::BytePos, + /// The end of this FileMap within the codemap of its original crate + pub original_end_pos: codemap::BytePos, + /// The imported FileMap's representation within the local codemap + pub translated_filemap: Rc<codemap::FileMap> +} + pub struct crate_metadata { pub name: String, pub data: MetadataBlob, pub cnum_map: cnum_map, pub cnum: ast::CrateNum, - pub span: Span, + pub codemap_import_info: Vec<ImportedFileMap>, + pub span: codemap::Span, } #[derive(Copy, Debug, PartialEq, Clone)] @@ -66,8 +79,8 @@ pub enum NativeLibraryKind { // must be non-None. #[derive(PartialEq, Clone)] pub struct CrateSource { - pub dylib: Option<(Path, PathKind)>, - pub rlib: Option<(Path, PathKind)>, + pub dylib: Option<(PathBuf, PathKind)>, + pub rlib: Option<(PathBuf, PathKind)>, pub cnum: ast::CrateNum, } @@ -160,7 +173,7 @@ impl CStore { // topological sort of all crates putting the leaves at the right-most // positions. pub fn get_used_crates(&self, prefer: LinkagePreference) - -> Vec<(ast::CrateNum, Option<Path>)> { + -> Vec<(ast::CrateNum, Option<PathBuf>)> { let mut ordering = Vec::new(); fn visit(cstore: &CStore, cnum: ast::CrateNum, ordering: &mut Vec<ast::CrateNum>) { diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index e32fcaec047..dbbc17c018a 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -22,9 +22,8 @@ use metadata::csearch::MethodInfo; use metadata::csearch; use metadata::cstore; use metadata::tydecode::{parse_ty_data, parse_region_data, parse_def_id, - parse_type_param_def_data, parse_bounds_data, - parse_bare_fn_ty_data, parse_trait_ref_data, - parse_predicate_data}; + parse_type_param_def_data, parse_bare_fn_ty_data, + parse_trait_ref_data, parse_predicate_data}; use middle::def; use middle::lang_items; use middle::subst; @@ -34,9 +33,9 @@ use middle::astencode::vtable_decoder_helpers; use std::collections::HashMap; use std::hash::{self, Hash, SipHasher}; -use std::num::FromPrimitive; -use std::num::Int; -use std::old_io; +use std::io::prelude::*; +use std::io; +use std::num::{FromPrimitive, Int}; use std::rc::Rc; use std::slice::bytes; use std::str; @@ -260,18 +259,6 @@ fn item_trait_ref<'tcx>(doc: rbml::Doc, tcx: &ty::ctxt<'tcx>, cdata: Cmd) doc_trait_ref(tp, tcx, cdata) } -fn doc_bounds<'tcx>(doc: rbml::Doc, tcx: &ty::ctxt<'tcx>, cdata: Cmd) - -> ty::ParamBounds<'tcx> { - parse_bounds_data(doc.data, cdata.cnum, doc.start, tcx, - |_, did| translate_def_id(cdata, did)) -} - -fn trait_def_bounds<'tcx>(doc: rbml::Doc, tcx: &ty::ctxt<'tcx>, cdata: Cmd) - -> ty::ParamBounds<'tcx> { - let d = reader::get_doc(doc, tag_trait_def_bounds); - doc_bounds(d, tcx, cdata) -} - fn enum_variant_ids(item: rbml::Doc, cdata: Cmd) -> Vec<ast::DefId> { let mut ids: Vec<ast::DefId> = Vec::new(); let v = tag_items_data_item_variant; @@ -406,7 +393,6 @@ pub fn get_trait_def<'tcx>(cdata: Cmd, { let item_doc = lookup_item(item_id, cdata.data()); let generics = doc_generics(item_doc, tcx, cdata, tag_item_generics); - let bounds = trait_def_bounds(item_doc, tcx, cdata); let unsafety = parse_unsafety(item_doc); let associated_type_names = parse_associated_type_names(item_doc); let paren_sugar = parse_paren_sugar(item_doc); @@ -415,7 +401,6 @@ pub fn get_trait_def<'tcx>(cdata: Cmd, paren_sugar: paren_sugar, unsafety: unsafety, generics: generics, - bounds: bounds, trait_ref: item_trait_ref(item_doc, tcx, cdata), associated_type_names: associated_type_names, } @@ -430,6 +415,15 @@ pub fn get_predicates<'tcx>(cdata: Cmd, doc_predicates(item_doc, tcx, cdata, tag_item_generics) } +pub fn get_super_predicates<'tcx>(cdata: Cmd, + item_id: ast::NodeId, + tcx: &ty::ctxt<'tcx>) + -> ty::GenericPredicates<'tcx> +{ + let item_doc = lookup_item(item_id, cdata.data()); + doc_predicates(item_doc, tcx, cdata, tag_item_super_predicates) +} + pub fn get_type<'tcx>(cdata: Cmd, id: ast::NodeId, tcx: &ty::ctxt<'tcx>) -> ty::TypeScheme<'tcx> { @@ -971,24 +965,6 @@ pub fn get_provided_trait_methods<'tcx>(intr: Rc<IdentInterner>, return result; } -/// Returns the supertraits of the given trait. -pub fn get_supertraits<'tcx>(cdata: Cmd, id: ast::NodeId, tcx: &ty::ctxt<'tcx>) - -> Vec<Rc<ty::TraitRef<'tcx>>> { - let mut results = Vec::new(); - let item_doc = lookup_item(id, cdata.data()); - reader::tagged_docs(item_doc, tag_item_super_trait_ref, |trait_doc| { - // NB. Only reads the ones that *aren't* builtin-bounds. See also - // get_trait_def() for collecting the builtin bounds. - // FIXME(#8559): The builtin bounds shouldn't be encoded in the first place. - let trait_ref = doc_trait_ref(trait_doc, tcx, cdata); - if tcx.lang_items.to_builtin_kind(trait_ref.def_id).is_none() { - results.push(trait_ref); - } - true - }); - return results; -} - pub fn get_type_name_if_impl(cdata: Cmd, node_id: ast::NodeId) -> Option<ast::Name> { let item = lookup_item(node_id, cdata.data()); @@ -1191,7 +1167,7 @@ fn get_attributes(md: rbml::Doc) -> Vec<ast::Attribute> { } fn list_crate_attributes(md: rbml::Doc, hash: &Svh, - out: &mut old_io::Writer) -> old_io::IoResult<()> { + out: &mut io::Write) -> io::Result<()> { try!(write!(out, "=Crate Attributes ({})=\n", *hash)); let r = get_attributes(md); @@ -1236,7 +1212,7 @@ pub fn get_crate_deps(data: &[u8]) -> Vec<CrateDep> { return deps; } -fn list_crate_deps(data: &[u8], out: &mut old_io::Writer) -> old_io::IoResult<()> { +fn list_crate_deps(data: &[u8], out: &mut io::Write) -> io::Result<()> { try!(write!(out, "=External Dependencies=\n")); for dep in &get_crate_deps(data) { try!(write!(out, "{} {}-{}\n", dep.cnum, dep.name, dep.hash)); @@ -1275,7 +1251,7 @@ pub fn get_crate_name(data: &[u8]) -> String { maybe_get_crate_name(data).expect("no crate name in crate") } -pub fn list_crate_metadata(bytes: &[u8], out: &mut old_io::Writer) -> old_io::IoResult<()> { +pub fn list_crate_metadata(bytes: &[u8], out: &mut io::Write) -> io::Result<()> { let hash = get_crate_hash(bytes); let md = rbml::Doc::new(bytes); try!(list_crate_attributes(md, &hash, out)); @@ -1561,11 +1537,25 @@ pub fn is_associated_type(cdata: Cmd, id: ast::NodeId) -> bool { } } +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 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 get_imported_filemaps(metadata: &[u8]) -> Vec<codemap::FileMap> { + let crate_doc = rbml::Doc::new(metadata); + let cm_doc = reader::get_doc(crate_doc, tag_codemap); + + let mut filemaps = vec![]; + + reader::tagged_docs(cm_doc, tag_codemap_filemap, |filemap_doc| { + let mut decoder = reader::Decoder::new(filemap_doc); + let filemap: codemap::FileMap = Decodable::decode(&mut decoder).unwrap(); + filemaps.push(filemap); + true + }); + + return filemaps; } diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index 8152a2bf16d..08263eb8e6a 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -206,21 +206,6 @@ pub fn write_region(ecx: &EncodeContext, tyencode::enc_region(rbml_w, ty_str_ctxt, r); } -fn encode_bounds<'a, 'tcx>(rbml_w: &mut Encoder, - ecx: &EncodeContext<'a, 'tcx>, - bounds: &ty::ParamBounds<'tcx>, - tag: uint) { - rbml_w.start_tag(tag); - - let ty_str_ctxt = &tyencode::ctxt { diag: ecx.diag, - ds: def_to_string, - tcx: ecx.tcx, - abbrevs: &ecx.type_abbrevs }; - tyencode::enc_bounds(rbml_w, ty_str_ctxt, bounds); - - rbml_w.end_tag(); -} - fn encode_type<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, rbml_w: &mut Encoder, typ: Ty<'tcx>) { @@ -728,6 +713,7 @@ fn encode_generics<'a, 'tcx>(rbml_w: &mut Encoder, tcx: ecx.tcx, abbrevs: &ecx.type_abbrevs }; + for param in generics.types.iter() { rbml_w.start_tag(tag_type_param_def); tyencode::enc_type_param_def(rbml_w, ty_str_ctxt, param); @@ -758,6 +744,22 @@ fn encode_generics<'a, 'tcx>(rbml_w: &mut Encoder, rbml_w.end_tag(); } + encode_predicates_in_current_doc(rbml_w, ecx, predicates); + + rbml_w.end_tag(); +} + +fn encode_predicates_in_current_doc<'a,'tcx>(rbml_w: &mut Encoder, + ecx: &EncodeContext<'a,'tcx>, + predicates: &ty::GenericPredicates<'tcx>) +{ + let ty_str_ctxt = &tyencode::ctxt { + diag: ecx.diag, + ds: def_to_string, + tcx: ecx.tcx, + abbrevs: &ecx.type_abbrevs + }; + for (space, _, predicate) in predicates.predicates.iter_enumerated() { rbml_w.start_tag(tag_predicate); @@ -769,7 +771,15 @@ fn encode_generics<'a, 'tcx>(rbml_w: &mut Encoder, rbml_w.end_tag(); } +} +fn encode_predicates<'a,'tcx>(rbml_w: &mut Encoder, + ecx: &EncodeContext<'a,'tcx>, + predicates: &ty::GenericPredicates<'tcx>, + tag: uint) +{ + rbml_w.start_tag(tag); + encode_predicates_in_current_doc(rbml_w, ecx, predicates); rbml_w.end_tag(); } @@ -1278,8 +1288,11 @@ fn encode_info_for_item(ecx: &EncodeContext, 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), + tag_item_super_predicates); encode_trait_ref(rbml_w, ecx, &*trait_def.trait_ref, tag_item_trait_ref); encode_name(rbml_w, item.ident.name); encode_attributes(rbml_w, &item.attrs); @@ -1304,8 +1317,6 @@ fn encode_info_for_item(ecx: &EncodeContext, } encode_path(rbml_w, path.clone()); - encode_bounds(rbml_w, ecx, &trait_def.bounds, tag_trait_def_bounds); - // Encode the implementations of this trait. encode_extension_implementations(ecx, rbml_w, def_id); @@ -1650,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 { @@ -1751,6 +1767,28 @@ fn encode_plugin_registrar_fn(ecx: &EncodeContext, rbml_w: &mut Encoder) { } } +fn encode_codemap(ecx: &EncodeContext, rbml_w: &mut Encoder) { + rbml_w.start_tag(tag_codemap); + let codemap = ecx.tcx.sess.codemap(); + + for filemap in &codemap.files.borrow()[..] { + + if filemap.lines.borrow().len() == 0 || filemap.is_imported() { + // No need to export empty filemaps, as they can't contain spans + // that need translation. + // Also no need to re-export imported filemaps, as any downstream + // crate will import them from their original source. + continue; + } + + rbml_w.start_tag(tag_codemap_filemap); + filemap.encode(rbml_w); + rbml_w.end_tag(); + } + + rbml_w.end_tag(); +} + /// Serialize the text of the exported macros fn encode_macro_defs(rbml_w: &mut Encoder, krate: &ast::Crate) { @@ -1968,6 +2006,7 @@ fn encode_metadata_inner(wr: &mut SeekableMemWriter, lang_item_bytes: u64, native_lib_bytes: u64, plugin_registrar_fn_bytes: u64, + codemap_bytes: u64, macro_defs_bytes: u64, impl_bytes: u64, misc_bytes: u64, @@ -1982,6 +2021,7 @@ fn encode_metadata_inner(wr: &mut SeekableMemWriter, lang_item_bytes: 0, native_lib_bytes: 0, plugin_registrar_fn_bytes: 0, + codemap_bytes: 0, macro_defs_bytes: 0, impl_bytes: 0, misc_bytes: 0, @@ -2047,6 +2087,11 @@ fn encode_metadata_inner(wr: &mut SeekableMemWriter, encode_plugin_registrar_fn(&ecx, &mut rbml_w); stats.plugin_registrar_fn_bytes = rbml_w.writer.tell().unwrap() - i; + // Encode codemap + i = rbml_w.writer.tell().unwrap(); + encode_codemap(&ecx, &mut rbml_w); + stats.codemap_bytes = rbml_w.writer.tell().unwrap() - i; + // Encode macro definitions i = rbml_w.writer.tell().unwrap(); encode_macro_defs(&mut rbml_w, krate); @@ -2091,6 +2136,7 @@ fn encode_metadata_inner(wr: &mut SeekableMemWriter, println!(" lang item bytes: {}", stats.lang_item_bytes); println!(" native bytes: {}", stats.native_lib_bytes); println!("plugin registrar bytes: {}", stats.plugin_registrar_fn_bytes); + println!(" codemap bytes: {}", stats.codemap_bytes); println!(" macro def bytes: {}", stats.macro_defs_bytes); println!(" impl bytes: {}", stats.impl_bytes); println!(" misc bytes: {}", stats.misc_bytes); diff --git a/src/librustc/metadata/filesearch.rs b/src/librustc/metadata/filesearch.rs index d1091b1d3f7..22a4a6fc978 100644 --- a/src/librustc/metadata/filesearch.rs +++ b/src/librustc/metadata/filesearch.rs @@ -14,9 +14,9 @@ pub use self::FileMatch::*; use std::collections::HashSet; use std::env; -use std::os; -use std::old_io::fs::PathExtensions; -use std::old_io::fs; +use std::fs; +use std::io::prelude::*; +use std::path::{Path, PathBuf}; use util::fs as myfs; use session::search_paths::{SearchPaths, PathKind}; @@ -50,20 +50,20 @@ impl<'a> FileSearch<'a> { FileMatches => found = true, FileDoesntMatch => () } - visited_dirs.insert(path.as_vec().to_vec()); + visited_dirs.insert(path.to_path_buf()); } debug!("filesearch: searching lib path"); let tlib_path = make_target_lib_path(self.sysroot, self.triple); - if !visited_dirs.contains(tlib_path.as_vec()) { + if !visited_dirs.contains(&tlib_path) { match f(&tlib_path, PathKind::All) { FileMatches => found = true, FileDoesntMatch => () } } - visited_dirs.insert(tlib_path.as_vec().to_vec()); + visited_dirs.insert(tlib_path); // Try RUST_PATH if !found { let rustpath = rust_path(); @@ -71,10 +71,10 @@ impl<'a> FileSearch<'a> { let tlib_path = make_rustpkg_lib_path( self.sysroot, path, self.triple); debug!("is {} in visited_dirs? {}", tlib_path.display(), - visited_dirs.contains(&tlib_path.as_vec().to_vec())); + visited_dirs.contains(&tlib_path)); - if !visited_dirs.contains(tlib_path.as_vec()) { - visited_dirs.insert(tlib_path.as_vec().to_vec()); + if !visited_dirs.contains(&tlib_path) { + visited_dirs.insert(tlib_path.clone()); // Don't keep searching the RUST_PATH if one match turns up -- // if we did, we'd get a "multiple matching crates" error match f(&tlib_path, PathKind::All) { @@ -88,7 +88,7 @@ impl<'a> FileSearch<'a> { } } - pub fn get_lib_path(&self) -> Path { + pub fn get_lib_path(&self) -> PathBuf { make_target_lib_path(self.sysroot, self.triple) } @@ -97,11 +97,13 @@ impl<'a> FileSearch<'a> { { self.for_each_lib_search_path(|lib_search_path, kind| { debug!("searching {}", lib_search_path.display()); - match fs::readdir(lib_search_path) { + match fs::read_dir(lib_search_path) { Ok(files) => { + let files = files.filter_map(|p| p.ok().map(|s| s.path())) + .collect::<Vec<_>>(); let mut rslt = FileDoesntMatch; - fn is_rlib(p: & &Path) -> bool { - p.extension_str() == Some("rlib") + fn is_rlib(p: &Path) -> bool { + p.extension().and_then(|s| s.to_str()) == Some("rlib") } // Reading metadata out of rlibs is faster, and if we find both // an rlib and a dylib we only read one of the files of @@ -143,59 +145,60 @@ impl<'a> FileSearch<'a> { } // Returns a list of directories where target-specific dylibs might be located. - pub fn get_dylib_search_paths(&self) -> Vec<Path> { + pub fn get_dylib_search_paths(&self) -> Vec<PathBuf> { let mut paths = Vec::new(); self.for_each_lib_search_path(|lib_search_path, _| { - paths.push(lib_search_path.clone()); + paths.push(lib_search_path.to_path_buf()); FileDoesntMatch }); paths } // Returns a list of directories where target-specific tool binaries are located. - pub fn get_tools_search_paths(&self) -> Vec<Path> { - let mut p = Path::new(self.sysroot); - p.push(find_libdir(self.sysroot)); - p.push(rustlibdir()); - p.push(self.triple); + pub fn get_tools_search_paths(&self) -> Vec<PathBuf> { + let mut p = PathBuf::new(self.sysroot); + p.push(&find_libdir(self.sysroot)); + p.push(&rustlibdir()); + p.push(&self.triple); p.push("bin"); vec![p] } } -pub fn relative_target_lib_path(sysroot: &Path, target_triple: &str) -> Path { - let mut p = Path::new(find_libdir(sysroot)); +pub fn relative_target_lib_path(sysroot: &Path, target_triple: &str) -> PathBuf { + let mut p = PathBuf::new(&find_libdir(sysroot)); assert!(p.is_relative()); - p.push(rustlibdir()); + p.push(&rustlibdir()); p.push(target_triple); p.push("lib"); p } fn make_target_lib_path(sysroot: &Path, - target_triple: &str) -> Path { + target_triple: &str) -> PathBuf { sysroot.join(&relative_target_lib_path(sysroot, target_triple)) } fn make_rustpkg_lib_path(sysroot: &Path, dir: &Path, - triple: &str) -> Path { - let mut p = dir.join(find_libdir(sysroot)); + triple: &str) -> PathBuf { + let mut p = dir.join(&find_libdir(sysroot)); p.push(triple); p } -pub fn get_or_default_sysroot() -> Path { +pub fn get_or_default_sysroot() -> PathBuf { // Follow symlinks. If the resolved path is relative, make it absolute. - fn canonicalize(path: Option<Path>) -> Option<Path> { - path.and_then(|path| + fn canonicalize(path: Option<PathBuf>) -> Option<PathBuf> { + path.and_then(|path| { match myfs::realpath(&path) { Ok(canon) => Some(canon), Err(e) => panic!("failed to get realpath: {}", e), - }) + } + }) } - match canonicalize(os::self_exe_name()) { + match canonicalize(env::current_exe().ok()) { Some(mut p) => { p.pop(); p.pop(); p } None => panic!("can't determine value for sysroot") } @@ -216,16 +219,16 @@ pub fn get_rust_path() -> Option<String> { /// $HOME/.rust /// DIR/.rust for any DIR that's the current working directory /// or an ancestor of it -pub fn rust_path() -> Vec<Path> { - let mut env_rust_path: Vec<Path> = match get_rust_path() { +pub fn rust_path() -> Vec<PathBuf> { + let mut env_rust_path: Vec<PathBuf> = match get_rust_path() { Some(env_path) => { let env_path_components = env_path.split(PATH_ENTRY_SEPARATOR); - env_path_components.map(|s| Path::new(s)).collect() + env_path_components.map(|s| PathBuf::new(s)).collect() } None => Vec::new() }; - let mut cwd = os::getcwd().unwrap(); + let cwd = env::current_dir().unwrap(); // now add in default entries let cwd_dot_rust = cwd.join(".rust"); if !env_rust_path.contains(&cwd_dot_rust) { @@ -234,17 +237,15 @@ pub fn rust_path() -> Vec<Path> { if !env_rust_path.contains(&cwd) { env_rust_path.push(cwd.clone()); } - loop { - if { let f = cwd.filename(); f.is_none() || f.unwrap() == b".." } { - break - } - cwd.set_filename(".rust"); - if !env_rust_path.contains(&cwd) && cwd.exists() { - env_rust_path.push(cwd.clone()); + let mut cur = &*cwd; + while let Some(parent) = cur.parent() { + let candidate = parent.join(".rust"); + if !env_rust_path.contains(&candidate) && candidate.exists() { + env_rust_path.push(candidate.clone()); } - cwd.pop(); + cur = parent; } - if let Some(h) = os::homedir() { + if let Some(h) = env::home_dir() { let p = h.join(".rust"); if !env_rust_path.contains(&p) && p.exists() { env_rust_path.push(p); @@ -267,7 +268,7 @@ fn find_libdir(sysroot: &Path) -> String { match option_env!("CFG_LIBDIR_RELATIVE") { Some(libdir) if libdir != "lib" => return libdir.to_string(), - _ => if sysroot.join(primary_libdir_name()).join(rustlibdir()).exists() { + _ => if sysroot.join(&primary_libdir_name()).join(&rustlibdir()).exists() { return primary_libdir_name(); } else { return secondary_libdir_name(); diff --git a/src/librustc/metadata/loader.rs b/src/librustc/metadata/loader.rs index 07082d81876..8486bf782b0 100644 --- a/src/librustc/metadata/loader.rs +++ b/src/librustc/metadata/loader.rs @@ -226,13 +226,14 @@ use metadata::filesearch::{FileSearch, FileMatches, FileDoesntMatch}; use syntax::codemap::Span; use syntax::diagnostic::SpanHandler; use util::fs; +use util::common; use rustc_back::target::Target; -use std::ffi::CString; use std::cmp; use std::collections::HashMap; -use std::old_io::fs::PathExtensions; -use std::old_io; +use std::io::prelude::*; +use std::io; +use std::path::{Path, PathBuf}; use std::ptr; use std::slice; use std::time::Duration; @@ -240,7 +241,7 @@ use std::time::Duration; use flate; pub struct CrateMismatch { - path: Path, + path: PathBuf, got: String, } @@ -262,8 +263,8 @@ pub struct Context<'a> { } pub struct Library { - pub dylib: Option<(Path, PathKind)>, - pub rlib: Option<(Path, PathKind)>, + pub dylib: Option<(PathBuf, PathKind)>, + pub rlib: Option<(PathBuf, PathKind)>, pub metadata: MetadataBlob, } @@ -275,12 +276,12 @@ pub struct ArchiveMetadata { pub struct CratePaths { pub ident: String, - pub dylib: Option<Path>, - pub rlib: Option<Path> + pub dylib: Option<PathBuf>, + pub rlib: Option<PathBuf> } impl CratePaths { - fn paths(&self) -> Vec<Path> { + fn paths(&self) -> Vec<PathBuf> { match (&self.dylib, &self.rlib) { (&None, &None) => vec!(), (&Some(ref p), &None) | @@ -353,7 +354,7 @@ impl<'a> Context<'a> { } } if self.rejected_via_kind.len() > 0 { - self.sess.span_help(self.span, "please recompile this crate using \ + self.sess.fileline_help(self.span, "please recompile this crate using \ --crate-type lib"); let mismatches = self.rejected_via_kind.iter(); for (i, &CrateMismatch { ref path, .. }) in mismatches.enumerate() { @@ -400,7 +401,7 @@ impl<'a> Context<'a> { // // The goal of this step is to look at as little metadata as possible. self.filesearch.search(|path, kind| { - let file = match path.filename_str() { + let file = match path.file_name().and_then(|s| s.to_str()) { None => return FileDoesntMatch, Some(file) => file, }; @@ -416,7 +417,7 @@ impl<'a> Context<'a> { if file.starts_with(&staticlib_prefix[..]) && file.ends_with(".a") { staticlibs.push(CrateMismatch { - path: path.clone(), + path: path.to_path_buf(), got: "static".to_string() }); } @@ -506,9 +507,9 @@ impl<'a> Context<'a> { // read the metadata from it if `*slot` is `None`. If the metadata couldn't // be read, it is assumed that the file isn't a valid rust library (no // errors are emitted). - fn extract_one(&mut self, m: HashMap<Path, PathKind>, flavor: &str, - slot: &mut Option<MetadataBlob>) -> Option<(Path, PathKind)> { - let mut ret = None::<(Path, PathKind)>; + fn extract_one(&mut self, m: HashMap<PathBuf, PathKind>, flavor: &str, + slot: &mut Option<MetadataBlob>) -> Option<(PathBuf, PathKind)> { + let mut ret = None::<(PathBuf, PathKind)>; let mut error = 0; if slot.is_some() { @@ -587,7 +588,7 @@ impl<'a> Context<'a> { if triple != self.triple { info!("Rejecting via crate triple: expected {} got {}", self.triple, triple); self.rejected_via_triple.push(CrateMismatch { - path: libpath.clone(), + path: libpath.to_path_buf(), got: triple.to_string() }); return false; @@ -599,7 +600,7 @@ impl<'a> Context<'a> { if *myhash != hash { info!("Rejecting via hash: expected {} got {}", *myhash, hash); self.rejected_via_hash.push(CrateMismatch { - path: libpath.clone(), + path: libpath.to_path_buf(), got: myhash.as_str().to_string() }); false @@ -627,13 +628,13 @@ impl<'a> Context<'a> { let mut rlibs = HashMap::new(); let mut dylibs = HashMap::new(); { - let locs = locs.iter().map(|l| Path::new(&l[..])).filter(|loc| { + let locs = locs.iter().map(|l| PathBuf::new(&l[..])).filter(|loc| { if !loc.exists() { sess.err(&format!("extern location for {} does not exist: {}", self.crate_name, loc.display())); return false; } - let file = match loc.filename_str() { + let file = match loc.file_name().and_then(|s| s.to_str()) { Some(file) => file, None => { sess.err(&format!("extern location for {} is not a file: {}", @@ -658,7 +659,7 @@ impl<'a> Context<'a> { // Now that we have an iterator of good candidates, make sure // there's at most one rlib and at most one dylib. for loc in locs { - if loc.filename_str().unwrap().ends_with(".rlib") { + if loc.file_name().unwrap().to_str().unwrap().ends_with(".rlib") { rlibs.insert(fs::realpath(&loc).unwrap(), PathKind::ExternFlag); } else { @@ -714,7 +715,7 @@ fn get_metadata_section(is_osx: bool, filename: &Path) -> Result<MetadataBlob, S let dur = Duration::span(|| { ret = Some(get_metadata_section_imp(is_osx, filename)); }); - info!("reading {} => {}ms", filename.filename_display(), + info!("reading {:?} => {}ms", filename.file_name().unwrap(), dur.num_milliseconds()); return ret.unwrap();; } @@ -723,7 +724,7 @@ fn get_metadata_section_imp(is_osx: bool, filename: &Path) -> Result<MetadataBlo if !filename.exists() { return Err(format!("no such file: '{}'", filename.display())); } - if filename.filename_str().unwrap().ends_with(".rlib") { + if filename.file_name().unwrap().to_str().unwrap().ends_with(".rlib") { // Use ArchiveRO for speed here, it's backed by LLVM and uses mmap // internally to read the file. We also avoid even using a memcpy by // just keeping the archive along while the metadata is in use. @@ -742,7 +743,7 @@ fn get_metadata_section_imp(is_osx: bool, filename: &Path) -> Result<MetadataBlo }; } unsafe { - let buf = CString::new(filename.as_vec()).unwrap(); + let buf = common::path2cstr(filename); let mb = llvm::LLVMRustCreateMemoryBufferWithContentsOfFile(buf.as_ptr()); if mb as int == 0 { return Err(format!("error reading library: '{}'", @@ -811,7 +812,7 @@ pub fn read_meta_section_name(is_osx: bool) -> &'static str { // A diagnostic function for dumping crate metadata to an output stream pub fn list_file_metadata(is_osx: bool, path: &Path, - out: &mut old_io::Writer) -> old_io::IoResult<()> { + out: &mut io::Write) -> io::Result<()> { match get_metadata_section(is_osx, path) { Ok(bytes) => decoder::list_crate_metadata(bytes.as_slice(), out), Err(msg) => { diff --git a/src/librustc/metadata/macro_import.rs b/src/librustc/metadata/macro_import.rs index d25dc4f58a5..3714e3b8c73 100644 --- a/src/librustc/metadata/macro_import.rs +++ b/src/librustc/metadata/macro_import.rs @@ -84,7 +84,7 @@ impl<'a, 'v> Visitor<'v> for MacroLoader<'a> { } "plugin" => { self.sess.span_err(attr.span, "#[plugin] on `extern crate` is deprecated"); - self.sess.span_help(attr.span, &format!("use a crate attribute instead, \ + self.sess.fileline_help(attr.span, &format!("use a crate attribute instead, \ i.e. #![plugin({})]", item.ident.as_str())); } @@ -166,6 +166,9 @@ impl<'a> MacroLoader<'a> { Some(sel) => sel.contains_key(&name), }; def.export = reexport.contains_key(&name); + def.allow_internal_unstable = attr::contains_name(&def.attrs, + "allow_internal_unstable"); + debug!("load_macros: loaded: {:?}", def); self.macros.push(def); } diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index 33c0fb8b031..9d712c7c0fc 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -42,6 +42,7 @@ use syntax; use std::old_io::Seek; use std::num::FromPrimitive; use std::rc::Rc; +use std::cell::Cell; use rbml::reader; use rbml::writer::Encoder; @@ -58,7 +59,9 @@ struct DecodeContext<'a, 'b, 'tcx: 'a> { tcx: &'a ty::ctxt<'tcx>, cdata: &'b cstore::crate_metadata, from_id_range: ast_util::IdRange, - to_id_range: ast_util::IdRange + to_id_range: ast_util::IdRange, + // Cache the last used filemap for translating spans as an optimization. + last_filemap_index: Cell<usize>, } trait tr { @@ -120,6 +123,8 @@ impl<'a, 'b, 'c, 'tcx> ast_map::FoldOps for &'a DecodeContext<'b, 'c, 'tcx> { } } +/// Decodes an item from its AST in the cdata's metadata and adds it to the +/// ast-map. pub fn decode_inlined_item<'tcx>(cdata: &cstore::crate_metadata, tcx: &ty::ctxt<'tcx>, path: Vec<ast_map::PathElem>, @@ -143,7 +148,8 @@ pub fn decode_inlined_item<'tcx>(cdata: &cstore::crate_metadata, cdata: cdata, tcx: tcx, from_id_range: from_id_range, - to_id_range: to_id_range + to_id_range: to_id_range, + last_filemap_index: Cell::new(0) }; let raw_ii = decode_ast(ast_doc); let ii = ast_map::map_decoded_item(&dcx.tcx.map, path, raw_ii, dcx); @@ -234,8 +240,47 @@ impl<'a, 'b, 'tcx> DecodeContext<'a, 'b, 'tcx> { assert_eq!(did.krate, ast::LOCAL_CRATE); ast::DefId { krate: ast::LOCAL_CRATE, node: self.tr_id(did.node) } } - pub fn tr_span(&self, _span: Span) -> Span { - codemap::DUMMY_SP // FIXME (#1972): handle span properly + + /// Translates a `Span` from an extern crate to the corresponding `Span` + /// within the local crate's codemap. `creader::import_codemap()` will + /// already have allocated any additionally needed FileMaps in the local + /// codemap as a side-effect of creating the crate_metadata's + /// `codemap_import_info`. + pub fn tr_span(&self, span: Span) -> Span { + let imported_filemaps = &self.cdata.codemap_import_info[..]; + + let filemap_index = { + // Optimize for the case that most spans within a translated item + // originate from the same filemap. + let last_filemap_index = self.last_filemap_index.get(); + + if span.lo >= imported_filemaps[last_filemap_index].original_start_pos && + span.hi <= imported_filemaps[last_filemap_index].original_end_pos { + last_filemap_index + } else { + let mut a = 0; + let mut b = imported_filemaps.len(); + + while b - a > 1 { + let m = (a + b) / 2; + if imported_filemaps[m].original_start_pos > span.lo { + b = m; + } else { + a = m; + } + } + + self.last_filemap_index.set(a); + a + } + }; + + let lo = (span.lo - imported_filemaps[filemap_index].original_start_pos) + + imported_filemaps[filemap_index].translated_filemap.start_pos; + let hi = (span.hi - imported_filemaps[filemap_index].original_start_pos) + + imported_filemaps[filemap_index].translated_filemap.start_pos; + + codemap::mk_sp(lo, hi) } } diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs index f8a2c507e42..40bba6fb0ac 100644 --- a/src/librustc/middle/check_match.rs +++ b/src/librustc/middle/check_match.rs @@ -246,7 +246,7 @@ fn check_for_bindings_named_the_same_as_variants(cx: &MatchCheckCtxt, pat: &Pat) "pattern binding `{}` is named the same as one \ of the variants of the type `{}`", &token::get_ident(ident.node), ty_to_string(cx.tcx, pat_ty)); - span_help!(cx.tcx.sess, p.span, + fileline_help!(cx.tcx.sess, p.span, "if you meant to match on a variant, \ consider making the path in the pattern qualified: `{}::{}`", ty_to_string(cx.tcx, pat_ty), &token::get_ident(ident.node)); @@ -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") diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs index ae43738d471..f215b59a6cd 100644 --- a/src/librustc/middle/const_eval.rs +++ b/src/librustc/middle/const_eval.rs @@ -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()) } } @@ -537,7 +537,7 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>, ast::ExprBlock(ref block) => { match block.expr { Some(ref expr) => try!(eval_const_expr_partial(tcx, &**expr, ety)), - None => const_int(0i64) + None => const_int(0) } } ast::ExprTupField(ref base, index) => { @@ -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; } }; diff --git a/src/librustc/middle/dataflow.rs b/src/librustc/middle/dataflow.rs index faed3f5977f..a1ce8d18184 100644 --- a/src/librustc/middle/dataflow.rs +++ b/src/librustc/middle/dataflow.rs @@ -19,7 +19,7 @@ pub use self::EntryOrExit::*; use middle::cfg; use middle::cfg::CFGIndex; use middle::ty; -use std::old_io; +use std::io; use std::usize; use std::iter::repeat; use syntax::ast; @@ -103,7 +103,7 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> { impl<'a, 'tcx, O:DataFlowOperator> pprust::PpAnn for DataFlowContext<'a, 'tcx, O> { fn pre(&self, ps: &mut pprust::State, - node: pprust::AnnNode) -> old_io::IoResult<()> { + node: pprust::AnnNode) -> io::Result<()> { let id = match node { pprust::NodeIdent(_) | pprust::NodeName(_) => 0, pprust::NodeExpr(expr) => expr.id, @@ -485,13 +485,15 @@ impl<'a, 'tcx, O:DataFlowOperator+Clone+'static> DataFlowContext<'a, 'tcx, O> { debug!("Dataflow result for {}:", self.analysis_name); debug!("{}", { - self.pretty_print_to(box old_io::stderr(), blk).unwrap(); + let mut v = Vec::new(); + self.pretty_print_to(box &mut v, blk).unwrap(); + println!("{}", String::from_utf8(v).unwrap()); "" }); } - fn pretty_print_to(&self, wr: Box<old_io::Writer+'static>, - blk: &ast::Block) -> old_io::IoResult<()> { + fn pretty_print_to<'b>(&self, wr: Box<io::Write + 'b>, + blk: &ast::Block) -> io::Result<()> { let mut ps = pprust::rust_printer_annotated(wr, self); try!(ps.cbox(pprust::indent_unit)); try!(ps.ibox(0)); diff --git a/src/librustc/middle/infer/error_reporting.rs b/src/librustc/middle/infer/error_reporting.rs index da4df813030..a7f5c2c8437 100644 --- a/src/librustc/middle/infer/error_reporting.rs +++ b/src/librustc/middle/infer/error_reporting.rs @@ -444,7 +444,7 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> { // Does the required lifetime have a nice name we can print? span_err!(self.tcx.sess, origin.span(), E0309, "{} may not live long enough", labeled_user_string); - self.tcx.sess.span_help( + self.tcx.sess.fileline_help( origin.span(), &format!( "consider adding an explicit lifetime bound `{}: {}`...", @@ -456,7 +456,7 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> { // Does the required lifetime have a nice name we can print? span_err!(self.tcx.sess, origin.span(), E0310, "{} may not live long enough", labeled_user_string); - self.tcx.sess.span_help( + self.tcx.sess.fileline_help( origin.span(), &format!( "consider adding an explicit lifetime bound `{}: 'static`...", @@ -468,7 +468,7 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> { span_err!(self.tcx.sess, origin.span(), E0311, "{} may not live long enough", labeled_user_string); - self.tcx.sess.span_help( + self.tcx.sess.fileline_help( origin.span(), &format!( "consider adding an explicit lifetime bound for `{}`", diff --git a/src/librustc/middle/infer/region_inference/graphviz.rs b/src/librustc/middle/infer/region_inference/graphviz.rs index 43cd1fc8edb..6211fde7919 100644 --- a/src/librustc/middle/infer/region_inference/graphviz.rs +++ b/src/librustc/middle/infer/region_inference/graphviz.rs @@ -28,8 +28,10 @@ use util::ppaux::Repr; use std::borrow::Cow; use std::collections::hash_map::Entry::Vacant; -use std::old_io::{self, File}; use std::env; +use std::fs::File; +use std::io; +use std::io::prelude::*; use std::sync::atomic::{AtomicBool, Ordering, ATOMIC_BOOL_INIT}; use syntax::ast; @@ -256,10 +258,11 @@ pub type ConstraintMap<'tcx> = FnvHashMap<Constraint, SubregionOrigin<'tcx>>; fn dump_region_constraints_to<'a, 'tcx:'a >(tcx: &'a ty::ctxt<'tcx>, map: &ConstraintMap<'tcx>, - path: &str) -> old_io::IoResult<()> { + path: &str) -> io::Result<()> { debug!("dump_region_constraints map (len: {}) path: {}", map.len(), path); let g = ConstraintGraph::new(tcx, format!("region_constraints"), map); - let mut f = File::create(&Path::new(path)); debug!("dump_region_constraints calling render"); - dot::render(&g, &mut f) + let mut v = Vec::new(); + dot::render(&g, &mut v).unwrap(); + File::create(path).and_then(|mut f| f.write_all(&v)) } diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index ddac6cc7514..3599ba5a0f7 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -362,8 +362,6 @@ pub fn check_item(tcx: &ty::ctxt, item: &ast::Item, warn_about_defns: bool, /// Helper for discovering nodes to check for stability pub fn check_expr(tcx: &ty::ctxt, e: &ast::Expr, cb: &mut FnMut(ast::DefId, Span, &Option<Stability>)) { - if is_internal(tcx, e.span) { return; } - let span; let id = match e.node { ast::ExprMethodCall(i, _, _) => { @@ -527,12 +525,13 @@ pub fn check_pat(tcx: &ty::ctxt, pat: &ast::Pat, fn maybe_do_stability_check(tcx: &ty::ctxt, id: ast::DefId, span: Span, cb: &mut FnMut(ast::DefId, Span, &Option<Stability>)) { if !is_staged_api(tcx, id) { return } + if is_internal(tcx, span) { return } let ref stability = lookup(tcx, id); cb(id, span, stability); } fn is_internal(tcx: &ty::ctxt, span: Span) -> bool { - tcx.sess.codemap().span_is_internal(span) + tcx.sess.codemap().span_allows_unstable(span) } fn is_staged_api(tcx: &ty::ctxt, id: DefId) -> bool { diff --git a/src/librustc/middle/traits/mod.rs b/src/librustc/middle/traits/mod.rs index 5a5639c7012..f46cac30828 100644 --- a/src/librustc/middle/traits/mod.rs +++ b/src/librustc/middle/traits/mod.rs @@ -280,7 +280,11 @@ pub struct VtableBuiltinData<N> { /// for the object type `Foo`. #[derive(PartialEq,Eq,Clone)] pub struct VtableObjectData<'tcx> { + /// the object type `Foo`. pub object_ty: Ty<'tcx>, + + /// `Foo` upcast to the obligation trait. This will be some supertrait of `Foo`. + pub upcast_trait_ref: ty::PolyTraitRef<'tcx>, } /// Creates predicate obligations from the generic bounds. diff --git a/src/librustc/middle/traits/object_safety.rs b/src/librustc/middle/traits/object_safety.rs index 64835a666fa..881487a2dad 100644 --- a/src/librustc/middle/traits/object_safety.rs +++ b/src/librustc/middle/traits/object_safety.rs @@ -22,7 +22,7 @@ use super::elaborate_predicates; use middle::subst::{self, SelfSpace, TypeSpace}; use middle::traits; -use middle::ty::{self, Ty}; +use middle::ty::{self, ToPolyTraitRef, Ty}; use std::rc::Rc; use syntax::ast; use util::ppaux::Repr; @@ -128,9 +128,12 @@ fn supertraits_reference_self<'tcx>(tcx: &ty::ctxt<'tcx>, { let trait_def = ty::lookup_trait_def(tcx, trait_def_id); let trait_ref = trait_def.trait_ref.clone(); - let predicates = ty::predicates_for_trait_ref(tcx, &ty::Binder(trait_ref)); + let trait_ref = trait_ref.to_poly_trait_ref(); + let predicates = ty::lookup_super_predicates(tcx, trait_def_id); predicates + .predicates .into_iter() + .map(|predicate| predicate.subst_supertrait(tcx, &trait_ref)) .any(|predicate| { match predicate { ty::Predicate::Trait(ref data) => { diff --git a/src/librustc/middle/traits/select.rs b/src/librustc/middle/traits/select.rs index 470315c78f8..7dfbccea0dc 100644 --- a/src/librustc/middle/traits/select.rs +++ b/src/librustc/middle/traits/select.rs @@ -1260,19 +1260,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { poly_trait_ref.repr(self.tcx())); // see whether the object trait can be upcast to the trait we are looking for - let obligation_def_id = obligation.predicate.def_id(); - let upcast_trait_ref = match util::upcast(self.tcx(), poly_trait_ref, obligation_def_id) { - Some(r) => r, - None => { return; } - }; - - debug!("assemble_candidates_from_object_ty: upcast_trait_ref={}", - upcast_trait_ref.repr(self.tcx())); - - // check whether the upcast version of the trait-ref matches what we are looking for - if let Ok(()) = self.infcx.probe(|_| self.match_poly_trait_ref(obligation, - upcast_trait_ref.clone())) { - debug!("assemble_candidates_from_object_ty: matched, pushing candidate"); + let upcast_trait_refs = self.upcast(poly_trait_ref, obligation); + if upcast_trait_refs.len() > 1 { + // can be upcast in many ways; need more type information + candidates.ambiguous = true; + } else if upcast_trait_refs.len() == 1 { candidates.vec.push(ObjectCandidate); } } @@ -1455,9 +1447,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let principal = data.principal_trait_ref_with_self_ty(self.tcx(), self.tcx().types.err); + let desired_def_id = obligation.predicate.def_id(); for tr in util::supertraits(self.tcx(), principal) { - let td = ty::lookup_trait_def(self.tcx(), tr.def_id()); - if td.bounds.builtin_bounds.contains(&bound) { + if tr.def_id() == desired_def_id { return Ok(If(Vec::new())) } } @@ -1700,6 +1692,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } } + // for `PhantomData<T>`, we pass `T` + ty::ty_struct(def_id, substs) + if Some(def_id) == self.tcx().lang_items.phantom_data() => + { + Some(substs.types.get_slice(TypeSpace).to_vec()) + } + ty::ty_struct(def_id, substs) => { Some(ty::struct_fields(self.tcx(), def_id, substs).iter() .map(|f| f.mt.ty) @@ -2063,20 +2062,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } }; - let obligation_def_id = obligation.predicate.def_id(); - let upcast_trait_ref = match util::upcast(self.tcx(), - poly_trait_ref.clone(), - obligation_def_id) { - Some(r) => r, - None => { - self.tcx().sess.span_bug(obligation.cause.span, - &format!("unable to upcast from {} to {}", - poly_trait_ref.repr(self.tcx()), - obligation_def_id.repr(self.tcx()))); - } - }; + // Upcast the object type to the obligation type. There must + // be exactly one applicable trait-reference; if this were not + // the case, we would have reported an ambiguity error rather + // than successfully selecting one of the candidates. + let upcast_trait_refs = self.upcast(poly_trait_ref.clone(), obligation); + assert_eq!(upcast_trait_refs.len(), 1); + let upcast_trait_ref = upcast_trait_refs.into_iter().next().unwrap(); - match self.match_poly_trait_ref(obligation, upcast_trait_ref) { + match self.match_poly_trait_ref(obligation, upcast_trait_ref.clone()) { Ok(()) => { } Err(()) => { self.tcx().sess.span_bug(obligation.cause.span, @@ -2084,7 +2078,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } } - VtableObjectData { object_ty: self_ty } + VtableObjectData { object_ty: self_ty, + upcast_trait_ref: upcast_trait_ref } } fn confirm_fn_pointer_candidate(&mut self, @@ -2501,6 +2496,32 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { obligation.cause.clone() } } + + /// Upcasts an object trait-reference into those that match the obligation. + fn upcast(&mut self, obj_trait_ref: ty::PolyTraitRef<'tcx>, obligation: &TraitObligation<'tcx>) + -> Vec<ty::PolyTraitRef<'tcx>> + { + debug!("upcast(obj_trait_ref={}, obligation={})", + obj_trait_ref.repr(self.tcx()), + obligation.repr(self.tcx())); + + let obligation_def_id = obligation.predicate.def_id(); + let mut upcast_trait_refs = util::upcast(self.tcx(), obj_trait_ref, obligation_def_id); + + // Retain only those upcast versions that match the trait-ref + // we are looking for. In particular, we know that all of + // `upcast_trait_refs` apply to the correct trait, but + // possibly with incorrect type parameters. For example, we + // may be trying to upcast `Foo` to `Bar<i32>`, but `Foo` is + // declared as `trait Foo : Bar<u32>`. + upcast_trait_refs.retain(|upcast_trait_ref| { + let upcast_trait_ref = upcast_trait_ref.clone(); + self.infcx.probe(|_| self.match_poly_trait_ref(obligation, upcast_trait_ref)).is_ok() + }); + + debug!("upcast: upcast_trait_refs={}", upcast_trait_refs.repr(self.tcx())); + upcast_trait_refs + } } impl<'tcx> Repr<'tcx> for SelectionCandidate<'tcx> { diff --git a/src/librustc/middle/traits/util.rs b/src/librustc/middle/traits/util.rs index 7bef5f32475..4527985302a 100644 --- a/src/librustc/middle/traits/util.rs +++ b/src/librustc/middle/traits/util.rs @@ -76,15 +76,10 @@ impl<'a,'tcx> PredicateSet<'a,'tcx> { /// 'static`. pub struct Elaborator<'cx, 'tcx:'cx> { tcx: &'cx ty::ctxt<'tcx>, - stack: Vec<StackEntry<'tcx>>, + stack: Vec<ty::Predicate<'tcx>>, visited: PredicateSet<'cx,'tcx>, } -struct StackEntry<'tcx> { - position: uint, - predicates: Vec<ty::Predicate<'tcx>>, -} - pub fn elaborate_trait_ref<'cx, 'tcx>( tcx: &'cx ty::ctxt<'tcx>, trait_ref: ty::PolyTraitRef<'tcx>) @@ -111,21 +106,28 @@ pub fn elaborate_predicates<'cx, 'tcx>( { let mut visited = PredicateSet::new(tcx); predicates.retain(|pred| visited.insert(pred)); - let entry = StackEntry { position: 0, predicates: predicates }; - Elaborator { tcx: tcx, stack: vec![entry], visited: visited } + Elaborator { tcx: tcx, stack: predicates, visited: visited } } impl<'cx, 'tcx> Elaborator<'cx, 'tcx> { - pub fn filter_to_traits(self) -> Supertraits<'cx, 'tcx> { - Supertraits { elaborator: self } + pub fn filter_to_traits(self) -> FilterToTraits<Elaborator<'cx, 'tcx>> { + FilterToTraits::new(self) } fn push(&mut self, predicate: &ty::Predicate<'tcx>) { match *predicate { ty::Predicate::Trait(ref data) => { - let mut predicates = - ty::predicates_for_trait_ref(self.tcx, - &data.to_poly_trait_ref()); + // Predicates declared on the trait. + let predicates = ty::lookup_super_predicates(self.tcx, data.def_id()); + + let mut predicates: Vec<_> = + predicates.predicates + .iter() + .map(|p| p.subst_supertrait(self.tcx, &data.to_poly_trait_ref())) + .collect(); + + debug!("super_predicates: data={} predicates={}", + data.repr(self.tcx), predicates.repr(self.tcx)); // Only keep those bounds that we haven't already // seen. This is necessary to prevent infinite @@ -134,8 +136,7 @@ impl<'cx, 'tcx> Elaborator<'cx, 'tcx> { // Sized { }`. predicates.retain(|r| self.visited.insert(r)); - self.stack.push(StackEntry { position: 0, - predicates: predicates }); + self.stack.extend(predicates.into_iter()); } ty::Predicate::Equate(..) => { // Currently, we do not "elaborate" predicates like @@ -175,41 +176,16 @@ impl<'cx, 'tcx> Iterator for Elaborator<'cx, 'tcx> { type Item = ty::Predicate<'tcx>; fn next(&mut self) -> Option<ty::Predicate<'tcx>> { - loop { - // Extract next item from top-most stack frame, if any. - let next_predicate = match self.stack.last_mut() { - None => { - // No more stack frames. Done. - return None; - } - Some(entry) => { - let p = entry.position; - if p < entry.predicates.len() { - // Still more predicates left in the top stack frame. - entry.position += 1; - - let next_predicate = - entry.predicates[p].clone(); - - Some(next_predicate) - } else { - None - } - } - }; - - match next_predicate { - Some(next_predicate) => { - self.push(&next_predicate); - return Some(next_predicate); - } - - None => { - // Top stack frame is exhausted, pop it. - self.stack.pop(); - } + // Extract next item from top-most stack frame, if any. + let next_predicate = match self.stack.pop() { + Some(predicate) => predicate, + None => { + // No more stack frames. Done. + return None; } - } + }; + self.push(&next_predicate); + return Some(next_predicate); } } @@ -217,11 +193,7 @@ impl<'cx, 'tcx> Iterator for Elaborator<'cx, 'tcx> { // Supertrait iterator /////////////////////////////////////////////////////////////////////////// -/// A filter around the `Elaborator` that just yields up supertrait references, -/// not other kinds of predicates. -pub struct Supertraits<'cx, 'tcx:'cx> { - elaborator: Elaborator<'cx, 'tcx>, -} +pub type Supertraits<'cx, 'tcx> = FilterToTraits<Elaborator<'cx, 'tcx>>; pub fn supertraits<'cx, 'tcx>(tcx: &'cx ty::ctxt<'tcx>, trait_ref: ty::PolyTraitRef<'tcx>) @@ -237,12 +209,28 @@ pub fn transitive_bounds<'cx, 'tcx>(tcx: &'cx ty::ctxt<'tcx>, elaborate_trait_refs(tcx, bounds).filter_to_traits() } -impl<'cx, 'tcx> Iterator for Supertraits<'cx, 'tcx> { +/////////////////////////////////////////////////////////////////////////// +// Other +/////////////////////////////////////////////////////////////////////////// + +/// A filter around an iterator of predicates that makes it yield up +/// just trait references. +pub struct FilterToTraits<I> { + base_iterator: I +} + +impl<I> FilterToTraits<I> { + fn new(base: I) -> FilterToTraits<I> { + FilterToTraits { base_iterator: base } + } +} + +impl<'tcx,I:Iterator<Item=ty::Predicate<'tcx>>> Iterator for FilterToTraits<I> { type Item = ty::PolyTraitRef<'tcx>; fn next(&mut self) -> Option<ty::PolyTraitRef<'tcx>> { loop { - match self.elaborator.next() { + match self.base_iterator.next() { None => { return None; } @@ -256,6 +244,7 @@ impl<'cx, 'tcx> Iterator for Supertraits<'cx, 'tcx> { } } + /////////////////////////////////////////////////////////////////////////// // Other /////////////////////////////////////////////////////////////////////////// @@ -370,19 +359,15 @@ pub fn predicate_for_builtin_bound<'tcx>( pub fn upcast<'tcx>(tcx: &ty::ctxt<'tcx>, source_trait_ref: ty::PolyTraitRef<'tcx>, target_trait_def_id: ast::DefId) - -> Option<ty::PolyTraitRef<'tcx>> + -> Vec<ty::PolyTraitRef<'tcx>> { if source_trait_ref.def_id() == target_trait_def_id { - return Some(source_trait_ref); // shorcut the most common case - } - - for super_trait_ref in supertraits(tcx, source_trait_ref) { - if super_trait_ref.def_id() == target_trait_def_id { - return Some(super_trait_ref); - } + return vec![source_trait_ref]; // shorcut the most common case } - None + supertraits(tcx, source_trait_ref) + .filter(|r| r.def_id() == target_trait_def_id) + .collect() } /// Given an object of type `object_trait_ref`, returns the index of diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index f522b4ea03c..4cb4d343de7 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -17,7 +17,6 @@ pub use self::InferTy::*; pub use self::InferRegion::*; pub use self::ImplOrTraitItemId::*; pub use self::ClosureKind::*; -pub use self::ast_ty_to_ty_cache_entry::*; pub use self::Variance::*; pub use self::AutoAdjustment::*; pub use self::Representability::*; @@ -266,12 +265,6 @@ pub struct creader_cache_key { pub len: uint } -#[derive(Copy)] -pub enum ast_ty_to_ty_cache_entry<'tcx> { - atttce_unresolved, /* not resolved yet */ - atttce_resolved(Ty<'tcx>) /* resolved to a type, irrespective of region */ -} - #[derive(Clone, PartialEq, RustcDecodable, RustcEncodable)] pub struct ItemVariances { pub types: VecPerParamSpace<Variance>, @@ -716,6 +709,14 @@ pub struct ctxt<'tcx> { /// associated predicates. pub predicates: RefCell<DefIdMap<GenericPredicates<'tcx>>>, + /// Maps from the def-id of a trait to the list of + /// super-predicates. This is a subset of the full list of + /// predicates. We store these in a separate map because we must + /// evaluate them even during type conversion, often before the + /// full predicates are available (note that supertraits have + /// additional acyclicity requirements). + pub super_predicates: RefCell<DefIdMap<GenericPredicates<'tcx>>>, + /// Maps from node-id of a trait object cast (like `foo as /// Box<Trait>`) to the trait reference. pub object_cast_map: ObjectCastMap<'tcx>, @@ -727,7 +728,7 @@ pub struct ctxt<'tcx> { pub rcache: RefCell<FnvHashMap<creader_cache_key, Ty<'tcx>>>, pub short_names_cache: RefCell<FnvHashMap<Ty<'tcx>, String>>, pub tc_cache: RefCell<FnvHashMap<Ty<'tcx>, TypeContents>>, - pub ast_ty_to_ty_cache: RefCell<NodeMap<ast_ty_to_ty_cache_entry<'tcx>>>, + pub ast_ty_to_ty_cache: RefCell<NodeMap<Ty<'tcx>>>, pub enum_var_cache: RefCell<DefIdMap<Rc<Vec<Rc<VariantInfo<'tcx>>>>>>, pub ty_param_defs: RefCell<NodeMap<TypeParameterDef<'tcx>>>, pub adjustments: RefCell<NodeMap<AutoAdjustment<'tcx>>>, @@ -756,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. @@ -1352,7 +1353,7 @@ pub enum sty<'tcx> { /// definition and not a concrete use of it. To get the correct `ty_enum` /// from the tcx, use the `NodeId` from the `ast::Ty` and look it up in /// the `ast_ty_to_ty_cache`. This is probably true for `ty_struct` as - /// well.` + /// well. ty_enum(DefId, &'tcx Substs<'tcx>), ty_uniq(Ty<'tcx>), ty_str, @@ -1495,6 +1496,27 @@ impl<'tcx> PolyTraitRef<'tcx> { #[derive(Clone, PartialEq, Eq, Hash, Debug)] pub struct Binder<T>(pub T); +impl<T> Binder<T> { + /// Skips the binder and returns the "bound" value. This is a + /// risky thing to do because it's easy to get confused about + /// debruijn indices and the like. It is usually better to + /// discharge the binder using `no_late_bound_regions` or + /// `replace_late_bound_regions` or something like + /// that. `skip_binder` is only valid when you are either + /// extracting data that has nothing to do with bound regions, you + /// are doing some sort of test that does not involve bound + /// regions, or you are being very careful about your depth + /// accounting. + /// + /// Some examples where `skip_binder` is reasonable: + /// - extracting the def-id from a PolyTraitRef; + /// - comparing the self type of a PolyTraitRef to see if it is equal to + /// a type parameter `X`, since the type `X` does not reference any regions + pub fn skip_binder(&self) -> &T { + &self.0 + } +} + #[derive(Clone, Copy, PartialEq)] pub enum IntVarValue { IntType(ast::IntTy), @@ -1817,6 +1839,16 @@ impl<'tcx> GenericPredicates<'tcx> { predicates: self.predicates.subst(tcx, substs), } } + + pub fn instantiate_supertrait(&self, + tcx: &ty::ctxt<'tcx>, + poly_trait_ref: &ty::PolyTraitRef<'tcx>) + -> InstantiatedPredicates<'tcx> + { + InstantiatedPredicates { + predicates: self.predicates.map(|pred| pred.subst_supertrait(tcx, poly_trait_ref)) + } + } } #[derive(Clone, PartialEq, Eq, Hash, Debug)] @@ -1840,6 +1872,93 @@ pub enum Predicate<'tcx> { Projection(PolyProjectionPredicate<'tcx>), } +impl<'tcx> Predicate<'tcx> { + /// Performs a substituion suitable for going from a + /// poly-trait-ref to supertraits that must hold if that + /// poly-trait-ref holds. This is slightly different from a normal + /// substitution in terms of what happens with bound regions. See + /// lengthy comment below for details. + pub fn subst_supertrait(&self, + tcx: &ty::ctxt<'tcx>, + trait_ref: &ty::PolyTraitRef<'tcx>) + -> ty::Predicate<'tcx> + { + // The interaction between HRTB and supertraits is not entirely + // obvious. Let me walk you (and myself) through an example. + // + // Let's start with an easy case. Consider two traits: + // + // trait Foo<'a> : Bar<'a,'a> { } + // trait Bar<'b,'c> { } + // + // Now, if we have a trait reference `for<'x> T : Foo<'x>`, then + // we can deduce that `for<'x> T : Bar<'x,'x>`. Basically, if we + // knew that `Foo<'x>` (for any 'x) then we also know that + // `Bar<'x,'x>` (for any 'x). This more-or-less falls out from + // normal substitution. + // + // In terms of why this is sound, the idea is that whenever there + // is an impl of `T:Foo<'a>`, it must show that `T:Bar<'a,'a>` + // holds. So if there is an impl of `T:Foo<'a>` that applies to + // all `'a`, then we must know that `T:Bar<'a,'a>` holds for all + // `'a`. + // + // Another example to be careful of is this: + // + // trait Foo1<'a> : for<'b> Bar1<'a,'b> { } + // trait Bar1<'b,'c> { } + // + // Here, if we have `for<'x> T : Foo1<'x>`, then what do we know? + // The answer is that we know `for<'x,'b> T : Bar1<'x,'b>`. The + // reason is similar to the previous example: any impl of + // `T:Foo1<'x>` must show that `for<'b> T : Bar1<'x, 'b>`. So + // basically we would want to collapse the bound lifetimes from + // the input (`trait_ref`) and the supertraits. + // + // To achieve this in practice is fairly straightforward. Let's + // consider the more complicated scenario: + // + // - We start out with `for<'x> T : Foo1<'x>`. In this case, `'x` + // has a De Bruijn index of 1. We want to produce `for<'x,'b> T : Bar1<'x,'b>`, + // where both `'x` and `'b` would have a DB index of 1. + // The substitution from the input trait-ref is therefore going to be + // `'a => 'x` (where `'x` has a DB index of 1). + // - The super-trait-ref is `for<'b> Bar1<'a,'b>`, where `'a` is an + // early-bound parameter and `'b' is a late-bound parameter with a + // DB index of 1. + // - If we replace `'a` with `'x` from the input, it too will have + // a DB index of 1, and thus we'll have `for<'x,'b> Bar1<'x,'b>` + // just as we wanted. + // + // There is only one catch. If we just apply the substitution `'a + // => 'x` to `for<'b> Bar1<'a,'b>`, the substitution code will + // adjust the DB index because we substituting into a binder (it + // tries to be so smart...) resulting in `for<'x> for<'b> + // Bar1<'x,'b>` (we have no syntax for this, so use your + // imagination). Basically the 'x will have DB index of 2 and 'b + // will have DB index of 1. Not quite what we want. So we apply + // the substitution to the *contents* of the trait reference, + // rather than the trait reference itself (put another way, the + // substitution code expects equal binding levels in the values + // from the substitution and the value being substituted into, and + // this trick achieves that). + + let substs = &trait_ref.0.substs; + match *self { + Predicate::Trait(ty::Binder(ref data)) => + Predicate::Trait(ty::Binder(data.subst(tcx, substs))), + Predicate::Equate(ty::Binder(ref data)) => + Predicate::Equate(ty::Binder(data.subst(tcx, substs))), + Predicate::RegionOutlives(ty::Binder(ref data)) => + Predicate::RegionOutlives(ty::Binder(data.subst(tcx, substs))), + Predicate::TypeOutlives(ty::Binder(ref data)) => + Predicate::TypeOutlives(ty::Binder(data.subst(tcx, substs))), + Predicate::Projection(ty::Binder(ref data)) => + Predicate::Projection(ty::Binder(data.subst(tcx, substs))), + } + } +} + #[derive(Clone, PartialEq, Eq, Hash, Debug)] pub struct TraitPredicate<'tcx> { pub trait_ref: Rc<TraitRef<'tcx>> @@ -2324,9 +2443,6 @@ pub struct TraitDef<'tcx> { /// implements the trait. pub generics: Generics<'tcx>, - /// The "supertrait" bounds. - pub bounds: ParamBounds<'tcx>, - pub trait_ref: Rc<ty::TraitRef<'tcx>>, /// A list of the associated types defined in this trait. Useful @@ -2451,6 +2567,7 @@ pub fn mk_ctxt<'tcx>(s: Session, impl_trait_refs: RefCell::new(NodeMap()), trait_defs: RefCell::new(DefIdMap()), predicates: RefCell::new(DefIdMap()), + super_predicates: RefCell::new(DefIdMap()), object_cast_map: RefCell::new(NodeMap()), map: map, intrinsic_defs: RefCell::new(DefIdMap()), @@ -2474,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()), @@ -5368,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 { @@ -5432,7 +5549,7 @@ pub fn lookup_trait_def<'tcx>(cx: &ctxt<'tcx>, did: ast::DefId) }) } -/// Given the did of a trait, returns its full set of predicates. +/// Given the did of an item, returns its full set of predicates. pub fn lookup_predicates<'tcx>(cx: &ctxt<'tcx>, did: ast::DefId) -> GenericPredicates<'tcx> { @@ -5442,117 +5559,14 @@ pub fn lookup_predicates<'tcx>(cx: &ctxt<'tcx>, did: ast::DefId) }) } -/// Given a reference to a trait, returns the "superbounds" declared -/// on the trait, with appropriate substitutions applied. Basically, -/// this applies a filter to the where clauses on the trait, returning -/// those that have the form: -/// -/// Self : SuperTrait<...> -/// Self : 'region -pub fn predicates_for_trait_ref<'tcx>(tcx: &ctxt<'tcx>, - trait_ref: &PolyTraitRef<'tcx>) - -> Vec<ty::Predicate<'tcx>> +/// Given the did of a trait, returns its superpredicates. +pub fn lookup_super_predicates<'tcx>(cx: &ctxt<'tcx>, did: ast::DefId) + -> GenericPredicates<'tcx> { - let trait_def = lookup_trait_def(tcx, trait_ref.def_id()); - - debug!("bounds_for_trait_ref(trait_def={:?}, trait_ref={:?})", - trait_def.repr(tcx), trait_ref.repr(tcx)); - - // The interaction between HRTB and supertraits is not entirely - // obvious. Let me walk you (and myself) through an example. - // - // Let's start with an easy case. Consider two traits: - // - // trait Foo<'a> : Bar<'a,'a> { } - // trait Bar<'b,'c> { } - // - // Now, if we have a trait reference `for<'x> T : Foo<'x>`, then - // we can deduce that `for<'x> T : Bar<'x,'x>`. Basically, if we - // knew that `Foo<'x>` (for any 'x) then we also know that - // `Bar<'x,'x>` (for any 'x). This more-or-less falls out from - // normal substitution. - // - // In terms of why this is sound, the idea is that whenever there - // is an impl of `T:Foo<'a>`, it must show that `T:Bar<'a,'a>` - // holds. So if there is an impl of `T:Foo<'a>` that applies to - // all `'a`, then we must know that `T:Bar<'a,'a>` holds for all - // `'a`. - // - // Another example to be careful of is this: - // - // trait Foo1<'a> : for<'b> Bar1<'a,'b> { } - // trait Bar1<'b,'c> { } - // - // Here, if we have `for<'x> T : Foo1<'x>`, then what do we know? - // The answer is that we know `for<'x,'b> T : Bar1<'x,'b>`. The - // reason is similar to the previous example: any impl of - // `T:Foo1<'x>` must show that `for<'b> T : Bar1<'x, 'b>`. So - // basically we would want to collapse the bound lifetimes from - // the input (`trait_ref`) and the supertraits. - // - // To achieve this in practice is fairly straightforward. Let's - // consider the more complicated scenario: - // - // - We start out with `for<'x> T : Foo1<'x>`. In this case, `'x` - // has a De Bruijn index of 1. We want to produce `for<'x,'b> T : Bar1<'x,'b>`, - // where both `'x` and `'b` would have a DB index of 1. - // The substitution from the input trait-ref is therefore going to be - // `'a => 'x` (where `'x` has a DB index of 1). - // - The super-trait-ref is `for<'b> Bar1<'a,'b>`, where `'a` is an - // early-bound parameter and `'b' is a late-bound parameter with a - // DB index of 1. - // - If we replace `'a` with `'x` from the input, it too will have - // a DB index of 1, and thus we'll have `for<'x,'b> Bar1<'x,'b>` - // just as we wanted. - // - // There is only one catch. If we just apply the substitution `'a - // => 'x` to `for<'b> Bar1<'a,'b>`, the substitution code will - // adjust the DB index because we substituting into a binder (it - // tries to be so smart...) resulting in `for<'x> for<'b> - // Bar1<'x,'b>` (we have no syntax for this, so use your - // imagination). Basically the 'x will have DB index of 2 and 'b - // will have DB index of 1. Not quite what we want. So we apply - // the substitution to the *contents* of the trait reference, - // rather than the trait reference itself (put another way, the - // substitution code expects equal binding levels in the values - // from the substitution and the value being substituted into, and - // this trick achieves that). - - // Carefully avoid the binder introduced by each trait-ref by - // substituting over the substs, not the trait-refs themselves, - // thus achieving the "collapse" described in the big comment - // above. - let trait_bounds: Vec<_> = - trait_def.bounds.trait_bounds - .iter() - .map(|poly_trait_ref| ty::Binder(poly_trait_ref.0.subst(tcx, trait_ref.substs()))) - .collect(); - - let projection_bounds: Vec<_> = - trait_def.bounds.projection_bounds - .iter() - .map(|poly_proj| ty::Binder(poly_proj.0.subst(tcx, trait_ref.substs()))) - .collect(); - - debug!("bounds_for_trait_ref: trait_bounds={} projection_bounds={}", - trait_bounds.repr(tcx), - projection_bounds.repr(tcx)); - - // The region bounds and builtin bounds do not currently introduce - // binders so we can just substitute in a straightforward way here. - let region_bounds = - trait_def.bounds.region_bounds.subst(tcx, trait_ref.substs()); - let builtin_bounds = - trait_def.bounds.builtin_bounds.subst(tcx, trait_ref.substs()); - - let bounds = ty::ParamBounds { - trait_bounds: trait_bounds, - region_bounds: region_bounds, - builtin_bounds: builtin_bounds, - projection_bounds: projection_bounds, - }; - - predicates(tcx, trait_ref.self_ty(), &bounds) + memoized(&cx.super_predicates, did, |did: DefId| { + assert!(did.krate != ast::LOCAL_CRATE); + csearch::get_super_predicates(cx, did) + }) } pub fn predicates<'tcx>( @@ -5960,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, @@ -6016,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. @@ -6063,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. @@ -6093,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(_) => {} diff --git a/src/librustc/middle/ty_fold.rs b/src/librustc/middle/ty_fold.rs index 1b904aacc30..f3a7c1ee6a0 100644 --- a/src/librustc/middle/ty_fold.rs +++ b/src/librustc/middle/ty_fold.rs @@ -544,7 +544,8 @@ impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::Vtable<'tcx, N> impl<'tcx> TypeFoldable<'tcx> for traits::VtableObjectData<'tcx> { fn fold_with<F:TypeFolder<'tcx>>(&self, folder: &mut F) -> traits::VtableObjectData<'tcx> { traits::VtableObjectData { - object_ty: self.object_ty.fold_with(folder) + object_ty: self.object_ty.fold_with(folder), + upcast_trait_ref: self.upcast_trait_ref.fold_with(folder), } } } diff --git a/src/librustc/plugin/load.rs b/src/librustc/plugin/load.rs index a419d4134b4..8267b79ff9e 100644 --- a/src/librustc/plugin/load.rs +++ b/src/librustc/plugin/load.rs @@ -14,10 +14,12 @@ use session::Session; use metadata::creader::CrateReader; use plugin::registry::Registry; -use std::mem; -use std::os; -use std::dynamic_lib::DynamicLibrary; use std::borrow::ToOwned; +use std::dynamic_lib::DynamicLibrary; +use std::env; +use std::mem; +use std::old_path; +use std::path::PathBuf; use syntax::ast; use syntax::codemap::{Span, COMMAND_LINE_SP}; use syntax::ptr::P; @@ -100,10 +102,11 @@ impl<'a> PluginLoader<'a> { // Dynamically link a registrar function into the compiler process. fn dylink_registrar(&mut self, span: Span, - path: Path, + path: PathBuf, symbol: String) -> PluginRegistrarFun { // Make sure the path contains a / or the linker will search for it. - let path = os::getcwd().unwrap().join(&path); + let path = env::current_dir().unwrap().join(&path); + let path = old_path::Path::new(path.to_str().unwrap()); let lib = match DynamicLibrary::open(Some(&path)) { Ok(lib) => lib, diff --git a/src/librustc/plugin/registry.rs b/src/librustc/plugin/registry.rs index 6f98b79e782..78f7b3b91dd 100644 --- a/src/librustc/plugin/registry.rs +++ b/src/librustc/plugin/registry.rs @@ -81,8 +81,12 @@ impl<'a> Registry<'a> { /// This is the most general hook into `libsyntax`'s expansion behavior. pub fn register_syntax_extension(&mut self, name: ast::Name, extension: SyntaxExtension) { self.syntax_exts.push((name, match extension { - NormalTT(ext, _) => NormalTT(ext, Some(self.krate_span)), - IdentTT(ext, _) => IdentTT(ext, Some(self.krate_span)), + NormalTT(ext, _, allow_internal_unstable) => { + NormalTT(ext, Some(self.krate_span), allow_internal_unstable) + } + IdentTT(ext, _, allow_internal_unstable) => { + IdentTT(ext, Some(self.krate_span), allow_internal_unstable) + } Decorator(ext) => Decorator(ext), Modifier(ext) => Modifier(ext), MultiModifier(ext) => MultiModifier(ext), @@ -99,7 +103,8 @@ impl<'a> Registry<'a> { /// It builds for you a `NormalTT` that calls `expander`, /// and also takes care of interning the macro's name. pub fn register_macro(&mut self, name: &str, expander: MacroExpanderFn) { - self.register_syntax_extension(token::intern(name), NormalTT(Box::new(expander), None)); + self.register_syntax_extension(token::intern(name), + NormalTT(Box::new(expander), None, false)); } /// Register a compiler lint pass. diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 536caece21f..1b09be05020 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -38,6 +38,7 @@ use std::collections::HashMap; use std::collections::hash_map::Entry::{Occupied, Vacant}; use std::env; use std::fmt; +use std::path::PathBuf; use llvm; @@ -80,6 +81,7 @@ pub struct Options { pub gc: bool, pub optimize: OptLevel, + pub debug_assertions: bool, pub debuginfo: DebugInfoLevel, pub lint_opts: Vec<(String, lint::Level)>, pub describe_lints: bool, @@ -89,7 +91,7 @@ pub struct Options { // this. pub search_paths: SearchPaths, pub libs: Vec<(String, cstore::NativeLibraryKind)>, - pub maybe_sysroot: Option<Path>, + pub maybe_sysroot: Option<PathBuf>, pub target_triple: String, // User-specified cfg meta items. The compiler itself will add additional // items to the crate config, and during parsing the entire crate config @@ -103,7 +105,7 @@ pub struct Options { pub no_analysis: bool, pub debugging_opts: DebuggingOptions, /// Whether to write dependency files. It's (enabled, optional filename). - pub write_dependency_info: (bool, Option<Path>), + pub write_dependency_info: (bool, Option<PathBuf>), pub prints: Vec<PrintRequest>, pub cg: CodegenOptions, pub color: ColorConfig, @@ -142,7 +144,7 @@ pub enum PrintRequest { pub enum Input { /// Load source from file - File(Path), + File(PathBuf), /// The string is the source Str(String) } @@ -150,7 +152,8 @@ pub enum Input { impl Input { pub fn filestem(&self) -> String { match *self { - Input::File(ref ifile) => ifile.filestem_str().unwrap().to_string(), + Input::File(ref ifile) => ifile.file_stem().unwrap() + .to_str().unwrap().to_string(), Input::Str(_) => "rust_out".to_string(), } } @@ -158,14 +161,14 @@ impl Input { #[derive(Clone)] pub struct OutputFilenames { - pub out_directory: Path, + pub out_directory: PathBuf, pub out_filestem: String, - pub single_output_file: Option<Path>, + pub single_output_file: Option<PathBuf>, pub extra: String, } impl OutputFilenames { - pub fn path(&self, flavor: OutputType) -> Path { + pub fn path(&self, flavor: OutputType) -> PathBuf { match self.single_output_file { Some(ref path) => return path.clone(), None => {} @@ -173,8 +176,8 @@ impl OutputFilenames { self.temp_path(flavor) } - pub fn temp_path(&self, flavor: OutputType) -> Path { - let base = self.out_directory.join(self.filestem()); + pub fn temp_path(&self, flavor: OutputType) -> PathBuf { + let base = self.out_directory.join(&self.filestem()); match flavor { OutputTypeBitcode => base.with_extension("bc"), OutputTypeAssembly => base.with_extension("s"), @@ -185,8 +188,8 @@ impl OutputFilenames { } } - pub fn with_extension(&self, extension: &str) -> Path { - self.out_directory.join(self.filestem()).with_extension(extension) + pub fn with_extension(&self, extension: &str) -> PathBuf { + self.out_directory.join(&self.filestem()).with_extension(extension) } pub fn filestem(&self) -> String { @@ -236,7 +239,8 @@ pub fn basic_options() -> Options { crate_name: None, alt_std_name: None, libs: Vec::new(), - unstable_features: UnstableFeatures::Disallow + unstable_features: UnstableFeatures::Disallow, + debug_assertions: true, } } @@ -526,6 +530,8 @@ options! {CodegenOptions, CodegenSetter, basic_codegen_options, 2 = full debug info with variable and type information"), opt_level: Option<uint> = (None, parse_opt_uint, "Optimize with possible levels 0-3"), + debug_assertions: Option<bool> = (None, parse_opt_bool, + "explicitly enable the cfg(debug_assertions) directive"), } @@ -619,7 +625,7 @@ pub fn default_configuration(sess: &Session) -> ast::CrateConfig { }; let mk = attr::mk_name_value_item_str; - return vec!(// Target bindings. + let mut ret = vec![ // Target bindings. attr::mk_word_item(fam.clone()), mk(InternedString::new("target_os"), intern(os)), mk(InternedString::new("target_family"), fam), @@ -627,7 +633,11 @@ pub fn default_configuration(sess: &Session) -> ast::CrateConfig { mk(InternedString::new("target_endian"), intern(end)), mk(InternedString::new("target_pointer_width"), intern(wordsz)) - ); + ]; + if sess.opts.debug_assertions { + ret.push(attr::mk_word_item(InternedString::new("debug_assertions"))); + } + return ret; } pub fn append_configuration(cfg: &mut ast::CrateConfig, @@ -897,7 +907,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options { let cg = build_codegen_options(matches); - let sysroot_opt = matches.opt_str("sysroot").map(|m| Path::new(m)); + let sysroot_opt = matches.opt_str("sysroot").map(|m| PathBuf::new(&m)); let target = matches.opt_str("target").unwrap_or( host_triple().to_string()); let opt_level = { @@ -921,6 +931,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options { } } }; + let debug_assertions = cg.debug_assertions.unwrap_or(opt_level == No); let gc = debugging_opts.gc; let debuginfo = if matches.opt_present("g") { if cg.debuginfo.is_some() { @@ -1062,6 +1073,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options { alt_std_name: None, libs: libs, unstable_features: get_unstable_features_setting(), + debug_assertions: debug_assertions, } } diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index 67c39bcca81..8bc842671a0 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -26,8 +26,9 @@ use syntax::{ast, codemap}; use rustc_back::target::Target; +use std::path::{Path, PathBuf}; use std::cell::{Cell, RefCell}; -use std::os; +use std::env; pub mod config; pub mod search_paths; @@ -44,11 +45,11 @@ pub struct Session { pub entry_fn: RefCell<Option<(NodeId, codemap::Span)>>, pub entry_type: Cell<Option<config::EntryFnType>>, pub plugin_registrar_fn: Cell<Option<ast::NodeId>>, - pub default_sysroot: Option<Path>, + pub default_sysroot: Option<PathBuf>, // The name of the root source file of the crate, in the local file system. The path is always // expected to be absolute. `None` means that there is no source file. - pub local_crate_source_file: Option<Path>, - pub working_dir: Path, + pub local_crate_source_file: Option<PathBuf>, + pub working_dir: PathBuf, pub lint_store: RefCell<lint::LintStore>, pub lints: RefCell<NodeMap<Vec<(lint::LintId, codemap::Span, String)>>>, pub crate_types: RefCell<Vec<config::CrateType>>, @@ -64,12 +65,21 @@ pub struct Session { impl Session { pub fn span_fatal(&self, sp: Span, msg: &str) -> ! { + if self.opts.treat_err_as_bug { + self.span_bug(sp, msg); + } self.diagnostic().span_fatal(sp, msg) } pub fn span_fatal_with_code(&self, sp: Span, msg: &str, code: &str) -> ! { + if self.opts.treat_err_as_bug { + self.span_bug(sp, msg); + } self.diagnostic().span_fatal_with_code(sp, msg, code) } pub fn fatal(&self, msg: &str) -> ! { + if self.opts.treat_err_as_bug { + self.bug(msg); + } self.diagnostic().handler().fatal(msg) } pub fn span_err(&self, sp: Span, msg: &str) { @@ -310,7 +320,7 @@ fn split_msg_into_multilines(msg: &str) -> Option<String> { } pub fn build_session(sopts: config::Options, - local_crate_source_file: Option<Path>, + local_crate_source_file: Option<PathBuf>, registry: diagnostics::registry::Registry) -> Session { // FIXME: This is not general enough to make the warning lint completely override @@ -333,7 +343,7 @@ pub fn build_session(sopts: config::Options, } pub fn build_session_(sopts: config::Options, - local_crate_source_file: Option<Path>, + local_crate_source_file: Option<PathBuf>, span_diagnostic: diagnostic::SpanHandler) -> Session { let host = match Target::search(config::host_triple()) { @@ -355,7 +365,7 @@ pub fn build_session_(sopts: config::Options, if path.is_absolute() { path.clone() } else { - os::getcwd().unwrap().join(&path) + env::current_dir().unwrap().join(&path) } ); @@ -378,7 +388,7 @@ pub fn build_session_(sopts: config::Options, plugin_registrar_fn: Cell::new(None), default_sysroot: default_sysroot, local_crate_source_file: local_crate_source_file, - working_dir: os::getcwd().unwrap(), + working_dir: env::current_dir().unwrap(), lint_store: RefCell::new(lint::LintStore::new()), lints: RefCell::new(NodeMap()), crate_types: RefCell::new(Vec::new()), diff --git a/src/librustc/session/search_paths.rs b/src/librustc/session/search_paths.rs index c314a999f24..f85fb303910 100644 --- a/src/librustc/session/search_paths.rs +++ b/src/librustc/session/search_paths.rs @@ -9,15 +9,16 @@ // except according to those terms. use std::slice; +use std::path::{Path, PathBuf}; #[derive(Clone, Debug)] pub struct SearchPaths { - paths: Vec<(PathKind, Path)>, + paths: Vec<(PathKind, PathBuf)>, } pub struct Iter<'a> { kind: PathKind, - iter: slice::Iter<'a, (PathKind, Path)>, + iter: slice::Iter<'a, (PathKind, PathBuf)>, } #[derive(Eq, PartialEq, Clone, Copy, Debug)] @@ -49,7 +50,7 @@ impl SearchPaths { } else { (PathKind::All, path) }; - self.paths.push((kind, Path::new(path))); + self.paths.push((kind, PathBuf::new(path))); } pub fn iter(&self, kind: PathKind) -> Iter { diff --git a/src/librustc/util/common.rs b/src/librustc/util/common.rs index ca740f53782..0b32f7f69eb 100644 --- a/src/librustc/util/common.rs +++ b/src/librustc/util/common.rs @@ -12,11 +12,13 @@ use std::cell::{RefCell, Cell}; use std::collections::HashMap; +use std::collections::hash_state::HashState; +use std::ffi::CString; use std::fmt::Debug; use std::hash::Hash; use std::iter::repeat; +use std::path::Path; use std::time::Duration; -use std::collections::hash_state::HashState; use syntax::ast; use syntax::visit; @@ -222,3 +224,14 @@ pub fn memoized<T, U, S, F>(cache: &RefCell<HashMap<T, U, S>>, arg: T, f: F) -> } } } + +#[cfg(unix)] +pub fn path2cstr(p: &Path) -> CString { + use std::os::unix::prelude::*; + use std::ffi::AsOsStr; + CString::new(p.as_os_str().as_bytes()).unwrap() +} +#[cfg(windows)] +pub fn path2cstr(p: &Path) -> CString { + CString::new(p.to_str().unwrap()).unwrap() +} diff --git a/src/librustc/util/lev_distance.rs b/src/librustc/util/lev_distance.rs index 10a7b2abea8..d3b9b07ea41 100644 --- a/src/librustc/util/lev_distance.rs +++ b/src/librustc/util/lev_distance.rs @@ -45,7 +45,7 @@ pub fn lev_distance(me: &str, t: &str) -> uint { fn test_lev_distance() { use std::char::{ from_u32, MAX }; // Test bytelength agnosticity - for c in (0u32..MAX as u32) + for c in (0..MAX as u32) .filter_map(|i| from_u32(i)) .map(|i| i.to_string()) { assert_eq!(lev_distance(&c[..], &c[..]), 0); diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 0eeb746022c..f41d969c1a2 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -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 {}", @@ -820,9 +820,8 @@ impl<'tcx> Repr<'tcx> for ty::TraitRef<'tcx> { impl<'tcx> Repr<'tcx> for ty::TraitDef<'tcx> { fn repr(&self, tcx: &ctxt<'tcx>) -> String { - format!("TraitDef(generics={}, bounds={}, trait_ref={})", + format!("TraitDef(generics={}, trait_ref={})", self.generics.repr(tcx), - self.bounds.repr(tcx), self.trait_ref.repr(tcx)) } } diff --git a/src/librustc_back/archive.rs b/src/librustc_back/archive.rs index 97b1a8aaaba..ed44bf89529 100644 --- a/src/librustc_back/archive.rs +++ b/src/librustc_back/archive.rs @@ -10,20 +10,23 @@ //! A helper class for dealing with static archives -use std::old_io::fs::PathExtensions; -use std::old_io::process::{Command, ProcessOutput}; -use std::old_io::{fs, TempDir}; -use std::old_io; -use std::os; +use std::env; +use std::fs; +use std::io::prelude::*; +use std::io; +use std::path::{Path, PathBuf}; +use std::process::{Command, Output, Stdio}; use std::str; use syntax::diagnostic::Handler as ErrorHandler; +use tempdir::TempDir; + pub const METADATA_FILENAME: &'static str = "rust.metadata.bin"; pub struct ArchiveConfig<'a> { pub handler: &'a ErrorHandler, - pub dst: Path, - pub lib_search_paths: Vec<Path>, + pub dst: PathBuf, + pub lib_search_paths: Vec<PathBuf>, pub slib_prefix: String, pub slib_suffix: String, pub maybe_ar_prog: Option<String> @@ -31,8 +34,8 @@ pub struct ArchiveConfig<'a> { pub struct Archive<'a> { handler: &'a ErrorHandler, - dst: Path, - lib_search_paths: Vec<Path>, + dst: PathBuf, + lib_search_paths: Vec<PathBuf>, slib_prefix: String, slib_suffix: String, maybe_ar_prog: Option<String> @@ -45,25 +48,25 @@ pub struct ArchiveBuilder<'a> { archive: Archive<'a>, work_dir: TempDir, /// Filename of each member that should be added to the archive. - members: Vec<Path>, + members: Vec<PathBuf>, should_update_symbols: bool, } fn run_ar(handler: &ErrorHandler, maybe_ar_prog: &Option<String>, args: &str, cwd: Option<&Path>, - paths: &[&Path]) -> ProcessOutput { + paths: &[&Path]) -> Output { let ar = match *maybe_ar_prog { Some(ref ar) => &ar[..], None => "ar" }; let mut cmd = Command::new(ar); - cmd.arg(args).args(paths); + cmd.arg(args).args(paths).stdout(Stdio::piped()).stderr(Stdio::piped()); debug!("{:?}", cmd); match cwd { Some(p) => { - cmd.cwd(p); + cmd.current_dir(p); debug!("inside {:?}", p.display()); } None => {} @@ -75,9 +78,9 @@ fn run_ar(handler: &ErrorHandler, maybe_ar_prog: &Option<String>, if !o.status.success() { handler.err(&format!("{:?} failed with: {}", cmd, o.status)); handler.note(&format!("stdout ---\n{}", - str::from_utf8(&o.output).unwrap())); + str::from_utf8(&o.stdout).unwrap())); handler.note(&format!("stderr ---\n{}", - str::from_utf8(&o.error).unwrap()) + str::from_utf8(&o.stderr).unwrap()) ); handler.abort_if_errors(); } @@ -93,14 +96,15 @@ fn run_ar(handler: &ErrorHandler, maybe_ar_prog: &Option<String>, } pub fn find_library(name: &str, osprefix: &str, ossuffix: &str, - search_paths: &[Path], handler: &ErrorHandler) -> Path { + search_paths: &[PathBuf], + handler: &ErrorHandler) -> PathBuf { // On Windows, static libraries sometimes show up as libfoo.a and other // times show up as foo.lib let oslibname = format!("{}{}{}", osprefix, name, ossuffix); let unixlibname = format!("lib{}.a", name); for path in search_paths { - debug!("looking for {} inside {:?}", name, path.display()); + debug!("looking for {} inside {:?}", name, path); let test = path.join(&oslibname[..]); if test.exists() { return test } if oslibname != unixlibname { @@ -142,7 +146,7 @@ impl<'a> Archive<'a> { /// Lists all files in an archive pub fn files(&self) -> Vec<String> { let output = run_ar(self.handler, &self.maybe_ar_prog, "t", None, &[&self.dst]); - let output = str::from_utf8(&output.output).unwrap(); + let output = str::from_utf8(&output.stdout).unwrap(); // use lines_any because windows delimits output with `\r\n` instead of // just `\n` output.lines_any().map(|s| s.to_string()).collect() @@ -172,7 +176,7 @@ impl<'a> ArchiveBuilder<'a> { /// Adds all of the contents of a native library to this archive. This will /// search in the relevant locations for a library named `name`. - pub fn add_native_library(&mut self, name: &str) -> old_io::IoResult<()> { + pub fn add_native_library(&mut self, name: &str) -> io::Result<()> { let location = find_library(name, &self.archive.slib_prefix, &self.archive.slib_suffix, @@ -187,7 +191,7 @@ impl<'a> ArchiveBuilder<'a> { /// This ignores adding the bytecode from the rlib, and if LTO is enabled /// then the object file also isn't added. pub fn add_rlib(&mut self, rlib: &Path, name: &str, - lto: bool) -> old_io::IoResult<()> { + lto: bool) -> io::Result<()> { // Ignoring obj file starting with the crate name // as simple comparison is not enough - there // might be also an extra name suffix @@ -205,11 +209,11 @@ impl<'a> ArchiveBuilder<'a> { } /// Adds an arbitrary file to this archive - pub fn add_file(&mut self, file: &Path) -> old_io::IoResult<()> { - let filename = Path::new(file.filename().unwrap()); + pub fn add_file(&mut self, file: &Path) -> io::Result<()> { + let filename = Path::new(file.file_name().unwrap()); let new_file = self.work_dir.path().join(&filename); try!(fs::copy(file, &new_file)); - self.members.push(filename); + self.members.push(filename.to_path_buf()); Ok(()) } @@ -224,10 +228,10 @@ impl<'a> ArchiveBuilder<'a> { pub fn build(self) -> Archive<'a> { // Get an absolute path to the destination, so `ar` will work even // though we run it from `self.work_dir`. - let abs_dst = os::getcwd().unwrap().join(&self.archive.dst); + let abs_dst = env::current_dir().unwrap().join(&self.archive.dst); assert!(!abs_dst.is_relative()); - let mut args = vec![&abs_dst]; - let mut total_len = abs_dst.as_vec().len(); + let mut args = vec![&*abs_dst]; + let mut total_len = abs_dst.to_string_lossy().len(); if self.members.is_empty() { // OSX `ar` does not allow using `r` with no members, but it does @@ -245,7 +249,7 @@ impl<'a> ArchiveBuilder<'a> { const ARG_LENGTH_LIMIT: uint = 32_000; for member_name in &self.members { - let len = member_name.as_vec().len(); + let len = member_name.to_string_lossy().len(); // `len + 1` to account for the space that's inserted before each // argument. (Windows passes command-line arguments as a single @@ -258,7 +262,7 @@ impl<'a> ArchiveBuilder<'a> { args.clear(); args.push(&abs_dst); - total_len = abs_dst.as_vec().len(); + total_len = abs_dst.to_string_lossy().len(); } args.push(member_name); @@ -275,7 +279,7 @@ impl<'a> ArchiveBuilder<'a> { } fn add_archive<F>(&mut self, archive: &Path, name: &str, - mut skip: F) -> old_io::IoResult<()> + mut skip: F) -> io::Result<()> where F: FnMut(&str) -> bool, { let loc = TempDir::new("rsar").unwrap(); @@ -283,7 +287,7 @@ impl<'a> ArchiveBuilder<'a> { // First, extract the contents of the archive to a temporary directory. // We don't unpack directly into `self.work_dir` due to the possibility // of filename collisions. - let archive = os::getcwd().unwrap().join(archive); + let archive = env::current_dir().unwrap().join(archive); run_ar(self.archive.handler, &self.archive.maybe_ar_prog, "x", Some(loc.path()), &[&archive]); @@ -296,9 +300,10 @@ impl<'a> ArchiveBuilder<'a> { // We skip any files explicitly desired for skipping, and we also skip // all SYMDEF files as these are just magical placeholders which get // re-created when we make a new archive anyway. - let files = try!(fs::readdir(loc.path())); - for file in &files { - let filename = file.filename_str().unwrap(); + let files = try!(fs::read_dir(loc.path())); + for file in files { + let file = try!(file).path(); + let filename = file.file_name().unwrap().to_str().unwrap(); if skip(filename) { continue } if filename.contains(".SYMDEF") { continue } @@ -313,8 +318,8 @@ impl<'a> ArchiveBuilder<'a> { filename }; let new_filename = self.work_dir.path().join(&filename[..]); - try!(fs::rename(file, &new_filename)); - self.members.push(Path::new(filename)); + try!(fs::rename(&file, &new_filename)); + self.members.push(PathBuf::new(&filename)); } Ok(()) } diff --git a/src/librustc_back/fs.rs b/src/librustc_back/fs.rs index 56d71820176..c00c33d4c2f 100644 --- a/src/librustc_back/fs.rs +++ b/src/librustc_back/fs.rs @@ -8,14 +8,29 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::old_io; +use std::io; use std::old_io::fs; +use std::old_io; +use std::old_path; use std::os; +use std::path::{Path, PathBuf}; /// Returns an absolute path in the filesystem that `path` points to. The /// returned path does not contain any symlinks in its hierarchy. -pub fn realpath(original: &Path) -> old_io::IoResult<Path> { - const MAX_LINKS_FOLLOWED: uint = 256; +#[allow(deprecated)] // readlink is deprecated +pub fn realpath(original: &Path) -> io::Result<PathBuf> { + let old = old_path::Path::new(original.to_str().unwrap()); + match old_realpath(&old) { + Ok(p) => Ok(PathBuf::new(p.as_str().unwrap())), + Err(e) => Err(io::Error::new(io::ErrorKind::Other, + "realpath error", + Some(e.to_string()))) + } +} + +#[allow(deprecated)] +fn old_realpath(original: &old_path::Path) -> old_io::IoResult<old_path::Path> { + const MAX_LINKS_FOLLOWED: usize = 256; let original = try!(os::getcwd()).join(original); // Right now lstat on windows doesn't work quite well @@ -55,7 +70,7 @@ pub fn realpath(original: &Path) -> old_io::IoResult<Path> { mod test { use std::old_io; use std::old_io::fs::{File, symlink, mkdir, mkdir_recursive}; - use super::realpath; + use super::old_realpath as realpath; use std::old_io::TempDir; #[test] diff --git a/src/librustc_back/lib.rs b/src/librustc_back/lib.rs index 9005c666afb..333c97b446b 100644 --- a/src/librustc_back/lib.rs +++ b/src/librustc_back/lib.rs @@ -21,6 +21,8 @@ //! one that doesn't; the one that doesn't might get decent parallel //! build speedups. +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "rustc_back"] #![unstable(feature = "rustc_private")] #![staged_api] @@ -33,14 +35,18 @@ #![feature(box_syntax)] #![feature(collections)] #![feature(core)] +#![feature(old_fs)] #![feature(hash)] #![feature(int_uint)] +#![feature(io)] #![feature(old_io)] -#![feature(os)] #![feature(old_path)] +#![feature(os)] +#![feature(path)] #![feature(rustc_private)] #![feature(staged_api)] -#![feature(path)] +#![feature(rand)] +#![feature(path_ext)] extern crate syntax; extern crate serialize; @@ -48,6 +54,7 @@ extern crate serialize; pub mod abi; pub mod archive; +pub mod tempdir; pub mod arm; pub mod fs; pub mod mips; diff --git a/src/librustc_back/rpath.rs b/src/librustc_back/rpath.rs index 943ff52925a..4f9f1447d8a 100644 --- a/src/librustc_back/rpath.rs +++ b/src/librustc_back/rpath.rs @@ -10,26 +10,20 @@ use std::collections::HashSet; use std::env; -use std::old_io::IoError; -use std::os; +use std::io; +use std::path::{Path, PathBuf}; use syntax::ast; -pub struct RPathConfig<F, G> where - F: FnOnce() -> Path, - G: FnMut(&Path) -> Result<Path, IoError>, -{ - pub used_crates: Vec<(ast::CrateNum, Option<Path>)>, - pub out_filename: Path, +pub struct RPathConfig<'a> { + pub used_crates: Vec<(ast::CrateNum, Option<PathBuf>)>, + pub out_filename: PathBuf, pub is_like_osx: bool, pub has_rpath: bool, - pub get_install_prefix_lib_path: F, - pub realpath: G, + pub get_install_prefix_lib_path: &'a mut FnMut() -> PathBuf, + pub realpath: &'a mut FnMut(&Path) -> io::Result<PathBuf>, } -pub fn get_rpath_flags<F, G>(config: RPathConfig<F, G>) -> Vec<String> where - F: FnOnce() -> Path, - G: FnMut(&Path) -> Result<Path, IoError>, -{ +pub fn get_rpath_flags(config: &mut RPathConfig) -> Vec<String> { // No rpath on windows if !config.has_rpath { return Vec::new(); @@ -54,10 +48,7 @@ fn rpaths_to_flags(rpaths: &[String]) -> Vec<String> { return ret; } -fn get_rpaths<F, G>(mut config: RPathConfig<F, G>, libs: &[Path]) -> Vec<String> where - F: FnOnce() -> Path, - G: FnMut(&Path) -> Result<Path, IoError>, -{ +fn get_rpaths(config: &mut RPathConfig, libs: &[PathBuf]) -> Vec<String> { debug!("output: {:?}", config.out_filename.display()); debug!("libs:"); for libpath in libs { @@ -67,7 +58,7 @@ fn get_rpaths<F, G>(mut config: RPathConfig<F, G>, libs: &[Path]) -> Vec<String> // Use relative paths to the libraries. Binaries can be moved // as long as they maintain the relative relationship to the // crates they depend on. - let rel_rpaths = get_rpaths_relative_to_output(&mut config, libs); + let rel_rpaths = get_rpaths_relative_to_output(config, libs); // And a final backup rpath to the global library location. let fallback_rpaths = vec!(get_install_prefix_rpath(config)); @@ -90,18 +81,12 @@ fn get_rpaths<F, G>(mut config: RPathConfig<F, G>, libs: &[Path]) -> Vec<String> return rpaths; } -fn get_rpaths_relative_to_output<F, G>(config: &mut RPathConfig<F, G>, - libs: &[Path]) -> Vec<String> where - F: FnOnce() -> Path, - G: FnMut(&Path) -> Result<Path, IoError>, -{ +fn get_rpaths_relative_to_output(config: &mut RPathConfig, + libs: &[PathBuf]) -> Vec<String> { libs.iter().map(|a| get_rpath_relative_to_output(config, a)).collect() } -fn get_rpath_relative_to_output<F, G>(config: &mut RPathConfig<F, G>, lib: &Path) -> String where - F: FnOnce() -> Path, - G: FnMut(&Path) -> Result<Path, IoError>, -{ +fn get_rpath_relative_to_output(config: &mut RPathConfig, lib: &Path) -> String { // Mac doesn't appear to support $ORIGIN let prefix = if config.is_like_osx { "@loader_path" @@ -109,23 +94,36 @@ fn get_rpath_relative_to_output<F, G>(config: &mut RPathConfig<F, G>, lib: &Path "$ORIGIN" }; - let cwd = os::getcwd().unwrap(); + let cwd = env::current_dir().unwrap(); let mut lib = (config.realpath)(&cwd.join(lib)).unwrap(); lib.pop(); let mut output = (config.realpath)(&cwd.join(&config.out_filename)).unwrap(); output.pop(); - let relative = lib.path_relative_from(&output); - let relative = relative.expect("could not create rpath relative to output"); + let relative = relativize(&lib, &output); // FIXME (#9639): This needs to handle non-utf8 paths - format!("{}/{}", - prefix, - relative.as_str().expect("non-utf8 component in path")) + format!("{}/{}", prefix, + relative.to_str().expect("non-utf8 component in path")) } -fn get_install_prefix_rpath<F, G>(config: RPathConfig<F, G>) -> String where - F: FnOnce() -> Path, - G: FnMut(&Path) -> Result<Path, IoError>, -{ +fn relativize(path: &Path, rel: &Path) -> PathBuf { + let mut res = PathBuf::new(""); + let mut cur = rel; + while !path.starts_with(cur) { + res.push(".."); + match cur.parent() { + Some(p) => cur = p, + None => panic!("can't create relative paths across filesystems"), + } + } + match path.relative_from(cur) { + Some(s) => { res.push(s); res } + None => panic!("couldn't create relative path from {:?} to {:?}", + rel, path), + } + +} + +fn get_install_prefix_rpath(config: &mut RPathConfig) -> String { let path = (config.get_install_prefix_lib_path)(); let path = env::current_dir().unwrap().join(&path); // FIXME (#9639): This needs to handle non-utf8 paths @@ -147,6 +145,7 @@ fn minimize_rpaths(rpaths: &[String]) -> Vec<String> { mod test { use super::{RPathConfig}; use super::{minimize_rpaths, rpaths_to_flags, get_rpath_relative_to_output}; + use std::path::{Path, PathBuf}; #[test] fn test_rpaths_to_flags() { @@ -195,50 +194,31 @@ mod test { } #[test] - #[cfg(any(target_os = "linux", target_os = "android"))] fn test_rpath_relative() { - let config = &mut RPathConfig { - used_crates: Vec::new(), - out_filename: Path::new("bin/rustc"), - get_install_prefix_lib_path: || panic!(), - has_rpath: true, - is_like_osx: false, - realpath: |p| Ok(p.clone()) - }; - let res = get_rpath_relative_to_output(config, &Path::new("lib/libstd.so")); - assert_eq!(res, "$ORIGIN/../lib"); - } - - #[test] - #[cfg(any(target_os = "freebsd", - target_os = "dragonfly", - target_os = "bitrig", - target_os = "openbsd"))] - fn test_rpath_relative() { - let config = &mut RPathConfig { - used_crates: Vec::new(), - has_rpath: true, - is_like_osx: false, - out_filename: Path::new("bin/rustc"), - get_install_prefix_lib_path: || panic!(), - realpath: |p| Ok(p.clone()) - }; - let res = get_rpath_relative_to_output(config, &Path::new("lib/libstd.so")); - assert_eq!(res, "$ORIGIN/../lib"); - } - - #[test] - #[cfg(target_os = "macos")] - fn test_rpath_relative() { - let config = &mut RPathConfig { - used_crates: Vec::new(), - has_rpath: true, - is_like_osx: true, - out_filename: Path::new("bin/rustc"), - get_install_prefix_lib_path: || panic!(), - realpath: |p| Ok(p.clone()) - }; - let res = get_rpath_relative_to_output(config, &Path::new("lib/libstd.so")); - assert_eq!(res, "@loader_path/../lib"); + if cfg!(target_os = "macos") { + let config = &mut RPathConfig { + used_crates: Vec::new(), + has_rpath: true, + is_like_osx: true, + out_filename: PathBuf::new("bin/rustc"), + get_install_prefix_lib_path: &mut || panic!(), + realpath: &mut |p| Ok(p.to_path_buf()), + }; + let res = get_rpath_relative_to_output(config, + Path::new("lib/libstd.so")); + assert_eq!(res, "@loader_path/../lib"); + } else { + let config = &mut RPathConfig { + used_crates: Vec::new(), + out_filename: PathBuf::new("bin/rustc"), + get_install_prefix_lib_path: &mut || panic!(), + has_rpath: true, + is_like_osx: false, + realpath: &mut |p| Ok(p.to_path_buf()), + }; + let res = get_rpath_relative_to_output(config, + Path::new("lib/libstd.so")); + assert_eq!(res, "$ORIGIN/../lib"); + } } } diff --git a/src/librustc_back/sha2.rs b/src/librustc_back/sha2.rs index 844920ad5ec..1a399519296 100644 --- a/src/librustc_back/sha2.rs +++ b/src/librustc_back/sha2.rs @@ -119,7 +119,7 @@ impl FixedBuffer64 { /// Create a new FixedBuffer64 fn new() -> FixedBuffer64 { return FixedBuffer64 { - buffer: [0u8; 64], + buffer: [0; 64], buffer_idx: 0 }; } @@ -258,7 +258,7 @@ pub trait Digest { /// Convenience function that retrieves the result of a digest as a /// newly allocated vec of bytes. fn result_bytes(&mut self) -> Vec<u8> { - let mut buf: Vec<u8> = repeat(0u8).take((self.output_bits()+7)/8).collect(); + let mut buf: Vec<u8> = repeat(0).take((self.output_bits()+7)/8).collect(); self.result(&mut buf); buf } @@ -342,7 +342,7 @@ impl Engine256State { let mut g = self.h6; let mut h = self.h7; - let mut w = [0u32; 64]; + let mut w = [0; 64]; // Sha-512 and Sha-256 use basically the same calculations which are implemented // by these macros. Inlining the calculations seems to result in better generated code. @@ -548,7 +548,7 @@ mod tests { // 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); } @@ -660,7 +660,7 @@ mod bench { #[bench] pub fn sha256_10(b: &mut Bencher) { let mut sh = Sha256::new(); - let bytes = [1u8; 10]; + let bytes = [1; 10]; b.iter(|| { sh.input(&bytes); }); @@ -670,7 +670,7 @@ mod bench { #[bench] pub fn sha256_1k(b: &mut Bencher) { let mut sh = Sha256::new(); - let bytes = [1u8; 1024]; + let bytes = [1; 1024]; b.iter(|| { sh.input(&bytes); }); @@ -680,7 +680,7 @@ mod bench { #[bench] pub fn sha256_64k(b: &mut Bencher) { let mut sh = Sha256::new(); - let bytes = [1u8; 65536]; + let bytes = [1; 65536]; b.iter(|| { sh.input(&bytes); }); diff --git a/src/librustc_back/target/apple_ios_base.rs b/src/librustc_back/target/apple_ios_base.rs index 904b337c03f..2fbbe7d1f7c 100644 --- a/src/librustc_back/target/apple_ios_base.rs +++ b/src/librustc_back/target/apple_ios_base.rs @@ -8,7 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::old_io::{Command, IoError, OtherIoError}; +use std::io; +use std::process::Command; use target::TargetOptions; use self::Arch::*; @@ -40,16 +41,15 @@ pub fn get_sdk_root(sdk_name: &str) -> String { .arg("--show-sdk-path") .arg("-sdk") .arg(sdk_name) - .spawn() - .and_then(|c| c.wait_with_output()) + .output() .and_then(|output| { if output.status.success() { - Ok(String::from_utf8(output.output).unwrap()) + Ok(String::from_utf8(output.stdout).unwrap()) } else { - Err(IoError { - kind: OtherIoError, - desc: "process exit with error", - detail: String::from_utf8(output.error).ok()}) + let error = String::from_utf8(output.stderr); + Err(io::Error::new(io::ErrorKind::Other, + "process exit with error", + error.ok())) } }); diff --git a/src/librustc_back/target/mod.rs b/src/librustc_back/target/mod.rs index d09a7c355d3..4663901a7b4 100644 --- a/src/librustc_back/target/mod.rs +++ b/src/librustc_back/target/mod.rs @@ -48,7 +48,7 @@ use serialize::json::Json; use syntax::{diagnostic, abi}; use std::default::Default; -use std::old_io::fs::PathExtensions; +use std::io::prelude::*; mod windows_base; mod linux_base; @@ -302,23 +302,26 @@ impl Target { base } - /// Search RUST_TARGET_PATH for a JSON file specifying the given target triple. Note that it - /// could also just be a bare filename already, so also check for that. If one of the hardcoded - /// targets we know about, just return it directly. + /// Search RUST_TARGET_PATH for a JSON file specifying the given target + /// triple. Note that it could also just be a bare filename already, so also + /// check for that. If one of the hardcoded targets we know about, just + /// return it directly. /// - /// The error string could come from any of the APIs called, including filesystem access and - /// JSON decoding. + /// The error string could come from any of the APIs called, including + /// filesystem access and JSON decoding. pub fn search(target: &str) -> Result<Target, String> { use std::env; - use std::os; use std::ffi::OsString; - use std::old_io::File; - use std::old_path::Path; + use std::fs::File; + use std::path::{Path, PathBuf}; use serialize::json; fn load_file(path: &Path) -> Result<Target, String> { - let mut f = try!(File::open(path).map_err(|e| format!("{:?}", e))); - let obj = try!(json::from_reader(&mut f).map_err(|e| format!("{:?}", e))); + let mut f = try!(File::open(path).map_err(|e| e.to_string())); + let mut contents = Vec::new(); + try!(f.read_to_end(&mut contents).map_err(|e| e.to_string())); + let obj = try!(json::from_reader(&mut &contents[..]) + .map_err(|e| e.to_string())); Ok(Target::from_json(obj)) } @@ -390,15 +393,16 @@ impl Target { let path = { let mut target = target.to_string(); target.push_str(".json"); - Path::new(target) + PathBuf::new(&target) }; - let target_path = env::var_os("RUST_TARGET_PATH").unwrap_or(OsString::from_str("")); + let target_path = env::var_os("RUST_TARGET_PATH") + .unwrap_or(OsString::from_str("")); // FIXME 16351: add a sane default search path? - for dir in os::split_paths(target_path.to_str().unwrap()).iter() { - let p = dir.join(path.clone()); + for dir in env::split_paths(&target_path) { + let p = dir.join(&path); if p.is_file() { return load_file(&p); } diff --git a/src/librustc_back/tempdir.rs b/src/librustc_back/tempdir.rs new file mode 100644 index 00000000000..4d8619a8121 --- /dev/null +++ b/src/librustc_back/tempdir.rs @@ -0,0 +1,121 @@ +// 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. + +use std::env; +use std::io::{self, Error, ErrorKind}; +use std::fs; +use std::path::{self, PathBuf, AsPath}; +use std::rand::{thread_rng, Rng}; + +/// A wrapper for a path to temporary directory implementing automatic +/// scope-based deletion. +pub struct TempDir { + path: Option<PathBuf>, +} + +// How many times should we (re)try finding an unused random name? It should be +// enough that an attacker will run out of luck before we run out of patience. +const NUM_RETRIES: u32 = 1 << 31; +// How many characters should we include in a random file name? It needs to +// be enough to dissuade an attacker from trying to preemptively create names +// of that length, but not so huge that we unnecessarily drain the random number +// generator of entropy. +const NUM_RAND_CHARS: uint = 12; + +impl TempDir { + /// Attempts to make a temporary directory inside of `tmpdir` whose name + /// will have the prefix `prefix`. The directory will be automatically + /// deleted once the returned wrapper is destroyed. + /// + /// If no directory can be created, `Err` is returned. + #[allow(deprecated)] // rand usage + pub fn new_in<P: AsPath + ?Sized>(tmpdir: &P, prefix: &str) + -> io::Result<TempDir> { + let storage; + let mut tmpdir = tmpdir.as_path(); + if !tmpdir.is_absolute() { + let cur_dir = try!(env::current_dir()); + storage = cur_dir.join(tmpdir); + tmpdir = &storage; + // return TempDir::new_in(&cur_dir.join(tmpdir), prefix); + } + + let mut rng = thread_rng(); + for _ in 0..NUM_RETRIES { + let suffix: String = rng.gen_ascii_chars().take(NUM_RAND_CHARS).collect(); + let leaf = if prefix.len() > 0 { + format!("{}.{}", prefix, suffix) + } else { + // If we're given an empty string for a prefix, then creating a + // directory starting with "." would lead to it being + // semi-invisible on some systems. + suffix + }; + let path = tmpdir.join(&leaf); + match fs::create_dir(&path) { + Ok(_) => return Ok(TempDir { path: Some(path) }), + Err(ref e) if e.kind() == ErrorKind::PathAlreadyExists => {} + Err(e) => return Err(e) + } + } + + Err(Error::new(ErrorKind::PathAlreadyExists, + "too many temporary directories already exist", + None)) + } + + /// Attempts to make a temporary directory inside of `env::temp_dir()` whose + /// name will have the prefix `prefix`. The directory will be automatically + /// deleted once the returned wrapper is destroyed. + /// + /// If no directory can be created, `Err` is returned. + #[allow(deprecated)] + pub fn new(prefix: &str) -> io::Result<TempDir> { + TempDir::new_in(&env::temp_dir(), prefix) + } + + /// Unwrap the wrapped `std::path::Path` from the `TempDir` wrapper. + /// This discards the wrapper so that the automatic deletion of the + /// temporary directory is prevented. + pub fn into_path(mut self) -> PathBuf { + self.path.take().unwrap() + } + + /// Access the wrapped `std::path::Path` to the temporary directory. + pub fn path(&self) -> &path::Path { + self.path.as_ref().unwrap() + } + + /// Close and remove the temporary directory + /// + /// Although `TempDir` removes the directory on drop, in the destructor + /// any errors are ignored. To detect errors cleaning up the temporary + /// directory, call `close` instead. + pub fn close(mut self) -> io::Result<()> { + self.cleanup_dir() + } + + fn cleanup_dir(&mut self) -> io::Result<()> { + match self.path { + Some(ref p) => fs::remove_dir_all(p), + None => Ok(()) + } + } +} + +impl Drop for TempDir { + fn drop(&mut self) { + let _ = self.cleanup_dir(); + } +} + +// the tests for this module need to change the path using change_dir, +// and this doesn't play nicely with other tests so these unit tests are located +// in src/test/run-pass/tempfile.rs diff --git a/src/librustc_bitflags/lib.rs b/src/librustc_bitflags/lib.rs index 370a5d48dec..0367130c132 100644 --- a/src/librustc_bitflags/lib.rs +++ b/src/librustc_bitflags/lib.rs @@ -8,6 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. + +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "rustc_bitflags"] #![feature(staged_api)] #![staged_api] @@ -83,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!"); /// } /// ``` /// @@ -316,7 +319,7 @@ mod tests { bitflags! { flags AnotherSetOfFlags: i8 { - const AnotherFlag = -1_i8, + const AnotherFlag = -1, } } @@ -327,7 +330,7 @@ mod tests { assert_eq!(FlagABC.bits(), 0b00000111); assert_eq!(AnotherSetOfFlags::empty().bits(), 0b00); - assert_eq!(AnotherFlag.bits(), !0_i8); + assert_eq!(AnotherFlag.bits(), !0); } #[test] @@ -338,7 +341,7 @@ mod tests { assert!(Flags::from_bits(0b11) == Some(FlagA | FlagB)); assert!(Flags::from_bits(0b1000) == None); - assert!(AnotherSetOfFlags::from_bits(!0_i8) == Some(AnotherFlag)); + assert!(AnotherSetOfFlags::from_bits(!0) == Some(AnotherFlag)); } #[test] @@ -350,7 +353,7 @@ mod tests { assert!(Flags::from_bits_truncate(0b1000) == Flags::empty()); assert!(Flags::from_bits_truncate(0b1001) == FlagA); - assert!(AnotherSetOfFlags::from_bits_truncate(0_i8) == AnotherSetOfFlags::empty()); + assert!(AnotherSetOfFlags::from_bits_truncate(0) == AnotherSetOfFlags::empty()); } #[test] diff --git a/src/librustc_borrowck/borrowck/gather_loans/move_error.rs b/src/librustc_borrowck/borrowck/gather_loans/move_error.rs index 53761eb1471..84636ebaae4 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/move_error.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/move_error.rs @@ -165,7 +165,7 @@ fn note_move_destination(bccx: &BorrowckCtxt, bccx.span_note( move_to_span, "attempting to move value to here"); - bccx.span_help( + bccx.fileline_help( move_to_span, &format!("to prevent the move, \ use `ref {0}` or `ref mut {0}` to capture value by \ diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index f6df2acce59..b176d8d4118 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -643,7 +643,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { ol, moved_lp_msg, pat_ty.user_string(self.tcx))); - self.tcx.sess.span_help(span, + self.tcx.sess.fileline_help(span, "use `ref` to override"); } @@ -675,7 +675,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { moved_lp_msg, expr_ty.user_string(self.tcx), suggestion)); - self.tcx.sess.span_help(expr_span, help); + self.tcx.sess.fileline_help(expr_span, help); } } @@ -704,9 +704,9 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { 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, @@ -741,6 +741,10 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { self.tcx.sess.span_help(s, m); } + pub fn fileline_help(&self, s: Span, m: &str) { + self.tcx.sess.fileline_help(s, m); + } + pub fn bckerr_to_string(&self, err: &BckError<'tcx>) -> String { match err.code { err_mutbl => { @@ -870,7 +874,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { } if is_closure { - self.tcx.sess.span_help( + self.tcx.sess.fileline_help( span, "closures behind references must be called via `&mut`"); } diff --git a/src/librustc_borrowck/lib.rs b/src/librustc_borrowck/lib.rs index b7cfda28092..e09457970e1 100644 --- a/src/librustc_borrowck/lib.rs +++ b/src/librustc_borrowck/lib.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "rustc_borrowck"] #![unstable(feature = "rustc_private")] #![staged_api] diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 425ec7ec452..dc27a301109 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -32,10 +32,10 @@ use super::Compilation; use serialize::json; use std::env; -use std::os; use std::ffi::OsString; -use std::old_io::fs; -use std::old_io; +use std::fs; +use std::io::{self, Write}; +use std::path::{Path, PathBuf}; use syntax::ast; use syntax::ast_map; use syntax::attr; @@ -48,8 +48,8 @@ use syntax; pub fn compile_input(sess: Session, cfg: ast::CrateConfig, input: &Input, - outdir: &Option<Path>, - output: &Option<Path>, + outdir: &Option<PathBuf>, + output: &Option<PathBuf>, addl_plugins: Option<Vec<String>>, control: CompileController) { macro_rules! controller_entry_point{($point: ident, $make_state: expr) => ({ @@ -166,7 +166,7 @@ pub fn anon_src() -> String { pub fn source_name(input: &Input) -> String { match *input { // FIXME (#9639): This needs to handle non-utf8 paths - Input::File(ref ifile) => ifile.as_str().unwrap().to_string(), + Input::File(ref ifile) => ifile.to_str().unwrap().to_string(), Input::Str(_) => anon_src() } } @@ -243,12 +243,12 @@ pub struct CompileState<'a, 'ast: 'a, 'tcx: 'a> { impl<'a, 'ast, 'tcx> CompileState<'a, 'ast, 'tcx> { fn empty(input: &'a Input, session: &'a Session, - out_dir: &'a Option<Path>) + out_dir: &'a Option<PathBuf>) -> CompileState<'a, 'ast, 'tcx> { CompileState { input: input, session: session, - out_dir: out_dir.as_ref(), + out_dir: out_dir.as_ref().map(|s| &**s), cfg: None, krate: None, crate_name: None, @@ -263,7 +263,7 @@ impl<'a, 'ast, 'tcx> CompileState<'a, 'ast, 'tcx> { fn state_after_parse(input: &'a Input, session: &'a Session, - out_dir: &'a Option<Path>, + out_dir: &'a Option<PathBuf>, krate: &'a ast::Crate) -> CompileState<'a, 'ast, 'tcx> { CompileState { @@ -274,7 +274,7 @@ impl<'a, 'ast, 'tcx> CompileState<'a, 'ast, 'tcx> { fn state_after_expand(input: &'a Input, session: &'a Session, - out_dir: &'a Option<Path>, + out_dir: &'a Option<PathBuf>, expanded_crate: &'a ast::Crate, crate_name: &'a str) -> CompileState<'a, 'ast, 'tcx> { @@ -287,7 +287,7 @@ impl<'a, 'ast, 'tcx> CompileState<'a, 'ast, 'tcx> { fn state_after_write_deps(input: &'a Input, session: &'a Session, - out_dir: &'a Option<Path>, + out_dir: &'a Option<PathBuf>, ast_map: &'a ast_map::Map<'ast>, expanded_crate: &'a ast::Crate, crate_name: &'a str) @@ -302,7 +302,7 @@ impl<'a, 'ast, 'tcx> CompileState<'a, 'ast, 'tcx> { fn state_after_analysis(input: &'a Input, session: &'a Session, - out_dir: &'a Option<Path>, + out_dir: &'a Option<PathBuf>, expanded_crate: &'a ast::Crate, analysis: &'a ty::CrateAnalysis<'tcx>, tcx: &'a ty::ctxt<'tcx>) @@ -318,7 +318,7 @@ impl<'a, 'ast, 'tcx> CompileState<'a, 'ast, 'tcx> { fn state_after_llvm(input: &'a Input, session: &'a Session, - out_dir: &'a Option<Path>, + out_dir: &'a Option<PathBuf>, trans: &'a trans::CrateTranslation) -> CompileState<'a, 'ast, 'tcx> { CompileState { @@ -472,7 +472,7 @@ pub fn phase_2_configure_and_expand(sess: &Session, if cfg!(windows) { _old_path = env::var_os("PATH").unwrap_or(_old_path); let mut new_path = sess.host_filesearch(PathKind::All).get_dylib_search_paths(); - new_path.extend(os::split_paths(_old_path.to_str().unwrap()).into_iter()); + new_path.extend(env::split_paths(&_old_path)); env::set_var("PATH", &env::join_paths(new_path.iter()).unwrap()); } let features = sess.features.borrow(); @@ -493,12 +493,16 @@ pub fn phase_2_configure_and_expand(sess: &Session, } ); - // Needs to go *after* expansion to be able to check the results of macro expansion. - time(time_passes, "complete gated feature checking", (), |_| { + // Needs to go *after* expansion to be able to check the results + // of macro expansion. This runs before #[cfg] to try to catch as + // much as possible (e.g. help the programmer avoid platform + // specific differences) + time(time_passes, "complete gated feature checking 1", (), |_| { let features = syntax::feature_gate::check_crate(sess.codemap(), - &sess.parse_sess.span_diagnostic, - &krate); + &sess.parse_sess.span_diagnostic, + &krate, + true); *sess.features.borrow_mut() = features; sess.abort_if_errors(); }); @@ -521,6 +525,19 @@ pub fn phase_2_configure_and_expand(sess: &Session, time(time_passes, "checking that all macro invocations are gone", &krate, |krate| syntax::ext::expand::check_for_macros(&sess.parse_sess, krate)); + // One final feature gating of the true AST that gets compiled + // later, to make sure we've got everything (e.g. configuration + // can insert new attributes via `cfg_attr`) + time(time_passes, "complete gated feature checking 2", (), |_| { + let features = + syntax::feature_gate::check_crate(sess.codemap(), + &sess.parse_sess.span_diagnostic, + &krate, + false); + *sess.features.borrow_mut() = features; + sess.abort_if_errors(); + }); + Some(krate) } @@ -717,7 +734,7 @@ pub fn phase_5_run_llvm_passes(sess: &Session, // Remove assembly source, unless --save-temps was specified if !sess.opts.cg.save_temps { - fs::unlink(&outputs.temp_path(config::OutputTypeAssembly)).unwrap(); + fs::remove_file(&outputs.temp_path(config::OutputTypeAssembly)).unwrap(); } } else { time(sess.time_passes(), "LLVM passes", (), |_| @@ -737,7 +754,7 @@ pub fn phase_6_link_output(sess: &Session, outputs: &OutputFilenames) { let old_path = env::var_os("PATH").unwrap_or(OsString::from_str("")); let mut new_path = sess.host_filesearch(PathKind::All).get_tools_search_paths(); - new_path.extend(os::split_paths(old_path.to_str().unwrap()).into_iter()); + new_path.extend(env::split_paths(&old_path)); env::set_var("PATH", &env::join_paths(new_path.iter()).unwrap()); time(sess.time_passes(), "linking", (), |_| @@ -793,17 +810,19 @@ fn write_out_deps(sess: &Session, _ => return, }; - let result = (|| -> old_io::IoResult<()> { + let result = (|| -> io::Result<()> { // Build a list of files used to compile the output and // write Makefile-compatible dependency rules let files: Vec<String> = sess.codemap().files.borrow() - .iter().filter(|fmap| fmap.is_real_file()) + .iter() + .filter(|fmap| fmap.is_real_file()) + .filter(|fmap| !fmap.is_imported()) .map(|fmap| escape_dep_filename(&fmap.name)) .collect(); - let mut file = try!(old_io::File::create(&deps_filename)); + let mut file = try!(fs::File::create(&deps_filename)); for path in &out_filenames { - try!(write!(&mut file as &mut Writer, - "{}: {}\n\n", path.display(), files.connect(" "))); + try!(write!(&mut file, + "{}: {}\n\n", path.display(), files.connect(" "))); } Ok(()) })(); @@ -896,8 +915,8 @@ pub fn collect_crate_metadata(session: &Session, } pub fn build_output_filenames(input: &Input, - odir: &Option<Path>, - ofile: &Option<Path>, + odir: &Option<PathBuf>, + ofile: &Option<PathBuf>, attrs: &[ast::Attribute], sess: &Session) -> OutputFilenames { @@ -908,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 => Path::new(".") + None => PathBuf::new("") }; // If a crate name is present, we use it as the link name @@ -935,9 +954,13 @@ 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.dir_path(), - out_filestem: out_file.filestem_str().unwrap().to_string(), + 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, extra: sess.opts.cg.extra_filename.clone(), } diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 15fae351ddb..c09b018ab63 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -14,6 +14,8 @@ //! //! This API is completely unstable and subject to change. +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "rustc_driver"] #![unstable(feature = "rustc_private")] #![staged_api] @@ -29,8 +31,6 @@ #![feature(int_uint)] #![feature(old_io)] #![feature(libc)] -#![feature(os)] -#![feature(old_path)] #![feature(quote)] #![feature(rustc_diagnostic_macros)] #![feature(rustc_private)] @@ -38,6 +38,8 @@ #![feature(staged_api)] #![feature(unicode)] #![feature(exit_status)] +#![feature(path)] +#![feature(io)] extern crate arena; extern crate flate; @@ -73,9 +75,10 @@ use rustc::metadata; use rustc::util::common::time; use std::cmp::Ordering::Equal; -use std::old_io::{self, stdio}; -use std::iter::repeat; use std::env; +use std::iter::repeat; +use std::old_io::{self, stdio}; +use std::path::PathBuf; use std::sync::mpsc::channel; use std::thread; @@ -159,14 +162,14 @@ pub fn run_compiler<'a>(args: &[String], } // Extract output directory and file from matches. -fn make_output(matches: &getopts::Matches) -> (Option<Path>, Option<Path>) { - let odir = matches.opt_str("out-dir").map(|o| Path::new(o)); - let ofile = matches.opt_str("o").map(|o| Path::new(o)); +fn make_output(matches: &getopts::Matches) -> (Option<PathBuf>, Option<PathBuf>) { + let odir = matches.opt_str("out-dir").map(|o| PathBuf::new(&o)); + let ofile = matches.opt_str("o").map(|o| PathBuf::new(&o)); (odir, ofile) } // Extract input (string or file and optional path) from matches. -fn make_input(free_matches: &[String]) -> Option<(Input, Option<Path>)> { +fn make_input(free_matches: &[String]) -> Option<(Input, Option<PathBuf>)> { if free_matches.len() == 1 { let ifile = &free_matches[0][..]; if ifile == "-" { @@ -174,7 +177,7 @@ fn make_input(free_matches: &[String]) -> Option<(Input, Option<Path>)> { let src = String::from_utf8(contents).unwrap(); Some((Input::Str(src), None)) } else { - Some((Input::File(Path::new(ifile)), Some(Path::new(ifile)))) + Some((Input::File(PathBuf::new(ifile)), Some(PathBuf::new(ifile)))) } } else { None @@ -215,14 +218,15 @@ pub trait CompilerCalls<'a> { &getopts::Matches, &Session, &Input, - &Option<Path>, - &Option<Path>) + &Option<PathBuf>, + &Option<PathBuf>) -> Compilation; // Called after we extract the input from the arguments. Gives the implementer // an opportunity to change the inputs or to add some custom input handling. // The default behaviour is to simply pass through the inputs. - fn some_input(&mut self, input: Input, input_path: Option<Path>) -> (Input, Option<Path>) { + fn some_input(&mut self, input: Input, input_path: Option<PathBuf>) + -> (Input, Option<PathBuf>) { (input, input_path) } @@ -234,10 +238,10 @@ pub trait CompilerCalls<'a> { fn no_input(&mut self, &getopts::Matches, &config::Options, - &Option<Path>, - &Option<Path>, + &Option<PathBuf>, + &Option<PathBuf>, &diagnostics::registry::Registry) - -> Option<(Input, Option<Path>)>; + -> Option<(Input, Option<PathBuf>)>; // Parse pretty printing information from the arguments. The implementer can // choose to ignore this (the default will return None) which will skip pretty @@ -293,10 +297,10 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls { fn no_input(&mut self, matches: &getopts::Matches, sopts: &config::Options, - odir: &Option<Path>, - ofile: &Option<Path>, + odir: &Option<PathBuf>, + ofile: &Option<PathBuf>, descriptions: &diagnostics::registry::Registry) - -> Option<(Input, Option<Path>)> { + -> Option<(Input, Option<PathBuf>)> { match matches.free.len() { 0 => { if sopts.describe_lints { @@ -346,8 +350,8 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls { matches: &getopts::Matches, sess: &Session, input: &Input, - odir: &Option<Path>, - ofile: &Option<Path>) + odir: &Option<PathBuf>, + ofile: &Option<PathBuf>) -> Compilation { RustcDefaultCalls::print_crate_info(sess, Some(input), odir, ofile).and_then( || RustcDefaultCalls::list_metadata(sess, matches, input)) @@ -400,11 +404,12 @@ impl RustcDefaultCalls { if r.contains(&("ls".to_string())) { match input { &Input::File(ref ifile) => { - let mut stdout = old_io::stdout(); let path = &(*ifile); + let mut v = Vec::new(); metadata::loader::list_file_metadata(sess.target.target.options.is_like_osx, path, - &mut stdout).unwrap(); + &mut v).unwrap(); + println!("{}", String::from_utf8(v).unwrap()); } &Input::Str(_) => { early_error("cannot list metadata for stdin"); @@ -419,8 +424,8 @@ impl RustcDefaultCalls { fn print_crate_info(sess: &Session, input: Option<&Input>, - odir: &Option<Path>, - ofile: &Option<Path>) + odir: &Option<PathBuf>, + ofile: &Option<PathBuf>) -> Compilation { if sess.opts.prints.len() == 0 { return Compilation::Continue; @@ -457,7 +462,8 @@ impl RustcDefaultCalls { style, &id, &t_outputs.with_extension("")); - println!("{}", fname.filename_display()); + println!("{}", fname.file_name().unwrap() + .to_string_lossy()); } } } @@ -769,6 +775,7 @@ fn parse_crate_attrs(sess: &Session, input: &Input) -> /// /// The diagnostic emitter yielded to the procedure should be used for reporting /// errors of the compiler. +#[allow(deprecated)] pub fn monitor<F:FnOnce()+Send+'static>(f: F) { const STACK_SIZE: uint = 8 * 1024 * 1024; // 8MB diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs index 22473099baf..ffb2a05e437 100644 --- a/src/librustc_driver/pretty.rs +++ b/src/librustc_driver/pretty.rs @@ -38,8 +38,11 @@ use syntax::ptr::P; use graphviz as dot; -use std::old_io::{self, MemReader}; +use std::fs::File; +use std::io::{self, Write}; +use std::old_io; use std::option; +use std::path::PathBuf; use std::str::FromStr; #[derive(Copy, PartialEq, Debug)] @@ -208,7 +211,7 @@ impl<'ast> PrinterSupport<'ast> for IdentifiedAnnotation<'ast> { impl<'ast> pprust::PpAnn for IdentifiedAnnotation<'ast> { fn pre(&self, s: &mut pprust::State, - node: pprust::AnnNode) -> old_io::IoResult<()> { + node: pprust::AnnNode) -> io::Result<()> { match node { pprust::NodeExpr(_) => s.popen(), _ => Ok(()) @@ -216,7 +219,7 @@ impl<'ast> pprust::PpAnn for IdentifiedAnnotation<'ast> { } fn post(&self, s: &mut pprust::State, - node: pprust::AnnNode) -> old_io::IoResult<()> { + node: pprust::AnnNode) -> io::Result<()> { match node { pprust::NodeIdent(_) | pprust::NodeName(_) => Ok(()), @@ -259,7 +262,7 @@ impl<'ast> PrinterSupport<'ast> for HygieneAnnotation<'ast> { impl<'ast> pprust::PpAnn for HygieneAnnotation<'ast> { fn post(&self, s: &mut pprust::State, - node: pprust::AnnNode) -> old_io::IoResult<()> { + node: pprust::AnnNode) -> io::Result<()> { match node { pprust::NodeIdent(&ast::Ident { name: ast::Name(nm), ctxt }) => { try!(pp::space(&mut s.s)); @@ -294,7 +297,7 @@ impl<'tcx> PrinterSupport<'tcx> for TypedAnnotation<'tcx> { impl<'tcx> pprust::PpAnn for TypedAnnotation<'tcx> { fn pre(&self, s: &mut pprust::State, - node: pprust::AnnNode) -> old_io::IoResult<()> { + node: pprust::AnnNode) -> io::Result<()> { match node { pprust::NodeExpr(_) => s.popen(), _ => Ok(()) @@ -302,7 +305,7 @@ impl<'tcx> pprust::PpAnn for TypedAnnotation<'tcx> { } fn post(&self, s: &mut pprust::State, - node: pprust::AnnNode) -> old_io::IoResult<()> { + node: pprust::AnnNode) -> io::Result<()> { let tcx = &self.analysis.ty_cx; match node { pprust::NodeExpr(expr) => { @@ -507,7 +510,7 @@ pub fn pretty_print_input(sess: Session, input: &Input, ppm: PpMode, opt_uii: Option<UserIdentifiedItem>, - ofile: Option<Path>) { + ofile: Option<PathBuf>) { let krate = driver::phase_1_parse_input(&sess, cfg, input); let krate = if let PpmSource(PpmEveryBodyLoops) = ppm { @@ -542,25 +545,20 @@ pub fn pretty_print_input(sess: Session, let src_name = driver::source_name(input); let src = sess.codemap().get_filemap(&src_name[..]) - .src.as_bytes().to_vec(); - let mut rdr = MemReader::new(src); + .src + .as_ref() + .unwrap() + .as_bytes() + .to_vec(); + let mut rdr = &src[..]; - let out = match ofile { - None => box old_io::stdout() as Box<Writer+'static>, - Some(p) => { - let r = old_io::File::create(&p); - match r { - Ok(w) => box w as Box<Writer+'static>, - Err(e) => panic!("print-print failed to open {} due to {}", - p.display(), e), - } - } - }; + let mut out = Vec::new(); match (ppm, opt_uii) { - (PpmSource(s), None) => + (PpmSource(s), None) => { + let out: &mut Write = &mut out; s.call_with_pp_support( - sess, ast_map, &arenas, id, out, |annotation, out| { + sess, ast_map, &arenas, id, box out, |annotation, out| { debug!("pretty printing source code {:?}", s); let sess = annotation.sess(); pprust::print_crate(sess.codemap(), @@ -571,9 +569,11 @@ pub fn pretty_print_input(sess: Session, out, annotation.pp_ann(), is_expanded) - }), + }) + } - (PpmSource(s), Some(uii)) => + (PpmSource(s), Some(uii)) => { + let out: &mut Write = &mut out; s.call_with_pp_support( sess, ast_map, &arenas, id, (out,uii), |annotation, (out,uii)| { debug!("pretty printing source code {:?}", s); @@ -585,7 +585,7 @@ pub fn pretty_print_input(sess: Session, sess.diagnostic(), src_name.to_string(), &mut rdr, - out, + box out, annotation.pp_ann(), is_expanded); for node_id in uii.all_matching_node_ids(ast_map) { @@ -596,7 +596,8 @@ pub fn pretty_print_input(sess: Session, try!(pp::hardbreak(&mut pp_state.s)); } pp::eof(&mut pp_state.s) - }), + }) + } (PpmFlowGraph(mode), opt_uii) => { debug!("pretty printing flow graph for {:?}", opt_uii); @@ -614,6 +615,7 @@ pub fn pretty_print_input(sess: Session, }); let code = blocks::Code::from_node(node); + let out: &mut Writer = &mut out; match code { Some(code) => { let variants = gather_flowgraph_variants(&sess); @@ -638,14 +640,25 @@ pub fn pretty_print_input(sess: Session, } } } - }.unwrap() + }.unwrap(); + + match ofile { + None => print!("{}", String::from_utf8(out).unwrap()), + Some(p) => { + match File::create(&p) { + Ok(mut w) => w.write_all(&out).unwrap(), + Err(e) => panic!("print-print failed to open {} due to {}", + p.display(), e), + } + } + } } fn print_flowgraph<W:old_io::Writer>(variants: Vec<borrowck_dot::Variant>, analysis: ty::CrateAnalysis, code: blocks::Code, mode: PpFlowGraphMode, - mut out: W) -> old_io::IoResult<()> { + mut out: W) -> io::Result<()> { let ty_cx = &analysis.ty_cx; let cfg = match code { blocks::BlockCode(block) => cfg::CFG::new(ty_cx, &*block), @@ -685,17 +698,10 @@ fn print_flowgraph<W:old_io::Writer>(variants: Vec<borrowck_dot::Variant>, } } - fn expand_err_details(r: old_io::IoResult<()>) -> old_io::IoResult<()> { + fn expand_err_details(r: old_io::IoResult<()>) -> io::Result<()> { r.map_err(|ioerr| { - let orig_detail = ioerr.detail.clone(); - let m = "graphviz::render failed"; - old_io::IoError { - detail: Some(match orig_detail { - None => m.to_string(), - Some(d) => format!("{}: {}", m, d) - }), - ..ioerr - } + io::Error::new(io::ErrorKind::Other, "graphviz::render failed", + Some(ioerr.to_string())) }) } } diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 22311a71583..c24f170a381 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -432,8 +432,8 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { } def::DefTy(..) => { let tty = match self.cx.tcx.ast_ty_to_ty_cache.borrow().get(&id) { - Some(&ty::atttce_resolved(t)) => t, - _ => panic!("ast_ty_to_ty_cache was incomplete after typeck!") + Some(&t) => t, + None => panic!("ast_ty_to_ty_cache was incomplete after typeck!") }; if !ty::is_ffi_safe(self.cx.tcx, tty) { @@ -1921,7 +1921,8 @@ impl LintPass for UnconditionalRecursion { for call in &self_call_spans { sess.span_note(*call, "recursive call site") } - sess.span_help(sp, "a `loop` may express intention better if this is on purpose") + sess.fileline_help(sp, "a `loop` may express intention \ + better if this is on purpose") } } @@ -2079,7 +2080,7 @@ impl LintPass for InvalidNoMangleItems { !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(..) => { diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 9eef0f1cf8b..9781e9944f6 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -19,6 +19,8 @@ //! //! This API is completely unstable and subject to change. +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "rustc_lint"] #![unstable(feature = "rustc_private")] #![staged_api] diff --git a/src/librustc_llvm/archive_ro.rs b/src/librustc_llvm/archive_ro.rs index 14a99026aac..f54480e3e52 100644 --- a/src/librustc_llvm/archive_ro.rs +++ b/src/librustc_llvm/archive_ro.rs @@ -16,6 +16,7 @@ use ArchiveRef; use std::ffi::CString; use std::mem; use std::raw; +use std::path::Path; pub struct ArchiveRO { ptr: ArchiveRef, @@ -29,14 +30,25 @@ impl ArchiveRO { /// If this archive is used with a mutable method, then an error will be /// raised. pub fn open(dst: &Path) -> Option<ArchiveRO> { - unsafe { - let s = CString::new(dst.as_vec()).unwrap(); + return unsafe { + let s = path2cstr(dst); let ar = ::LLVMRustOpenArchive(s.as_ptr()); if ar.is_null() { None } else { Some(ArchiveRO { ptr: ar }) } + }; + + #[cfg(unix)] + fn path2cstr(p: &Path) -> CString { + use std::os::unix::prelude::*; + use std::ffi::AsOsStr; + CString::new(p.as_os_str().as_bytes()).unwrap() + } + #[cfg(windows)] + fn path2cstr(p: &Path) -> CString { + CString::new(p.to_str().unwrap()).unwrap() } } diff --git a/src/librustc_llvm/lib.rs b/src/librustc_llvm/lib.rs index 09a187befb2..0ff96784e58 100644 --- a/src/librustc_llvm/lib.rs +++ b/src/librustc_llvm/lib.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![allow(non_upper_case_globals)] #![allow(non_camel_case_types)] #![allow(non_snake_case)] @@ -28,9 +30,9 @@ #![feature(int_uint)] #![feature(libc)] #![feature(link_args)] -#![feature(old_path)] #![feature(staged_api)] -#![feature(std_misc)] +#![feature(path)] +#![cfg_attr(unix, feature(std_misc))] extern crate libc; #[macro_use] #[no_link] extern crate rustc_bitflags; diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index ab3b56c31b6..c766b20389e 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "rustc_privacy"] #![unstable(feature = "rustc_private")] #![staged_api] diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 78ce9abe07d..ccca99f8b4e 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "rustc_resolve"] #![unstable(feature = "rustc_private")] #![staged_api] @@ -4115,10 +4117,14 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { uses it like a function name", path_name)); - self.session.span_help(expr.span, - &format!("Did you mean to write: \ - `{} {{ /* fields */ }}`?", - path_name)); + let msg = format!("Did you mean to write: \ + `{} {{ /* fields */ }}`?", + path_name); + if self.emit_errors { + self.session.fileline_help(expr.span, &msg); + } else { + self.session.span_help(expr.span, &msg); + } } else { // Write the result into the def map. debug!("(resolving expr) resolved `{}`", @@ -4146,18 +4152,21 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { match type_res.map(|r| r.base_def) { Some(DefTy(struct_id, _)) if self.structs.contains_key(&struct_id) => { - self.resolve_error(expr.span, + self.resolve_error(expr.span, &format!("`{}` is a structure name, but \ this expression \ uses it like a function name", path_name)); - self.session.span_help(expr.span, - &format!("Did you mean to write: \ - `{} {{ /* fields */ }}`?", - path_name)); - - } + let msg = format!("Did you mean to write: \ + `{} {{ /* fields */ }}`?", + path_name); + if self.emit_errors { + self.session.fileline_help(expr.span, &msg); + } else { + self.session.span_help(expr.span, &msg); + } + } _ => { // Keep reporting some errors even if they're ignored above. self.resolve_path(expr.id, path, 0, ValueNS, true); diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index 7b377ac3611..3087a8ea45d 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -26,13 +26,15 @@ use middle::ty::{self, Ty}; use util::common::time; use util::ppaux; use util::sha2::{Digest, Sha256}; +use rustc_back::tempdir::TempDir; -use std::old_io::fs::PathExtensions; -use std::old_io::{fs, TempDir, Command}; -use std::old_io; +use std::ffi::OsString; +use std::fs::{self, PathExt}; +use std::io::{self, Read, Write}; use std::mem; +use std::path::{Path, PathBuf}; +use std::process::Command; use std::str; -use std::string::String; use flate; use serialize::hex::ToHex; use syntax::ast; @@ -156,7 +158,7 @@ pub fn find_crate_name(sess: Option<&Session>, return validate(s.to_string(), Some(attr.span)); } if let Input::File(ref path) = *input { - if let Some(s) = path.filestem_str() { + if let Some(s) = path.file_stem().and_then(|s| s.to_str()) { return validate(s.to_string(), None); } } @@ -356,7 +358,7 @@ pub fn get_cc_prog(sess: &Session) -> String { } pub fn remove(sess: &Session, path: &Path) { - match fs::unlink(path) { + match fs::remove_file(path) { Ok(..) => {} Err(e) => { sess.err(&format!("failed to remove {}: {}", @@ -371,7 +373,7 @@ pub fn remove(sess: &Session, path: &Path) { pub fn link_binary(sess: &Session, trans: &CrateTranslation, outputs: &OutputFilenames, - crate_name: &str) -> Vec<Path> { + crate_name: &str) -> Vec<PathBuf> { let mut out_filenames = Vec::new(); for &crate_type in &*sess.crate_types.borrow() { if invalid_output_for_target(sess, crate_type) { @@ -425,35 +427,35 @@ pub fn invalid_output_for_target(sess: &Session, } fn is_writeable(p: &Path) -> bool { - match p.stat() { + match p.metadata() { Err(..) => true, - Ok(m) => m.perm & old_io::USER_WRITE == old_io::USER_WRITE + Ok(m) => !m.permissions().readonly() } } pub fn filename_for_input(sess: &Session, crate_type: config::CrateType, name: &str, - out_filename: &Path) -> Path { + out_filename: &Path) -> PathBuf { let libname = format!("{}{}", name, sess.opts.cg.extra_filename); match crate_type { config::CrateTypeRlib => { - out_filename.with_filename(format!("lib{}.rlib", libname)) + out_filename.with_file_name(&format!("lib{}.rlib", libname)) } config::CrateTypeDylib => { let (prefix, suffix) = (&sess.target.target.options.dll_prefix, &sess.target.target.options.dll_suffix); - out_filename.with_filename(format!("{}{}{}", - prefix, - libname, - suffix)) + out_filename.with_file_name(&format!("{}{}{}", + prefix, + libname, + suffix)) } config::CrateTypeStaticlib => { - out_filename.with_filename(format!("lib{}.a", libname)) + out_filename.with_file_name(&format!("lib{}.a", libname)) } config::CrateTypeExecutable => { let suffix = &sess.target.target.options.exe_suffix; - out_filename.with_filename(format!("{}{}", libname, suffix)) + out_filename.with_file_name(&format!("{}{}", libname, suffix)) } } } @@ -462,7 +464,7 @@ fn link_binary_output(sess: &Session, trans: &CrateTranslation, crate_type: config::CrateType, outputs: &OutputFilenames, - crate_name: &str) -> Path { + crate_name: &str) -> PathBuf { let obj_filename = outputs.temp_path(OutputTypeObject); let out_filename = match outputs.single_output_file { Some(ref file) => file.clone(), @@ -507,10 +509,10 @@ fn link_binary_output(sess: &Session, out_filename } -fn archive_search_paths(sess: &Session) -> Vec<Path> { +fn archive_search_paths(sess: &Session) -> Vec<PathBuf> { let mut search = Vec::new(); sess.target_filesearch(PathKind::Native).for_each_lib_search_path(|path, _| { - search.push(path.clone()); + search.push(path.to_path_buf()); FileDoesntMatch }); return search; @@ -529,7 +531,7 @@ fn link_rlib<'a>(sess: &'a Session, let handler = &sess.diagnostic().handler; let config = ArchiveConfig { handler: handler, - dst: out_filename.clone(), + dst: out_filename.to_path_buf(), lib_search_paths: archive_search_paths(sess), slib_prefix: sess.target.target.options.staticlib_prefix.clone(), slib_suffix: sess.target.target.options.staticlib_suffix.clone(), @@ -588,7 +590,9 @@ fn link_rlib<'a>(sess: &'a Session, // the same filename for metadata (stomping over one another) let tmpdir = TempDir::new("rustc").ok().expect("needs a temp dir"); let metadata = tmpdir.path().join(METADATA_FILENAME); - match fs::File::create(&metadata).write_all(&trans.metadata) { + match fs::File::create(&metadata).and_then(|mut f| { + f.write_all(&trans.metadata) + }) { Ok(..) => {} Err(e) => { sess.err(&format!("failed to write {}: {}", @@ -613,28 +617,32 @@ fn link_rlib<'a>(sess: &'a Session, let bc_deflated_filename = obj_filename.with_extension( &format!("{}.bytecode.deflate", i)); - let bc_data = match fs::File::open(&bc_filename).read_to_end() { - Ok(buffer) => buffer, + let mut bc_data = Vec::new(); + match fs::File::open(&bc_filename).and_then(|mut f| { + f.read_to_end(&mut bc_data) + }) { + Ok(..) => {} Err(e) => sess.fatal(&format!("failed to read bytecode: {}", e)) - }; + } let bc_data_deflated = match flate::deflate_bytes(&bc_data[..]) { Some(compressed) => compressed, - None => sess.fatal(&format!("failed to compress bytecode from {}", - bc_filename.display())) + None => sess.fatal(&format!("failed to compress bytecode \ + from {}", + bc_filename.display())) }; let mut bc_file_deflated = match fs::File::create(&bc_deflated_filename) { Ok(file) => file, Err(e) => { - sess.fatal(&format!("failed to create compressed bytecode \ - file: {}", e)) + sess.fatal(&format!("failed to create compressed \ + bytecode file: {}", e)) } }; match write_rlib_bytecode_object_v1(&mut bc_file_deflated, - bc_data_deflated.as_slice()) { + &bc_data_deflated) { Ok(()) => {} Err(e) => { sess.err(&format!("failed to write compressed bytecode: \ @@ -670,15 +678,23 @@ fn link_rlib<'a>(sess: &'a Session, ab } -fn write_rlib_bytecode_object_v1<T: Writer>(writer: &mut T, - bc_data_deflated: &[u8]) - -> ::std::old_io::IoResult<()> { +fn write_rlib_bytecode_object_v1(writer: &mut Write, + bc_data_deflated: &[u8]) -> io::Result<()> { let bc_data_deflated_size: u64 = bc_data_deflated.len() as u64; - try! { writer.write_all(RLIB_BYTECODE_OBJECT_MAGIC) }; - try! { writer.write_le_u32(1) }; - try! { writer.write_le_u64(bc_data_deflated_size) }; - try! { writer.write_all(&bc_data_deflated[..]) }; + try!(writer.write_all(RLIB_BYTECODE_OBJECT_MAGIC)); + try!(writer.write_all(&[1, 0, 0, 0])); + try!(writer.write_all(&[ + (bc_data_deflated_size >> 0) as u8, + (bc_data_deflated_size >> 8) as u8, + (bc_data_deflated_size >> 16) as u8, + (bc_data_deflated_size >> 24) as u8, + (bc_data_deflated_size >> 32) as u8, + (bc_data_deflated_size >> 40) as u8, + (bc_data_deflated_size >> 48) as u8, + (bc_data_deflated_size >> 56) as u8, + ])); + try!(writer.write_all(&bc_data_deflated)); let number_of_bytes_written_so_far = RLIB_BYTECODE_OBJECT_MAGIC.len() + // magic id @@ -690,7 +706,7 @@ fn write_rlib_bytecode_object_v1<T: Writer>(writer: &mut T, // padding byte to make it even. This works around a crash bug in LLDB // (see issue #15950) if number_of_bytes_written_so_far % 2 == 1 { - try! { writer.write_u8(0) }; + try!(writer.write_all(&[0])); } return Ok(()); @@ -796,13 +812,13 @@ fn link_natively(sess: &Session, trans: &CrateTranslation, dylib: bool, pname, prog.status)); sess.note(&format!("{:?}", &cmd)); - let mut output = prog.error.clone(); - output.push_all(&prog.output); + let mut output = prog.stderr.clone(); + output.push_all(&prog.stdout); sess.note(str::from_utf8(&output[..]).unwrap()); sess.abort_if_errors(); } - debug!("linker stderr:\n{}", String::from_utf8(prog.error).unwrap()); - debug!("linker stdout:\n{}", String::from_utf8(prog.output).unwrap()); + debug!("linker stderr:\n{}", String::from_utf8(prog.stderr).unwrap()); + debug!("linker stdout:\n{}", String::from_utf8(prog.stdout).unwrap()); }, Err(e) => { sess.err(&format!("could not exec the linker `{}`: {}", @@ -866,9 +882,9 @@ fn link_args(cmd: &mut Command, if t.options.is_like_osx { let morestack = lib_path.join("libmorestack.a"); - let mut v = b"-Wl,-force_load,".to_vec(); - v.push_all(morestack.as_vec()); - cmd.arg(&v[..]); + let mut v = OsString::from_str("-Wl,-force_load,"); + v.push(&morestack); + cmd.arg(&v); } else { cmd.args(&["-Wl,--whole-archive", "-lmorestack", "-Wl,--no-whole-archive"]); } @@ -878,7 +894,7 @@ fn link_args(cmd: &mut Command, // executable. This metadata is in a separate object file from the main // object file, so we link that in here. if dylib { - cmd.arg(obj_filename.with_extension("metadata.o")); + cmd.arg(&obj_filename.with_extension("metadata.o")); } if t.options.is_like_osx { @@ -991,9 +1007,9 @@ fn link_args(cmd: &mut Command, cmd.args(&["-dynamiclib", "-Wl,-dylib"]); if sess.opts.cg.rpath { - let mut v = "-Wl,-install_name,@rpath/".as_bytes().to_vec(); - v.push_all(out_filename.filename().unwrap()); - cmd.arg(&v[..]); + let mut v = OsString::from_str("-Wl,-install_name,@rpath/"); + v.push(out_filename.file_name().unwrap()); + cmd.arg(&v); } } else { cmd.arg("-shared"); @@ -1006,23 +1022,23 @@ fn link_args(cmd: &mut Command, if sess.opts.cg.rpath { let sysroot = sess.sysroot(); let target_triple = &sess.opts.target_triple; - let get_install_prefix_lib_path = || { + let mut get_install_prefix_lib_path = || { let install_prefix = option_env!("CFG_PREFIX").expect("CFG_PREFIX"); let tlib = filesearch::relative_target_lib_path(sysroot, target_triple); - let mut path = Path::new(install_prefix); + let mut path = PathBuf::new(install_prefix); path.push(&tlib); path }; - let rpath_config = RPathConfig { + let mut rpath_config = RPathConfig { used_crates: sess.cstore.get_used_crates(cstore::RequireDynamic), - out_filename: out_filename.clone(), + out_filename: out_filename.to_path_buf(), has_rpath: sess.target.target.options.has_rpath, is_like_osx: sess.target.target.options.is_like_osx, - get_install_prefix_lib_path: get_install_prefix_lib_path, - realpath: ::util::fs::realpath + get_install_prefix_lib_path: &mut get_install_prefix_lib_path, + realpath: &mut ::util::fs::realpath }; - cmd.args(&rpath::get_rpath_flags(rpath_config)); + cmd.args(&rpath::get_rpath_flags(&mut rpath_config)); } // Finally add all the linker arguments provided on the command line along @@ -1082,7 +1098,7 @@ fn add_local_native_libraries(cmd: &mut Command, sess: &Session) { let search_path = archive_search_paths(sess); for l in staticlibs { if takes_hints { - cmd.arg(format!("-l{}", l)); + cmd.arg(&format!("-l{}", l)); } else { // -force_load is the OSX equivalent of --whole-archive, but it // involves passing the full path to the library to link. @@ -1091,9 +1107,9 @@ fn add_local_native_libraries(cmd: &mut Command, sess: &Session) { &sess.target.target.options.staticlib_suffix, &search_path[..], &sess.diagnostic().handler); - let mut v = b"-Wl,-force_load,".to_vec(); - v.push_all(lib.as_vec()); - cmd.arg(&v[..]); + let mut v = OsString::from_str("-Wl,-force_load,"); + v.push(&lib); + cmd.arg(&v); } } if takes_hints { @@ -1103,7 +1119,7 @@ fn add_local_native_libraries(cmd: &mut Command, sess: &Session) { for &(ref l, kind) in others { match kind { cstore::NativeUnknown => { - cmd.arg(format!("-l{}", l)); + cmd.arg(&format!("-l{}", l)); } cstore::NativeFramework => { cmd.arg("-framework").arg(&l[..]); @@ -1150,18 +1166,18 @@ fn add_upstream_rust_crates(cmd: &mut Command, sess: &Session, let src = sess.cstore.get_used_crate_source(cnum).unwrap(); match kind { cstore::RequireDynamic => { - add_dynamic_crate(cmd, sess, src.dylib.unwrap().0) + add_dynamic_crate(cmd, sess, &src.dylib.unwrap().0) } cstore::RequireStatic => { - add_static_crate(cmd, sess, tmpdir, src.rlib.unwrap().0) + add_static_crate(cmd, sess, tmpdir, &src.rlib.unwrap().0) } } } // Converts a library file-stem into a cc -l argument - fn unlib<'a>(config: &config::Config, stem: &'a [u8]) -> &'a [u8] { - if stem.starts_with("lib".as_bytes()) && !config.target.options.is_like_windows { + fn unlib<'a>(config: &config::Config, stem: &'a str) -> &'a str { + if stem.starts_with("lib") && !config.target.options.is_like_windows { &stem[3..] } else { stem @@ -1170,7 +1186,7 @@ fn add_upstream_rust_crates(cmd: &mut Command, sess: &Session, // Adds the static "rlib" versions of all crates to the command line. fn add_static_crate(cmd: &mut Command, sess: &Session, tmpdir: &Path, - cratepath: Path) { + cratepath: &Path) { // When performing LTO on an executable output, all of the // bytecode from the upstream libraries has already been // included in our object file output. We need to modify all of @@ -1186,12 +1202,12 @@ fn add_upstream_rust_crates(cmd: &mut Command, sess: &Session, // If we're not doing LTO, then our job is simply to just link // against the archive. if sess.lto() { - let name = cratepath.filename_str().unwrap(); + let name = cratepath.file_name().unwrap().to_str().unwrap(); let name = &name[3..name.len() - 5]; // chop off lib/.rlib time(sess.time_passes(), &format!("altering {}.rlib", name), (), |()| { - let dst = tmpdir.join(cratepath.filename().unwrap()); + let dst = tmpdir.join(cratepath.file_name().unwrap()); match fs::copy(&cratepath, &dst) { Ok(..) => {} Err(e) => { @@ -1205,7 +1221,11 @@ fn add_upstream_rust_crates(cmd: &mut Command, sess: &Session, // Fix up permissions of the copy, as fs::copy() preserves // permissions, but the original file may have been installed // by a package manager and may be read-only. - match fs::chmod(&dst, old_io::USER_READ | old_io::USER_WRITE) { + match fs::metadata(&dst).and_then(|m| { + let mut perms = m.permissions(); + perms.set_readonly(false); + fs::set_permissions(&dst, perms) + }) { Ok(..) => {} Err(e) => { sess.err(&format!("failed to chmod {} when preparing \ @@ -1227,7 +1247,7 @@ fn add_upstream_rust_crates(cmd: &mut Command, sess: &Session, archive.remove_file(&format!("{}.o", name)); let files = archive.files(); if files.iter().any(|s| s.ends_with(".o")) { - cmd.arg(dst); + cmd.arg(&dst); } }); } else { @@ -1236,19 +1256,18 @@ fn add_upstream_rust_crates(cmd: &mut Command, sess: &Session, } // Same thing as above, but for dynamic crates instead of static crates. - fn add_dynamic_crate(cmd: &mut Command, sess: &Session, cratepath: Path) { + fn add_dynamic_crate(cmd: &mut Command, sess: &Session, cratepath: &Path) { // If we're performing LTO, then it should have been previously required // that all upstream rust dependencies were available in an rlib format. assert!(!sess.lto()); // Just need to tell the linker about where the library lives and // what its name is - let dir = cratepath.dirname(); - if !dir.is_empty() { cmd.arg("-L").arg(dir); } - - let mut v = "-l".as_bytes().to_vec(); - v.push_all(unlib(&sess.target, cratepath.filestem().unwrap())); - cmd.arg(&v[..]); + if let Some(dir) = cratepath.parent() { + cmd.arg("-L").arg(dir); + } + let filestem = cratepath.file_stem().unwrap().to_str().unwrap(); + cmd.arg(&format!("-l{}", unlib(&sess.target, filestem))); } } @@ -1286,7 +1305,7 @@ fn add_upstream_native_libraries(cmd: &mut Command, sess: &Session) { for &(kind, ref lib) in &libs { match kind { cstore::NativeUnknown => { - cmd.arg(format!("-l{}", *lib)); + cmd.arg(&format!("-l{}", *lib)); } cstore::NativeFramework => { cmd.arg("-framework"); diff --git a/src/librustc_trans/back/lto.rs b/src/librustc_trans/back/lto.rs index d8a296bf041..db9966e0548 100644 --- a/src/librustc_trans/back/lto.rs +++ b/src/librustc_trans/back/lto.rs @@ -59,7 +59,7 @@ pub fn run(sess: &session::Session, llmod: ModuleRef, }; let archive = ArchiveRO::open(&path).expect("wanted an rlib"); - let file = path.filename_str().unwrap(); + let file = path.file_name().unwrap().to_str().unwrap(); let file = &file[3..file.len() - 5]; // chop off lib/.rlib debug!("reading {}", file); for i in iter::count(0, 1) { diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs index cd14fe529b1..156cfa6c4b2 100644 --- a/src/librustc_trans/back/write.rs +++ b/src/librustc_trans/back/write.rs @@ -18,17 +18,19 @@ use llvm::{ModuleRef, TargetMachineRef, PassManagerRef, DiagnosticInfoRef, Conte use llvm::SMDiagnosticRef; use trans::{CrateTranslation, ModuleTranslation}; use util::common::time; +use util::common::path2cstr; use syntax::codemap; use syntax::diagnostic; use syntax::diagnostic::{Emitter, Handler, Level, mk_handler}; use std::ffi::{CStr, CString}; -use std::old_io::Command; -use std::old_io::fs; +use std::fs; use std::iter::Unfold; +use std::mem; +use std::path::Path; +use std::process::{Command, Stdio}; use std::ptr; use std::str; -use std::mem; use std::sync::{Arc, Mutex}; use std::sync::mpsc::channel; use std::thread; @@ -67,7 +69,7 @@ pub fn write_output_file( output: &Path, file_type: llvm::FileType) { unsafe { - let output_c = CString::new(output.as_vec()).unwrap(); + let output_c = path2cstr(output); let result = llvm::LLVMRustWriteOutputFile( target, pm, m, output_c.as_ptr(), file_type); if !result { @@ -424,7 +426,7 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext, if config.emit_no_opt_bc { let ext = format!("{}.no-opt.bc", name_extra); let out = output_names.with_extension(&ext); - let out = CString::new(out.as_vec()).unwrap(); + let out = path2cstr(&out); llvm::LLVMWriteBitcodeToFile(llmod, out.as_ptr()); } @@ -477,7 +479,7 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext, if config.emit_lto_bc { let name = format!("{}.lto.bc", name_extra); let out = output_names.with_extension(&name); - let out = CString::new(out.as_vec()).unwrap(); + let out = path2cstr(&out); llvm::LLVMWriteBitcodeToFile(llmod, out.as_ptr()); } }, @@ -511,7 +513,7 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext, if config.emit_bc { let ext = format!("{}.bc", name_extra); let out = output_names.with_extension(&ext); - let out = CString::new(out.as_vec()).unwrap(); + let out = path2cstr(&out); llvm::LLVMWriteBitcodeToFile(llmod, out.as_ptr()); } @@ -519,7 +521,7 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext, if config.emit_ir { let ext = format!("{}.ll", name_extra); let out = output_names.with_extension(&ext); - let out = CString::new(out.as_vec()).unwrap(); + let out = path2cstr(&out); with_codegen(tm, llmod, config.no_builtins, |cpm| { llvm::LLVMRustPrintModule(cpm, llmod, out.as_ptr()); }) @@ -717,12 +719,11 @@ pub fn run_passes(sess: &Session, cmd.arg("-nostdlib"); for index in 0..trans.modules.len() { - cmd.arg(crate_output.with_extension(&format!("{}.o", index))); + cmd.arg(&crate_output.with_extension(&format!("{}.o", index))); } - cmd.arg("-r") - .arg("-o") - .arg(windows_output_path.as_ref().unwrap_or(output_path)); + cmd.arg("-r").arg("-o") + .arg(windows_output_path.as_ref().map(|s| &**s).unwrap_or(output_path)); cmd.args(&sess.target.target.options.post_link_args); @@ -730,9 +731,7 @@ pub fn run_passes(sess: &Session, println!("{:?}", &cmd); } - cmd.stdin(::std::old_io::process::Ignored) - .stdout(::std::old_io::process::InheritFd(1)) - .stderr(::std::old_io::process::InheritFd(2)); + cmd.stdin(Stdio::null()); match cmd.status() { Ok(status) => { if !status.success() { @@ -964,9 +963,9 @@ pub fn run_assembler(sess: &Session, outputs: &OutputFilenames) { let pname = get_cc_prog(sess); let mut cmd = Command::new(&pname[..]); - cmd.arg("-c").arg("-o").arg(outputs.path(config::OutputTypeObject)) - .arg(outputs.temp_path(config::OutputTypeAssembly)); - debug!("{:?}", &cmd); + cmd.arg("-c").arg("-o").arg(&outputs.path(config::OutputTypeObject)) + .arg(&outputs.temp_path(config::OutputTypeAssembly)); + debug!("{:?}", cmd); match cmd.output() { Ok(prog) => { @@ -975,8 +974,8 @@ pub fn run_assembler(sess: &Session, outputs: &OutputFilenames) { pname, prog.status)); sess.note(&format!("{:?}", &cmd)); - let mut note = prog.error.clone(); - note.push_all(&prog.output); + let mut note = prog.stderr.clone(); + note.push_all(&prog.stdout); sess.note(str::from_utf8(¬e[..]).unwrap()); sess.abort_if_errors(); } diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs index 71317d5875b..b74f85aa866 100644 --- a/src/librustc_trans/lib.rs +++ b/src/librustc_trans/lib.rs @@ -14,6 +14,8 @@ //! //! This API is completely unstable and subject to change. +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "rustc_trans"] #![unstable(feature = "rustc_private")] #![staged_api] @@ -29,16 +31,18 @@ #![feature(collections)] #![feature(core)] #![feature(int_uint)] -#![feature(old_io)] #![feature(libc)] -#![feature(old_path)] #![feature(quote)] #![feature(rustc_diagnostic_macros)] #![feature(rustc_private)] #![feature(unsafe_destructor)] #![feature(staged_api)] -#![feature(std_misc)] #![feature(unicode)] +#![feature(io)] +#![feature(path)] +#![feature(path_ext)] +#![feature(fs)] +#![feature(hash)] extern crate arena; extern crate flate; diff --git a/src/librustc_trans/save/mod.rs b/src/librustc_trans/save/mod.rs index 371b9268fba..3c6cb5f9de9 100644 --- a/src/librustc_trans/save/mod.rs +++ b/src/librustc_trans/save/mod.rs @@ -33,8 +33,9 @@ use middle::def; use middle::ty::{self, Ty}; use std::cell::Cell; -use std::old_io::{self, File, fs}; use std::env; +use std::fs::{self, File}; +use std::path::{Path, PathBuf}; use syntax::ast_util::{self, PostExpansionMethod}; use syntax::ast::{self, NodeId, DefId}; @@ -1537,6 +1538,7 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> { } } +#[allow(deprecated)] pub fn process_crate(sess: &Session, krate: &ast::Crate, analysis: &ty::CrateAnalysis, @@ -1557,15 +1559,15 @@ pub fn process_crate(sess: &Session, info!("Dumping crate {}", cratename); // find a path to dump our data to - let mut root_path = match env::var("DXR_RUST_TEMP_FOLDER") { - Ok(val) => Path::new(val), - Err(..) => match odir { + let mut root_path = match env::var_os("DXR_RUST_TEMP_FOLDER") { + Some(val) => PathBuf::new(&val), + None => match odir { Some(val) => val.join("dxr"), - None => Path::new("dxr-temp"), + None => PathBuf::new("dxr-temp"), }, }; - match fs::mkdir_recursive(&root_path, old_io::USER_RWX) { + match fs::create_dir_all(&root_path) { Err(e) => sess.err(&format!("Could not create directory {}: {}", root_path.display(), e)), _ => (), @@ -1579,7 +1581,7 @@ pub fn process_crate(sess: &Session, // Create output file. let mut out_name = cratename.clone(); out_name.push_str(".csv"); - root_path.push(out_name); + root_path.push(&out_name); let output_file = match File::create(&root_path) { Ok(f) => box f, Err(e) => { @@ -1595,7 +1597,7 @@ pub fn process_crate(sess: &Session, collected_paths: vec!(), collecting: false, fmt: FmtStrs::new(box Recorder { - out: output_file as Box<Writer+'static>, + out: output_file, dump_spans: false, }, SpanUtils { diff --git a/src/librustc_trans/save/recorder.rs b/src/librustc_trans/save/recorder.rs index 937f2d07677..f7c0d6a983f 100644 --- a/src/librustc_trans/save/recorder.rs +++ b/src/librustc_trans/save/recorder.rs @@ -13,7 +13,7 @@ pub use self::Row::*; use super::escape; use super::span_utils::SpanUtils; -use std::vec::Vec; +use std::io::Write; use syntax::ast; use syntax::ast::{NodeId,DefId}; @@ -23,7 +23,7 @@ const ZERO_DEF_ID: DefId = DefId { node: 0, krate: 0 }; pub struct Recorder { // output file - pub out: Box<Writer+'static>, + pub out: Box<Write+'static>, pub dump_spans: bool, } diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs index 13f882bc363..f49905613d2 100644 --- a/src/librustc_trans/trans/base.rs +++ b/src/librustc_trans/trans/base.rs @@ -833,11 +833,11 @@ pub fn fail_if_zero_or_overflows<'blk, 'tcx>( let (is_zero, is_signed) = match rhs_t.sty { ty::ty_int(t) => { - let zero = C_integral(Type::int_from_ty(cx.ccx(), t), 0u64, false); + let zero = C_integral(Type::int_from_ty(cx.ccx(), t), 0, false); (ICmp(cx, llvm::IntEQ, rhs, zero, debug_loc), true) } ty::ty_uint(t) => { - let zero = C_integral(Type::uint_from_ty(cx.ccx(), t), 0u64, false); + let zero = C_integral(Type::uint_from_ty(cx.ccx(), t), 0, false); (ICmp(cx, llvm::IntEQ, rhs, zero, debug_loc), false) } _ => { @@ -3089,7 +3089,7 @@ pub fn trans_crate<'tcx>(analysis: ty::CrateAnalysis<'tcx>) let check_overflow = if let Some(v) = tcx.sess.opts.debugging_opts.force_overflow_checks { v } else { - !attr::contains_name(&krate.config, "ndebug") + tcx.sess.opts.debug_assertions }; // Before we touch LLVM, make sure that multithreading is enabled. diff --git a/src/librustc_trans/trans/cabi_aarch64.rs b/src/librustc_trans/trans/cabi_aarch64.rs index 5d1e6d2c9e8..03496a966bf 100644 --- a/src/librustc_trans/trans/cabi_aarch64.rs +++ b/src/librustc_trans/trans/cabi_aarch64.rs @@ -117,7 +117,7 @@ fn classify_arg_ty(ccx: &CrateContext, ty: Type) -> ArgType { let size = ty_size(ty); if size <= 16 { let llty = if size == 0 { - Type::array(&Type::i64(ccx), 0u64) + Type::array(&Type::i64(ccx), 0) } else if size == 1 { Type::i8(ccx) } else if size == 2 { diff --git a/src/librustc_trans/trans/consts.rs b/src/librustc_trans/trans/consts.rs index a39f5d42b55..39b430b7ad5 100644 --- a/src/librustc_trans/trans/consts.rs +++ b/src/librustc_trans/trans/consts.rs @@ -173,7 +173,7 @@ pub fn get_const_expr<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, &**expr } else { ccx.sess().span_bug(ref_expr.span, - &format!("get_const_val given non-constant item {}", + &format!("get_const_expr given non-constant item {}", item.repr(ccx.tcx()))); } } diff --git a/src/librustc_trans/trans/debuginfo.rs b/src/librustc_trans/trans/debuginfo.rs index f3b7058336b..95c39270cc6 100644 --- a/src/librustc_trans/trans/debuginfo.rs +++ b/src/librustc_trans/trans/debuginfo.rs @@ -206,10 +206,12 @@ use middle::pat_util; use session::config::{self, FullDebugInfo, LimitedDebugInfo, NoDebugInfo}; use util::nodemap::{DefIdMap, NodeMap, FnvHashMap, FnvHashSet}; use util::ppaux; +use util::common::path2cstr; use libc::{c_uint, c_longlong}; -use std::ffi::CString; use std::cell::{Cell, RefCell}; +use std::ffi::CString; +use std::path::Path; use std::ptr; use std::rc::{Rc, Weak}; use syntax::util::interner::Interner; @@ -695,6 +697,7 @@ struct FunctionDebugContextData { fn_metadata: DISubprogram, argument_counter: Cell<uint>, source_locations_enabled: Cell<bool>, + source_location_override: Cell<bool>, } enum VariableAccess<'a> { @@ -1174,6 +1177,12 @@ pub fn set_source_location(fcx: &FunctionContext, return; } FunctionDebugContext::RegularContext(box ref function_debug_context) => { + if function_debug_context.source_location_override.get() { + // Just ignore any attempts to set a new debug location while + // the override is active. + return; + } + let cx = fcx.ccx; debug!("set_source_location: {}", cx.sess().codemap().span_to_string(span)); @@ -1192,6 +1201,35 @@ pub fn set_source_location(fcx: &FunctionContext, } } +/// This function makes sure that all debug locations emitted while executing +/// `wrapped_function` are set to the given `debug_loc`. +pub fn with_source_location_override<F, R>(fcx: &FunctionContext, + debug_loc: DebugLoc, + wrapped_function: F) -> R + where F: FnOnce() -> R +{ + match fcx.debug_context { + FunctionDebugContext::DebugInfoDisabled => { + wrapped_function() + } + FunctionDebugContext::FunctionWithoutDebugInfo => { + set_debug_location(fcx.ccx, UnknownLocation); + wrapped_function() + } + FunctionDebugContext::RegularContext(box ref function_debug_context) => { + if function_debug_context.source_location_override.get() { + wrapped_function() + } else { + debug_loc.apply(fcx); + function_debug_context.source_location_override.set(true); + let result = wrapped_function(); + function_debug_context.source_location_override.set(false); + result + } + } + } +} + /// Clears the current debug location. /// /// Instructions generated hereafter won't be assigned a source location. @@ -1412,6 +1450,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, fn_metadata: fn_metadata, argument_counter: Cell::new(1), source_locations_enabled: Cell::new(false), + source_location_override: Cell::new(false), }; @@ -1588,20 +1627,13 @@ fn compile_unit_metadata(cx: &CrateContext) -> DIDescriptor { cx.sess().warn("debuginfo: Invalid path to crate's local root source file!"); fallback_path(cx) } else { - match abs_path.path_relative_from(work_dir) { + match abs_path.relative_from(work_dir) { Some(ref p) if p.is_relative() => { - // prepend "./" if necessary - let dotdot = b".."; - let prefix: &[u8] = &[dotdot[0], ::std::old_path::SEP_BYTE]; - let mut path_bytes = p.as_vec().to_vec(); - - if &path_bytes[..2] != prefix && - &path_bytes[..2] != dotdot { - path_bytes.insert(0, prefix[0]); - path_bytes.insert(1, prefix[1]); + if p.starts_with(Path::new("./")) { + path2cstr(p) + } else { + path2cstr(&Path::new(".").join(p)) } - - CString::new(path_bytes).unwrap() } _ => fallback_path(cx) } @@ -1614,7 +1646,7 @@ fn compile_unit_metadata(cx: &CrateContext) -> DIDescriptor { (option_env!("CFG_VERSION")).expect("CFG_VERSION")); let compile_unit_name = compile_unit_name.as_ptr(); - let work_dir = CString::new(work_dir.as_vec()).unwrap(); + let work_dir = path2cstr(&work_dir); let producer = CString::new(producer).unwrap(); let flags = "\0"; let split_name = "\0"; @@ -1716,7 +1748,7 @@ fn file_metadata(cx: &CrateContext, full_path: &str) -> DIFile { debug!("file_metadata: {}", full_path); // FIXME (#9639): This needs to handle non-utf8 paths - let work_dir = cx.sess().working_dir.as_str().unwrap(); + let work_dir = cx.sess().working_dir.to_str().unwrap(); let file_name = if full_path.starts_with(work_dir) { &full_path[work_dir.len() + 1..full_path.len()] diff --git a/src/librustc_trans/trans/expr.rs b/src/librustc_trans/trans/expr.rs index 60455119d58..ecdc7c06bb1 100644 --- a/src/librustc_trans/trans/expr.rs +++ b/src/librustc_trans/trans/expr.rs @@ -147,7 +147,7 @@ pub fn trans_into<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, ast::ExprPath(..) => { match bcx.def(expr.id) { def::DefConst(did) => { - let expr = consts::get_const_expr(bcx.ccx(), did, expr); + let const_expr = consts::get_const_expr(bcx.ccx(), did, expr); // Temporarily get cleanup scopes out of the way, // as they require sub-expressions to be contained // inside the current AST scope. @@ -155,7 +155,13 @@ pub fn trans_into<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, // can't have destructors. let scopes = mem::replace(&mut *bcx.fcx.scopes.borrow_mut(), vec![]); - bcx = trans_into(bcx, expr, dest); + // Lock emitted debug locations to the location of + // the constant reference expression. + debuginfo::with_source_location_override(bcx.fcx, + expr.debug_loc(), + || { + bcx = trans_into(bcx, const_expr, dest) + }); let scopes = mem::replace(&mut *bcx.fcx.scopes.borrow_mut(), scopes); assert!(scopes.is_empty()); @@ -1494,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) { @@ -1514,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); diff --git a/src/librustc_trans/trans/foreign.rs b/src/librustc_trans/trans/foreign.rs index efae76c5ef4..b0383e355e4 100644 --- a/src/librustc_trans/trans/foreign.rs +++ b/src/librustc_trans/trans/foreign.rs @@ -440,7 +440,7 @@ fn gate_simd_ffi(tcx: &ty::ctxt, decl: &ast::FnDecl, ty: &ty::BareFnTy) { &format!("use of SIMD type `{}` in FFI is highly experimental and \ may result in invalid code", pprust::ty_to_string(ast_ty))); - tcx.sess.span_help(ast_ty.span, + tcx.sess.fileline_help(ast_ty.span, "add #![feature(simd_ffi)] to the crate attributes to enable"); } }; diff --git a/src/librustc_trans/trans/meth.rs b/src/librustc_trans/trans/meth.rs index c07de3a87ec..0c82d681eed 100644 --- a/src/librustc_trans/trans/meth.rs +++ b/src/librustc_trans/trans/meth.rs @@ -300,7 +300,10 @@ pub fn trans_static_method_callee<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, .position(|item| item.def_id() == method_id) .unwrap(); let (llfn, ty) = - trans_object_shim(ccx, data.object_ty, trait_id, method_offset_in_trait); + trans_object_shim(ccx, + data.object_ty, + data.upcast_trait_ref.clone(), + method_offset_in_trait); immediate_rvalue(llfn, ty) } _ => { @@ -386,7 +389,10 @@ fn trans_monomorphized_callee<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, Callee { bcx: bcx, data: Fn(llfn) } } traits::VtableObject(ref data) => { - let (llfn, _) = trans_object_shim(bcx.ccx(), data.object_ty, trait_id, n_method); + let (llfn, _) = trans_object_shim(bcx.ccx(), + data.object_ty, + data.upcast_trait_ref.clone(), + n_method); Callee { bcx: bcx, data: Fn(llfn) } } traits::VtableBuiltin(..) | @@ -551,16 +557,17 @@ pub fn trans_trait_callee_from_llval<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, pub fn trans_object_shim<'a, 'tcx>( ccx: &'a CrateContext<'a, 'tcx>, object_ty: Ty<'tcx>, - trait_id: ast::DefId, + upcast_trait_ref: ty::PolyTraitRef<'tcx>, method_offset_in_trait: uint) -> (ValueRef, Ty<'tcx>) { let _icx = push_ctxt("trans_object_shim"); let tcx = ccx.tcx(); + let trait_id = upcast_trait_ref.def_id(); - debug!("trans_object_shim(object_ty={}, trait_id={}, method_offset_in_trait={})", + debug!("trans_object_shim(object_ty={}, upcast_trait_ref={}, method_offset_in_trait={})", object_ty.repr(tcx), - trait_id.repr(tcx), + upcast_trait_ref.repr(tcx), method_offset_in_trait); let object_trait_ref = @@ -575,7 +582,6 @@ pub fn trans_object_shim<'a, 'tcx>( }; // Upcast to the trait in question and extract out the substitutions. - let upcast_trait_ref = traits::upcast(ccx.tcx(), object_trait_ref.clone(), trait_id).unwrap(); let upcast_trait_ref = ty::erase_late_bound_regions(tcx, &upcast_trait_ref); let object_substs = upcast_trait_ref.substs.clone().erase_regions(); debug!("trans_object_shim: object_substs={}", object_substs.repr(tcx)); diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 1e7b90d5a18..2c7a9bf8020 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -59,7 +59,6 @@ use middle::ty::{self, RegionEscape, ToPolyTraitRef, Ty}; use rscope::{self, UnelidableRscope, RegionScope, ElidableRscope, ObjectLifetimeDefaultRscope, ShiftedRscope, BindingRscope}; use util::common::{ErrorReported, FN_OUTPUT_NAME}; -use util::nodemap::DefIdMap; use util::ppaux::{self, Repr, UserString}; use std::iter::{repeat, AdditiveIterator}; @@ -73,15 +72,33 @@ use syntax::print::pprust; pub trait AstConv<'tcx> { fn tcx<'a>(&'a self) -> &'a ty::ctxt<'tcx>; + /// Identify the type scheme for an item with a type, like a type + /// alias, fn, or struct. This allows you to figure out the set of + /// type parameters defined on the item. fn get_item_type_scheme(&self, span: Span, id: ast::DefId) -> Result<ty::TypeScheme<'tcx>, ErrorReported>; + /// Returns the `TraitDef` for a given trait. This allows you to + /// figure out the set of type parameters defined on the trait. fn get_trait_def(&self, span: Span, id: ast::DefId) -> Result<Rc<ty::TraitDef<'tcx>>, ErrorReported>; + /// Ensure that the super-predicates for the trait with the given + /// id are available and also for the transitive set of + /// super-predicates. + fn ensure_super_predicates(&self, span: Span, id: ast::DefId) + -> Result<(), ErrorReported>; + + /// Returns the set of bounds in scope for the type parameter with + /// the given id. fn get_type_parameter_bounds(&self, span: Span, def_id: ast::NodeId) -> Result<Vec<ty::PolyTraitRef<'tcx>>, ErrorReported>; + /// Returns true if the trait with id `trait_def_id` defines an + /// associated type with the name `name`. + fn trait_defines_associated_type_named(&self, trait_def_id: ast::DefId, name: ast::Name) + -> bool; + /// Return an (optional) substitution to convert bound type parameters that /// are in scope into free ones. This function should only return Some /// within a fn body. @@ -212,18 +229,18 @@ pub fn opt_ast_region_to_region<'tcx>( } } if len == 1 { - span_help!(this.tcx().sess, default_span, + fileline_help!(this.tcx().sess, default_span, "this function's return type contains a borrowed value, but \ the signature does not say which {} it is borrowed from", m); } else if len == 0 { - span_help!(this.tcx().sess, default_span, + fileline_help!(this.tcx().sess, default_span, "this function's return type contains a borrowed value, but \ there is no value for it to be borrowed from"); - span_help!(this.tcx().sess, default_span, + fileline_help!(this.tcx().sess, default_span, "consider giving it a 'static lifetime"); } else { - span_help!(this.tcx().sess, default_span, + fileline_help!(this.tcx().sess, default_span, "this function's return type contains a borrowed value, but \ the signature does not say whether it is borrowed from {}", m); @@ -705,7 +722,7 @@ fn ast_path_to_trait_ref<'a,'tcx>( span_err!(this.tcx().sess, span, E0215, "angle-bracket notation is not stable when \ used with the `Fn` family of traits, use parentheses"); - span_help!(this.tcx().sess, span, + fileline_help!(this.tcx().sess, span, "add `#![feature(unboxed_closures)]` to \ the crate attributes to enable"); } @@ -719,7 +736,7 @@ fn ast_path_to_trait_ref<'a,'tcx>( span_err!(this.tcx().sess, span, E0216, "parenthetical notation is only stable when \ used with the `Fn` family of traits"); - span_help!(this.tcx().sess, span, + fileline_help!(this.tcx().sess, span, "add `#![feature(unboxed_closures)]` to \ the crate attributes to enable"); } @@ -783,7 +800,7 @@ fn ast_type_binding_to_projection_predicate<'tcx>( // We want to produce `<B as SuperTrait<int>>::T == foo`. // Simple case: X is defined in the current trait. - if trait_defines_associated_type_named(this, trait_ref.def_id, binding.item_name) { + if this.trait_defines_associated_type_named(trait_ref.def_id, binding.item_name) { return Ok(ty::ProjectionPredicate { projection_ty: ty::ProjectionTy { trait_ref: trait_ref, @@ -810,9 +827,11 @@ fn ast_type_binding_to_projection_predicate<'tcx>( tcx.mk_substs(dummy_substs))); } + try!(this.ensure_super_predicates(binding.span, trait_ref.def_id)); + let mut candidates: Vec<ty::PolyTraitRef> = traits::supertraits(tcx, trait_ref.to_poly_trait_ref()) - .filter(|r| trait_defines_associated_type_named(this, r.def_id(), binding.item_name)) + .filter(|r| this.trait_defines_associated_type_named(r.def_id(), binding.item_name)) .collect(); // If converting for an object type, then remove the dummy-ty from `Self` now. @@ -944,14 +963,14 @@ fn ast_ty_to_trait_ref<'tcx>(this: &AstConv<'tcx>, pprust::ty_to_string(ty)); match ty.node { ast::TyRptr(None, ref mut_ty) => { - span_help!(this.tcx().sess, ty.span, + fileline_help!(this.tcx().sess, ty.span, "perhaps you meant `&{}({} +{})`? (per RFC 438)", ppaux::mutability_to_string(mut_ty.mutbl), pprust::ty_to_string(&*mut_ty.ty), pprust::bounds_to_string(bounds)); } ast::TyRptr(Some(ref lt), ref mut_ty) => { - span_help!(this.tcx().sess, ty.span, + fileline_help!(this.tcx().sess, ty.span, "perhaps you meant `&{} {}({} +{})`? (per RFC 438)", pprust::lifetime_to_string(lt), ppaux::mutability_to_string(mut_ty.mutbl), @@ -960,7 +979,7 @@ fn ast_ty_to_trait_ref<'tcx>(this: &AstConv<'tcx>, } _ => { - span_help!(this.tcx().sess, ty.span, + fileline_help!(this.tcx().sess, ty.span, "perhaps you forgot parentheses? (per RFC 438)"); } } @@ -1029,14 +1048,19 @@ fn associated_path_def_to_ty<'tcx>(this: &AstConv<'tcx>, let ty_param_name = tcx.ty_param_defs.borrow()[ty_param_node_id].name; - // FIXME(#20300) -- search where clauses, not bounds - let bounds = - this.get_type_parameter_bounds(span, ty_param_node_id) - .unwrap_or(Vec::new()); + let bounds = match this.get_type_parameter_bounds(span, ty_param_node_id) { + Ok(v) => v, + Err(ErrorReported) => { return (tcx.types.err, ty_path_def); } + }; + + // ensure the super predicates and stop if we encountered an error + if bounds.iter().any(|b| this.ensure_super_predicates(span, b.def_id()).is_err()) { + return (this.tcx().types.err, ty_path_def); + } let mut suitable_bounds: Vec<_> = traits::transitive_bounds(tcx, &bounds) - .filter(|b| trait_defines_associated_type_named(this, b.def_id(), assoc_name)) + .filter(|b| this.trait_defines_associated_type_named(b.def_id(), assoc_name)) .collect(); if suitable_bounds.len() == 0 { @@ -1090,16 +1114,6 @@ fn associated_path_def_to_ty<'tcx>(this: &AstConv<'tcx>, (ty, def::DefAssociatedTy(trait_did, item_did)) } -fn trait_defines_associated_type_named(this: &AstConv, - trait_def_id: ast::DefId, - assoc_name: ast::Name) - -> bool -{ - let tcx = this.tcx(); - let trait_def = ty::lookup_trait_def(tcx, trait_def_id); - trait_def.associated_type_names.contains(&assoc_name) -} - fn qpath_to_ty<'tcx>(this: &AstConv<'tcx>, rscope: &RegionScope, span: Span, @@ -1275,20 +1289,9 @@ pub fn ast_ty_to_ty<'tcx>(this: &AstConv<'tcx>, let tcx = this.tcx(); - let mut ast_ty_to_ty_cache = tcx.ast_ty_to_ty_cache.borrow_mut(); - match ast_ty_to_ty_cache.get(&ast_ty.id) { - Some(&ty::atttce_resolved(ty)) => return ty, - Some(&ty::atttce_unresolved) => { - span_err!(tcx.sess, ast_ty.span, E0246, - "illegal recursive type; insert an enum \ - or struct in the cycle, if this is \ - desired"); - return this.tcx().types.err; - } - None => { /* go on */ } + if let Some(&ty) = tcx.ast_ty_to_ty_cache.borrow().get(&ast_ty.id) { + return ty; } - ast_ty_to_ty_cache.insert(ast_ty.id, ty::atttce_unresolved); - drop(ast_ty_to_ty_cache); let typ = match ast_ty.node { ast::TyVec(ref ty) => { @@ -1401,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") } @@ -1421,7 +1424,7 @@ pub fn ast_ty_to_ty<'tcx>(this: &AstConv<'tcx>, } }; - tcx.ast_ty_to_ty_cache.borrow_mut().insert(ast_ty.id, ty::atttce_resolved(typ)); + tcx.ast_ty_to_ty_cache.borrow_mut().insert(ast_ty.id, typ); return typ; } @@ -1838,6 +1841,10 @@ fn compute_object_lifetime_bound<'tcx>( return ast_region_to_region(tcx, r); } + if let Err(ErrorReported) = this.ensure_super_predicates(span,principal_trait_ref.def_id()) { + return ty::ReStatic; + } + // No explicit region bound specified. Therefore, examine trait // bounds and see if we can derive region bounds from those. let derived_region_bounds = @@ -1923,34 +1930,11 @@ pub fn partition_bounds<'a>(tcx: &ty::ctxt, let mut builtin_bounds = ty::empty_builtin_bounds(); let mut region_bounds = Vec::new(); let mut trait_bounds = Vec::new(); - let mut trait_def_ids = DefIdMap(); for ast_bound in ast_bounds { match *ast_bound { ast::TraitTyParamBound(ref b, ast::TraitBoundModifier::None) => { match ::lookup_full_def(tcx, b.trait_ref.path.span, b.trait_ref.ref_id) { def::DefTrait(trait_did) => { - match trait_def_ids.get(&trait_did) { - // Already seen this trait. We forbid - // duplicates in the list (for some - // reason). - Some(span) => { - span_err!( - tcx.sess, b.trait_ref.path.span, E0127, - "trait `{}` already appears in the \ - list of bounds", - b.trait_ref.path.user_string(tcx)); - tcx.sess.span_note( - *span, - "previous appearance is here"); - - continue; - } - - None => { } - } - - trait_def_ids.insert(trait_did, b.trait_ref.path.span); - if ty::try_add_builtin_trait(tcx, trait_did, &mut builtin_bounds) { diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs index f31dbf5138b..6ba21e25e1f 100644 --- a/src/librustc_typeck/check/callee.rs +++ b/src/librustc_typeck/check/callee.rs @@ -63,7 +63,7 @@ pub fn check_legal_trait_for_method_call(ccx: &CrateCtxt, span: Span, trait_id: span_err!(tcx.sess, span, E0174, "explicit use of unboxed closure method `{}` is experimental", method); - span_help!(tcx.sess, span, + fileline_help!(tcx.sess, span, "add `#![feature(unboxed_closures)]` to the crate attributes to enable"); } } diff --git a/src/librustc_typeck/check/dropck.rs b/src/librustc_typeck/check/dropck.rs index cffd74ccd72..9c48ac43ee4 100644 --- a/src/librustc_typeck/check/dropck.rs +++ b/src/librustc_typeck/check/dropck.rs @@ -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); diff --git a/src/librustc_typeck/check/implicator.rs b/src/librustc_typeck/check/implicator.rs index f99ba894029..6b4a7761d0a 100644 --- a/src/librustc_typeck/check/implicator.rs +++ b/src/librustc_typeck/check/implicator.rs @@ -22,6 +22,7 @@ use syntax::ast; use syntax::codemap::Span; use util::common::ErrorReported; +use util::nodemap::FnvHashSet; use util::ppaux::Repr; // Helper functions related to manipulating region types. @@ -40,6 +41,7 @@ struct Implicator<'a, 'tcx: 'a> { stack: Vec<(ty::Region, Option<Ty<'tcx>>)>, span: Span, out: Vec<Implication<'tcx>>, + visited: FnvHashSet<Ty<'tcx>>, } /// This routine computes the well-formedness constraints that must hold for the type `ty` to @@ -65,7 +67,8 @@ pub fn implications<'a,'tcx>( body_id: body_id, span: span, stack: stack, - out: Vec::new() }; + out: Vec::new(), + visited: FnvHashSet() }; wf.accumulate_from_ty(ty); debug!("implications: out={}", wf.out.repr(closure_typer.tcx())); wf.out @@ -80,6 +83,12 @@ impl<'a, 'tcx> Implicator<'a, 'tcx> { debug!("accumulate_from_ty(ty={})", ty.repr(self.tcx())); + // When expanding out associated types, we can visit a cyclic + // set of types. Issue #23003. + if !self.visited.insert(ty) { + return; + } + match ty.sty { ty::ty_bool | ty::ty_char | diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs index d7db21f3a2f..6ef6953f707 100644 --- a/src/librustc_typeck/check/method/confirm.rs +++ b/src/librustc_typeck/check/method/confirm.rs @@ -634,16 +634,21 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> { target_trait_def_id: ast::DefId) -> ty::PolyTraitRef<'tcx> { - match traits::upcast(self.tcx(), source_trait_ref.clone(), target_trait_def_id) { - Some(super_trait_ref) => super_trait_ref, - None => { - self.tcx().sess.span_bug( - self.span, - &format!("cannot upcast `{}` to `{}`", - source_trait_ref.repr(self.tcx()), - target_trait_def_id.repr(self.tcx()))); - } + let upcast_trait_refs = traits::upcast(self.tcx(), + source_trait_ref.clone(), + target_trait_def_id); + + // must be exactly one trait ref or we'd get an ambig error etc + if upcast_trait_refs.len() != 1 { + self.tcx().sess.span_bug( + self.span, + &format!("cannot uniquely upcast `{}` to `{}`: `{}`", + source_trait_ref.repr(self.tcx()), + target_trait_def_id.repr(self.tcx()), + upcast_trait_refs.repr(self.tcx()))); } + + upcast_trait_refs.into_iter().next().unwrap() } fn replace_late_bound_regions_with_fresh_var<T>(&self, value: &ty::Binder<T>) -> T diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index fbf002b709e..718804d317f 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -456,13 +456,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> { debug!("elaborate_bounds(bounds={})", bounds.repr(self.tcx())); let tcx = self.tcx(); - let mut cache = HashSet::new(); for bound_trait_ref in traits::transitive_bounds(tcx, bounds) { - // Already visited this trait, skip it. - if !cache.insert(bound_trait_ref.def_id()) { - continue; - } - let (pos, method) = match trait_method(tcx, bound_trait_ref.def_id(), self.method_name) { @@ -1269,10 +1263,12 @@ impl<'tcx> Candidate<'tcx> { fn to_trait_data(&self) -> Option<(ast::DefId,MethodIndex)> { match self.kind { - InherentImplCandidate(..) | - ObjectCandidate(..) => { + InherentImplCandidate(..) => { None } + ObjectCandidate(trait_def_id, method_num, _) => { + Some((trait_def_id, method_num)) + } ClosureCandidate(trait_def_id, method_num) => { Some((trait_def_id, method_num)) } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index a12ff04912c..44500ce0bbb 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1218,6 +1218,11 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> { Ok(ty::lookup_trait_def(self.tcx(), id)) } + fn ensure_super_predicates(&self, _: Span, _: ast::DefId) -> Result<(), ErrorReported> { + // all super predicates are ensured during collect pass + Ok(()) + } + fn get_free_substs(&self) -> Option<&Substs<'tcx>> { Some(&self.inh.param_env.free_substs) } @@ -1248,6 +1253,15 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> { Ok(r) } + fn trait_defines_associated_type_named(&self, + trait_def_id: ast::DefId, + assoc_name: ast::Name) + -> bool + { + let trait_def = ty::lookup_trait_def(self.ccx.tcx, trait_def_id); + trait_def.associated_type_names.contains(&assoc_name) + } + fn ty_infer(&self, _span: Span) -> Ty<'tcx> { self.infcx().next_ty_var() } @@ -3098,7 +3112,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, }, expr_t, None); - tcx.sess.span_help(field.span, + tcx.sess.fileline_help(field.span, "maybe a `()` to call it is missing? \ If not, try an anonymous function"); } else { @@ -4480,7 +4494,7 @@ pub fn check_instantiable(tcx: &ty::ctxt, span_err!(tcx.sess, sp, E0073, "this type cannot be instantiated without an \ instance of itself"); - span_help!(tcx.sess, sp, "consider using `Option<{}>`", + fileline_help!(tcx.sess, sp, "consider using `Option<{}>`", ppaux::ty_to_string(tcx, item_ty)); false } else { @@ -4606,7 +4620,7 @@ pub fn check_enum_variants<'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()); } } }, diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index a3e98b0c4c6..e1bcad2af37 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -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()))); } } } diff --git a/src/librustc_typeck/check/wf.rs b/src/librustc_typeck/check/wf.rs index e024526d001..32bd40ebda2 100644 --- a/src/librustc_typeck/check/wf.rs +++ b/src/librustc_typeck/check/wf.rs @@ -118,7 +118,7 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> { self.check_variances_for_type_defn(item, ast_generics); } - ast::ItemTrait(_, ref ast_generics, _, _) => { + ast::ItemTrait(_, ref ast_generics, _, ref items) => { let trait_predicates = ty::lookup_predicates(ccx.tcx, local_def(item.id)); reject_non_type_param_bounds( @@ -127,6 +127,14 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> { &trait_predicates); self.check_variances(item, ast_generics, &trait_predicates, self.tcx().lang_items.phantom_fn()); + if ty::trait_has_default_impl(ccx.tcx, local_def(item.id)) { + if !items.is_empty() { + ccx.tcx.sess.span_err( + item.span, + "traits with default impls (`e.g. unsafe impl Trait for ..`) must \ + have no methods or associated items") + } + } } _ => {} } @@ -281,12 +289,13 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> { // Find the supertrait bounds. This will add `int:Bar`. let poly_trait_ref = ty::Binder(trait_ref); - let predicates = ty::predicates_for_trait_ref(fcx.tcx(), &poly_trait_ref); + let predicates = ty::lookup_super_predicates(fcx.tcx(), poly_trait_ref.def_id()); + let predicates = predicates.instantiate_supertrait(fcx.tcx(), &poly_trait_ref); let predicates = { let selcx = &mut traits::SelectionContext::new(fcx.infcx(), fcx); traits::normalize(selcx, cause.clone(), &predicates) }; - for predicate in predicates.value { + for predicate in predicates.value.predicates { fcx.register_predicate(traits::Obligation::new(cause.clone(), predicate)); } for obligation in predicates.obligations { @@ -400,11 +409,11 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> { match suggested_marker_id { Some(def_id) => { - self.tcx().sess.span_help( + 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 index e89c96b36e1..00000000000 --- a/src/librustc_typeck/coherence/impls.rs +++ /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"); - } - } - } - } - _ => {} - } - } -} diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index 58b67d31ab5..a06dcbaf556 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -49,7 +49,6 @@ use syntax::visit; use util::nodemap::{DefIdMap, FnvHashMap}; use util::ppaux::Repr; -mod impls; mod orphan; mod overlap; mod unsafety; @@ -524,7 +523,7 @@ fn enforce_trait_manually_implementable(tcx: &ty::ctxt, sp: Span, trait_def_id: return // everything OK }; span_err!(tcx.sess, sp, E0183, "manual implementations of `{}` are experimental", trait_name); - span_help!(tcx.sess, sp, + fileline_help!(tcx.sess, sp, "add `#![feature(unboxed_closures)]` to the crate attributes to enable"); } @@ -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); diff --git a/src/librustc_typeck/coherence/orphan.rs b/src/librustc_typeck/coherence/orphan.rs index 95dafccd866..5dfe80cfcb2 100644 --- a/src/librustc_typeck/coherence/orphan.rs +++ b/src/librustc_typeck/coherence/orphan.rs @@ -37,10 +37,13 @@ impl<'cx, 'tcx> OrphanChecker<'cx, 'tcx> { 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 @@ impl<'cx, 'tcx,'v> visit::Visitor<'v> for OrphanChecker<'cx, 'tcx> { 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 @@ impl<'cx, 'tcx,'v> visit::Visitor<'v> for OrphanChecker<'cx, 'tcx> { 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 @@ impl<'cx, 'tcx,'v> visit::Visitor<'v> for OrphanChecker<'cx, 'tcx> { 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 @@ impl<'cx, 'tcx,'v> visit::Visitor<'v> for OrphanChecker<'cx, 'tcx> { 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); } } diff --git a/src/librustc_typeck/coherence/overlap.rs b/src/librustc_typeck/coherence/overlap.rs index a6ecafb6241..466d00b348b 100644 --- a/src/librustc_typeck/coherence/overlap.rs +++ b/src/librustc_typeck/coherence/overlap.rs @@ -20,10 +20,11 @@ use syntax::ast; 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 => { } } } _ => {} diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 74fed6cbf39..bd68802f262 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -26,35 +26,17 @@ represented by an instance of `ty::TypeScheme`. This combines the core type along with a list of the bounds for each parameter. Type parameters themselves are represented as `ty_param()` instances. -The phasing of type conversion is somewhat complicated. There are a -number of possible cycles that can arise. - -Converting types can require: - -1. `Foo<X>` where `Foo` is a type alias, or trait requires knowing: - - number of region / type parameters - - for type parameters, `T:'a` annotations to control defaults for object lifetimes - - defaults for type parameters (which are themselves types!) -2. `Foo<X>` where `Foo` is a type alias requires knowing what `Foo` expands to -3. Translating `SomeTrait` with no explicit lifetime bound requires knowing - - supertraits of `SomeTrait` -4. Translating `T::X` (vs `<T as Trait>::X`) requires knowing - - bounds on `T` - - supertraits of those bounds - -So as you can see, in general translating types requires knowing the -trait hierarchy. But this gets a bit tricky because translating the -trait hierarchy requires converting the types that appear in trait -references. One potential saving grace is that in general knowing the -trait hierarchy is only necessary for shorthands like `T::X` or -handling omitted lifetime bounds on object types. Therefore, if we are -lazy about expanding out the trait hierachy, users can sever cycles if -necessary. Lazy expansion is also needed for type aliases. - -This system is not perfect yet. Currently, we "convert" types and -traits in three phases (note that conversion only affects the types of -items / enum variants / methods; it does not e.g. compute the types of -individual expressions): +The phasing of type conversion is somewhat complicated. There is no +clear set of phases we can enforce (e.g., converting traits first, +then types, or something like that) because the user can introduce +arbitrary interdependencies. So instead we generally convert things +lazilly and on demand, and include logic that checks for cycles. +Demand is driven by calls to `AstConv::get_item_type_scheme` or +`AstConv::lookup_trait_def`. + +Currently, we "convert" types and traits in three phases (note that +conversion only affects the types of items / enum variants / methods; +it does not e.g. compute the types of individual expressions): 0. Intrinsics 1. Trait definitions @@ -64,16 +46,13 @@ Conversion itself is done by simply walking each of the items in turn and invoking an appropriate function (e.g., `trait_def_of_item` or `convert_item`). However, it is possible that while converting an item, we may need to compute the *type scheme* or *trait definition* -for other items. This is a kind of shallow conversion that is -triggered on demand by calls to `AstConv::get_item_type_scheme` or -`AstConv::lookup_trait_def`. It is possible for cycles to result from -this (e.g., `type A = B; type B = A;`), in which case astconv -(currently) reports the error. +for other items. There are some shortcomings in this design: -- Cycles through trait definitions (e.g. supertraits) are not currently - detected by astconv. (#12511) +- Before walking the set of supertraits for a given trait, you must + call `ensure_super_predicates` on that trait def-id. Otherwise, + `lookup_super_predicates` will result in ICEs. - Because the type scheme includes defaults, cycles through type parameter defaults are illegal even if those defaults are never employed. This is not necessarily a bug. @@ -169,6 +148,7 @@ struct ItemCtxt<'a,'tcx:'a> { enum AstConvRequest { GetItemTypeScheme(ast::DefId), GetTraitDef(ast::DefId), + EnsureSuperPredicates(ast::DefId), GetTypeParameterBounds(ast::NodeId), } @@ -245,7 +225,7 @@ impl<'a,'tcx> CrateCtxt<'a,'tcx> { request: AstConvRequest, code: F) -> Result<R,ErrorReported> - where F: FnOnce() -> R + where F: FnOnce() -> Result<R,ErrorReported> { { let mut stack = self.stack.borrow_mut(); @@ -263,7 +243,7 @@ impl<'a,'tcx> CrateCtxt<'a,'tcx> { let result = code(); self.stack.borrow_mut().pop(); - Ok(result) + result } fn report_cycle(&self, @@ -284,6 +264,11 @@ impl<'a,'tcx> CrateCtxt<'a,'tcx> { &format!("the cycle begins when processing `{}`...", ty::item_path_str(tcx, def_id))); } + AstConvRequest::EnsureSuperPredicates(def_id) => { + tcx.sess.note( + &format!("the cycle begins when computing the supertraits of `{}`...", + ty::item_path_str(tcx, def_id))); + } AstConvRequest::GetTypeParameterBounds(id) => { let def = tcx.type_parameter_def(id); tcx.sess.note( @@ -301,6 +286,11 @@ impl<'a,'tcx> CrateCtxt<'a,'tcx> { &format!("...which then requires processing `{}`...", ty::item_path_str(tcx, def_id))); } + AstConvRequest::EnsureSuperPredicates(def_id) => { + tcx.sess.note( + &format!("...which then requires computing the supertraits of `{}`...", + ty::item_path_str(tcx, def_id))); + } AstConvRequest::GetTypeParameterBounds(id) => { let def = tcx.type_parameter_def(id); tcx.sess.note( @@ -318,6 +308,12 @@ impl<'a,'tcx> CrateCtxt<'a,'tcx> { &format!("...which then again requires processing `{}`, completing the cycle.", ty::item_path_str(tcx, def_id))); } + AstConvRequest::EnsureSuperPredicates(def_id) => { + tcx.sess.note( + &format!("...which then again requires computing the supertraits of `{}`, \ + completing the cycle.", + ty::item_path_str(tcx, def_id))); + } AstConvRequest::GetTypeParameterBounds(id) => { let def = tcx.type_parameter_def(id); tcx.sess.note( @@ -327,6 +323,41 @@ impl<'a,'tcx> CrateCtxt<'a,'tcx> { } } } + + /// Loads the trait def for a given trait, returning ErrorReported if a cycle arises. + fn get_trait_def(&self, trait_id: ast::DefId) + -> Rc<ty::TraitDef<'tcx>> + { + let tcx = self.tcx; + + if trait_id.krate != ast::LOCAL_CRATE { + return ty::lookup_trait_def(tcx, trait_id) + } + + let item = match tcx.map.get(trait_id.node) { + ast_map::NodeItem(item) => item, + _ => tcx.sess.bug(&format!("get_trait_def({}): not an item", trait_id.repr(tcx))) + }; + + trait_def_of_item(self, &*item) + } + + /// Ensure that the (transitive) super predicates for + /// `trait_def_id` are available. This will report a cycle error + /// if a trait `X` (transitively) extends itself in some form. + fn ensure_super_predicates(&self, span: Span, trait_def_id: ast::DefId) + -> Result<(), ErrorReported> + { + self.cycle_check(span, AstConvRequest::EnsureSuperPredicates(trait_def_id), || { + let def_ids = ensure_super_predicates_step(self, trait_def_id); + + for def_id in def_ids { + try!(self.ensure_super_predicates(span, def_id)); + } + + Ok(()) + }) + } } impl<'a,'tcx> ItemCtxt<'a,'tcx> { @@ -342,7 +373,7 @@ impl<'a, 'tcx> AstConv<'tcx> for ItemCtxt<'a, 'tcx> { -> Result<ty::TypeScheme<'tcx>, ErrorReported> { self.ccx.cycle_check(span, AstConvRequest::GetItemTypeScheme(id), || { - type_scheme_of_def_id(self.ccx, id) + Ok(type_scheme_of_def_id(self.ccx, id)) }) } @@ -350,20 +381,49 @@ impl<'a, 'tcx> AstConv<'tcx> for ItemCtxt<'a, 'tcx> { -> Result<Rc<ty::TraitDef<'tcx>>, ErrorReported> { self.ccx.cycle_check(span, AstConvRequest::GetTraitDef(id), || { - get_trait_def(self.ccx, id) + Ok(self.ccx.get_trait_def(id)) }) } + fn ensure_super_predicates(&self, + span: Span, + trait_def_id: ast::DefId) + -> Result<(), ErrorReported> + { + debug!("ensure_super_predicates(trait_def_id={})", + trait_def_id.repr(self.tcx())); + + self.ccx.ensure_super_predicates(span, trait_def_id) + } + + fn get_type_parameter_bounds(&self, span: Span, node_id: ast::NodeId) -> Result<Vec<ty::PolyTraitRef<'tcx>>, ErrorReported> { self.ccx.cycle_check(span, AstConvRequest::GetTypeParameterBounds(node_id), || { - self.param_bounds.get_type_parameter_bounds(self, span, node_id) + let v = self.param_bounds.get_type_parameter_bounds(self, span, node_id) + .into_iter() + .filter_map(|p| p.to_opt_poly_trait_ref()) + .collect(); + Ok(v) }) } + fn trait_defines_associated_type_named(&self, + trait_def_id: ast::DefId, + assoc_name: ast::Name) + -> bool + { + if trait_def_id.krate == ast::LOCAL_CRATE { + trait_defines_associated_type_named(self.ccx, trait_def_id.node, assoc_name) + } else { + let trait_def = ty::lookup_trait_def(self.tcx(), trait_def_id); + trait_def.associated_type_names.contains(&assoc_name) + } + } + fn ty_infer(&self, span: Span) -> Ty<'tcx> { span_err!(self.tcx().sess, span, E0121, "the type placeholder `_` is not allowed within types on item signatures"); @@ -387,7 +447,7 @@ trait GetTypeParameterBounds<'tcx> { astconv: &AstConv<'tcx>, span: Span, node_id: ast::NodeId) - -> Vec<ty::PolyTraitRef<'tcx>>; + -> Vec<ty::Predicate<'tcx>>; } /// Find bounds from both elements of the tuple. @@ -398,7 +458,7 @@ impl<'a,'b,'tcx,A,B> GetTypeParameterBounds<'tcx> for (&'a A,&'b B) astconv: &AstConv<'tcx>, span: Span, node_id: ast::NodeId) - -> Vec<ty::PolyTraitRef<'tcx>> + -> Vec<ty::Predicate<'tcx>> { let mut v = self.0.get_type_parameter_bounds(astconv, span, node_id); v.extend(self.1.get_type_parameter_bounds(astconv, span, node_id).into_iter()); @@ -412,7 +472,7 @@ impl<'tcx> GetTypeParameterBounds<'tcx> for () { _astconv: &AstConv<'tcx>, _span: Span, _node_id: ast::NodeId) - -> Vec<ty::PolyTraitRef<'tcx>> + -> Vec<ty::Predicate<'tcx>> { Vec::new() } @@ -426,29 +486,28 @@ impl<'tcx> GetTypeParameterBounds<'tcx> for ty::GenericPredicates<'tcx> { astconv: &AstConv<'tcx>, _span: Span, node_id: ast::NodeId) - -> Vec<ty::PolyTraitRef<'tcx>> + -> Vec<ty::Predicate<'tcx>> { let def = astconv.tcx().type_parameter_def(node_id); self.predicates .iter() - .filter_map(|predicate| { - match *predicate { + .filter(|predicate| { + match **predicate { ty::Predicate::Trait(ref data) => { - if data.0.self_ty().is_param(def.space, def.index) { - Some(data.to_poly_trait_ref()) - } else { - None - } + data.skip_binder().self_ty().is_param(def.space, def.index) + } + ty::Predicate::TypeOutlives(ref data) => { + data.skip_binder().0.is_param(def.space, def.index) } ty::Predicate::Equate(..) | ty::Predicate::RegionOutlives(..) | - ty::Predicate::TypeOutlives(..) | ty::Predicate::Projection(..) => { - None + false } } }) + .cloned() .collect() } } @@ -462,7 +521,7 @@ impl<'tcx> GetTypeParameterBounds<'tcx> for ast::Generics { astconv: &AstConv<'tcx>, _: Span, node_id: ast::NodeId) - -> Vec<ty::PolyTraitRef<'tcx>> + -> Vec<ty::Predicate<'tcx>> { // In the AST, bounds can derive from two places. Either // written inline like `<T:Foo>` or in a where clause like @@ -476,7 +535,7 @@ impl<'tcx> GetTypeParameterBounds<'tcx> for ast::Generics { .iter() .filter(|p| p.id == node_id) .flat_map(|p| p.bounds.iter()) - .filter_map(|b| poly_trait_ref_from_bound(astconv, ty, b, &mut Vec::new())); + .flat_map(|b| predicates_from_bound(astconv, ty, b).into_iter()); let from_where_clauses = self.where_clause @@ -488,7 +547,7 @@ impl<'tcx> GetTypeParameterBounds<'tcx> for ast::Generics { }) .filter(|bp| is_param(astconv.tcx(), &bp.bounded_ty, node_id)) .flat_map(|bp| bp.bounds.iter()) - .filter_map(|b| poly_trait_ref_from_bound(astconv, ty, b, &mut Vec::new())); + .flat_map(|b| predicates_from_bound(astconv, ty, b).into_iter()); from_ty_params.chain(from_where_clauses).collect() } @@ -505,10 +564,15 @@ fn is_param<'tcx>(tcx: &ty::ctxt<'tcx>, { if let ast::TyPath(None, _) = ast_ty.node { let path_res = tcx.def_map.borrow()[ast_ty.id]; - if let def::DefTyParam(_, _, def_id, _) = path_res.base_def { - path_res.depth == 0 && def_id == local_def(param_id) - } else { - false + match path_res.base_def { + def::DefSelfTy(node_id) => + path_res.depth == 0 && node_id == param_id, + + def::DefTyParam(_, _, def_id, _) => + path_res.depth == 0 && def_id == local_def(param_id), + + _ => + false, } } else { false @@ -777,9 +841,10 @@ fn convert_methods<'a,'tcx,'i,I>(ccx: &CrateCtxt<'a, 'tcx>, rcvr_visibility: ast::Visibility) where I: Iterator<Item=&'i ast::Method> { - debug!("convert_methods(untransformed_rcvr_ty={}, rcvr_ty_generics={})", + debug!("convert_methods(untransformed_rcvr_ty={}, rcvr_ty_generics={}, rcvr_ty_predicates={})", untransformed_rcvr_ty.repr(ccx.tcx), - rcvr_ty_generics.repr(ccx.tcx)); + rcvr_ty_generics.repr(ccx.tcx), + rcvr_ty_predicates.repr(ccx.tcx)); let tcx = ccx.tcx; let mut seen_methods = FnvHashSet(); @@ -914,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, @@ -1023,6 +1088,8 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) { }, ast::ItemTrait(_, _, _, ref trait_items) => { let trait_def = trait_def_of_item(ccx, it); + let _: Result<(), ErrorReported> = // any error is already reported, can ignore + ccx.ensure_super_predicates(it.span, local_def(it.id)); convert_trait_predicates(ccx, it); let trait_predicates = ty::lookup_predicates(ccx.tcx, local_def(it.id)); @@ -1168,22 +1235,89 @@ fn convert_struct<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, } } -fn get_trait_def<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, - trait_id: ast::DefId) - -> Rc<ty::TraitDef<'tcx>> { +/// Ensures that the super-predicates of the trait with def-id +/// trait_def_id are converted and stored. This does NOT ensure that +/// the transitive super-predicates are converted; that is the job of +/// the `ensure_super_predicates()` method in the `AstConv` impl +/// above. Returns a list of trait def-ids that must be ensured as +/// well to guarantee that the transitive superpredicates are +/// converted. +fn ensure_super_predicates_step(ccx: &CrateCtxt, + trait_def_id: ast::DefId) + -> Vec<ast::DefId> +{ let tcx = ccx.tcx; - if trait_id.krate != ast::LOCAL_CRATE { - return ty::lookup_trait_def(tcx, trait_id) - } + debug!("ensure_super_predicates_step(trait_def_id={})", trait_def_id.repr(tcx)); - match tcx.map.get(trait_id.node) { - ast_map::NodeItem(item) => trait_def_of_item(ccx, &*item), - _ => { - tcx.sess.bug(&format!("get_trait_def({}): not an item", - trait_id.node)) - } + if trait_def_id.krate != ast::LOCAL_CRATE { + // If this trait comes from an external crate, then all of the + // supertraits it may depend on also must come from external + // crates, and hence all of them already have their + // super-predicates "converted" (and available from crate + // meta-data), so there is no need to transitively test them. + return Vec::new(); } + + let superpredicates = tcx.super_predicates.borrow().get(&trait_def_id).cloned(); + let superpredicates = superpredicates.unwrap_or_else(|| { + let trait_node_id = trait_def_id.node; + + let item = match ccx.tcx.map.get(trait_node_id) { + ast_map::NodeItem(item) => item, + _ => ccx.tcx.sess.bug(&format!("trait_node_id {} is not an item", trait_node_id)) + }; + + let (generics, bounds) = match item.node { + ast::ItemTrait(_, ref generics, ref supertraits, _) => (generics, supertraits), + _ => tcx.sess.span_bug(item.span, + "ensure_super_predicates_step invoked on non-trait"), + }; + + // In-scope when converting the superbounds for `Trait` are + // that `Self:Trait` as well as any bounds that appear on the + // generic types: + let trait_def = trait_def_of_item(ccx, item); + let self_predicate = ty::GenericPredicates { + predicates: VecPerParamSpace::new(vec![], + vec![trait_def.trait_ref.as_predicate()], + vec![]) + }; + let scope = &(generics, &self_predicate); + + // Convert the bounds that follow the colon, e.g. `Bar+Zed` in `trait Foo : Bar+Zed`. + let self_param_ty = ty::mk_self_type(tcx); + let superbounds1 = compute_bounds(&ccx.icx(scope), self_param_ty, bounds, + SizedByDefault::No, item.span); + let superbounds1 = ty::predicates(tcx, self_param_ty, &superbounds1); + + // Convert any explicit superbounds in the where clause, + // e.g. `trait Foo where Self : Bar`: + let superbounds2 = generics.get_type_parameter_bounds(&ccx.icx(scope), item.span, item.id); + + // Combine the two lists to form the complete set of superbounds: + let superbounds = superbounds1.into_iter().chain(superbounds2.into_iter()).collect(); + let superpredicates = ty::GenericPredicates { + predicates: VecPerParamSpace::new(superbounds, vec![], vec![]) + }; + debug!("superpredicates for trait {} = {}", + local_def(item.id).repr(ccx.tcx), + superpredicates.repr(ccx.tcx)); + + tcx.super_predicates.borrow_mut().insert(trait_def_id, superpredicates.clone()); + + superpredicates + }); + + let def_ids: Vec<_> = superpredicates.predicates + .iter() + .filter_map(|p| p.to_opt_poly_trait_ref()) + .map(|tr| tr.def_id()) + .collect(); + + debug!("ensure_super_predicates_step: def_ids={}", def_ids.repr(tcx)); + + def_ids } fn trait_def_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, @@ -1197,18 +1331,9 @@ fn trait_def_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, return def.clone(); } - let (unsafety, generics, bounds, items) = match it.node { - ast::ItemTrait(unsafety, - ref generics, - ref supertraits, - ref items) => { - (unsafety, generics, supertraits, items) - } - ref s => { - tcx.sess.span_bug( - it.span, - &format!("trait_def_of_item invoked on {:?}", s)); - } + let (unsafety, generics, items) = match it.node { + ast::ItemTrait(unsafety, ref generics, _, ref items) => (unsafety, generics, items), + _ => tcx.sess.span_bug(it.span, "trait_def_of_item invoked on non-trait"), }; let paren_sugar = ty::has_attr(tcx, def_id, "rustc_paren_sugar"); @@ -1217,7 +1342,7 @@ fn trait_def_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it.span, "the `#[rustc_paren_sugar]` attribute is a temporary means of controlling \ which traits can use parenthetical notation"); - span_help!(ccx.tcx.sess, it.span, + fileline_help!(ccx.tcx.sess, it.span, "add `#![feature(unboxed_closures)]` to \ the crate attributes to use it"); } @@ -1226,15 +1351,6 @@ fn trait_def_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, let ty_generics = ty_generics_for_trait(ccx, it.id, substs, generics); - let self_param_ty = ty::ParamTy::for_self().to_ty(ccx.tcx); - - // supertraits: - let bounds = compute_bounds(&ccx.icx(generics), - self_param_ty, - bounds, - SizedByDefault::No, - it.span); - let associated_type_names: Vec<_> = items.iter() .filter_map(|item| { @@ -1254,7 +1370,6 @@ fn trait_def_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, paren_sugar: paren_sugar, unsafety: unsafety, generics: ty_generics, - bounds: bounds, trait_ref: trait_ref, associated_type_names: associated_type_names, }); @@ -1296,6 +1411,30 @@ fn trait_def_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, } } +fn trait_defines_associated_type_named(ccx: &CrateCtxt, + trait_node_id: ast::NodeId, + assoc_name: ast::Name) + -> bool +{ + let item = match ccx.tcx.map.get(trait_node_id) { + ast_map::NodeItem(item) => item, + _ => ccx.tcx.sess.bug(&format!("trait_node_id {} is not an item", trait_node_id)) + }; + + let trait_items = match item.node { + ast::ItemTrait(_, _, _, ref trait_items) => trait_items, + _ => ccx.tcx.sess.bug(&format!("trait_node_id {} is not a trait", trait_node_id)) + }; + + trait_items.iter() + .any(|trait_item| { + match *trait_item { + ast::TypeTraitItem(ref t) => t.ty_param.ident.name == assoc_name, + ast::RequiredMethod(..) | ast::ProvidedMethod(..) => false, + } + }) +} + fn convert_trait_predicates<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &ast::Item) { let tcx = ccx.tcx; let trait_def = trait_def_of_item(ccx, it); @@ -1311,19 +1450,14 @@ fn convert_trait_predicates<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &ast::Item) } }; - let self_param_ty = ty::ParamTy::for_self().to_ty(ccx.tcx); - - let super_predicates = ty::predicates(ccx.tcx, self_param_ty, &trait_def.bounds); + let super_predicates = ty::lookup_super_predicates(ccx.tcx, def_id); // `ty_generic_predicates` below will consider the bounds on the type // parameters (including `Self`) and the explicit where-clauses, // but to get the full set of predicates on a trait we need to add // in the supertrait bounds and anything declared on the // associated types. - let mut base_predicates = - ty::GenericPredicates { - predicates: VecPerParamSpace::new(super_predicates, vec![], vec![]) - }; + let mut base_predicates = super_predicates; // Add in a predicate that `Self:Trait` (where `Trait` is the // current trait). This is needed for builtin bounds. @@ -1456,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)); } } } @@ -1953,7 +2087,7 @@ fn compute_object_lifetime_default<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, } } -enum SizedByDefault { Yes, No } +enum SizedByDefault { Yes, No, } /// Translate the AST's notion of ty param bounds (which are an enum consisting of a newtyped Ty or /// a region) to ty's notion of ty param bounds, which can either be user-defined traits, or the @@ -1975,11 +2109,6 @@ fn compute_bounds<'tcx>(astconv: &AstConv<'tcx>, &mut param_bounds.builtin_bounds, ast_bounds, span); - - check_bounds_compatible(astconv, - param_ty, - ¶m_bounds, - span); } param_bounds.trait_bounds.sort_by(|a,b| a.def_id().cmp(&b.def_id())); @@ -1987,48 +2116,32 @@ fn compute_bounds<'tcx>(astconv: &AstConv<'tcx>, param_bounds } -fn check_bounds_compatible<'tcx>(astconv: &AstConv<'tcx>, - param_ty: Ty<'tcx>, - param_bounds: &ty::ParamBounds<'tcx>, - span: Span) { - let tcx = astconv.tcx(); - if !param_bounds.builtin_bounds.contains(&ty::BoundSized) { - ty::each_bound_trait_and_supertraits( - tcx, - ¶m_bounds.trait_bounds, - |trait_ref| { - match astconv.get_trait_def(span, trait_ref.def_id()) { - Ok(trait_def) => { - if trait_def.bounds.builtin_bounds.contains(&ty::BoundSized) { - span_err!(tcx.sess, span, E0129, - "incompatible bounds on `{}`, \ - bound `{}` does not allow unsized type", - param_ty.user_string(tcx), - trait_ref.user_string(tcx)); - } - } - Err(ErrorReported) => { } - } - true - }); - } -} - -/// Converts a specific TyParamBound from the AST into the -/// appropriate poly-trait-reference. -fn poly_trait_ref_from_bound<'tcx>(astconv: &AstConv<'tcx>, - param_ty: Ty<'tcx>, - bound: &ast::TyParamBound, - projections: &mut Vec<ty::PolyProjectionPredicate<'tcx>>) - -> Option<ty::PolyTraitRef<'tcx>> +/// Converts a specific TyParamBound from the AST into a set of +/// predicates that apply to the self-type. A vector is returned +/// because this can be anywhere from 0 predicates (`T:?Sized` adds no +/// predicates) to 1 (`T:Foo`) to many (`T:Bar<X=i32>` adds `T:Bar` +/// and `<T as Bar>::X == i32`). +fn predicates_from_bound<'tcx>(astconv: &AstConv<'tcx>, + param_ty: Ty<'tcx>, + bound: &ast::TyParamBound) + -> Vec<ty::Predicate<'tcx>> { match *bound { ast::TraitTyParamBound(ref tr, ast::TraitBoundModifier::None) => { - Some(conv_poly_trait_ref(astconv, param_ty, tr, projections)) + let mut projections = Vec::new(); + let pred = conv_poly_trait_ref(astconv, param_ty, tr, &mut projections); + projections.into_iter() + .map(|p| p.as_predicate()) + .chain(Some(pred.as_predicate()).into_iter()) + .collect() } - ast::TraitTyParamBound(_, ast::TraitBoundModifier::Maybe) | - ast::RegionTyParamBound(_) => { - None + ast::RegionTyParamBound(ref lifetime) => { + let region = ast_region_to_region(astconv.tcx(), lifetime); + let pred = ty::Binder(ty::OutlivesPredicate(param_ty, region)); + vec![ty::Predicate::TypeOutlives(pred)] + } + ast::TraitTyParamBound(_, ast::TraitBoundModifier::Maybe) => { + Vec::new() } } } diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index 3bd15fbc7db..03fa269ccf8 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -175,7 +175,9 @@ register_diagnostics! { 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 } diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index 78dd66c8e7d..bbc64a54013 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -62,7 +62,8 @@ independently: This API is completely unstable and subject to change. */ - +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "rustc_typeck"] #![unstable(feature = "rustc_private")] #![staged_api] diff --git a/src/librustc_typeck/variance.rs b/src/librustc_typeck/variance.rs index 1fba4a21ccd..9b27128ce2f 100644 --- a/src/librustc_typeck/variance.rs +++ b/src/librustc_typeck/variance.rs @@ -644,9 +644,9 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ConstraintContext<'a, 'tcx> { ast::ItemTrait(..) => { let trait_def = ty::lookup_trait_def(tcx, did); - let predicates = ty::predicates(tcx, ty::mk_self_type(tcx), &trait_def.bounds); + let predicates = ty::lookup_super_predicates(tcx, did); self.add_constraints_from_predicates(&trait_def.generics, - &predicates, + predicates.predicates.as_slice(), self.covariant); let trait_items = ty::trait_items(tcx, did); diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 2bb4424822a..db41bf9fee3 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -165,14 +165,12 @@ pub fn build_external_trait(cx: &DocContext, tcx: &ty::ctxt, _ => unreachable!() } }); - let trait_def = ty::lookup_trait_def(tcx, did); let predicates = ty::lookup_predicates(tcx, did); - let bounds = trait_def.bounds.clean(cx); clean::Trait { unsafety: def.unsafety, generics: (&def.generics, &predicates, subst::TypeSpace).clean(cx), items: items.collect(), - bounds: bounds, + bounds: vec![], // supertraits can be found in the list of predicates } } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 36d39fa58ba..c39451b15ad 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -49,7 +49,7 @@ use rustc::middle::stability; use std::rc::Rc; use std::u32; -use std::old_path::Path as FsPath; // Conflicts with Path struct +use std::path::PathBuf; use core::DocContext; use doctree; @@ -118,7 +118,7 @@ impl<T: Clean<U>, U> Clean<Vec<U>> for syntax::owned_slice::OwnedSlice<T> { #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] pub struct Crate { pub name: String, - pub src: FsPath, + pub src: PathBuf, pub module: Option<Item>, pub externs: Vec<(ast::CrateNum, ExternalCrate)>, pub primitives: Vec<PrimitiveType>, @@ -191,7 +191,7 @@ impl<'a, 'tcx> Clean<Crate> for visit_ast::RustdocVisitor<'a, 'tcx> { let src = match cx.input { Input::File(ref path) => path.clone(), - Input::Str(_) => FsPath::new("") // FIXME: this is wrong + Input::Str(_) => PathBuf::new("") // FIXME: this is wrong }; Crate { diff --git a/src/librustdoc/externalfiles.rs b/src/librustdoc/externalfiles.rs index 942aec7d22f..6cfe7a33dd4 100644 --- a/src/librustdoc/externalfiles.rs +++ b/src/librustdoc/externalfiles.rs @@ -8,7 +8,12 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::{old_io, str}; +use std::fs::File; +use std::io::prelude::*; +use std::io; +use std::old_io; +use std::path::{PathBuf, Path}; +use std::str; #[derive(Clone)] pub struct ExternalHtml{ @@ -33,16 +38,17 @@ impl ExternalHtml { } } -pub fn load_string(input: &Path) -> old_io::IoResult<Option<String>> { - let mut f = try!(old_io::File::open(input)); - let d = try!(f.read_to_end()); +pub fn load_string(input: &Path) -> io::Result<Option<String>> { + let mut f = try!(File::open(input)); + let mut d = Vec::new(); + try!(f.read_to_end(&mut d)); Ok(str::from_utf8(&d).map(|s| s.to_string()).ok()) } macro_rules! load_or_return { ($input: expr, $cant_read: expr, $not_utf8: expr) => { { - let input = Path::new($input); + let input = PathBuf::new($input); match ::externalfiles::load_string(&input) { Err(e) => { let _ = writeln!(&mut old_io::stderr(), diff --git a/src/librustdoc/flock.rs b/src/librustdoc/flock.rs index 79e348cb03e..51c58861b4b 100644 --- a/src/librustdoc/flock.rs +++ b/src/librustdoc/flock.rs @@ -20,7 +20,9 @@ pub use self::imp::Lock; #[cfg(unix)] mod imp { - use std::ffi::CString; + use std::ffi::{AsOsStr, CString}; + use std::os::unix::prelude::*; + use std::path::Path; use libc; use std::os as stdos; @@ -114,7 +116,7 @@ mod imp { impl Lock { pub fn new(p: &Path) -> Lock { - let buf = CString::new(p.as_vec()).unwrap(); + let buf = CString::new(p.as_os_str().as_bytes()).unwrap(); let fd = unsafe { libc::open(buf.as_ptr(), libc::O_RDWR | libc::O_CREAT, libc::S_IRWXU) @@ -163,8 +165,11 @@ mod imp { #[cfg(windows)] mod imp { use libc; + use std::ffi::AsOsStr; use std::mem; + use std::os::windows::prelude::*; use std::os; + use std::path::Path; use std::ptr; const LOCKFILE_EXCLUSIVE_LOCK: libc::DWORD = 0x00000002; @@ -190,7 +195,7 @@ mod imp { impl Lock { pub fn new(p: &Path) -> Lock { - let mut p_16: Vec<u16> = p.as_str().unwrap().utf16_units().collect(); + let mut p_16: Vec<_> = p.as_os_str().encode_wide().collect(); p_16.push(0); let handle = unsafe { libc::CreateFileW(p_16.as_ptr(), diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs index c537e370723..3acd17dedd5 100644 --- a/src/librustdoc/html/layout.rs +++ b/src/librustdoc/html/layout.rs @@ -9,7 +9,8 @@ // except according to those terms. use std::fmt; -use std::old_io; +use std::io::prelude::*; +use std::io; use externalfiles::ExternalHtml; @@ -31,8 +32,8 @@ pub struct Page<'a> { } pub fn render<T: fmt::Display, S: fmt::Display>( - dst: &mut old_io::Writer, layout: &Layout, page: &Page, sidebar: &S, t: &T) - -> old_io::IoResult<()> + dst: &mut io::Write, layout: &Layout, page: &Page, sidebar: &S, t: &T) + -> io::Result<()> { write!(dst, r##"<!DOCTYPE html> @@ -159,7 +160,7 @@ r##"<!DOCTYPE html> ) } -pub fn redirect(dst: &mut old_io::Writer, url: &str) -> old_io::IoResult<()> { +pub fn redirect(dst: &mut io::Write, url: &str) -> io::Result<()> { // <script> triggers a redirect before refresh, so this is fine. write!(dst, r##"<!DOCTYPE html> diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 735487611dc..d60f9ad50a1 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -39,10 +39,11 @@ use std::cmp::Ordering; use std::collections::{HashMap, HashSet}; use std::default::Default; use std::fmt; -use std::old_io::fs::PathExtensions; -use std::old_io::{fs, File, BufferedWriter, BufferedReader}; -use std::old_io; +use std::fs::{self, File}; +use std::io::prelude::*; +use std::io::{self, BufWriter, BufReader}; use std::iter::repeat; +use std::path::{PathBuf, Path}; use std::str; use std::sync::Arc; @@ -65,12 +66,10 @@ use html::item_type::ItemType; use html::layout; use html::markdown::Markdown; use html::markdown; -use html::escape::Escape; use stability_summary; /// A pair of name and its optional document. -#[derive(Clone, Eq, Ord, PartialEq, PartialOrd)] -pub struct NameDoc(String, Option<String>); +pub type NameDoc = (String, Option<String>); /// Major driving force in all rustdoc rendering. This contains information /// about where in the tree-like hierarchy rendering is occurring and controls @@ -89,19 +88,13 @@ pub struct Context { pub root_path: String, /// The path to the crate root source minus the file name. /// Used for simplifying paths to the highlighted source code files. - pub src_root: Path, + pub src_root: PathBuf, /// The current destination folder of where HTML artifacts should be placed. /// This changes as the context descends into the module hierarchy. - pub dst: Path, + pub dst: PathBuf, /// This describes the layout of each page, and is not modified after /// creation of the context (contains info like the favicon and added html). pub layout: layout::Layout, - /// This map is a list of what should be displayed on the sidebar of the - /// current page. The key is the section header (traits, modules, - /// functions), and the value is the list of containers belonging to this - /// header. This map will change depending on the surrounding context of the - /// page. - pub sidebar: HashMap<String, Vec<NameDoc>>, /// This flag indicates whether [src] links should be generated or not. If /// the source files are present in the html rendering, then this will be /// `true`. @@ -220,7 +213,7 @@ struct SourceCollector<'a> { /// Processed source-file paths seen: HashSet<String>, /// Root destination to place all HTML output into - dst: Path, + dst: PathBuf, } /// Wrapper struct to render the source code of a file. This will do things like @@ -257,15 +250,18 @@ thread_local!(pub static CURRENT_LOCATION_KEY: RefCell<Vec<String>> = /// Generates the documentation for `crate` into the directory `dst` pub fn run(mut krate: clean::Crate, external_html: &ExternalHtml, - dst: Path, - passes: HashSet<String>) -> old_io::IoResult<()> { + dst: PathBuf, + passes: HashSet<String>) -> io::Result<()> { + let src_root = match krate.src.parent() { + Some(p) => p.to_path_buf(), + None => PathBuf::new(""), + }; let mut cx = Context { dst: dst, - src_root: krate.src.dir_path(), + src_root: src_root, passes: passes, current: Vec::new(), root_path: String::new(), - sidebar: HashMap::new(), layout: layout::Layout { logo: "".to_string(), favicon: "".to_string(), @@ -392,7 +388,7 @@ pub fn run(mut krate: clean::Crate, cx.krate(krate, summary) } -fn build_index(krate: &clean::Crate, cache: &mut Cache) -> old_io::IoResult<String> { +fn build_index(krate: &clean::Crate, cache: &mut Cache) -> io::Result<String> { // Build the search index from the collected metadata let mut nodeid_to_pathid = HashMap::new(); let mut pathid_to_nodeid = Vec::new(); @@ -437,7 +433,7 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> old_io::IoResult<Stri } // Collect the index into a string - let mut w = Vec::new(); + let mut w = io::Cursor::new(Vec::new()); try!(write!(&mut w, r#"searchIndex['{}'] = {{"items":["#, krate.name)); let mut lastpath = "".to_string(); @@ -480,13 +476,13 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> old_io::IoResult<Stri try!(write!(&mut w, "]}};")); - Ok(String::from_utf8(w).unwrap()) + Ok(String::from_utf8(w.into_inner()).unwrap()) } fn write_shared(cx: &Context, krate: &clean::Crate, cache: &Cache, - search_index: String) -> old_io::IoResult<()> { + search_index: String) -> io::Result<()> { // Write out the shared files. Note that these are shared among all rustdoc // docs placed in the output directory, so this needs to be a synchronized // operation with respect to all other rustdocs running around. @@ -518,10 +514,10 @@ fn write_shared(cx: &Context, include_bytes!("static/SourceCodePro-Semibold.woff"))); fn collect(path: &Path, krate: &str, - key: &str) -> old_io::IoResult<Vec<String>> { + key: &str) -> io::Result<Vec<String>> { let mut ret = Vec::new(); if path.exists() { - for line in BufferedReader::new(File::open(path)).lines() { + for line in BufReader::new(try!(File::open(path))).lines() { let line = try!(line); if !line.starts_with(key) { continue @@ -567,14 +563,14 @@ fn write_shared(cx: &Context, mydst.push(part); try!(mkdir(&mydst)); } - mydst.push(format!("{}.{}.js", - remote_item_type.to_static_str(), - remote_path[remote_path.len() - 1])); + mydst.push(&format!("{}.{}.js", + remote_item_type.to_static_str(), + remote_path[remote_path.len() - 1])); let all_implementors = try!(collect(&mydst, &krate.name, "implementors")); - try!(mkdir(&mydst.dir_path())); - let mut f = BufferedWriter::new(try!(File::create(&mydst))); + try!(mkdir(mydst.parent().unwrap())); + let mut f = BufWriter::new(try!(File::create(&mydst))); try!(writeln!(&mut f, "(function() {{var implementors = {{}};")); for implementor in &all_implementors { @@ -606,7 +602,7 @@ fn write_shared(cx: &Context, } fn render_sources(cx: &mut Context, - krate: clean::Crate) -> old_io::IoResult<clean::Crate> { + krate: clean::Crate) -> io::Result<clean::Crate> { info!("emitting source files"); let dst = cx.dst.join("src"); try!(mkdir(&dst)); @@ -624,15 +620,15 @@ fn render_sources(cx: &mut Context, /// Writes the entire contents of a string to a destination, not attempting to /// catch any errors. -fn write(dst: Path, contents: &[u8]) -> old_io::IoResult<()> { - File::create(&dst).write_all(contents) +fn write(dst: PathBuf, contents: &[u8]) -> io::Result<()> { + try!(File::create(&dst)).write_all(contents) } /// Makes a directory on the filesystem, failing the task if an error occurs and /// skipping if the directory already exists. -fn mkdir(path: &Path) -> old_io::IoResult<()> { +fn mkdir(path: &Path) -> io::Result<()> { if !path.exists() { - fs::mkdir(path, old_io::USER_RWX) + fs::create_dir(path) } else { Ok(()) } @@ -648,21 +644,17 @@ fn shortty(item: &clean::Item) -> ItemType { /// static HTML tree. // FIXME (#9639): The closure should deal with &[u8] instead of &str // FIXME (#9639): This is too conservative, rejecting non-UTF-8 paths -fn clean_srcpath<F>(src_root: &Path, src: &[u8], mut f: F) where +fn clean_srcpath<F>(src_root: &Path, p: &Path, mut f: F) where F: FnMut(&str), { - let p = Path::new(src); - // make it relative, if possible - let p = p.path_relative_from(src_root).unwrap_or(p); + let p = p.relative_from(src_root).unwrap_or(p); - if p.as_vec() != b"." { - for c in p.str_components().map(|x|x.unwrap()) { - if ".." == c { - f("up"); - } else { - f(c) - } + for c in p.iter().map(|x| x.to_str().unwrap()) { + if ".." == c { + f("up"); + } else { + f(c) } } } @@ -733,13 +725,14 @@ impl<'a> DocFolder for SourceCollector<'a> { impl<'a> SourceCollector<'a> { /// Renders the given filename into its corresponding HTML source file. - fn emit_source(&mut self, filename: &str) -> old_io::IoResult<()> { - let p = Path::new(filename); + fn emit_source(&mut self, filename: &str) -> io::Result<()> { + let p = PathBuf::new(filename); // If we couldn't open this file, then just returns because it // probably means that it's some standard library macro thing and we // can't have the source to it anyway. - let contents = match File::open(&p).read_to_end() { + let mut contents = Vec::new(); + match File::open(&p).and_then(|mut f| f.read_to_end(&mut contents)) { Ok(r) => r, // macros from other libraries get special filenames which we can // safely ignore @@ -759,18 +752,20 @@ impl<'a> SourceCollector<'a> { // Create the intermediate directories let mut cur = self.dst.clone(); let mut root_path = String::from_str("../../"); - clean_srcpath(&self.cx.src_root, p.dirname(), |component| { + clean_srcpath(&self.cx.src_root, &p, |component| { cur.push(component); mkdir(&cur).unwrap(); root_path.push_str("../"); }); - let mut fname = p.filename().expect("source has no filename").to_vec(); - fname.extend(".html".bytes()); - cur.push(fname); - let mut w = BufferedWriter::new(try!(File::create(&cur))); + let mut fname = p.file_name().expect("source has no filename") + .to_os_string(); + fname.push(".html"); + cur.push(&fname); + let mut w = BufWriter::new(try!(File::create(&cur))); - let title = format!("{} -- source", cur.filename_display()); + let title = format!("{} -- source", cur.file_name().unwrap() + .to_string_lossy()); let desc = format!("Source to the Rust file `{}`.", filename); let page = layout::Page { title: &title, @@ -779,7 +774,7 @@ impl<'a> SourceCollector<'a> { description: &desc, keywords: get_basic_keywords(), }; - try!(layout::render(&mut w as &mut Writer, &self.cx.layout, + try!(layout::render(&mut w, &self.cx.layout, &page, &(""), &Source(contents))); try!(w.flush()); return Ok(()); @@ -1081,7 +1076,7 @@ impl Context { /// This currently isn't parallelized, but it'd be pretty easy to add /// parallelization to this function. fn krate(mut self, mut krate: clean::Crate, - stability: stability_summary::ModuleSummary) -> old_io::IoResult<()> { + stability: stability_summary::ModuleSummary) -> io::Result<()> { let mut item = match krate.module.take() { Some(i) => i, None => return Ok(()) @@ -1091,7 +1086,7 @@ impl Context { // render stability dashboard try!(self.recurse(stability.name.clone(), |this| { let json_dst = &this.dst.join("stability.json"); - let mut json_out = BufferedWriter::new(try!(File::create(json_dst))); + let mut json_out = BufWriter::new(try!(File::create(json_dst))); try!(write!(&mut json_out, "{}", json::as_json(&stability))); let mut title = stability.name.clone(); @@ -1106,7 +1101,7 @@ impl Context { keywords: get_basic_keywords(), }; let html_dst = &this.dst.join("stability.html"); - let mut html_out = BufferedWriter::new(try!(File::create(html_dst))); + let mut html_out = BufWriter::new(try!(File::create(html_dst))); layout::render(&mut html_out, &this.layout, &page, &Sidebar{ cx: this, item: &item }, &stability) @@ -1131,12 +1126,12 @@ impl Context { /// all sub-items which need to be rendered. /// /// The rendering driver uses this closure to queue up more work. - fn item<F>(&mut self, item: clean::Item, mut f: F) -> old_io::IoResult<()> where + fn item<F>(&mut self, item: clean::Item, mut f: F) -> io::Result<()> where F: FnMut(&mut Context, clean::Item), { - fn render(w: old_io::File, cx: &Context, it: &clean::Item, - pushname: bool) -> old_io::IoResult<()> { - info!("Rendering an item to {}", w.path().display()); + fn render(w: File, cx: &Context, it: &clean::Item, + pushname: bool) -> io::Result<()> { + info!("Rendering an item to {}", w.path().unwrap().display()); // A little unfortunate that this is done like this, but it sure // does make formatting *a lot* nicer. CURRENT_LOCATION_KEY.with(|slot| { @@ -1177,7 +1172,7 @@ impl Context { // We have a huge number of calls to write, so try to alleviate some // of the pain by using a buffered writer instead of invoking the // write syscall all the time. - let mut writer = BufferedWriter::new(w); + let mut writer = BufWriter::new(w); if !cx.render_redirect_pages { try!(layout::render(&mut writer, &cx.layout, &page, &Sidebar{ cx: cx, item: it }, @@ -1227,7 +1222,16 @@ impl Context { clean::ModuleItem(m) => m, _ => unreachable!() }; - this.sidebar = this.build_sidebar(&m); + + // render sidebar-items.js used throughout this module + { + let items = this.build_sidebar_items(&m); + let js_dst = this.dst.join("sidebar-items.js"); + let mut js_out = BufWriter::new(try!(File::create(&js_dst))); + try!(write!(&mut js_out, "initSidebarItems({});", + json::as_json(&items))); + } + for item in m.items { f(this,item); } @@ -1238,7 +1242,7 @@ impl Context { // Things which don't have names (like impls) don't get special // pages dedicated to them. _ if item.name.is_some() => { - let dst = self.dst.join(item_path(&item)); + let dst = self.dst.join(&item_path(&item)); let dst = try!(File::create(&dst)); render(dst, self, &item, true) } @@ -1247,15 +1251,11 @@ impl Context { } } - fn build_sidebar(&self, m: &clean::Module) -> HashMap<String, Vec<NameDoc>> { + fn build_sidebar_items(&self, m: &clean::Module) -> HashMap<String, Vec<NameDoc>> { let mut map = HashMap::new(); for item in &m.items { if self.ignore_private_item(item) { continue } - // avoid putting foreign items to the sidebar. - if let &clean::ForeignFunctionItem(..) = &item.inner { continue } - if let &clean::ForeignStaticItem(..) = &item.inner { continue } - let short = shortty(item).to_static_str(); let myname = match item.name { None => continue, @@ -1264,7 +1264,7 @@ impl Context { 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(NameDoc(myname, Some(shorter_line(item.doc_value())))); + v.push((myname, Some(shorter_line(item.doc_value())))); } for (_, items) in &mut map { @@ -1307,7 +1307,7 @@ impl<'a> Item<'a> { // has anchors for the line numbers that we're linking to. if ast_util::is_local(self.item.def_id) { let mut path = Vec::new(); - clean_srcpath(&cx.src_root, self.item.source.filename.as_bytes(), + clean_srcpath(&cx.src_root, Path::new(&self.item.source.filename), |component| { path.push(component.to_string()); }); @@ -2211,9 +2211,18 @@ impl<'a> fmt::Display for Sidebar<'a> { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { let cx = self.cx; let it = self.item; + let parentlen = cx.current.len() - if it.is_mod() {1} else {0}; + + // the sidebar is designed to display sibling functions, modules and + // other miscellaneous informations. since there are lots of sibling + // items (and that causes quadratic growth in large modules), + // we refactor common parts into a shared JavaScript file per module. + // still, we don't move everything into JS because we want to preserve + // as much HTML as possible in order to allow non-JS-enabled browsers + // to navigate the documentation (though slightly inefficiently). + try!(write!(fmt, "<p class='location'>")); - let len = cx.current.len() - if it.is_mod() {1} else {0}; - for (i, name) in cx.current.iter().take(len).enumerate() { + for (i, name) in cx.current.iter().take(parentlen).enumerate() { if i > 0 { try!(write!(fmt, "::<wbr>")); } @@ -2223,40 +2232,25 @@ impl<'a> fmt::Display for Sidebar<'a> { } try!(write!(fmt, "</p>")); - fn block(w: &mut fmt::Formatter, short: &str, longty: &str, - cur: &clean::Item, cx: &Context) -> fmt::Result { - let items = match cx.sidebar.get(short) { - Some(items) => items, - None => return Ok(()) - }; - try!(write!(w, "<div class='block {}'><h2>{}</h2>", short, longty)); - for &NameDoc(ref name, ref doc) in items { - let curty = shortty(cur).to_static_str(); - let class = if cur.name.as_ref().unwrap() == name && - short == curty { "current" } else { "" }; - try!(write!(w, "<a class='{ty} {class}' href='{href}{path}' \ - title='{title}'>{name}</a>", - ty = short, - class = class, - href = if curty == "mod" {"../"} else {""}, - path = if short == "mod" { - format!("{}/index.html", name) - } else { - format!("{}.{}.html", short, name) - }, - title = Escape(doc.as_ref().unwrap()), - name = name)); - } - try!(write!(w, "</div>")); - Ok(()) + // sidebar refers to the enclosing module, not this module + let relpath = if shortty(it) == ItemType::Module { "../" } else { "" }; + try!(write!(fmt, + "<script>window.sidebarCurrent = {{\ + name: '{name}', \ + ty: '{ty}', \ + relpath: '{path}'\ + }};</script>", + name = it.name.as_ref().map(|x| &x[..]).unwrap_or(""), + ty = shortty(it).to_static_str(), + path = relpath)); + if parentlen == 0 { + // there is no sidebar-items.js beyond the crate root path + // FIXME maybe dynamic crate loading can be merged here + } else { + try!(write!(fmt, "<script defer src=\"{path}sidebar-items.js\"></script>", + path = relpath)); } - try!(block(fmt, "mod", "Modules", it, cx)); - try!(block(fmt, "struct", "Structs", it, cx)); - try!(block(fmt, "enum", "Enums", it, cx)); - try!(block(fmt, "trait", "Traits", it, cx)); - try!(block(fmt, "fn", "Functions", it, cx)); - try!(block(fmt, "macro", "Macros", it, cx)); Ok(()) } } diff --git a/src/librustdoc/html/static/main.css b/src/librustdoc/html/static/main.css index 21b7de9ff7c..1f075566ad5 100644 --- a/src/librustdoc/html/static/main.css +++ b/src/librustdoc/html/static/main.css @@ -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 { diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index aac3985f0cc..a9b233dd128 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -15,6 +15,27 @@ "use strict"; var resizeTimeout, interval; + // This mapping table should match the discriminants of + // `rustdoc::html::item_type::ItemType` type in Rust. + var itemTypes = ["mod", + "externcrate", + "import", + "struct", + "enum", + "fn", + "type", + "static", + "trait", + "impl", + "tymethod", + "method", + "structfield", + "variant", + "macro", + "primitive", + "associatedtype", + "constant"]; + $('.js-only').removeClass('js-only'); function getQueryStringParams() { @@ -552,27 +573,6 @@ showResults(results); } - // This mapping table should match the discriminants of - // `rustdoc::html::item_type::ItemType` type in Rust. - var itemTypes = ["mod", - "externcrate", - "import", - "struct", - "enum", - "fn", - "type", - "static", - "trait", - "impl", - "tymethod", - "method", - "structfield", - "variant", - "macro", - "primitive", - "associatedtype", - "constant"]; - function itemTypeFromName(typename) { for (var i = 0; i < itemTypes.length; ++i) { if (itemTypes[i] === typename) return i; @@ -708,6 +708,50 @@ window.initSearch = initSearch; + // delayed sidebar rendering. + function initSidebarItems(items) { + var sidebar = $('.sidebar'); + var current = window.sidebarCurrent; + + function block(shortty, longty) { + var filtered = items[shortty]; + if (!filtered) return; + + var div = $('<div>').attr('class', 'block ' + shortty); + div.append($('<h2>').text(longty)); + + for (var i = 0; i < filtered.length; ++i) { + var item = filtered[i]; + var name = item[0]; + var desc = item[1]; // can be null + + var klass = shortty; + if (name === current.name && shortty == current.ty) { + klass += ' current'; + } + var path; + if (shortty === 'mod') { + path = name + '/index.html'; + } else { + path = shortty + '.' + name + '.html'; + } + div.append($('<a>', {'href': current.relpath + path, + 'title': desc, + 'class': klass}).text(name)); + } + sidebar.append(div); + } + + block("mod", "Modules"); + block("struct", "Structs"); + block("enum", "Enums"); + block("trait", "Traits"); + block("fn", "Functions"); + block("macro", "Macros"); + } + + window.initSidebarItems = initSidebarItems; + window.register_implementors = function(imp) { var list = $('#implementors-list'); var libs = Object.getOwnPropertyNames(imp); diff --git a/src/librustdoc/html/static/playpen.js b/src/librustdoc/html/static/playpen.js index 687f764f020..8fb979875cd 100644 --- a/src/librustdoc/html/static/playpen.js +++ b/src/librustdoc/html/static/playpen.js @@ -15,7 +15,7 @@ if (window.playgroundUrl) { $('pre.rust').hover(function() { var a = $('<a>').text('⇱').attr('class', 'test-arrow'); - var code = $(this).siblings(".rusttest").text(); + var code = $(this).prev(".rusttest").text(); a.attr('href', window.playgroundUrl + '?code=' + encodeURIComponent(code)); a.attr('target', '_blank'); diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index fc304884ec9..c203dc0e719 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "rustdoc"] #![unstable(feature = "rustdoc")] #![staged_api] @@ -34,6 +36,10 @@ #![feature(test)] #![feature(unicode)] #![feature(str_words)] +#![feature(io)] +#![feature(path)] +#![feature(file_path)] +#![feature(path_ext)] extern crate arena; extern crate getopts; @@ -43,6 +49,7 @@ extern crate rustc_trans; extern crate rustc_driver; extern crate rustc_resolve; extern crate rustc_lint; +extern crate rustc_back; extern crate serialize; extern crate syntax; extern crate "test" as testing; @@ -53,10 +60,12 @@ extern crate "serialize" as rustc_serialize; // used by deriving use std::cell::RefCell; use std::collections::HashMap; use std::env; -use std::old_io::File; -use std::old_io; +use std::fs::File; +use std::io::{self, Read, Write}; +use std::path::PathBuf; use std::rc::Rc; use std::sync::mpsc::channel; + use externalfiles::ExternalHtml; use serialize::Decodable; use serialize::json::{self, Json}; @@ -242,7 +251,7 @@ pub fn main_args(args: &[String]) -> int { let should_test = matches.opt_present("test"); let markdown_input = input.ends_with(".md") || input.ends_with(".markdown"); - let output = matches.opt_str("o").map(|s| Path::new(s)); + let output = matches.opt_str("o").map(|s| PathBuf::new(&s)); let cfgs = matches.opt_strs("cfg"); let external_html = match ExternalHtml::load( @@ -261,7 +270,8 @@ pub fn main_args(args: &[String]) -> int { (true, false) => { return test::run(input, cfgs, libs, externs, test_args, crate_name) } - (false, true) => return markdown::render(input, output.unwrap_or(Path::new("doc")), + (false, true) => return markdown::render(input, + output.unwrap_or(PathBuf::new("doc")), &matches, &external_html, !matches.opt_present("markdown-no-toc")), (false, false) => {} @@ -278,7 +288,8 @@ pub fn main_args(args: &[String]) -> int { info!("going to format"); match matches.opt_str("w").as_ref().map(|s| &**s) { Some("html") | None => { - match html::render::run(krate, &external_html, output.unwrap_or(Path::new("doc")), + match html::render::run(krate, &external_html, + output.unwrap_or(PathBuf::new("doc")), passes.into_iter().collect()) { Ok(()) => {} Err(e) => panic!("failed to generate documentation: {}", e), @@ -286,7 +297,7 @@ pub fn main_args(args: &[String]) -> int { } Some("json") => { match json_output(krate, json_plugins, - output.unwrap_or(Path::new("doc.json"))) { + output.unwrap_or(PathBuf::new("doc.json"))) { Ok(()) => {} Err(e) => panic!("failed to write json: {}", e), } @@ -364,15 +375,15 @@ fn rust_input(cratefile: &str, externs: core::Externs, matches: &getopts::Matche let cfgs = matches.opt_strs("cfg"); let triple = matches.opt_str("target"); - let cr = Path::new(cratefile); + let cr = PathBuf::new(cratefile); info!("starting to run rustc"); let (tx, rx) = channel(); std::thread::spawn(move || { use rustc::session::config::Input; - let cr = cr; - tx.send(core::run_core(paths, cfgs, externs, Input::File(cr), triple)).unwrap(); + tx.send(core::run_core(paths, cfgs, externs, Input::File(cr), + triple)).unwrap(); }).join().map_err(|_| "rustc failed").unwrap(); let (mut krate, analysis) = rx.recv().unwrap(); info!("finished with rustc"); @@ -451,13 +462,12 @@ fn rust_input(cratefile: &str, externs: core::Externs, matches: &getopts::Matche /// This input format purely deserializes the json output file. No passes are /// run over the deserialized output. fn json_input(input: &str) -> Result<Output, String> { - let mut input = match File::open(&Path::new(input)) { - Ok(f) => f, - Err(e) => { - return Err(format!("couldn't open {}: {}", input, e)) - } + let mut bytes = Vec::new(); + match File::open(input).and_then(|mut f| f.read_to_end(&mut bytes)) { + Ok(()) => {} + Err(e) => return Err(format!("couldn't open {}: {}", input, e)), }; - match json::from_reader(&mut input) { + match json::from_reader(&mut &bytes[..]) { Err(s) => Err(format!("{:?}", s)), Ok(Json::Object(obj)) => { let mut obj = obj; @@ -495,7 +505,7 @@ fn json_input(input: &str) -> Result<Output, String> { /// Outputs the crate/plugin json as a giant json blob at the specified /// destination. fn json_output(krate: clean::Crate, res: Vec<plugins::PluginJson> , - dst: Path) -> old_io::IoResult<()> { + dst: PathBuf) -> io::Result<()> { // { // "schema": version, // "crate": { parsed crate ... }, diff --git a/src/librustdoc/markdown.rs b/src/librustdoc/markdown.rs index d64d9becc0c..7d635c8b232 100644 --- a/src/librustdoc/markdown.rs +++ b/src/librustdoc/markdown.rs @@ -8,7 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use std::fs::File; +use std::io::Write; use std::old_io; +use std::path::{PathBuf, Path}; use core; use getopts; @@ -40,10 +43,10 @@ fn extract_leading_metadata<'a>(s: &'a str) -> (Vec<&'a str>, &'a str) { /// Render `input` (e.g. "foo.md") into an HTML file in `output` /// (e.g. output = "bar" => "bar/foo.html"). -pub fn render(input: &str, mut output: Path, matches: &getopts::Matches, +pub fn render(input: &str, mut output: PathBuf, matches: &getopts::Matches, external_html: &ExternalHtml, include_toc: bool) -> int { let input_p = Path::new(input); - output.push(input_p.filestem().unwrap()); + output.push(input_p.file_stem().unwrap()); output.set_extension("html"); let mut css = String::new(); @@ -59,7 +62,7 @@ pub fn render(input: &str, mut output: Path, matches: &getopts::Matches, } let playground = playground.unwrap_or("".to_string()); - let mut out = match old_io::File::create(&output) { + let mut out = match File::create(&output) { Err(e) => { let _ = writeln!(&mut old_io::stderr(), "error opening `{}` for writing: {}", diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 43e8f44244e..e7312d6548e 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -9,21 +9,25 @@ // except according to those terms. use std::cell::RefCell; -use std::sync::mpsc::channel; +use std::collections::{HashSet, HashMap}; use std::dynamic_lib::DynamicLibrary; -use std::old_io::{Command, TempDir}; +use std::env; +use std::ffi::OsString; use std::old_io; -use std::os; +use std::io; +use std::path::PathBuf; +use std::process::Command; use std::str; +use std::sync::mpsc::channel; use std::thread; use std::thunk::Thunk; -use std::collections::{HashSet, HashMap}; use testing; use rustc_lint; use rustc::session::{self, config}; use rustc::session::config::get_unstable_features_setting; use rustc::session::search_paths::{SearchPaths, PathKind}; +use rustc_back::tempdir::TempDir; use rustc_driver::{driver, Compilation}; use syntax::codemap::CodeMap; use syntax::diagnostic; @@ -43,11 +47,12 @@ pub fn run(input: &str, mut test_args: Vec<String>, crate_name: Option<String>) -> int { - let input_path = Path::new(input); + let input_path = PathBuf::new(input); let input = config::Input::File(input_path.clone()); let sessopts = config::Options { - maybe_sysroot: Some(os::self_exe_name().unwrap().dir_path().dir_path()), + maybe_sysroot: Some(env::current_exe().unwrap().parent().unwrap() + .parent().unwrap().to_path_buf()), search_paths: libs.clone(), crate_types: vec!(config::CrateTypeDylib), externs: externs.clone(), @@ -106,16 +111,18 @@ pub fn run(input: &str, 0 } +#[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); let input = config::Input::Str(test.to_string()); let sessopts = config::Options { - maybe_sysroot: Some(os::self_exe_name().unwrap().dir_path().dir_path()), + maybe_sysroot: Some(env::current_exe().unwrap().parent().unwrap() + .parent().unwrap().to_path_buf()), search_paths: libs, crate_types: vec!(config::CrateTypeExecutable), output_types: vec!(config::OutputTypeExe), @@ -170,7 +177,7 @@ fn runtest(test: &str, cratename: &str, libs: SearchPaths, rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess)); let outdir = TempDir::new("rustdoctest").ok().expect("rustdoc needs a tempdir"); - let out = Some(outdir.path().clone()); + let out = Some(outdir.path().to_path_buf()); let cfg = config::build_configuration(&sess); let libdir = sess.target_filesearch(PathKind::All).get_lib_path(); let mut control = driver::CompileController::basic(); @@ -187,25 +194,27 @@ fn runtest(test: &str, cratename: &str, libs: SearchPaths, // environment to ensure that the target loads the right libraries at // runtime. It would be a sad day if the *host* libraries were loaded as a // mistake. - let mut cmd = Command::new(outdir.path().join("rust-out")); + let mut cmd = Command::new(&outdir.path().join("rust-out")); + let var = DynamicLibrary::envvar(); let newpath = { - let mut path = DynamicLibrary::search_path(); + let path = env::var_os(var).unwrap_or(OsString::new()); + let mut path = env::split_paths(&path).collect::<Vec<_>>(); path.insert(0, libdir.clone()); - DynamicLibrary::create_path(&path) + env::join_paths(path.iter()).unwrap() }; - cmd.env(DynamicLibrary::envvar(), newpath); + cmd.env(var, &newpath); match cmd.output() { Err(e) => panic!("couldn't run the test: {}{}", e, - if e.kind == old_io::PermissionDenied { + if e.kind() == io::ErrorKind::PermissionDenied { " - 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.error)); + str::from_utf8(&out.stdout)); } } } @@ -270,7 +279,7 @@ impl Collector { } 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) @@ -286,14 +295,14 @@ impl Collector { 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); })) diff --git a/src/libserialize/hex.rs b/src/libserialize/hex.rs index 970ae06763c..6f3d90d45b0 100644 --- a/src/libserialize/hex.rs +++ b/src/libserialize/hex.rs @@ -117,7 +117,7 @@ impl FromHex for str { // This may be an overestimate if there is any whitespace let mut b = Vec::with_capacity(self.len() / 2); let mut modulus = 0; - let mut buf = 0u8; + let mut buf = 0; for (idx, byte) in self.bytes().enumerate() { buf <<= 4; diff --git a/src/libserialize/json.rs b/src/libserialize/json.rs index bf4d006fcfa..6fc56522c6a 100644 --- a/src/libserialize/json.rs +++ b/src/libserialize/json.rs @@ -188,7 +188,7 @@ //! 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(); //! } //! ``` @@ -1653,7 +1653,7 @@ impl<T: Iterator<Item=char>> Parser<T> { fn decode_hex_escape(&mut self) -> Result<u16, ParserError> { let mut i = 0; - let mut n = 0u16; + let mut n = 0; while i < 4 && !self.eof() { self.bump(); n = match self.ch_or_null() { diff --git a/src/libserialize/lib.rs b/src/libserialize/lib.rs index d476fd72abc..ad7908c6dd5 100644 --- a/src/libserialize/lib.rs +++ b/src/libserialize/lib.rs @@ -14,6 +14,8 @@ Core encoding and decoding interfaces. */ +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "serialize"] #![unstable(feature = "rustc_private", reason = "deprecated in favor of rustc-serialize on crates.io")] @@ -35,6 +37,7 @@ Core encoding and decoding interfaces. #![feature(staged_api)] #![feature(std_misc)] #![feature(unicode)] +#![feature(path)] #![cfg_attr(test, feature(test))] // test harness access diff --git a/src/libserialize/serialize.rs b/src/libserialize/serialize.rs index 70f0ba4bb23..f287229e083 100644 --- a/src/libserialize/serialize.rs +++ b/src/libserialize/serialize.rs @@ -15,6 +15,7 @@ Core encoding and decoding interfaces. */ use std::old_path; +use std::path; use std::rc::Rc; use std::cell::{Cell, RefCell}; use std::sync::Arc; @@ -564,6 +565,19 @@ impl Decodable for old_path::windows::Path { } } +impl Encodable for path::PathBuf { + fn encode<S: Encoder>(&self, e: &mut S) -> Result<(), S::Error> { + self.to_str().unwrap().encode(e) + } +} + +impl Decodable for path::PathBuf { + fn decode<D: Decoder>(d: &mut D) -> Result<path::PathBuf, D::Error> { + let bytes: String = try!(Decodable::decode(d)); + Ok(path::PathBuf::new(&bytes)) + } +} + impl<T: Encodable + Copy> Encodable for Cell<T> { fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> { self.get().encode(s) diff --git a/src/libstd/ascii.rs b/src/libstd/ascii.rs index 94457a5d714..8b275d1bc4a 100644 --- a/src/libstd/ascii.rs +++ b/src/libstd/ascii.rs @@ -186,7 +186,7 @@ impl OwnedAsciiExt for Vec<u8> { impl AsciiExt for u8 { type Owned = u8; #[inline] - fn is_ascii(&self) -> bool { *self & 128 == 0u8 } + fn is_ascii(&self) -> bool { *self & 128 == 0 } #[inline] fn to_ascii_uppercase(&self) -> u8 { ASCII_UPPERCASE_MAP[*self as usize] } #[inline] @@ -398,7 +398,7 @@ mod tests { assert_eq!("url()URL()uRl()ürl".to_ascii_uppercase(), "URL()URL()URL()üRL"); assert_eq!("hıKß".to_ascii_uppercase(), "HıKß"); - for i in 0u32..501 { + for i in 0..501 { let upper = if 'a' as u32 <= i && i <= 'z' as u32 { i + 'A' as u32 - 'a' as u32 } else { i }; assert_eq!((from_u32(i).unwrap()).to_string().to_ascii_uppercase(), @@ -412,7 +412,7 @@ mod tests { // Dotted capital I, Kelvin sign, Sharp S. assert_eq!("HİKß".to_ascii_lowercase(), "hİKß"); - for i in 0u32..501 { + for i in 0..501 { let lower = if 'A' as u32 <= i && i <= 'Z' as u32 { i + 'a' as u32 - 'A' as u32 } else { i }; assert_eq!((from_u32(i).unwrap()).to_string().to_ascii_lowercase(), @@ -426,7 +426,7 @@ mod tests { "URL()URL()URL()üRL".to_string()); assert_eq!(("hıKß".to_string()).into_ascii_uppercase(), "HıKß"); - for i in 0u32..501 { + for i in 0..501 { let upper = if 'a' as u32 <= i && i <= 'z' as u32 { i + 'A' as u32 - 'a' as u32 } else { i }; assert_eq!((from_u32(i).unwrap()).to_string().into_ascii_uppercase(), @@ -441,7 +441,7 @@ mod tests { // Dotted capital I, Kelvin sign, Sharp S. assert_eq!(("HİKß".to_string()).into_ascii_lowercase(), "hİKß"); - for i in 0u32..501 { + for i in 0..501 { let lower = if 'A' as u32 <= i && i <= 'Z' as u32 { i + 'a' as u32 - 'A' as u32 } else { i }; assert_eq!((from_u32(i).unwrap()).to_string().into_ascii_lowercase(), @@ -459,7 +459,7 @@ mod tests { assert!(!"K".eq_ignore_ascii_case("k")); assert!(!"ß".eq_ignore_ascii_case("s")); - for i in 0u32..501 { + for i in 0..501 { let lower = if 'A' as u32 <= i && i <= 'Z' as u32 { i + 'a' as u32 - 'A' as u32 } else { i }; assert!((from_u32(i).unwrap()).to_string().eq_ignore_ascii_case( diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index 8eb29a8327a..9502302aa53 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -2197,7 +2197,7 @@ mod test_map { } #[test] - #[should_fail] + #[should_panic] fn test_index_nonexistent() { let mut map = HashMap::new(); diff --git a/src/libstd/collections/hash/table.rs b/src/libstd/collections/hash/table.rs index 2670cd0c003..69fd0a57d5f 100644 --- a/src/libstd/collections/hash/table.rs +++ b/src/libstd/collections/hash/table.rs @@ -28,7 +28,7 @@ use ptr::{self, PtrExt, Unique}; use rt::heap::{allocate, deallocate, EMPTY}; use collections::hash_state::HashState; -const EMPTY_BUCKET: u64 = 0u64; +const EMPTY_BUCKET: u64 = 0; /// The raw hashtable, providing safe-ish access to the unzipped and highly /// optimized arrays of hashes, keys, and values. @@ -149,7 +149,7 @@ pub fn make_hash<T: ?Sized, S>(hash_state: &S, t: &T) -> SafeHash { let mut state = hash_state.hasher(); t.hash(&mut state); - // We need to avoid 0u64 in order to prevent collisions with + // We need to avoid 0 in order to prevent collisions with // EMPTY_HASH. We can maintain our precious uniform distribution // of initial indexes by unconditionally setting the MSB, // effectively reducing 64-bits hashes to 63 bits. diff --git a/src/libstd/collections/mod.rs b/src/libstd/collections/mod.rs index 100d3e6ed4a..caada8ae50f 100644 --- a/src/libstd/collections/mod.rs +++ b/src/libstd/collections/mod.rs @@ -78,7 +78,7 @@ //! * You want a bit vector. //! //! ### Use a `BitSet` when: -//! * You want a `VecSet`. +//! * You want a `BitVec`, but want `Set` properties //! //! ### Use a `BinaryHeap` when: //! * You want to store a bunch of elements, but only ever want to process the "biggest" @@ -89,7 +89,8 @@ //! //! Choosing the right collection for the job requires an understanding of what each collection //! is good at. Here we briefly summarize the performance of different collections for certain -//! important operations. For further details, see each type's documentation. +//! important operations. For further details, see each type's documentation, and note that the +//! names of actual methods may differ from the tables below on certain collections. //! //! Throughout the documentation, we will follow a few conventions. For all operations, //! the collection's size is denoted by n. If another collection is involved in the operation, it @@ -280,16 +281,16 @@ //! a variant of the `Entry` enum. //! //! If a `Vacant(entry)` is yielded, then the key *was not* found. In this case the -//! only valid operation is to `set` the value of the entry. When this is done, +//! only valid operation is to `insert` a value into the entry. When this is done, //! the vacant entry is consumed and converted into a mutable reference to the //! the value that was inserted. This allows for further manipulation of the value //! beyond the lifetime of the search itself. This is useful if complex logic needs to //! be performed on the value regardless of whether the value was just inserted. //! //! If an `Occupied(entry)` is yielded, then the key *was* found. In this case, the user -//! has several options: they can `get`, `set`, or `take` the value of the occupied +//! has several options: they can `get`, `insert`, or `remove` the value of the occupied //! entry. Additionally, they can convert the occupied entry into a mutable reference -//! to its value, providing symmetry to the vacant `set` case. +//! to its value, providing symmetry to the vacant `insert` case. //! //! ### Examples //! @@ -329,7 +330,7 @@ //! use std::collections::btree_map::{BTreeMap, Entry}; //! //! // A client of the bar. They have an id and a blood alcohol level. -//! struct Person { id: u32, blood_alcohol: f32 }; +//! struct Person { id: u32, blood_alcohol: f32 } //! //! // All the orders made to the bar, by client id. //! let orders = vec![1,2,1,2,3,4,1,2,2,3,4,1,1,1]; diff --git a/src/libstd/env.rs b/src/libstd/env.rs index 1968ca4b9e7..b2ef04a5d63 100644 --- a/src/libstd/env.rs +++ b/src/libstd/env.rs @@ -616,6 +616,9 @@ mod os { mod os { pub const FAMILY: &'static str = "unix"; pub const OS: &'static str = "ios"; + pub const DLL_PREFIX: &'static str = "lib"; + pub const DLL_SUFFIX: &'static str = ".dylib"; + pub const DLL_EXTENSION: &'static str = "dylib"; pub const EXE_SUFFIX: &'static str = ""; pub const EXE_EXTENSION: &'static str = ""; } @@ -777,8 +780,8 @@ mod tests { 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] @@ -796,7 +799,7 @@ mod tests { 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); } diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs index 69bcc82f682..ec9f90723be 100644 --- a/src/libstd/ffi/c_str.rs +++ b/src/libstd/ffi/c_str.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![unstable(feature = "std_misc")] + use cmp::{PartialEq, Eq, PartialOrd, Ord, Ordering}; use error::{Error, FromError}; use fmt; @@ -59,6 +61,7 @@ use vec::Vec; /// # } /// ``` #[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash)] +#[stable(feature = "rust1", since = "1.0.0")] pub struct CString { inner: Vec<u8>, } @@ -110,13 +113,19 @@ pub struct CString { /// } /// ``` #[derive(Hash)] +#[stable(feature = "rust1", since = "1.0.0")] pub struct CStr { + // FIXME: this should not be represented with a DST slice but rather with + // just a raw `libc::c_char` along with some form of marker to make + // this an unsized type. Essentially `sizeof(&CStr)` should be the + // same as `sizeof(&c_char)` but `CStr` should be an unsized type. inner: [libc::c_char] } /// An error returned from `CString::new` to indicate that a nul byte was found /// in the vector provided. #[derive(Clone, PartialEq, Debug)] +#[stable(feature = "rust1", since = "1.0.0")] pub struct NulError(usize, Vec<u8>); /// A conversion trait used by the constructor of `CString` for types that can @@ -153,6 +162,7 @@ impl CString { /// This function will return an error if the bytes yielded contain an /// internal 0 byte. The error returned will contain the bytes as well as /// the position of the nul byte. + #[stable(feature = "rust1", since = "1.0.0")] pub fn new<T: IntoBytes>(t: T) -> Result<CString, NulError> { let bytes = t.into_bytes(); match bytes.iter().position(|x| *x == 0) { @@ -216,6 +226,7 @@ impl CString { /// /// This method is equivalent to `from_vec` except that no runtime assertion /// is made that `v` contains no 0 bytes. + #[stable(feature = "rust1", since = "1.0.0")] pub unsafe fn from_vec_unchecked(mut v: Vec<u8>) -> CString { v.push(0); CString { inner: v } @@ -225,17 +236,20 @@ impl CString { /// /// The returned slice does **not** contain the trailing nul separator and /// it is guaranteed to not have any interior nul bytes. + #[stable(feature = "rust1", since = "1.0.0")] pub fn as_bytes(&self) -> &[u8] { &self.inner[..self.inner.len() - 1] } /// Equivalent to the `as_bytes` function except that the returned slice /// includes the trailing nul byte. + #[stable(feature = "rust1", since = "1.0.0")] pub fn as_bytes_with_nul(&self) -> &[u8] { &self.inner } } +#[stable(feature = "rust1", since = "1.0.0")] impl Deref for CString { type Target = CStr; @@ -254,23 +268,28 @@ impl fmt::Debug for CString { impl NulError { /// Returns the position of the nul byte in the slice that was provided to /// `CString::from_vec`. + #[stable(feature = "rust1", since = "1.0.0")] pub fn nul_position(&self) -> usize { self.0 } /// Consumes this error, returning the underlying vector of bytes which /// generated the error in the first place. + #[stable(feature = "rust1", since = "1.0.0")] pub fn into_vec(self) -> Vec<u8> { self.1 } } +#[stable(feature = "rust1", since = "1.0.0")] impl Error for NulError { fn description(&self) -> &str { "nul byte found in data" } } +#[stable(feature = "rust1", since = "1.0.0")] impl fmt::Display for NulError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "nul byte found in provided data at position: {}", self.0) } } +#[stable(feature = "rust1", since = "1.0.0")] impl FromError<NulError> for io::Error { fn from_error(_: NulError) -> io::Error { io::Error::new(io::ErrorKind::InvalidInput, @@ -278,6 +297,7 @@ impl FromError<NulError> for io::Error { } } +#[stable(feature = "rust1", since = "1.0.0")] impl FromError<NulError> for old_io::IoError { fn from_error(_: NulError) -> old_io::IoError { old_io::IoError { @@ -325,6 +345,7 @@ impl CStr { /// } /// # } /// ``` + #[stable(feature = "rust1", since = "1.0.0")] pub unsafe fn from_ptr<'a>(ptr: *const libc::c_char) -> &'a CStr { let len = libc::strlen(ptr); mem::transmute(slice::from_raw_parts(ptr, len as usize + 1)) @@ -335,6 +356,7 @@ impl CStr { /// The returned pointer will be valid for as long as `self` is and points /// to a contiguous region of memory terminated with a 0 byte to represent /// the end of the string. + #[stable(feature = "rust1", since = "1.0.0")] pub fn as_ptr(&self) -> *const libc::c_char { self.inner.as_ptr() } @@ -351,6 +373,7 @@ impl CStr { /// > **Note**: This method is currently implemented as a 0-cost cast, but /// > it is planned to alter its definition in the future to perform the /// > length calculation whenever this method is called. + #[stable(feature = "rust1", since = "1.0.0")] pub fn to_bytes(&self) -> &[u8] { let bytes = self.to_bytes_with_nul(); &bytes[..bytes.len() - 1] @@ -364,22 +387,27 @@ impl CStr { /// > **Note**: This method is currently implemented as a 0-cost cast, but /// > it is planned to alter its definition in the future to perform the /// > length calculation whenever this method is called. + #[stable(feature = "rust1", since = "1.0.0")] pub fn to_bytes_with_nul(&self) -> &[u8] { unsafe { mem::transmute::<&[libc::c_char], &[u8]>(&self.inner) } } } +#[stable(feature = "rust1", since = "1.0.0")] impl PartialEq for CStr { fn eq(&self, other: &CStr) -> bool { self.to_bytes().eq(other.to_bytes()) } } +#[stable(feature = "rust1", since = "1.0.0")] impl Eq for CStr {} +#[stable(feature = "rust1", since = "1.0.0")] impl PartialOrd for CStr { fn partial_cmp(&self, other: &CStr) -> Option<Ordering> { self.to_bytes().partial_cmp(&other.to_bytes()) } } +#[stable(feature = "rust1", since = "1.0.0")] impl Ord for CStr { fn cmp(&self, other: &CStr) -> Ordering { self.to_bytes().cmp(&other.to_bytes()) @@ -422,15 +450,14 @@ mod tests { use prelude::v1::*; use super::*; use libc; - use mem; #[test] fn c_to_rust() { let data = b"123\0"; let ptr = data.as_ptr() as *const libc::c_char; unsafe { - assert_eq!(c_str_to_bytes(&ptr), b"123"); - assert_eq!(c_str_to_bytes_with_nul(&ptr), b"123\0"); + assert_eq!(CStr::from_ptr(ptr).to_bytes(), b"123"); + assert_eq!(CStr::from_ptr(ptr).to_bytes_with_nul(), b"123\0"); } } diff --git a/src/libstd/ffi/mod.rs b/src/libstd/ffi/mod.rs index 1bff6afb776..f17dc654249 100644 --- a/src/libstd/ffi/mod.rs +++ b/src/libstd/ffi/mod.rs @@ -10,17 +10,19 @@ //! Utilities related to FFI bindings. -#![unstable(feature = "std_misc", - reason = "module just underwent fairly large reorganization and the dust \ - still needs to settle")] +#![stable(feature = "rust1", since = "1.0.0")] -pub use self::c_str::{CString, CStr, NulError, IntoBytes}; +#[stable(feature = "rust1", since = "1.0.0")] +pub use self::c_str::{CString, CStr}; +pub use self::c_str::{NulError, IntoBytes}; #[allow(deprecated)] pub use self::c_str::c_str_to_bytes; #[allow(deprecated)] pub use self::c_str::c_str_to_bytes_with_nul; +#[stable(feature = "rust1", since = "1.0.0")] pub use self::os_str::OsString; +#[stable(feature = "rust1", since = "1.0.0")] pub use self::os_str::OsStr; mod c_str; @@ -28,6 +30,7 @@ mod os_str; // FIXME (#21670): these should be defined in the os_str module /// Freely convertible to an `&OsStr` slice. +#[unstable(feature = "std_misc")] pub trait AsOsStr { /// Convert to an `&OsStr` slice. fn as_os_str(&self) -> &OsStr; diff --git a/src/libstd/ffi/os_str.rs b/src/libstd/ffi/os_str.rs index 926d8e03f2c..77df831bbfe 100644 --- a/src/libstd/ffi/os_str.rs +++ b/src/libstd/ffi/os_str.rs @@ -49,17 +49,20 @@ use super::AsOsStr; /// Owned, mutable OS strings. #[derive(Clone)] +#[stable(feature = "rust1", since = "1.0.0")] pub struct OsString { inner: Buf } /// Slices into OS strings. +#[stable(feature = "rust1", since = "1.0.0")] pub struct OsStr { inner: Slice } impl OsString { /// Constructs an `OsString` at no cost by consuming a `String`. + #[stable(feature = "rust1", since = "1.0.0")] pub fn from_string(s: String) -> OsString { OsString { inner: Buf::from_string(s) } } @@ -67,11 +70,13 @@ impl OsString { /// Constructs an `OsString` by copying from a `&str` slice. /// /// Equivalent to: `OsString::from_string(String::from_str(s))`. + #[stable(feature = "rust1", since = "1.0.0")] pub fn from_str(s: &str) -> OsString { OsString { inner: Buf::from_str(s) } } /// Constructs a new empty `OsString`. + #[stable(feature = "rust1", since = "1.0.0")] pub fn new() -> OsString { OsString { inner: Buf::from_string(String::new()) } } @@ -79,16 +84,26 @@ impl OsString { /// Convert the `OsString` into a `String` if it contains valid Unicode data. /// /// On failure, ownership of the original `OsString` is returned. + #[stable(feature = "rust1", since = "1.0.0")] pub fn into_string(self) -> Result<String, OsString> { self.inner.into_string().map_err(|buf| OsString { inner: buf} ) } /// Extend the string with the given `&OsStr` slice. + #[deprecated(since = "1.0.0", reason = "renamed to `push`")] + #[unstable(feature = "os")] pub fn push_os_str(&mut self, s: &OsStr) { self.inner.push_slice(&s.inner) } + + /// Extend the string with the given `&OsStr` slice. + #[stable(feature = "rust1", since = "1.0.0")] + pub fn push<T: AsOsStr + ?Sized>(&mut self, s: &T) { + self.inner.push_slice(&s.as_os_str().inner) + } } +#[stable(feature = "rust1", since = "1.0.0")] impl ops::Index<ops::RangeFull> for OsString { type Output = OsStr; @@ -98,6 +113,7 @@ impl ops::Index<ops::RangeFull> for OsString { } } +#[stable(feature = "rust1", since = "1.0.0")] impl ops::Deref for OsString { type Target = OsStr; @@ -107,32 +123,38 @@ impl ops::Deref for OsString { } } +#[stable(feature = "rust1", since = "1.0.0")] impl Debug for OsString { fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> { fmt::Debug::fmt(&**self, formatter) } } +#[stable(feature = "rust1", since = "1.0.0")] impl PartialEq for OsString { fn eq(&self, other: &OsString) -> bool { &**self == &**other } } +#[stable(feature = "rust1", since = "1.0.0")] impl PartialEq<str> for OsString { fn eq(&self, other: &str) -> bool { &**self == other } } +#[stable(feature = "rust1", since = "1.0.0")] impl PartialEq<OsString> for str { fn eq(&self, other: &OsString) -> bool { &**other == self } } +#[stable(feature = "rust1", since = "1.0.0")] impl Eq for OsString {} +#[stable(feature = "rust1", since = "1.0.0")] impl PartialOrd for OsString { #[inline] fn partial_cmp(&self, other: &OsString) -> Option<cmp::Ordering> { @@ -148,6 +170,7 @@ impl PartialOrd for OsString { fn ge(&self, other: &OsString) -> bool { &**self >= &**other } } +#[stable(feature = "rust1", since = "1.0.0")] impl PartialOrd<str> for OsString { #[inline] fn partial_cmp(&self, other: &str) -> Option<cmp::Ordering> { @@ -155,6 +178,7 @@ impl PartialOrd<str> for OsString { } } +#[stable(feature = "rust1", since = "1.0.0")] impl Ord for OsString { #[inline] fn cmp(&self, other: &OsString) -> cmp::Ordering { @@ -172,6 +196,7 @@ impl Hash for OsString { impl OsStr { /// Coerce directly from a `&str` slice to a `&OsStr` slice. + #[stable(feature = "rust1", since = "1.0.0")] pub fn from_str(s: &str) -> &OsStr { unsafe { mem::transmute(Slice::from_str(s)) } } @@ -179,6 +204,7 @@ impl OsStr { /// Yield a `&str` slice if the `OsStr` is valid unicode. /// /// This conversion may entail doing a check for UTF-8 validity. + #[stable(feature = "rust1", since = "1.0.0")] pub fn to_str(&self) -> Option<&str> { self.inner.to_str() } @@ -186,11 +212,13 @@ impl OsStr { /// Convert an `OsStr` to a `Cow<str>`. /// /// Any non-Unicode sequences are replaced with U+FFFD REPLACEMENT CHARACTER. + #[stable(feature = "rust1", since = "1.0.0")] pub fn to_string_lossy(&self) -> Cow<str> { self.inner.to_string_lossy() } /// Copy the slice into an owned `OsString`. + #[stable(feature = "rust1", since = "1.0.0")] pub fn to_os_string(&self) -> OsString { OsString { inner: self.inner.to_owned() } } @@ -204,26 +232,31 @@ impl OsStr { } } +#[stable(feature = "rust1", since = "1.0.0")] impl PartialEq for OsStr { fn eq(&self, other: &OsStr) -> bool { self.bytes().eq(other.bytes()) } } +#[stable(feature = "rust1", since = "1.0.0")] impl PartialEq<str> for OsStr { fn eq(&self, other: &str) -> bool { *self == *OsStr::from_str(other) } } +#[stable(feature = "rust1", since = "1.0.0")] impl PartialEq<OsStr> for str { fn eq(&self, other: &OsStr) -> bool { *other == *OsStr::from_str(self) } } +#[stable(feature = "rust1", since = "1.0.0")] impl Eq for OsStr {} +#[stable(feature = "rust1", since = "1.0.0")] impl PartialOrd for OsStr { #[inline] fn partial_cmp(&self, other: &OsStr) -> Option<cmp::Ordering> { @@ -239,6 +272,7 @@ impl PartialOrd for OsStr { fn ge(&self, other: &OsStr) -> bool { self.bytes().ge(other.bytes()) } } +#[stable(feature = "rust1", since = "1.0.0")] impl PartialOrd<str> for OsStr { #[inline] fn partial_cmp(&self, other: &str) -> Option<cmp::Ordering> { @@ -249,6 +283,7 @@ impl PartialOrd<str> for OsStr { // FIXME (#19470): cannot provide PartialOrd<OsStr> for str until we // have more flexible coherence rules. +#[stable(feature = "rust1", since = "1.0.0")] impl Ord for OsStr { #[inline] fn cmp(&self, other: &OsStr) -> cmp::Ordering { self.bytes().cmp(other.bytes()) } @@ -262,21 +297,25 @@ impl Hash for OsStr { } } +#[stable(feature = "rust1", since = "1.0.0")] impl Debug for OsStr { fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> { self.inner.fmt(formatter) } } +#[stable(feature = "rust1", since = "1.0.0")] impl Borrow<OsStr> for OsString { fn borrow(&self) -> &OsStr { &self[..] } } +#[stable(feature = "rust1", since = "1.0.0")] impl ToOwned for OsStr { type Owned = OsString; fn to_owned(&self) -> OsString { self.to_os_string() } } +#[stable(feature = "rust1", since = "1.0.0")] impl<'a, T: AsOsStr + ?Sized> AsOsStr for &'a T { fn as_os_str(&self) -> &OsStr { (*self).as_os_str() @@ -307,15 +346,12 @@ impl AsOsStr for String { } } -#[cfg(unix)] impl AsOsStr for Path { + #[cfg(unix)] fn as_os_str(&self) -> &OsStr { unsafe { mem::transmute(self.as_vec()) } } -} - -#[cfg(windows)] -impl AsOsStr for Path { + #[cfg(windows)] fn as_os_str(&self) -> &OsStr { // currently .as_str() is actually infallible on windows OsStr::from_str(self.as_str().unwrap()) diff --git a/src/libstd/fs/mod.rs b/src/libstd/fs/mod.rs index 64ec025a5c4..9f9163eb9e6 100644 --- a/src/libstd/fs/mod.rs +++ b/src/libstd/fs/mod.rs @@ -15,7 +15,7 @@ //! operations. Extra platform-specific functionality can be found in the //! extension traits of `std::os::$platform`. -#![unstable(feature = "fs")] +#![stable(feature = "rust1", since = "1.0.0")] use core::prelude::*; @@ -25,6 +25,7 @@ use sys::fs2 as fs_imp; use sys_common::{AsInnerMut, FromInner, AsInner}; use vec::Vec; +#[allow(deprecated)] pub use self::tempdir::TempDir; mod tempdir; @@ -52,6 +53,7 @@ mod tempdir; /// # Ok(()) /// # } /// ``` +#[stable(feature = "rust1", since = "1.0.0")] pub struct File { inner: fs_imp::File, path: PathBuf, @@ -62,6 +64,7 @@ pub struct File { /// This structure is returned from the `metadata` function or method and /// represents known metadata about a file such as its permissions, size, /// modification times, etc. +#[stable(feature = "rust1", since = "1.0.0")] pub struct Metadata(fs_imp::FileAttr); /// Iterator over the entries in a directory. @@ -70,6 +73,7 @@ pub struct Metadata(fs_imp::FileAttr); /// will yield instances of `io::Result<DirEntry>`. Through a `DirEntry` /// information like the entry's path and possibly other metadata can be /// learned. +#[stable(feature = "rust1", since = "1.0.0")] pub struct ReadDir(fs_imp::ReadDir); /// Entries returned by the `ReadDir` iterator. @@ -77,9 +81,14 @@ pub struct ReadDir(fs_imp::ReadDir); /// An instance of `DirEntry` represents an entry inside of a directory on the /// filesystem. Each entry can be inspected via methods to learn about the full /// path or possibly other metadata through per-platform extension traits. +#[stable(feature = "rust1", since = "1.0.0")] pub struct DirEntry(fs_imp::DirEntry); /// An iterator that recursively walks over the contents of a directory. +#[unstable(feature = "fs_walk", + reason = "the precise semantics and defaults for a recursive walk \ + may change and this may end up accounting for files such \ + as symlinks differently")] pub struct WalkDir { cur: Option<ReadDir>, stack: Vec<io::Result<ReadDir>>, @@ -92,6 +101,7 @@ pub struct WalkDir { /// `File::create` methods are aliases for commonly used options using this /// builder. #[derive(Clone)] +#[stable(feature = "rust1", since = "1.0.0")] pub struct OpenOptions(fs_imp::OpenOptions); /// Representation of the various permissions on a file. @@ -101,6 +111,7 @@ pub struct OpenOptions(fs_imp::OpenOptions); /// functionality, such as mode bits, is available through the /// `os::unix::PermissionsExt` trait. #[derive(Clone, PartialEq, Eq, Debug)] +#[stable(feature = "rust1", since = "1.0.0")] pub struct Permissions(fs_imp::FilePermissions); impl File { @@ -112,6 +123,7 @@ impl File { /// /// This function will return an error if `path` does not already exist. /// Other errors may also be returned according to `OpenOptions::open`. + #[stable(feature = "rust1", since = "1.0.0")] pub fn open<P: AsPath + ?Sized>(path: &P) -> io::Result<File> { OpenOptions::new().read(true).open(path) } @@ -122,11 +134,15 @@ impl File { /// and will truncate it if it does. /// /// See the `OpenOptions::open` function for more details. + #[stable(feature = "rust1", since = "1.0.0")] pub fn create<P: AsPath + ?Sized>(path: &P) -> io::Result<File> { OpenOptions::new().write(true).create(true).truncate(true).open(path) } /// Returns the original path that was used to open this file. + #[unstable(feature = "file_path", + reason = "this abstraction is imposed by this library instead \ + of the underlying OS and may be removed")] pub fn path(&self) -> Option<&Path> { Some(&self.path) } @@ -135,6 +151,7 @@ impl File { /// /// This function will attempt to ensure that all in-core data reaches the /// filesystem before returning. + #[stable(feature = "rust1", since = "1.0.0")] pub fn sync_all(&self) -> io::Result<()> { self.inner.fsync() } @@ -148,6 +165,7 @@ impl File { /// /// Note that some platforms may simply implement this in terms of /// `sync_all`. + #[stable(feature = "rust1", since = "1.0.0")] pub fn sync_data(&self) -> io::Result<()> { self.inner.datasync() } @@ -159,11 +177,13 @@ impl File { /// be shrunk. If it is greater than the current file's size, then the file /// will be extended to `size` and have all of the intermediate data filled /// in with 0s. + #[stable(feature = "rust1", since = "1.0.0")] pub fn set_len(&self, size: u64) -> io::Result<()> { self.inner.truncate(size) } - /// Queries information about the underlying file. + /// Queries metadata about the underlying file. + #[stable(feature = "rust1", since = "1.0.0")] pub fn metadata(&self) -> io::Result<Metadata> { self.inner.file_attr().map(Metadata) } @@ -172,33 +192,39 @@ impl File { impl AsInner<fs_imp::File> for File { fn as_inner(&self) -> &fs_imp::File { &self.inner } } +#[stable(feature = "rust1", since = "1.0.0")] impl Read for File { fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { self.inner.read(buf) } } +#[stable(feature = "rust1", since = "1.0.0")] impl Write for File { fn write(&mut self, buf: &[u8]) -> io::Result<usize> { self.inner.write(buf) } fn flush(&mut self) -> io::Result<()> { self.inner.flush() } } +#[stable(feature = "rust1", since = "1.0.0")] impl Seek for File { fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> { self.inner.seek(pos) } } +#[stable(feature = "rust1", since = "1.0.0")] impl<'a> Read for &'a File { fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { self.inner.read(buf) } } +#[stable(feature = "rust1", since = "1.0.0")] impl<'a> Write for &'a File { fn write(&mut self, buf: &[u8]) -> io::Result<usize> { self.inner.write(buf) } fn flush(&mut self) -> io::Result<()> { self.inner.flush() } } +#[stable(feature = "rust1", since = "1.0.0")] impl<'a> Seek for &'a File { fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> { self.inner.seek(pos) @@ -209,6 +235,7 @@ impl OpenOptions { /// Creates a blank net set of options ready for configuration. /// /// All options are initially set to `false`. + #[stable(feature = "rust1", since = "1.0.0")] pub fn new() -> OpenOptions { OpenOptions(fs_imp::OpenOptions::new()) } @@ -217,6 +244,7 @@ impl OpenOptions { /// /// This option, when true, will indicate that the file should be /// `read`-able if opened. + #[stable(feature = "rust1", since = "1.0.0")] pub fn read(&mut self, read: bool) -> &mut OpenOptions { self.0.read(read); self } @@ -225,6 +253,7 @@ impl OpenOptions { /// /// This option, when true, will indicate that the file should be /// `write`-able if opened. + #[stable(feature = "rust1", since = "1.0.0")] pub fn write(&mut self, write: bool) -> &mut OpenOptions { self.0.write(write); self } @@ -233,6 +262,7 @@ impl OpenOptions { /// /// This option, when true, means that writes will append to a file instead /// of overwriting previous contents. + #[stable(feature = "rust1", since = "1.0.0")] pub fn append(&mut self, append: bool) -> &mut OpenOptions { self.0.append(append); self } @@ -241,6 +271,7 @@ impl OpenOptions { /// /// If a file is successfully opened with this option set it will truncate /// the file to 0 length if it already exists. + #[stable(feature = "rust1", since = "1.0.0")] pub fn truncate(&mut self, truncate: bool) -> &mut OpenOptions { self.0.truncate(truncate); self } @@ -249,6 +280,7 @@ impl OpenOptions { /// /// This option indicates whether a new file will be created if the file /// does not yet already exist. + #[stable(feature = "rust1", since = "1.0.0")] pub fn create(&mut self, create: bool) -> &mut OpenOptions { self.0.create(create); self } @@ -264,37 +296,33 @@ impl OpenOptions { /// * Attempting to open a file with access that the user lacks /// permissions for /// * Filesystem-level errors (full disk, etc) + #[stable(feature = "rust1", since = "1.0.0")] pub fn open<P: AsPath + ?Sized>(&self, path: &P) -> io::Result<File> { let path = path.as_path(); let inner = try!(fs_imp::File::open(path, &self.0)); - - // On *BSD systems, we can open a directory as a file and read from - // it: fd=open("/tmp", O_RDONLY); read(fd, buf, N); due to an old - // tradition before the introduction of opendir(3). We explicitly - // reject it because there are few use cases. - if cfg!(not(any(target_os = "linux", target_os = "android"))) && - try!(inner.file_attr()).is_dir() { - Err(Error::new(ErrorKind::InvalidInput, "is a directory", None)) - } else { - Ok(File { path: path.to_path_buf(), inner: inner }) - } + Ok(File { path: path.to_path_buf(), inner: inner }) } } + impl AsInnerMut<fs_imp::OpenOptions> for OpenOptions { fn as_inner_mut(&mut self) -> &mut fs_imp::OpenOptions { &mut self.0 } } impl Metadata { /// Returns whether this metadata is for a directory. + #[stable(feature = "rust1", since = "1.0.0")] pub fn is_dir(&self) -> bool { self.0.is_dir() } /// Returns whether this metadata is for a regular file. + #[stable(feature = "rust1", since = "1.0.0")] pub fn is_file(&self) -> bool { self.0.is_file() } /// Returns the size of the file, in bytes, this metadata is for. + #[stable(feature = "rust1", since = "1.0.0")] pub fn len(&self) -> u64 { self.0.size() } /// Returns the permissions of the file this metadata is for. + #[stable(feature = "rust1", since = "1.0.0")] pub fn permissions(&self) -> Permissions { Permissions(self.0.perm()) } @@ -302,22 +330,32 @@ impl Metadata { /// Returns the most recent access time for a file. /// /// The return value is in milliseconds since the epoch. + #[unstable(feature = "fs_time", + reason = "the return type of u64 is not quite appropriate for \ + this method and may change if the standard library \ + gains a type to represent a moment in time")] pub fn accessed(&self) -> u64 { self.0.accessed() } /// Returns the most recent modification time for a file. /// /// The return value is in milliseconds since the epoch. + #[unstable(feature = "fs_time", + reason = "the return type of u64 is not quite appropriate for \ + this method and may change if the standard library \ + gains a type to represent a moment in time")] pub fn modified(&self) -> u64 { self.0.modified() } } impl Permissions { /// Returns whether these permissions describe a readonly file. + #[stable(feature = "rust1", since = "1.0.0")] pub fn readonly(&self) -> bool { self.0.readonly() } /// Modify the readonly flag for this set of permissions. /// /// This operation does **not** modify the filesystem. To modify the /// filesystem use the `fs::set_permissions` function. + #[stable(feature = "rust1", since = "1.0.0")] pub fn set_readonly(&mut self, readonly: bool) { self.0.set_readonly(readonly) } @@ -333,6 +371,7 @@ impl AsInner<fs_imp::FilePermissions> for Permissions { fn as_inner(&self) -> &fs_imp::FilePermissions { &self.0 } } +#[stable(feature = "rust1", since = "1.0.0")] impl Iterator for ReadDir { type Item = io::Result<DirEntry>; @@ -341,11 +380,13 @@ impl Iterator for ReadDir { } } +#[stable(feature = "rust1", since = "1.0.0")] impl DirEntry { /// Returns the full path to the file that this entry represents. /// /// The full path is created by joining the original path to `read_dir` or /// `walk_dir` with the filename of this entry. + #[stable(feature = "rust1", since = "1.0.0")] pub fn path(&self) -> PathBuf { self.0.path() } } @@ -368,31 +409,9 @@ impl DirEntry { /// This function will return an error if `path` points to a directory, if the /// user lacks permissions to remove the file, or if some other filesystem-level /// error occurs. +#[stable(feature = "rust1", since = "1.0.0")] pub fn remove_file<P: AsPath + ?Sized>(path: &P) -> io::Result<()> { - let path = path.as_path(); - let e = match fs_imp::unlink(path) { - Ok(()) => return Ok(()), - Err(e) => e, - }; - if !cfg!(windows) { return Err(e) } - - // On unix, a readonly file can be successfully removed. On windows, - // however, it cannot. To keep the two platforms in line with - // respect to their behavior, catch this case on windows, attempt to - // change it to read-write, and then remove the file. - if e.kind() != ErrorKind::PermissionDenied { return Err(e) } - - let attr = match metadata(path) { Ok(a) => a, Err(..) => return Err(e) }; - let mut perms = attr.permissions(); - if !perms.readonly() { return Err(e) } - perms.set_readonly(false); - - if set_permissions(path, perms).is_err() { return Err(e) } - if fs_imp::unlink(path).is_ok() { return Ok(()) } - - // Oops, try to put things back the way we found it - let _ = set_permissions(path, attr.permissions()); - Err(e) + fs_imp::unlink(path.as_path()) } /// Given a path, query the file system to get information about a file, @@ -418,6 +437,7 @@ pub fn remove_file<P: AsPath + ?Sized>(path: &P) -> io::Result<()> { /// This function will return an error if the user lacks the requisite /// permissions to perform a `metadata` call on the given `path` or if there /// is no entry in the filesystem at the provided path. +#[stable(feature = "rust1", since = "1.0.0")] pub fn metadata<P: AsPath + ?Sized>(path: &P) -> io::Result<Metadata> { fs_imp::stat(path.as_path()).map(Metadata) } @@ -438,6 +458,7 @@ pub fn metadata<P: AsPath + ?Sized>(path: &P) -> io::Result<Metadata> { /// the process lacks permissions to view the contents, if `from` and `to` /// reside on separate filesystems, or if some other intermittent I/O error /// occurs. +#[stable(feature = "rust1", since = "1.0.0")] pub fn rename<P: AsPath + ?Sized, Q: AsPath + ?Sized>(from: &P, to: &Q) -> io::Result<()> { fs_imp::rename(from.as_path(), to.as_path()) @@ -468,6 +489,7 @@ pub fn rename<P: AsPath + ?Sized, Q: AsPath + ?Sized>(from: &P, to: &Q) /// * The `from` file does not exist /// * The current process does not have the permission rights to access /// `from` or write `to` +#[stable(feature = "rust1", since = "1.0.0")] pub fn copy<P: AsPath + ?Sized, Q: AsPath + ?Sized>(from: &P, to: &Q) -> io::Result<u64> { let from = from.as_path(); @@ -490,6 +512,7 @@ pub fn copy<P: AsPath + ?Sized, Q: AsPath + ?Sized>(from: &P, to: &Q) /// /// The `dst` path will be a link pointing to the `src` path. Note that systems /// often require these two paths to both be located on the same filesystem. +#[stable(feature = "rust1", since = "1.0.0")] pub fn hard_link<P: AsPath + ?Sized, Q: AsPath + ?Sized>(src: &P, dst: &Q) -> io::Result<()> { fs_imp::link(src.as_path(), dst.as_path()) @@ -498,6 +521,7 @@ pub fn hard_link<P: AsPath + ?Sized, Q: AsPath + ?Sized>(src: &P, dst: &Q) /// Creates a new soft link on the filesystem. /// /// The `dst` path will be a soft link pointing to the `src` path. +#[stable(feature = "rust1", since = "1.0.0")] pub fn soft_link<P: AsPath + ?Sized, Q: AsPath + ?Sized>(src: &P, dst: &Q) -> io::Result<()> { fs_imp::symlink(src.as_path(), dst.as_path()) @@ -510,6 +534,7 @@ pub fn soft_link<P: AsPath + ?Sized, Q: AsPath + ?Sized>(src: &P, dst: &Q) /// This function will return an error on failure. Failure conditions include /// reading a file that does not exist or reading a file that is not a soft /// link. +#[stable(feature = "rust1", since = "1.0.0")] pub fn read_link<P: AsPath + ?Sized>(path: &P) -> io::Result<PathBuf> { fs_imp::readlink(path.as_path()) } @@ -528,6 +553,7 @@ pub fn read_link<P: AsPath + ?Sized>(path: &P) -> io::Result<PathBuf> { /// /// This function will return an error if the user lacks permissions to make a /// new directory at the provided `path`, or if the directory already exists. +#[stable(feature = "rust1", since = "1.0.0")] pub fn create_dir<P: AsPath + ?Sized>(path: &P) -> io::Result<()> { fs_imp::mkdir(path.as_path()) } @@ -541,6 +567,7 @@ pub fn create_dir<P: AsPath + ?Sized>(path: &P) -> io::Result<()> { /// does not already exist and it could not be created otherwise. The specific /// error conditions for when a directory is being created (after it is /// determined to not exist) are outlined by `fs::create_dir`. +#[stable(feature = "rust1", since = "1.0.0")] pub fn create_dir_all<P: AsPath + ?Sized>(path: &P) -> io::Result<()> { let path = path.as_path(); if path.is_dir() { return Ok(()) } @@ -572,6 +599,7 @@ pub fn create_dir_all<P: AsPath + ?Sized>(path: &P) -> io::Result<()> { /// /// This function will return an error if the user lacks permissions to remove /// the directory at the provided `path`, or if the directory isn't empty. +#[stable(feature = "rust1", since = "1.0.0")] pub fn remove_dir<P: AsPath + ?Sized>(path: &P) -> io::Result<()> { fs_imp::rmdir(path.as_path()) } @@ -585,6 +613,7 @@ pub fn remove_dir<P: AsPath + ?Sized>(path: &P) -> io::Result<()> { /// # Errors /// /// See `file::remove_file` and `fs::remove_dir` +#[stable(feature = "rust1", since = "1.0.0")] pub fn remove_dir_all<P: AsPath + ?Sized>(path: &P) -> io::Result<()> { let path = path.as_path(); for child in try!(read_dir(path)) { @@ -637,6 +666,7 @@ pub fn remove_dir_all<P: AsPath + ?Sized>(path: &P) -> io::Result<()> { /// This function will return an error if the provided `path` doesn't exist, if /// the process lacks permissions to view the contents or if the `path` points /// at a non-directory file +#[stable(feature = "rust1", since = "1.0.0")] pub fn read_dir<P: AsPath + ?Sized>(path: &P) -> io::Result<ReadDir> { fs_imp::readdir(path.as_path()).map(ReadDir) } @@ -649,11 +679,16 @@ pub fn read_dir<P: AsPath + ?Sized>(path: &P) -> io::Result<ReadDir> { /// /// The iterator will yield instances of `io::Result<DirEntry>`. New errors may /// be encountered after an iterator is initially constructed. +#[unstable(feature = "fs_walk", + reason = "the precise semantics and defaults for a recursive walk \ + may change and this may end up accounting for files such \ + as symlinks differently")] pub fn walk_dir<P: AsPath + ?Sized>(path: &P) -> io::Result<WalkDir> { let start = try!(read_dir(path)); Ok(WalkDir { cur: Some(start), stack: Vec::new() }) } +#[unstable(feature = "fs_walk")] impl Iterator for WalkDir { type Item = io::Result<DirEntry>; @@ -683,6 +718,9 @@ impl Iterator for WalkDir { } /// Utility methods for paths. +#[unstable(feature = "path_ext", + reason = "the precise set of methods exposed on this trait may \ + change and some methods may be removed")] pub trait PathExt { /// Get information on the file, directory, etc at this path. /// @@ -727,6 +765,10 @@ impl PathExt for Path { /// The file at the path specified will have its last access time set to /// `atime` and its modification time set to `mtime`. The times specified should /// be in milliseconds. +#[unstable(feature = "fs_time", + reason = "the argument type of u64 is not quite appropriate for \ + this function and may change if the standard library \ + gains a type to represent a moment in time")] pub fn set_file_times<P: AsPath + ?Sized>(path: &P, accessed: u64, modified: u64) -> io::Result<()> { fs_imp::utimes(path.as_path(), accessed, modified) @@ -752,6 +794,10 @@ pub fn set_file_times<P: AsPath + ?Sized>(path: &P, accessed: u64, /// This function will return an error if the provided `path` doesn't exist, if /// the process lacks permissions to change the attributes of the file, or if /// some other I/O error is encountered. +#[unstable(feature = "fs", + reason = "a more granual ability to set specific permissions may \ + be exposed on the Permissions structure itself and this \ + method may not always exist")] pub fn set_permissions<P: AsPath + ?Sized>(path: &P, perm: Permissions) -> io::Result<()> { fs_imp::set_perm(path.as_path(), perm.0) @@ -782,7 +828,7 @@ mod tests { 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)) } ) } @@ -834,7 +880,7 @@ mod tests { -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)); } @@ -1053,7 +1099,7 @@ mod tests { check!(w.write(msg)); } let files = check!(fs::read_dir(dir)); - let mut mem = [0u8; 4]; + let mut mem = [0; 4]; for f in files { let f = f.unwrap().path(); { @@ -1061,7 +1107,7 @@ mod tests { 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)); } @@ -1083,7 +1129,7 @@ mod tests { check!(File::create(&dir2.join("14"))); let files = check!(fs::walk_dir(dir)); - let mut cur = [0u8; 2]; + let mut cur = [0; 2]; for f in files { let f = f.unwrap().path(); let stem = f.file_stem().unwrap().to_str().unwrap(); @@ -1267,6 +1313,8 @@ mod tests { check!(fs::set_permissions(&input, p)); check!(fs::copy(&input, &out)); assert!(check!(out.metadata()).permissions().readonly()); + check!(fs::set_permissions(&input, attr.permissions())); + check!(fs::set_permissions(&out, attr.permissions())); } #[cfg(not(windows))] // FIXME(#10264) operation not permitted? @@ -1350,10 +1398,13 @@ mod tests { let attr = check!(fs::metadata(&file)); assert!(attr.permissions().readonly()); - match fs::set_permissions(&tmpdir.join("foo"), p) { - Ok(..) => panic!("wanted a panic"), + match fs::set_permissions(&tmpdir.join("foo"), p.clone()) { + Ok(..) => panic!("wanted an error"), Err(..) => {} } + + p.set_readonly(false); + check!(fs::set_permissions(&file, p)); } #[test] @@ -1506,6 +1557,7 @@ mod tests { } #[test] + #[cfg(not(windows))] fn unlink_readonly() { let tmpdir = tmpdir(); let path = tmpdir.join("file"); diff --git a/src/libstd/fs/tempdir.rs b/src/libstd/fs/tempdir.rs index 79bdb35dd48..c1da77a6668 100644 --- a/src/libstd/fs/tempdir.rs +++ b/src/libstd/fs/tempdir.rs @@ -9,6 +9,9 @@ // except according to those terms. #![unstable(feature = "tempdir", reason = "needs an RFC before stabilization")] +#![deprecated(since = "1.0.0", + reason = "use the `tempdir` crate from crates.io instead")] +#![allow(deprecated)] use prelude::v1::*; diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs index 11356099590..3603f127504 100644 --- a/src/libstd/io/buffered.rs +++ b/src/libstd/io/buffered.rs @@ -616,14 +616,14 @@ mod tests { #[test] fn read_char_buffered() { - let buf = [195u8, 159u8]; + let buf = [195, 159]; let reader = BufReader::with_capacity(1, &buf[..]); assert_eq!(reader.chars().next(), Some(Ok('ß'))); } #[test] fn test_chars() { - let buf = [195u8, 159u8, b'a']; + let buf = [195, 159, b'a']; let reader = BufReader::with_capacity(1, &buf[..]); let mut it = reader.chars(); assert_eq!(it.next(), Some(Ok('ß'))); diff --git a/src/libstd/io/cursor.rs b/src/libstd/io/cursor.rs index b1779587528..2445f5a7a40 100644 --- a/src/libstd/io/cursor.rs +++ b/src/libstd/io/cursor.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![allow(missing_copy_implementations)] - use prelude::v1::*; use io::prelude::*; @@ -32,6 +30,7 @@ use slice; /// Implementations of the I/O traits for `Cursor<T>` are not currently generic /// over `T` itself. Instead, specific implementations are provided for various /// in-memory buffer types like `Vec<u8>` and `&[u8]`. +#[stable(feature = "rust1", since = "1.0.0")] pub struct Cursor<T> { inner: T, pos: u64, @@ -39,26 +38,32 @@ pub struct Cursor<T> { impl<T> Cursor<T> { /// Create a new cursor wrapping the provided underlying I/O object. + #[stable(feature = "rust1", since = "1.0.0")] pub fn new(inner: T) -> Cursor<T> { Cursor { pos: 0, inner: inner } } /// Consume this cursor, returning the underlying value. + #[stable(feature = "rust1", since = "1.0.0")] pub fn into_inner(self) -> T { self.inner } /// Get a reference to the underlying value in this cursor. + #[stable(feature = "rust1", since = "1.0.0")] pub fn get_ref(&self) -> &T { &self.inner } /// Get a mutable reference to the underlying value in this cursor. /// /// Care should be taken to avoid modifying the internal I/O state of the /// underlying value as it may corrupt this cursor's position. + #[stable(feature = "rust1", since = "1.0.0")] pub fn get_mut(&mut self) -> &mut T { &mut self.inner } /// Returns the current value of this cursor + #[stable(feature = "rust1", since = "1.0.0")] pub fn position(&self) -> u64 { self.pos } /// Sets the value of this cursor + #[stable(feature = "rust1", since = "1.0.0")] pub fn set_position(&mut self, pos: u64) { self.pos = pos; } } @@ -83,8 +88,11 @@ macro_rules! seek { } } +#[stable(feature = "rust1", since = "1.0.0")] impl<'a> io::Seek for Cursor<&'a [u8]> { seek!(); } +#[stable(feature = "rust1", since = "1.0.0")] impl<'a> io::Seek for Cursor<&'a mut [u8]> { seek!(); } +#[stable(feature = "rust1", since = "1.0.0")] impl io::Seek for Cursor<Vec<u8>> { seek!(); } macro_rules! read { @@ -97,8 +105,11 @@ macro_rules! read { } } +#[stable(feature = "rust1", since = "1.0.0")] impl<'a> Read for Cursor<&'a [u8]> { read!(); } +#[stable(feature = "rust1", since = "1.0.0")] impl<'a> Read for Cursor<&'a mut [u8]> { read!(); } +#[stable(feature = "rust1", since = "1.0.0")] impl Read for Cursor<Vec<u8>> { read!(); } macro_rules! buffer { @@ -111,10 +122,14 @@ macro_rules! buffer { } } +#[stable(feature = "rust1", since = "1.0.0")] impl<'a> BufRead for Cursor<&'a [u8]> { buffer!(); } +#[stable(feature = "rust1", since = "1.0.0")] impl<'a> BufRead for Cursor<&'a mut [u8]> { buffer!(); } +#[stable(feature = "rust1", since = "1.0.0")] impl<'a> BufRead for Cursor<Vec<u8>> { buffer!(); } +#[stable(feature = "rust1", since = "1.0.0")] impl<'a> Write for Cursor<&'a mut [u8]> { fn write(&mut self, data: &[u8]) -> io::Result<usize> { let pos = cmp::min(self.pos, self.inner.len() as u64); @@ -125,6 +140,7 @@ impl<'a> Write for Cursor<&'a mut [u8]> { fn flush(&mut self) -> io::Result<()> { Ok(()) } } +#[stable(feature = "rust1", since = "1.0.0")] impl Write for Cursor<Vec<u8>> { fn write(&mut self, buf: &[u8]) -> io::Result<usize> { // Make sure the internal buffer is as least as big as where we @@ -237,7 +253,7 @@ mod tests { #[test] fn test_mem_reader() { - let mut reader = Cursor::new(vec!(0u8, 1, 2, 3, 4, 5, 6, 7)); + let mut reader = Cursor::new(vec!(0, 1, 2, 3, 4, 5, 6, 7)); let mut buf = []; assert_eq!(reader.read(&mut buf), Ok(0)); assert_eq!(reader.position(), 0); @@ -259,7 +275,7 @@ mod tests { #[test] fn read_to_end() { - let mut reader = Cursor::new(vec!(0u8, 1, 2, 3, 4, 5, 6, 7)); + let mut reader = Cursor::new(vec!(0, 1, 2, 3, 4, 5, 6, 7)); let mut v = Vec::new(); reader.read_to_end(&mut v).ok().unwrap(); assert_eq!(v, [0, 1, 2, 3, 4, 5, 6, 7]); @@ -267,7 +283,7 @@ mod tests { #[test] fn test_slice_reader() { - let in_buf = vec![0u8, 1, 2, 3, 4, 5, 6, 7]; + let in_buf = vec![0, 1, 2, 3, 4, 5, 6, 7]; let mut reader = &mut in_buf.as_slice(); let mut buf = []; assert_eq!(reader.read(&mut buf), Ok(0)); @@ -289,7 +305,7 @@ mod tests { #[test] fn test_buf_reader() { - let in_buf = vec![0u8, 1, 2, 3, 4, 5, 6, 7]; + let in_buf = vec![0, 1, 2, 3, 4, 5, 6, 7]; let mut reader = Cursor::new(in_buf.as_slice()); let mut buf = []; assert_eq!(reader.read(&mut buf), Ok(0)); @@ -335,7 +351,7 @@ mod tests { assert_eq!(r.seek(SeekFrom::Start(10)), Ok(10)); assert_eq!(r.read(&mut [0]), Ok(0)); - let mut r = Cursor::new(vec!(10u8)); + let mut r = Cursor::new(vec!(10)); assert_eq!(r.seek(SeekFrom::Start(10)), Ok(10)); assert_eq!(r.read(&mut [0]), Ok(0)); @@ -347,11 +363,11 @@ mod tests { #[test] fn seek_before_0() { - let buf = [0xff_u8]; + let buf = [0xff]; let mut r = Cursor::new(&buf[..]); assert!(r.seek(SeekFrom::End(-2)).is_err()); - let mut r = Cursor::new(vec!(10u8)); + let mut r = Cursor::new(vec!(10)); assert!(r.seek(SeekFrom::End(-2)).is_err()); let mut buf = [0]; diff --git a/src/libstd/io/impls.rs b/src/libstd/io/impls.rs index 82b69ddebff..c968415d3ef 100644 --- a/src/libstd/io/impls.rs +++ b/src/libstd/io/impls.rs @@ -22,57 +22,88 @@ use vec::Vec; // ============================================================================= // Forwarding implementations +#[stable(feature = "rust1", since = "1.0.0")] impl<'a, R: Read + ?Sized> Read for &'a mut R { - fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { (**self).read(buf) } - - fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<()> { (**self).read_to_end(buf) } - + fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { + (**self).read(buf) + } + fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<()> { + (**self).read_to_end(buf) + } fn read_to_string(&mut self, buf: &mut String) -> io::Result<()> { (**self).read_to_string(buf) } } +#[stable(feature = "rust1", since = "1.0.0")] impl<'a, W: Write + ?Sized> Write for &'a mut W { fn write(&mut self, buf: &[u8]) -> io::Result<usize> { (**self).write(buf) } - - fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { (**self).write_all(buf) } - - fn write_fmt(&mut self, fmt: fmt::Arguments) -> io::Result<()> { (**self).write_fmt(fmt) } - fn flush(&mut self) -> io::Result<()> { (**self).flush() } + fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { + (**self).write_all(buf) + } + fn write_fmt(&mut self, fmt: fmt::Arguments) -> io::Result<()> { + (**self).write_fmt(fmt) + } } +#[stable(feature = "rust1", since = "1.0.0")] impl<'a, S: Seek + ?Sized> Seek for &'a mut S { fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> { (**self).seek(pos) } } +#[stable(feature = "rust1", since = "1.0.0")] impl<'a, B: BufRead + ?Sized> BufRead for &'a mut B { fn fill_buf(&mut self) -> io::Result<&[u8]> { (**self).fill_buf() } - fn consume(&mut self, amt: usize) { (**self).consume(amt) } - fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> io::Result<()> { (**self).read_until(byte, buf) } - - fn read_line(&mut self, buf: &mut String) -> io::Result<()> { (**self).read_line(buf) } + fn read_line(&mut self, buf: &mut String) -> io::Result<()> { + (**self).read_line(buf) + } } +#[stable(feature = "rust1", since = "1.0.0")] impl<R: Read + ?Sized> Read for Box<R> { - fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { (**self).read(buf) } + fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { + (**self).read(buf) + } + fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<()> { + (**self).read_to_end(buf) + } + fn read_to_string(&mut self, buf: &mut String) -> io::Result<()> { + (**self).read_to_string(buf) + } } +#[stable(feature = "rust1", since = "1.0.0")] impl<W: Write + ?Sized> Write for Box<W> { fn write(&mut self, buf: &[u8]) -> io::Result<usize> { (**self).write(buf) } fn flush(&mut self) -> io::Result<()> { (**self).flush() } + fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { + (**self).write_all(buf) + } + fn write_fmt(&mut self, fmt: fmt::Arguments) -> io::Result<()> { + (**self).write_fmt(fmt) + } } +#[stable(feature = "rust1", since = "1.0.0")] impl<S: Seek + ?Sized> Seek for Box<S> { fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> { (**self).seek(pos) } } +#[stable(feature = "rust1", since = "1.0.0")] impl<B: BufRead + ?Sized> BufRead for Box<B> { fn fill_buf(&mut self) -> io::Result<&[u8]> { (**self).fill_buf() } fn consume(&mut self, amt: usize) { (**self).consume(amt) } + fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> io::Result<()> { + (**self).read_until(byte, buf) + } + fn read_line(&mut self, buf: &mut String) -> io::Result<()> { + (**self).read_line(buf) + } } // ============================================================================= // In-memory buffer implementations +#[stable(feature = "rust1", since = "1.0.0")] impl<'a> Read for &'a [u8] { fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { let amt = cmp::min(buf.len(), self.len()); @@ -83,11 +114,13 @@ impl<'a> Read for &'a [u8] { } } +#[stable(feature = "rust1", since = "1.0.0")] impl<'a> BufRead for &'a [u8] { fn fill_buf(&mut self) -> io::Result<&[u8]> { Ok(*self) } fn consume(&mut self, amt: usize) { *self = &self[amt..]; } } +#[stable(feature = "rust1", since = "1.0.0")] impl<'a> Write for &'a mut [u8] { fn write(&mut self, data: &[u8]) -> io::Result<usize> { let amt = cmp::min(data.len(), self.len()); @@ -108,6 +141,7 @@ impl<'a> Write for &'a mut [u8] { fn flush(&mut self) -> io::Result<()> { Ok(()) } } +#[stable(feature = "rust1", since = "1.0.0")] impl Write for Vec<u8> { fn write(&mut self, buf: &[u8]) -> io::Result<usize> { self.push_all(buf); @@ -115,7 +149,7 @@ impl Write for Vec<u8> { } fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { - try!(self.write(buf)); + self.push_all(buf); Ok(()) } diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index 5510c0203e6..9137068076b 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -237,11 +237,13 @@ pub trait Read { /// Extension methods for all instances of `Read`, typically imported through /// `std::io::prelude::*`. +#[unstable(feature = "io", reason = "may merge into the Read trait")] pub trait ReadExt: Read + Sized { /// Create a "by reference" adaptor for this instance of `Read`. /// /// The returned adaptor also implements `Read` and will simply borrow this /// current reader. + #[stable(feature = "rust1", since = "1.0.0")] fn by_ref(&mut self) -> &mut Self { self } /// Transform this `Read` instance to an `Iterator` over its bytes. @@ -250,6 +252,7 @@ pub trait ReadExt: Read + Sized { /// R::Err>`. The yielded item is `Ok` if a byte was successfully read and /// `Err` otherwise for I/O errors. EOF is mapped to returning `None` from /// this iterator. + #[stable(feature = "rust1", since = "1.0.0")] fn bytes(self) -> Bytes<Self> { Bytes { inner: self } } @@ -264,6 +267,9 @@ pub trait ReadExt: Read + Sized { /// /// Currently this adaptor will discard intermediate data read, and should /// be avoided if this is not desired. + #[unstable(feature = "io", reason = "the semantics of a partial read/write \ + of where errors happen is currently \ + unclear and may change")] fn chars(self) -> Chars<Self> { Chars { inner: self } } @@ -273,6 +279,7 @@ pub trait ReadExt: Read + Sized { /// The returned `Read` instance will first read all bytes from this object /// until EOF is encountered. Afterwards the output is equivalent to the /// output of `next`. + #[stable(feature = "rust1", since = "1.0.0")] fn chain<R: Read>(self, next: R) -> Chain<Self, R> { Chain { first: self, second: next, done_first: false } } @@ -283,6 +290,7 @@ pub trait ReadExt: Read + Sized { /// `limit` bytes, after which it will always return EOF (`Ok(0)`). Any /// read errors will not count towards the number of bytes read and future /// calls to `read` may succeed. + #[stable(feature = "rust1", since = "1.0.0")] fn take(self, limit: u64) -> Take<Self> { Take { inner: self, limit: limit } } @@ -293,6 +301,9 @@ pub trait ReadExt: Read + Sized { /// Whenever the returned `Read` instance is read it will write the read /// data to `out`. The current semantics of this implementation imply that /// a `write` error will not report how much data was initially read. + #[unstable(feature = "io", reason = "the semantics of a partial read/write \ + of where errors happen is currently \ + unclear and may change")] fn tee<W: Write>(self, out: W) -> Tee<Self, W> { Tee { reader: self, writer: out } } @@ -415,11 +426,13 @@ pub trait Write { /// Extension methods for all instances of `Write`, typically imported through /// `std::io::prelude::*`. +#[unstable(feature = "io", reason = "may merge into the Read trait")] pub trait WriteExt: Write + Sized { /// Create a "by reference" adaptor for this instance of `Write`. /// /// The returned adaptor also implements `Write` and will simply borrow this /// current writer. + #[stable(feature = "rust1", since = "1.0.0")] fn by_ref(&mut self) -> &mut Self { self } /// Creates a new writer which will write all data to both this writer and @@ -430,11 +443,15 @@ pub trait WriteExt: Write + Sized { /// implementation do not precisely track where errors happen. For example /// an error on the second call to `write` will not report that the first /// call to `write` succeeded. + #[unstable(feature = "io", reason = "the semantics of a partial read/write \ + of where errors happen is currently \ + unclear and may change")] fn broadcast<W: Write>(self, other: W) -> Broadcast<Self, W> { Broadcast { first: self, second: other } } } +#[stable(feature = "rust1", since = "1.0.0")] impl<T: Write> WriteExt for T {} /// An object implementing `Seek` internally has some form of cursor which can @@ -592,6 +609,8 @@ pub trait BufReadExt: BufRead + Sized { /// /// This function will yield errors whenever `read_until` would have also /// yielded an error. + #[unstable(feature = "io", reason = "may be renamed to not conflict with \ + SliceExt::split")] fn split(self, byte: u8) -> Split<Self> { Split { buf: self, delim: byte } } @@ -604,11 +623,13 @@ pub trait BufReadExt: BufRead + Sized { /// /// This function will yield errors whenever `read_string` would have also /// yielded an error. + #[stable(feature = "rust1", since = "1.0.0")] fn lines(self) -> Lines<Self> { Lines { buf: self } } } +#[stable(feature = "rust1", since = "1.0.0")] impl<T: BufRead> BufReadExt for T {} /// A `Write` adaptor which will write data to multiple locations. @@ -635,12 +656,14 @@ impl<T: Write, U: Write> Write for Broadcast<T, U> { /// Adaptor to chain together two instances of `Read`. /// /// For more information, see `ReadExt::chain`. +#[stable(feature = "rust1", since = "1.0.0")] pub struct Chain<T, U> { first: T, second: U, done_first: bool, } +#[stable(feature = "rust1", since = "1.0.0")] impl<T: Read, U: Read> Read for Chain<T, U> { fn read(&mut self, buf: &mut [u8]) -> Result<usize> { if !self.done_first { @@ -656,11 +679,13 @@ impl<T: Read, U: Read> Read for Chain<T, U> { /// Reader adaptor which limits the bytes read from an underlying reader. /// /// For more information, see `ReadExt::take`. +#[stable(feature = "rust1", since = "1.0.0")] pub struct Take<T> { inner: T, limit: u64, } +#[stable(feature = "rust1", since = "1.0.0")] impl<T> Take<T> { /// Returns the number of bytes that can be read before this instance will /// return EOF. @@ -669,9 +694,11 @@ impl<T> Take<T> { /// /// This instance may reach EOF after reading fewer bytes than indicated by /// this method if the underlying `Read` instance reaches EOF. + #[stable(feature = "rust1", since = "1.0.0")] pub fn limit(&self) -> u64 { self.limit } } +#[stable(feature = "rust1", since = "1.0.0")] impl<T: Read> Read for Take<T> { fn read(&mut self, buf: &mut [u8]) -> Result<usize> { // Don't call into inner reader at all at EOF because it may still block @@ -686,6 +713,7 @@ impl<T: Read> Read for Take<T> { } } +#[stable(feature = "rust1", since = "1.0.0")] impl<T: BufRead> BufRead for Take<T> { fn fill_buf(&mut self) -> Result<&[u8]> { let buf = try!(self.inner.fill_buf()); @@ -721,10 +749,12 @@ impl<R: Read, W: Write> Read for Tee<R, W> { /// A bridge from implementations of `Read` to an `Iterator` of `u8`. /// /// See `ReadExt::bytes` for more information. +#[stable(feature = "rust1", since = "1.0.0")] pub struct Bytes<R> { inner: R, } +#[stable(feature = "rust1", since = "1.0.0")] impl<R: Read> Iterator for Bytes<R> { type Item = Result<u8>; @@ -845,10 +875,12 @@ impl<B: BufRead> Iterator for Split<B> { /// byte. /// /// See `BufReadExt::lines` for more information. +#[stable(feature = "rust1", since = "1.0.0")] pub struct Lines<B> { buf: B, } +#[stable(feature = "rust1", since = "1.0.0")] impl<B: BufRead> Iterator for Lines<B> { type Item = Result<String>; @@ -975,7 +1007,7 @@ mod tests { struct R; impl Read for R { - fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { + fn read(&mut self, _: &mut [u8]) -> io::Result<usize> { Err(io::Error::new(io::ErrorKind::Other, "", None)) } } diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs index 61ad9905771..4027f741654 100644 --- a/src/libstd/io/stdio.rs +++ b/src/libstd/io/stdio.rs @@ -157,9 +157,6 @@ impl Read for Stdin { impl<'a> Read for StdinLock<'a> { fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { - // Flush stdout so that weird issues like a print!'d prompt not being - // shown until after the user hits enter. - drop(stdout().flush()); self.inner.read(buf) } } diff --git a/src/libstd/io/util.rs b/src/libstd/io/util.rs index 3d342137c62..20426025257 100644 --- a/src/libstd/io/util.rs +++ b/src/libstd/io/util.rs @@ -12,7 +12,7 @@ use prelude::v1::*; -use io::{self, Read, Write, ErrorKind}; +use io::{self, Read, Write, ErrorKind, BufRead}; /// Copies the entire contents of a reader into a writer. /// @@ -27,6 +27,7 @@ use io::{self, Read, Write, ErrorKind}; /// This function will return an error immediately if any call to `read` or /// `write` returns an error. All instances of `ErrorKind::Interrupted` are /// handled by this function and the underlying operation is retried. +#[stable(feature = "rust1", since = "1.0.0")] pub fn copy<R: Read, W: Write>(r: &mut R, w: &mut W) -> io::Result<u64> { let mut buf = [0; super::DEFAULT_BUF_SIZE]; let mut written = 0; @@ -43,26 +44,37 @@ pub fn copy<R: Read, W: Write>(r: &mut R, w: &mut W) -> io::Result<u64> { } /// A reader which is always at EOF. +#[stable(feature = "rust1", since = "1.0.0")] pub struct Empty { _priv: () } /// Creates an instance of an empty reader. /// /// All reads from the returned reader will return `Ok(0)`. +#[stable(feature = "rust1", since = "1.0.0")] pub fn empty() -> Empty { Empty { _priv: () } } +#[stable(feature = "rust1", since = "1.0.0")] impl Read for Empty { fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> { Ok(0) } } +#[stable(feature = "rust1", since = "1.0.0")] +impl BufRead for Empty { + fn fill_buf(&mut self) -> io::Result<&[u8]> { Ok(&[]) } + fn consume(&mut self, _n: usize) {} +} /// A reader which infinitely yields one byte. +#[stable(feature = "rust1", since = "1.0.0")] pub struct Repeat { byte: u8 } /// Creates an instance of a reader that infinitely repeats one byte. /// /// All reads from this reader will succeed by filling the specified buffer with /// the given byte. +#[stable(feature = "rust1", since = "1.0.0")] pub fn repeat(byte: u8) -> Repeat { Repeat { byte: byte } } +#[stable(feature = "rust1", since = "1.0.0")] impl Read for Repeat { fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { for slot in buf.iter_mut() { @@ -73,14 +85,17 @@ impl Read for Repeat { } /// A writer which will move data into the void. +#[stable(feature = "rust1", since = "1.0.0")] pub struct Sink { _priv: () } /// Creates an instance of a writer which will successfully consume all data. /// /// All calls to `write` on the returned instance will return `Ok(buf.len())` /// and the contents of the buffer will not be inspected. +#[stable(feature = "rust1", since = "1.0.0")] pub fn sink() -> Sink { Sink { _priv: () } } +#[stable(feature = "rust1", since = "1.0.0")] impl Write for Sink { fn write(&mut self, buf: &[u8]) -> io::Result<usize> { Ok(buf.len()) } fn flush(&mut self) -> io::Result<()> { Ok(()) } diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index c890af631f0..ce14967090e 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -94,7 +94,8 @@ //! to all code by default. [`macros`](macros/index.html) contains //! all the standard macros, such as `assert!`, `panic!`, `println!`, //! and `format!`, also available to all Rust code. - +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "std"] #![stable(feature = "rust1", since = "1.0.0")] #![staged_api] @@ -125,7 +126,8 @@ #![feature(hash)] #![feature(int_uint)] #![feature(unique)] -#![cfg_attr(test, feature(test, rustc_private, env))] +#![feature(allow_internal_unstable)] +#![cfg_attr(test, feature(test, rustc_private))] // Don't link to std. We are std. #![feature(no_std)] diff --git a/src/libstd/net/addr.rs b/src/libstd/net/addr.rs index f16f501c46a..101aae3eb24 100644 --- a/src/libstd/net/addr.rs +++ b/src/libstd/net/addr.rs @@ -293,7 +293,7 @@ impl ToSocketAddrs for str { } // split the string by ':' and convert the second part to u16 - let mut parts_iter = self.rsplitn(2, ':'); + let mut parts_iter = self.rsplitn(1, ':'); let port_str = try_opt!(parts_iter.next(), "invalid socket address"); let host = try_opt!(parts_iter.next(), "invalid socket address"); let port: u16 = try_opt!(port_str.parse().ok(), "invalid port value"); @@ -562,7 +562,7 @@ mod tests { #[test] fn to_socket_addr_ipaddr_u16() { let a = IpAddr::new_v4(77, 88, 21, 11); - let p = 12345u16; + let p = 12345; let e = SocketAddr::new(a, p); assert_eq!(Ok(vec![e]), tsa((a, p))); } @@ -570,13 +570,13 @@ mod tests { #[test] fn to_socket_addr_str_u16() { let a = SocketAddr::new(IpAddr::new_v4(77, 88, 21, 11), 24352); - assert_eq!(Ok(vec![a]), tsa(("77.88.21.11", 24352u16))); + assert_eq!(Ok(vec![a]), tsa(("77.88.21.11", 24352))); let a = SocketAddr::new(IpAddr::new_v6(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), 53); assert_eq!(Ok(vec![a]), tsa(("2a02:6b8:0:1::1", 53))); let a = SocketAddr::new(IpAddr::new_v4(127, 0, 0, 1), 23924); - assert!(tsa(("localhost", 23924u16)).unwrap().contains(&a)); + assert!(tsa(("localhost", 23924)).unwrap().contains(&a)); } #[test] @@ -590,4 +590,10 @@ mod tests { let a = SocketAddr::new(IpAddr::new_v4(127, 0, 0, 1), 23924); assert!(tsa("localhost:23924").unwrap().contains(&a)); } + + #[test] + #[cfg(not(windows))] + fn to_socket_addr_str_bad() { + assert!(tsa("1200::AB00:1234::2552:7777:1313:34300").is_err()); + } } diff --git a/src/libstd/net/parser.rs b/src/libstd/net/parser.rs index e82dc88cddd..aa54a432d62 100644 --- a/src/libstd/net/parser.rs +++ b/src/libstd/net/parser.rs @@ -136,7 +136,7 @@ impl<'a> Parser<'a> { } fn read_number_impl(&mut self, radix: u8, max_digits: u32, upto: u32) -> Option<u32> { - let mut r = 0u32; + let mut r = 0; let mut digit_count = 0; loop { match self.read_digit(radix) { @@ -164,7 +164,7 @@ impl<'a> Parser<'a> { } fn read_ipv4_addr_impl(&mut self) -> Option<Ipv4Addr> { - let mut bs = [0u8; 4]; + let mut bs = [0; 4]; let mut i = 0; while i < 4 { if i != 0 && self.read_given_char('.').is_none() { @@ -189,7 +189,7 @@ impl<'a> Parser<'a> { fn read_ipv6_addr_impl(&mut self) -> Option<Ipv6Addr> { fn ipv6_addr_from_head_tail(head: &[u16], tail: &[u16]) -> Ipv6Addr { assert!(head.len() + tail.len() <= 8); - let mut gs = [0u16; 8]; + let mut gs = [0; 8]; gs.clone_from_slice(head); gs[(8 - tail.len()) .. 8].clone_from_slice(tail); Ipv6Addr::new(gs[0], gs[1], gs[2], gs[3], gs[4], gs[5], gs[6], gs[7]) @@ -231,7 +231,7 @@ impl<'a> Parser<'a> { (i, false) } - let mut head = [0u16; 8]; + let mut head = [0; 8]; let (head_size, head_ipv4) = read_groups(self, &mut head, 8); if head_size == 8 { @@ -250,7 +250,7 @@ impl<'a> Parser<'a> { return None; } - let mut tail = [0u16; 8]; + let mut tail = [0; 8]; let (tail_size, _) = read_groups(self, &mut tail, 8 - head_size); Some(ipv6_addr_from_head_tail(&head[..head_size], &tail[..tail_size])) } diff --git a/src/libstd/net/tcp.rs b/src/libstd/net/tcp.rs index 6ce3a939c6a..fd723ea13e9 100644 --- a/src/libstd/net/tcp.rs +++ b/src/libstd/net/tcp.rs @@ -233,13 +233,13 @@ mod tests { } } - // FIXME #11530 this fails on android because tests are run as root - #[cfg_attr(any(windows, target_os = "android"), ignore)] #[test] fn bind_error() { - match TcpListener::bind("0.0.0.0:1") { + match TcpListener::bind("1.1.1.1:9999") { Ok(..) => panic!(), - Err(e) => assert_eq!(e.kind(), ErrorKind::PermissionDenied), + Err(e) => + // EADDRNOTAVAIL is mapped to ConnectionRefused + assert_eq!(e.kind(), ErrorKind::ConnectionRefused), } } diff --git a/src/libstd/num/f32.rs b/src/libstd/num/f32.rs index 7d15a16309e..969dd35ba22 100644 --- a/src/libstd/num/f32.rs +++ b/src/libstd/num/f32.rs @@ -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. // @@ -469,6 +469,11 @@ mod tests { 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); assert_eq!(2.0f32.min(NAN), 2.0); @@ -481,8 +486,163 @@ mod tests { } #[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] @@ -556,6 +716,140 @@ mod tests { } #[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()); assert_approx_eq!(2.718282, 1.0f32.exp()); @@ -583,6 +877,172 @@ mod tests { } #[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); assert_eq!((-0.0f32).asinh(), -0.0f32); @@ -674,174 +1134,4 @@ mod tests { 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(), (13176795u64, -22i16, 1i8)); - assert_eq!((-8573.5918555f32).integer_decode(), (8779358u64, -10i16, -1i8)); - assert_eq!(2f32.powf(100.0).integer_decode(), (8388608u64, 77i16, 1i8)); - assert_eq!(0f32.integer_decode(), (0u64, -150i16, 1i8)); - assert_eq!((-0f32).integer_decode(), (0u64, -150i16, -1i8)); - assert_eq!(INFINITY.integer_decode(), (8388608u64, 105i16, 1i8)); - assert_eq!(NEG_INFINITY.integer_decode(), (8388608u64, 105i16, -1i8)); - assert_eq!(NAN.integer_decode(), (12582912u64, 105i16, 1i8)); - } - - #[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); - } } diff --git a/src/libstd/num/f64.rs b/src/libstd/num/f64.rs index 0ce56371c77..95065b59678 100644 --- a/src/libstd/num/f64.rs +++ b/src/libstd/num/f64.rs @@ -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. // @@ -478,6 +478,11 @@ mod tests { 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); assert_eq!(2.0f64.min(NAN), 2.0); @@ -490,8 +495,162 @@ mod tests { } #[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] @@ -565,6 +724,140 @@ mod tests { } #[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()); assert_approx_eq!(2.718282, 1.0f64.exp()); @@ -592,6 +885,172 @@ mod tests { } #[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); assert_eq!((-0.0f64).asinh(), -0.0f64); @@ -677,173 +1136,4 @@ mod tests { 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(), (7074237752028906u64, -51i16, 1i8)); - assert_eq!((-8573.5918555f64).integer_decode(), (4713381968463931u64, -39i16, -1i8)); - assert_eq!(2f64.powf(100.0).integer_decode(), (4503599627370496u64, 48i16, 1i8)); - assert_eq!(0f64.integer_decode(), (0u64, -1075i16, 1i8)); - assert_eq!((-0f64).integer_decode(), (0u64, -1075i16, -1i8)); - assert_eq!(INFINITY.integer_decode(), (4503599627370496u64, 972i16, 1i8)); - assert_eq!(NEG_INFINITY.integer_decode(), (4503599627370496, 972, -1)); - assert_eq!(NAN.integer_decode(), (6755399441055744u64, 972i16, 1i8)); - } - - #[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); - } } diff --git a/src/libstd/num/mod.rs b/src/libstd/num/mod.rs index 0bca60ed1a0..35d973d2d4e 100644 --- a/src/libstd/num/mod.rs +++ b/src/libstd/num/mod.rs @@ -312,7 +312,7 @@ pub trait Float /// /// let num = 2.0f32; /// - /// // (8388608u64, -22i16, 1i8) + /// // (8388608, -22, 1) /// let (mantissa, exponent, sign) = num.integer_decode(); /// let sign_f = sign as f32; /// let mantissa_f = mantissa as f32; @@ -1633,7 +1633,7 @@ mod tests { assert_eq!((3 as $T).is_power_of_two(), false); assert_eq!((4 as $T).is_power_of_two(), true); assert_eq!((5 as $T).is_power_of_two(), false); - assert!(($T::MAX / 2 + 1).is_power_of_two(), true); + assert_eq!(($T::MAX / 2 + 1).is_power_of_two(), true); } ) } @@ -1755,25 +1755,25 @@ mod tests { #[test] fn test_uint_to_str_overflow() { - let mut u8_val: u8 = 255_u8; + let mut u8_val: u8 = 255; assert_eq!(u8_val.to_string(), "255"); u8_val = u8_val.wrapping_add(1); assert_eq!(u8_val.to_string(), "0"); - let mut u16_val: u16 = 65_535_u16; + let mut u16_val: u16 = 65_535; assert_eq!(u16_val.to_string(), "65535"); u16_val = u16_val.wrapping_add(1); assert_eq!(u16_val.to_string(), "0"); - let mut u32_val: u32 = 4_294_967_295_u32; + let mut u32_val: u32 = 4_294_967_295; assert_eq!(u32_val.to_string(), "4294967295"); u32_val = u32_val.wrapping_add(1); assert_eq!(u32_val.to_string(), "0"); - let mut u64_val: u64 = 18_446_744_073_709_551_615_u64; + let mut u64_val: u64 = 18_446_744_073_709_551_615; assert_eq!(u64_val.to_string(), "18446744073709551615"); u64_val = u64_val.wrapping_add(1); @@ -1786,7 +1786,7 @@ mod tests { #[test] fn test_uint_from_str_overflow() { - let mut u8_val: u8 = 255_u8; + let mut u8_val: u8 = 255; assert_eq!(from_str::<u8>("255"), Some(u8_val)); assert_eq!(from_str::<u8>("256"), None); @@ -1794,7 +1794,7 @@ mod tests { assert_eq!(from_str::<u8>("0"), Some(u8_val)); assert_eq!(from_str::<u8>("-1"), None); - let mut u16_val: u16 = 65_535_u16; + let mut u16_val: u16 = 65_535; assert_eq!(from_str::<u16>("65535"), Some(u16_val)); assert_eq!(from_str::<u16>("65536"), None); @@ -1802,7 +1802,7 @@ mod tests { assert_eq!(from_str::<u16>("0"), Some(u16_val)); assert_eq!(from_str::<u16>("-1"), None); - let mut u32_val: u32 = 4_294_967_295_u32; + let mut u32_val: u32 = 4_294_967_295; assert_eq!(from_str::<u32>("4294967295"), Some(u32_val)); assert_eq!(from_str::<u32>("4294967296"), None); @@ -1810,7 +1810,7 @@ mod tests { assert_eq!(from_str::<u32>("0"), Some(u32_val)); assert_eq!(from_str::<u32>("-1"), None); - let mut u64_val: u64 = 18_446_744_073_709_551_615_u64; + let mut u64_val: u64 = 18_446_744_073_709_551_615; assert_eq!(from_str::<u64>("18446744073709551615"), Some(u64_val)); assert_eq!(from_str::<u64>("18446744073709551616"), None); diff --git a/src/libstd/num/strconv.rs b/src/libstd/num/strconv.rs index b38c52dad1a..5fdd42dbc7a 100644 --- a/src/libstd/num/strconv.rs +++ b/src/libstd/num/strconv.rs @@ -104,7 +104,7 @@ fn int_to_str_bytes_common<T, F>(num: T, radix: uint, sign: SignFormat, mut f: F // This is just for integral types, the largest of which is a u64. The // smallest base that we can have is 2, so the most number of digits we're // ever going to have is 64 - let mut buf = [0u8; 64]; + let mut buf = [0; 64]; let mut cur = 0; // Loop at least once to make sure at least a `0` gets emitted. @@ -221,10 +221,10 @@ pub fn float_to_str_bytes_common<T: Float>( let radix_gen: T = num::cast(radix as int).unwrap(); let (num, exp) = match exp_format { - ExpNone => (num, 0i32), + ExpNone => (num, 0), ExpDec | ExpBin => { if num == _0 { - (num, 0i32) + (num, 0) } else { let (exp, exp_base) = match exp_format { ExpDec => (num.abs().log10().floor(), num::cast::<f64, T>(10.0f64).unwrap()), @@ -432,25 +432,25 @@ mod tests { #[test] fn test_int_to_str_overflow() { - let mut i8_val: i8 = 127_i8; + let mut i8_val: i8 = 127; assert_eq!(i8_val.to_string(), "127"); i8_val = i8_val.wrapping_add(1); assert_eq!(i8_val.to_string(), "-128"); - let mut i16_val: i16 = 32_767_i16; + let mut i16_val: i16 = 32_767; assert_eq!(i16_val.to_string(), "32767"); i16_val = i16_val.wrapping_add(1); assert_eq!(i16_val.to_string(), "-32768"); - let mut i32_val: i32 = 2_147_483_647_i32; + let mut i32_val: i32 = 2_147_483_647; assert_eq!(i32_val.to_string(), "2147483647"); i32_val = i32_val.wrapping_add(1); assert_eq!(i32_val.to_string(), "-2147483648"); - let mut i64_val: i64 = 9_223_372_036_854_775_807_i64; + let mut i64_val: i64 = 9_223_372_036_854_775_807; assert_eq!(i64_val.to_string(), "9223372036854775807"); i64_val = i64_val.wrapping_add(1); diff --git a/src/libstd/old_io/buffered.rs b/src/libstd/old_io/buffered.rs index 2d2d0d8b33a..cbb7bf04327 100644 --- a/src/libstd/old_io/buffered.rs +++ b/src/libstd/old_io/buffered.rs @@ -642,14 +642,14 @@ mod test { #[test] fn read_char_buffered() { - let buf = [195u8, 159u8]; + let buf = [195, 159]; let mut reader = BufferedReader::with_capacity(1, &buf[..]); assert_eq!(reader.read_char(), Ok('ß')); } #[test] fn test_chars() { - let buf = [195u8, 159u8, b'a']; + let buf = [195, 159, b'a']; let mut reader = BufferedReader::with_capacity(1, &buf[..]); let mut it = reader.chars(); assert_eq!(it.next(), Some(Ok('ß'))); @@ -658,7 +658,7 @@ mod test { } #[test] - #[should_fail] + #[should_panic] fn dont_panic_in_drop_on_panicked_flush() { struct FailFlushWriter; diff --git a/src/libstd/old_io/comm_adapters.rs b/src/libstd/old_io/comm_adapters.rs index 207d3d39167..dec1ae98ba0 100644 --- a/src/libstd/old_io/comm_adapters.rs +++ b/src/libstd/old_io/comm_adapters.rs @@ -30,7 +30,7 @@ use vec::Vec; /// # drop(tx); /// let mut reader = ChanReader::new(rx); /// -/// let mut buf = [0u8; 100]; +/// let mut buf = [0; 100]; /// match reader.read(&mut buf) { /// Ok(nread) => println!("Read {} bytes", nread), /// Err(e) => println!("read error: {}", e), @@ -167,15 +167,15 @@ mod test { fn test_rx_reader() { let (tx, rx) = channel(); thread::spawn(move|| { - tx.send(vec![1u8, 2u8]).unwrap(); + tx.send(vec![1, 2]).unwrap(); tx.send(vec![]).unwrap(); - tx.send(vec![3u8, 4u8]).unwrap(); - tx.send(vec![5u8, 6u8]).unwrap(); - tx.send(vec![7u8, 8u8]).unwrap(); + tx.send(vec![3, 4]).unwrap(); + tx.send(vec![5, 6]).unwrap(); + tx.send(vec![7, 8]).unwrap(); }); let mut reader = ChanReader::new(rx); - let mut buf = [0u8; 3]; + let mut buf = [0; 3]; assert_eq!(Ok(0), reader.read(&mut [])); @@ -233,7 +233,7 @@ mod test { let mut writer = ChanWriter::new(tx); writer.write_be_u32(42).unwrap(); - let wanted = vec![0u8, 0u8, 0u8, 42u8]; + let wanted = vec![0, 0, 0, 42]; let got = thread::scoped(move|| { rx.recv().unwrap() }).join(); assert_eq!(wanted, got); diff --git a/src/libstd/old_io/extensions.rs b/src/libstd/old_io/extensions.rs index 45a86a9fde7..ec30121d78d 100644 --- a/src/libstd/old_io/extensions.rs +++ b/src/libstd/old_io/extensions.rs @@ -101,7 +101,7 @@ pub fn u64_to_le_bytes<T, F>(n: u64, size: uint, f: F) -> T where let mut i = size; let mut n = n; while i > 0 { - bytes.push((n & 255_u64) as u8); + bytes.push((n & 255) as u8); n >>= 8; i -= 1; } @@ -170,7 +170,7 @@ pub fn u64_from_be_bytes(data: &[u8], start: uint, size: uint) -> u64 { panic!("index out of bounds"); } - let mut buf = [0u8; 8]; + let mut buf = [0; 8]; unsafe { let ptr = data.as_ptr().offset(start as int); let out = buf.as_mut_ptr(); @@ -396,7 +396,7 @@ mod test { } #[test] - #[should_fail] + #[should_panic] fn read_to_end_error() { let mut reader = ThreeChunkReader { count: 0, @@ -522,8 +522,8 @@ mod bench { ({ use super::u64_from_be_bytes; - let data = (0u8..$stride*100+$start_index).collect::<Vec<_>>(); - let mut sum = 0u64; + let data = (0..$stride*100+$start_index).collect::<Vec<_>>(); + let mut sum = 0; $b.iter(|| { let mut i = $start_index; while i < data.len() { diff --git a/src/libstd/old_io/fs.rs b/src/libstd/old_io/fs.rs index 4e9c1b36055..afffed2278b 100644 --- a/src/libstd/old_io/fs.rs +++ b/src/libstd/old_io/fs.rs @@ -82,6 +82,8 @@ use sys_common; /// attempted against it for which its underlying file descriptor was not /// configured at creation time, via the `FileAccess` parameter to /// `File::open_mode()`. +#[deprecated(since = "1.0.0", reason = "replaced with std::fs::File")] +#[unstable(feature = "old_io")] pub struct File { fd: fs_imp::FileDesc, path: Path, @@ -94,6 +96,8 @@ impl sys_common::AsInner<fs_imp::FileDesc> for File { } } +#[deprecated(since = "1.0.0", reason = "replaced with std::fs")] +#[unstable(feature = "old_io")] impl File { /// Open a file at `path` in the mode specified by the `mode` and `access` /// arguments @@ -133,6 +137,8 @@ impl File { /// * Attempting to open a file with a `FileAccess` that the user lacks /// permissions for /// * Filesystem-level errors (full disk, etc) + #[deprecated(since = "1.0.0", reason = "replaced with std::fs::OpenOptions")] + #[unstable(feature = "old_io")] pub fn open_mode(path: &Path, mode: FileMode, access: FileAccess) -> IoResult<File> { @@ -174,6 +180,8 @@ impl File { /// /// let contents = File::open(&Path::new("foo.txt")).read_to_end(); /// ``` + #[deprecated(since = "1.0.0", reason = "replaced with std::fs::File::open")] + #[unstable(feature = "old_io")] pub fn open(path: &Path) -> IoResult<File> { File::open_mode(path, Open, Read) } @@ -195,12 +203,16 @@ impl File { /// # drop(f); /// # ::std::old_io::fs::unlink(&Path::new("foo.txt")); /// ``` + #[deprecated(since = "1.0.0", reason = "replaced with std::fs::File::create")] + #[unstable(feature = "old_io")] pub fn create(path: &Path) -> IoResult<File> { File::open_mode(path, Truncate, Write) .update_desc("couldn't create file") } /// Returns the original path that was used to open this file. + #[deprecated(since = "1.0.0", reason = "replaced with std::fs")] + #[unstable(feature = "old_io")] pub fn path<'a>(&'a self) -> &'a Path { &self.path } @@ -208,6 +220,8 @@ impl File { /// Synchronizes all modifications to this file to its permanent storage /// device. This will flush any internal buffers necessary to perform this /// operation. + #[deprecated(since = "1.0.0", reason = "replaced with std::fs")] + #[unstable(feature = "old_io")] pub fn fsync(&mut self) -> IoResult<()> { self.fd.fsync() .update_err("couldn't fsync file", @@ -218,6 +232,8 @@ impl File { /// file metadata to the filesystem. This is intended for use cases that /// must synchronize content, but don't need the metadata on disk. The goal /// of this method is to reduce disk operations. + #[deprecated(since = "1.0.0", reason = "replaced with std::fs")] + #[unstable(feature = "old_io")] pub fn datasync(&mut self) -> IoResult<()> { self.fd.datasync() .update_err("couldn't datasync file", @@ -232,6 +248,8 @@ impl File { /// be shrunk. If it is greater than the current file's size, then the file /// will be extended to `size` and have all of the intermediate data filled /// in with 0s. + #[deprecated(since = "1.0.0", reason = "replaced with std::fs")] + #[unstable(feature = "old_io")] pub fn truncate(&mut self, size: i64) -> IoResult<()> { self.fd.truncate(size) .update_err("couldn't truncate file", |e| @@ -247,11 +265,15 @@ impl File { /// until you have attempted to read past the end of the file, so if /// you've read _exactly_ the number of bytes in the file, this will /// return `false`, not `true`. + #[deprecated(since = "1.0.0", reason = "replaced with std::fs")] + #[unstable(feature = "old_io")] pub fn eof(&self) -> bool { self.last_nread == 0 } /// Queries information about the underlying file. + #[deprecated(since = "1.0.0", reason = "replaced with std::fs")] + #[unstable(feature = "old_io")] pub fn stat(&self) -> IoResult<FileStat> { self.fd.fstat() .update_err("couldn't fstat file", |e| @@ -280,6 +302,8 @@ impl File { /// This function will return an error if `path` points to a directory, if the /// user lacks permissions to remove the file, or if some other filesystem-level /// error occurs. +#[deprecated(since = "1.0.0", reason = "replaced with std::fs::remove_file")] +#[unstable(feature = "old_io")] pub fn unlink(path: &Path) -> IoResult<()> { fs_imp::unlink(path) .update_err("couldn't unlink path", |e| @@ -307,6 +331,8 @@ pub fn unlink(path: &Path) -> IoResult<()> { /// This function will return an error if the user lacks the requisite permissions /// to perform a `stat` call on the given `path` or if there is no entry in the /// filesystem at the provided path. +#[deprecated(since = "1.0.0", reason = "replaced with std::fs::metadata")] +#[unstable(feature = "old_io")] pub fn stat(path: &Path) -> IoResult<FileStat> { fs_imp::stat(path) .update_err("couldn't stat path", |e| @@ -321,6 +347,7 @@ pub fn stat(path: &Path) -> IoResult<FileStat> { /// # Error /// /// See `stat` +#[unstable(feature = "old_fs")] pub fn lstat(path: &Path) -> IoResult<FileStat> { fs_imp::lstat(path) .update_err("couldn't lstat path", |e| @@ -343,6 +370,8 @@ pub fn lstat(path: &Path) -> IoResult<FileStat> { /// This function will return an error if the provided `from` doesn't exist, if /// the process lacks permissions to view the contents, or if some other /// intermittent I/O error occurs. +#[deprecated(since = "1.0.0", reason = "replaced with std::fs::rename")] +#[unstable(feature = "old_io")] pub fn rename(from: &Path, to: &Path) -> IoResult<()> { fs_imp::rename(from, to) .update_err("couldn't rename path", |e| @@ -377,6 +406,8 @@ pub fn rename(from: &Path, to: &Path) -> IoResult<()> { /// Note that this copy is not atomic in that once the destination is /// ensured to not exist, there is nothing preventing the destination from /// being created and then destroyed by this operation. +#[deprecated(since = "1.0.0", reason = "replaced with std::fs::copy")] +#[unstable(feature = "old_io")] pub fn copy(from: &Path, to: &Path) -> IoResult<()> { fn update_err<T>(result: IoResult<T>, from: &Path, to: &Path) -> IoResult<T> { result.update_err("couldn't copy path", |e| { @@ -421,6 +452,8 @@ pub fn copy(from: &Path, to: &Path) -> IoResult<()> { /// This function will return an error if the provided `path` doesn't exist, if /// the process lacks permissions to change the attributes of the file, or if /// some other I/O error is encountered. +#[deprecated(since = "1.0.0", reason = "replaced with std::fs::set_permissions")] +#[unstable(feature = "old_io")] pub fn chmod(path: &Path, mode: old_io::FilePermission) -> IoResult<()> { fs_imp::chmod(path, mode.bits() as uint) .update_err("couldn't chmod path", |e| @@ -428,6 +461,7 @@ pub fn chmod(path: &Path, mode: old_io::FilePermission) -> IoResult<()> { } /// Change the user and group owners of a file at the specified path. +#[unstable(feature = "old_fs")] pub fn chown(path: &Path, uid: int, gid: int) -> IoResult<()> { fs_imp::chown(path, uid, gid) .update_err("couldn't chown path", |e| @@ -437,6 +471,8 @@ pub fn chown(path: &Path, uid: int, gid: int) -> IoResult<()> { /// Creates a new hard link on the filesystem. The `dst` path will be a /// link pointing to the `src` path. Note that systems often require these /// two paths to both be located on the same filesystem. +#[deprecated(since = "1.0.0", reason = "replaced with std::fs::hard_link")] +#[unstable(feature = "old_io")] pub fn link(src: &Path, dst: &Path) -> IoResult<()> { fs_imp::link(src, dst) .update_err("couldn't link path", |e| @@ -445,6 +481,8 @@ pub fn link(src: &Path, dst: &Path) -> IoResult<()> { /// Creates a new symbolic link on the filesystem. The `dst` path will be a /// symlink pointing to the `src` path. +#[deprecated(since = "1.0.0", reason = "replaced with std::fs::soft_link")] +#[unstable(feature = "old_io")] pub fn symlink(src: &Path, dst: &Path) -> IoResult<()> { fs_imp::symlink(src, dst) .update_err("couldn't symlink path", |e| @@ -457,6 +495,8 @@ pub fn symlink(src: &Path, dst: &Path) -> IoResult<()> { /// /// This function will return an error on failure. Failure conditions include /// reading a file that does not exist or reading a file that is not a symlink. +#[deprecated(since = "1.0.0", reason = "replaced with std::fs::read_link")] +#[unstable(feature = "old_io")] pub fn readlink(path: &Path) -> IoResult<Path> { fs_imp::readlink(path) .update_err("couldn't resolve symlink for path", |e| @@ -480,6 +520,7 @@ pub fn readlink(path: &Path) -> IoResult<Path> { /// /// This function will return an error if the user lacks permissions to make a /// new directory at the provided `path`, or if the directory already exists. +#[unstable(feature = "old_fs")] pub fn mkdir(path: &Path, mode: FilePermission) -> IoResult<()> { fs_imp::mkdir(path, mode.bits() as uint) .update_err("couldn't create directory", |e| @@ -502,6 +543,8 @@ pub fn mkdir(path: &Path, mode: FilePermission) -> IoResult<()> { /// /// This function will return an error if the user lacks permissions to remove /// the directory at the provided `path`, or if the directory isn't empty. +#[deprecated(since = "1.0.0", reason = "replaced with std::fs::remove_dir")] +#[unstable(feature = "old_io")] pub fn rmdir(path: &Path) -> IoResult<()> { fs_imp::rmdir(path) .update_err("couldn't remove directory", |e| @@ -542,6 +585,8 @@ pub fn rmdir(path: &Path) -> IoResult<()> { /// This function will return an error if the provided `path` doesn't exist, if /// the process lacks permissions to view the contents or if the `path` points /// at a non-directory file +#[deprecated(since = "1.0.0", reason = "replaced with std::fs::read_dir")] +#[unstable(feature = "old_io")] pub fn readdir(path: &Path) -> IoResult<Vec<Path>> { fs_imp::readdir(path) .update_err("couldn't read directory", @@ -552,6 +597,8 @@ pub fn readdir(path: &Path) -> IoResult<Vec<Path>> { /// rooted at `path`. The path given will not be iterated over, and this will /// perform iteration in some top-down order. The contents of unreadable /// subdirectories are ignored. +#[deprecated(since = "1.0.0", reason = "replaced with std::fs::walk_dir")] +#[unstable(feature = "old_io")] pub fn walk_dir(path: &Path) -> IoResult<Directories> { Ok(Directories { stack: try!(readdir(path).update_err("couldn't walk directory", @@ -561,6 +608,8 @@ pub fn walk_dir(path: &Path) -> IoResult<Directories> { /// An iterator that walks over a directory #[derive(Clone)] +#[deprecated(since = "1.0.0", reason = "replaced with std::fs::ReadDir")] +#[unstable(feature = "old_io")] pub struct Directories { stack: Vec<Path>, } @@ -590,6 +639,7 @@ impl Iterator for Directories { /// # Error /// /// See `fs::mkdir`. +#[unstable(feature = "old_fs")] pub fn mkdir_recursive(path: &Path, mode: FilePermission) -> IoResult<()> { // tjc: if directory exists but with different permissions, // should we return false? @@ -627,6 +677,8 @@ pub fn mkdir_recursive(path: &Path, mode: FilePermission) -> IoResult<()> { /// # Error /// /// See `file::unlink` and `fs::readdir` +#[deprecated(since = "1.0.0", reason = "replaced with std::fs::remove_dir_all")] +#[unstable(feature = "old_io")] pub fn rmdir_recursive(path: &Path) -> IoResult<()> { let mut rm_stack = Vec::new(); rm_stack.push(path.clone()); @@ -689,6 +741,8 @@ pub fn rmdir_recursive(path: &Path) -> IoResult<()> { /// `atime` and its modification time set to `mtime`. The times specified should /// be in milliseconds. // FIXME(#10301) these arguments should not be u64 +#[deprecated(since = "1.0.0", reason = "replaced with std::fs::set_file_times")] +#[unstable(feature = "old_io")] pub fn change_file_times(path: &Path, atime: u64, mtime: u64) -> IoResult<()> { fs_imp::utime(path, atime, mtime) .update_err("couldn't change_file_times", |e| @@ -748,6 +802,8 @@ impl Seek for File { } /// Utility methods for paths. +#[deprecated(since = "1.0.0", reason = "replaced with std::fs::PathExt")] +#[unstable(feature = "old_io")] pub trait PathExtensions { /// Get information on the file, directory, etc at this path. /// @@ -1110,7 +1166,7 @@ mod test { check!(w.write(msg)); } let files = check!(readdir(dir)); - let mut mem = [0u8; 4]; + let mut mem = [0; 4]; for f in &files { { let n = f.filestem_str(); @@ -1142,7 +1198,7 @@ mod test { check!(File::create(&dir2.join("14"))); let mut files = check!(walk_dir(dir)); - let mut cur = [0u8; 2]; + let mut cur = [0; 2]; for f in files { let stem = f.filestem_str().unwrap(); let root = stem.as_bytes()[0] - b'0'; diff --git a/src/libstd/old_io/mod.rs b/src/libstd/old_io/mod.rs index 728a5dac4e4..9ce888efceb 100644 --- a/src/libstd/old_io/mod.rs +++ b/src/libstd/old_io/mod.rs @@ -670,7 +670,7 @@ pub trait Reader { fn read_le_uint_n(&mut self, nbytes: uint) -> IoResult<u64> { assert!(nbytes > 0 && nbytes <= 8); - let mut val = 0u64; + let mut val = 0; let mut pos = 0; let mut i = nbytes; while i > 0 { @@ -694,7 +694,7 @@ pub trait Reader { fn read_be_uint_n(&mut self, nbytes: uint) -> IoResult<u64> { assert!(nbytes > 0 && nbytes <= 8); - let mut val = 0u64; + let mut val = 0; let mut i = nbytes; while i > 0 { i -= 1; @@ -1078,7 +1078,7 @@ pub trait Writer { /// Write a single char, encoded as UTF-8. #[inline] fn write_char(&mut self, c: char) -> IoResult<()> { - let mut buf = [0u8; 4]; + let mut buf = [0; 4]; let n = c.encode_utf8(&mut buf).unwrap_or(0); self.write_all(&buf[..n]) } @@ -1896,7 +1896,7 @@ mod tests { fn test_read_at_least() { let mut r = BadReader::new(MemReader::new(b"hello, world!".to_vec()), vec![GoodBehavior(usize::MAX)]); - let buf = &mut [0u8; 5]; + let buf = &mut [0; 5]; assert!(r.read_at_least(1, buf).unwrap() >= 1); assert!(r.read_exact(5).unwrap().len() == 5); // read_exact uses read_at_least assert!(r.read_at_least(0, buf).is_ok()); diff --git a/src/libstd/old_io/net/ip.rs b/src/libstd/old_io/net/ip.rs index f1634cd4229..6e2f491262d 100644 --- a/src/libstd/old_io/net/ip.rs +++ b/src/libstd/old_io/net/ip.rs @@ -198,7 +198,7 @@ impl<'a> Parser<'a> { } fn read_number_impl(&mut self, radix: u8, max_digits: u32, upto: u32) -> Option<u32> { - let mut r = 0u32; + let mut r = 0; let mut digit_count = 0; loop { match self.read_digit(radix) { @@ -226,7 +226,7 @@ impl<'a> Parser<'a> { } fn read_ipv4_addr_impl(&mut self) -> Option<IpAddr> { - let mut bs = [0u8; 4]; + let mut bs = [0; 4]; let mut i = 0; while i < 4 { if i != 0 && self.read_given_char('.').is_none() { @@ -251,7 +251,7 @@ impl<'a> Parser<'a> { fn read_ipv6_addr_impl(&mut self) -> Option<IpAddr> { fn ipv6_addr_from_head_tail(head: &[u16], tail: &[u16]) -> IpAddr { assert!(head.len() + tail.len() <= 8); - let mut gs = [0u16; 8]; + let mut gs = [0; 8]; gs.clone_from_slice(head); gs[(8 - tail.len()) .. 8].clone_from_slice(tail); Ipv6Addr(gs[0], gs[1], gs[2], gs[3], gs[4], gs[5], gs[6], gs[7]) @@ -294,7 +294,7 @@ impl<'a> Parser<'a> { (i, false) } - let mut head = [0u16; 8]; + let mut head = [0; 8]; let (head_size, head_ipv4) = read_groups(self, &mut head, 8); if head_size == 8 { @@ -313,7 +313,7 @@ impl<'a> Parser<'a> { return None; } - let mut tail = [0u16; 8]; + let mut tail = [0; 8]; let (tail_size, _) = read_groups(self, &mut tail, 8 - head_size); Some(ipv6_addr_from_head_tail(&head[..head_size], &tail[..tail_size])) } @@ -425,17 +425,17 @@ pub struct ParseError; /// // The following lines are equivalent modulo possible "localhost" name resolution /// // differences /// let tcp_s = TcpStream::connect(SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: 12345 }); -/// let tcp_s = TcpStream::connect((Ipv4Addr(127, 0, 0, 1), 12345u16)); -/// let tcp_s = TcpStream::connect(("127.0.0.1", 12345u16)); -/// let tcp_s = TcpStream::connect(("localhost", 12345u16)); +/// let tcp_s = TcpStream::connect((Ipv4Addr(127, 0, 0, 1), 12345)); +/// let tcp_s = TcpStream::connect(("127.0.0.1", 12345)); +/// let tcp_s = TcpStream::connect(("localhost", 12345)); /// let tcp_s = TcpStream::connect("127.0.0.1:12345"); /// let tcp_s = TcpStream::connect("localhost:12345"); /// /// // TcpListener::bind(), UdpSocket::bind() and UdpSocket::send_to() behave similarly /// let tcp_l = TcpListener::bind("localhost:12345"); /// -/// let mut udp_s = UdpSocket::bind(("127.0.0.1", 23451u16)).unwrap(); -/// udp_s.send_to([7u8, 7u8, 7u8].as_slice(), (Ipv4Addr(127, 0, 0, 1), 23451u16)); +/// let mut udp_s = UdpSocket::bind(("127.0.0.1", 23451)).unwrap(); +/// udp_s.send_to([7, 7, 7].as_slice(), (Ipv4Addr(127, 0, 0, 1), 23451)); /// } /// ``` pub trait ToSocketAddr { @@ -674,7 +674,7 @@ mod test { #[test] fn to_socket_addr_ipaddr_u16() { let a = Ipv4Addr(77, 88, 21, 11); - let p = 12345u16; + let p = 12345; let e = SocketAddr { ip: a, port: p }; assert_eq!(Ok(e), (a, p).to_socket_addr()); assert_eq!(Ok(vec![e]), (a, p).to_socket_addr_all()); @@ -683,15 +683,15 @@ mod test { #[test] fn to_socket_addr_str_u16() { let a = SocketAddr { ip: Ipv4Addr(77, 88, 21, 11), port: 24352 }; - assert_eq!(Ok(a), ("77.88.21.11", 24352u16).to_socket_addr()); - assert_eq!(Ok(vec![a]), ("77.88.21.11", 24352u16).to_socket_addr_all()); + assert_eq!(Ok(a), ("77.88.21.11", 24352).to_socket_addr()); + assert_eq!(Ok(vec![a]), ("77.88.21.11", 24352).to_socket_addr_all()); let a = SocketAddr { ip: Ipv6Addr(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), port: 53 }; assert_eq!(Ok(a), ("2a02:6b8:0:1::1", 53).to_socket_addr()); assert_eq!(Ok(vec![a]), ("2a02:6b8:0:1::1", 53).to_socket_addr_all()); let a = SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: 23924 }; - assert!(("localhost", 23924u16).to_socket_addr_all().unwrap().contains(&a)); + assert!(("localhost", 23924).to_socket_addr_all().unwrap().contains(&a)); } #[test] diff --git a/src/libstd/old_io/net/mod.rs b/src/libstd/old_io/net/mod.rs index bbe3a71dcc0..a3567290b0e 100644 --- a/src/libstd/old_io/net/mod.rs +++ b/src/libstd/old_io/net/mod.rs @@ -10,6 +10,10 @@ //! Networking I/O +#![deprecated(since = "1.0.0", + reason = "replaced with new I/O primitives in `std::net`")] +#![unstable(feature = "old_io")] + use old_io::{IoError, IoResult, InvalidInput}; use ops::FnMut; use option::Option::None; diff --git a/src/libstd/old_io/net/pipe.rs b/src/libstd/old_io/net/pipe.rs index d05669d32b8..2ecaf515f08 100644 --- a/src/libstd/old_io/net/pipe.rs +++ b/src/libstd/old_io/net/pipe.rs @@ -19,6 +19,12 @@ //! instances as clients. #![allow(missing_docs)] +#![deprecated(since = "1.0.0", + reason = "will be removed to be reintroduced at a later date; \ + in the meantime consider using the `unix_socket` crate \ + for unix sockets; there is currently no replacement \ + for named pipes")] +#![unstable(feature = "old_io")] use prelude::v1::*; diff --git a/src/libstd/old_io/net/tcp.rs b/src/libstd/old_io/net/tcp.rs index 19a6f6e3def..73ef21fa3aa 100644 --- a/src/libstd/old_io/net/tcp.rs +++ b/src/libstd/old_io/net/tcp.rs @@ -1162,7 +1162,7 @@ mod test { tx.send(TcpStream::connect(addr).unwrap()).unwrap(); }); let _l = rx.recv().unwrap(); - for i in 0i32..1001 { + for i in 0..1001 { match a.accept() { Ok(..) => break, Err(ref e) if e.kind == TimedOut => {} @@ -1262,7 +1262,7 @@ mod test { assert_eq!(s.read(&mut [0]).err().unwrap().kind, TimedOut); s.set_timeout(Some(20)); - for i in 0i32..1001 { + for i in 0..1001 { match s.write(&[0; 128 * 1024]) { Ok(()) | Err(IoError { kind: ShortWrite(..), .. }) => {}, Err(IoError { kind: TimedOut, .. }) => break, @@ -1320,7 +1320,7 @@ mod test { let mut s = a.accept().unwrap(); s.set_write_timeout(Some(20)); - for i in 0i32..1001 { + for i in 0..1001 { match s.write(&[0; 128 * 1024]) { Ok(()) | Err(IoError { kind: ShortWrite(..), .. }) => {}, Err(IoError { kind: TimedOut, .. }) => break, diff --git a/src/libstd/old_io/process.rs b/src/libstd/old_io/process.rs index a13295b1ccb..e02e863516a 100644 --- a/src/libstd/old_io/process.rs +++ b/src/libstd/old_io/process.rs @@ -11,6 +11,9 @@ //! Bindings for executing child processes #![allow(non_upper_case_globals)] +#![unstable(feature = "old_io")] +#![deprecated(since = "1.0.0", + reason = "replaced with the std::process module")] pub use self::StdioContainer::*; pub use self::ProcessExit::*; diff --git a/src/libstd/old_io/test.rs b/src/libstd/old_io/test.rs index 43c0b9268a2..9fbdac84a80 100644 --- a/src/libstd/old_io/test.rs +++ b/src/libstd/old_io/test.rs @@ -73,8 +73,8 @@ it is running in and assigns a port range based on it. */ fn base_port() -> u16 { - let base = 9600u16; - let range = 1000u16; + let base = 9600; + let range = 1000; let bases = [ ("32-opt", base + range * 1), diff --git a/src/libstd/old_io/timer.rs b/src/libstd/old_io/timer.rs index de5f2141095..375fe6ce483 100644 --- a/src/libstd/old_io/timer.rs +++ b/src/libstd/old_io/timer.rs @@ -333,7 +333,7 @@ mod test { } #[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 @@ mod test { } #[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 @@ mod test { } #[test] - #[should_fail] + #[should_panic] fn normal_fail() { let _timer = Timer::new().unwrap(); panic!(); diff --git a/src/libstd/old_io/util.rs b/src/libstd/old_io/util.rs index 8e49335ed54..4faf8af57b4 100644 --- a/src/libstd/old_io/util.rs +++ b/src/libstd/old_io/util.rs @@ -10,6 +10,8 @@ //! Utility implementations of Reader and Writer +#![allow(deprecated)] + use prelude::v1::*; use cmp; use old_io; @@ -17,13 +19,19 @@ use slice::bytes::MutableByteVector; /// Wraps a `Reader`, limiting the number of bytes that can be read from it. #[derive(Debug)] +#[deprecated(since = "1.0.0", reason = "use std::io::Take")] +#[unstable(feature = "old_io")] pub struct LimitReader<R> { limit: uint, inner: R } +#[deprecated(since = "1.0.0", reason = "use std::io::Take")] +#[unstable(feature = "old_io")] impl<R: Reader> LimitReader<R> { /// Creates a new `LimitReader` + #[deprecated(since = "1.0.0", reason = "use std::io's take method instead")] + #[unstable(feature = "old_io")] pub fn new(r: R, limit: uint) -> LimitReader<R> { LimitReader { limit: limit, inner: r } } @@ -41,6 +49,8 @@ impl<R: Reader> LimitReader<R> { pub fn limit(&self) -> uint { self.limit } } +#[deprecated(since = "1.0.0", reason = "use std::io's take method instead")] +#[unstable(feature = "old_io")] impl<R: Reader> Reader for LimitReader<R> { fn read(&mut self, buf: &mut [u8]) -> old_io::IoResult<uint> { if self.limit == 0 { @@ -57,6 +67,8 @@ impl<R: Reader> Reader for LimitReader<R> { } } +#[deprecated(since = "1.0.0", reason = "use std::io's take method instead")] +#[unstable(feature = "old_io")] impl<R: Buffer> Buffer for LimitReader<R> { fn fill_buf<'a>(&'a mut self) -> old_io::IoResult<&'a [u8]> { let amt = try!(self.inner.fill_buf()); @@ -79,8 +91,12 @@ impl<R: Buffer> Buffer for LimitReader<R> { /// A `Writer` which ignores bytes written to it, like /dev/null. #[derive(Copy, Debug)] +#[deprecated(since = "1.0.0", reason = "use std::io::sink() instead")] +#[unstable(feature = "old_io")] pub struct NullWriter; +#[deprecated(since = "1.0.0", reason = "use std::io::sink() instead")] +#[unstable(feature = "old_io")] impl Writer for NullWriter { #[inline] fn write_all(&mut self, _buf: &[u8]) -> old_io::IoResult<()> { Ok(()) } @@ -88,8 +104,12 @@ impl Writer for NullWriter { /// A `Reader` which returns an infinite stream of 0 bytes, like /dev/zero. #[derive(Copy, Debug)] +#[deprecated(since = "1.0.0", reason = "use std::io::repeat(0) instead")] +#[unstable(feature = "old_io")] pub struct ZeroReader; +#[deprecated(since = "1.0.0", reason = "use std::io::repeat(0) instead")] +#[unstable(feature = "old_io")] impl Reader for ZeroReader { #[inline] fn read(&mut self, buf: &mut [u8]) -> old_io::IoResult<uint> { @@ -98,6 +118,8 @@ impl Reader for ZeroReader { } } +#[deprecated(since = "1.0.0", reason = "use std::io::repeat(0) instead")] +#[unstable(feature = "old_io")] impl Buffer for ZeroReader { fn fill_buf<'a>(&'a mut self) -> old_io::IoResult<&'a [u8]> { static DATA: [u8; 64] = [0; 64]; @@ -109,8 +131,12 @@ impl Buffer for ZeroReader { /// A `Reader` which is always at EOF, like /dev/null. #[derive(Copy, Debug)] +#[deprecated(since = "1.0.0", reason = "use std::io::empty() instead")] +#[unstable(feature = "old_io")] pub struct NullReader; +#[deprecated(since = "1.0.0", reason = "use std::io::empty() instead")] +#[unstable(feature = "old_io")] impl Reader for NullReader { #[inline] fn read(&mut self, _buf: &mut [u8]) -> old_io::IoResult<uint> { @@ -118,6 +144,8 @@ impl Reader for NullReader { } } +#[deprecated(since = "1.0.0", reason = "use std::io::empty() instead")] +#[unstable(feature = "old_io")] impl Buffer for NullReader { fn fill_buf<'a>(&'a mut self) -> old_io::IoResult<&'a [u8]> { Err(old_io::standard_error(old_io::EndOfFile)) @@ -130,17 +158,23 @@ impl Buffer for NullReader { /// The `Writer`s are delegated to in order. If any `Writer` returns an error, /// that error is returned immediately and remaining `Writer`s are not called. #[derive(Debug)] +#[deprecated(since = "1.0.0", reason = "use std::io::Broadcast instead")] +#[unstable(feature = "old_io")] pub struct MultiWriter<W> { writers: Vec<W> } impl<W> MultiWriter<W> where W: Writer { /// Creates a new `MultiWriter` + #[deprecated(since = "1.0.0", reason = "use std::io's broadcast method instead")] + #[unstable(feature = "old_io")] pub fn new(writers: Vec<W>) -> MultiWriter<W> { MultiWriter { writers: writers } } } +#[deprecated(since = "1.0.0", reason = "use std::io::Broadcast instead")] +#[unstable(feature = "old_io")] impl<W> Writer for MultiWriter<W> where W: Writer { #[inline] fn write_all(&mut self, buf: &[u8]) -> old_io::IoResult<()> { @@ -162,6 +196,8 @@ impl<W> Writer for MultiWriter<W> where W: Writer { /// A `Reader` which chains input from multiple `Reader`s, reading each to /// completion before moving onto the next. #[derive(Clone, Debug)] +#[deprecated(since = "1.0.0", reason = "use std::io::Chain instead")] +#[unstable(feature = "old_io")] pub struct ChainedReader<I, R> { readers: I, cur_reader: Option<R>, @@ -169,12 +205,16 @@ pub struct ChainedReader<I, R> { impl<R: Reader, I: Iterator<Item=R>> ChainedReader<I, R> { /// Creates a new `ChainedReader` + #[deprecated(since = "1.0.0", reason = "use std::io's chain method instead")] + #[unstable(feature = "old_io")] pub fn new(mut readers: I) -> ChainedReader<I, R> { let r = readers.next(); ChainedReader { readers: readers, cur_reader: r } } } +#[deprecated(since = "1.0.0", reason = "use std::io::Chain instead")] +#[unstable(feature = "old_io")] impl<R: Reader, I: Iterator<Item=R>> Reader for ChainedReader<I, R> { fn read(&mut self, buf: &mut [u8]) -> old_io::IoResult<uint> { loop { @@ -201,13 +241,19 @@ impl<R: Reader, I: Iterator<Item=R>> Reader for ChainedReader<I, R> { /// A `Reader` which forwards input from another `Reader`, passing it along to /// a `Writer` as well. Similar to the `tee(1)` command. #[derive(Debug)] +#[deprecated(since = "1.0.0", reason = "use std::io::Tee instead")] +#[unstable(feature = "old_io")] pub struct TeeReader<R, W> { reader: R, writer: W, } +#[deprecated(since = "1.0.0", reason = "use std::io::Tee instead")] +#[unstable(feature = "old_io")] impl<R: Reader, W: Writer> TeeReader<R, W> { /// Creates a new `TeeReader` + #[deprecated(since = "1.0.0", reason = "use std::io's tee method instead")] + #[unstable(feature = "old_io")] pub fn new(r: R, w: W) -> TeeReader<R, W> { TeeReader { reader: r, writer: w } } @@ -220,6 +266,8 @@ impl<R: Reader, W: Writer> TeeReader<R, W> { } } +#[deprecated(since = "1.0.0", reason = "use std::io::Tee instead")] +#[unstable(feature = "old_io")] impl<R: Reader, W: Writer> Reader for TeeReader<R, W> { fn read(&mut self, buf: &mut [u8]) -> old_io::IoResult<uint> { self.reader.read(buf).and_then(|len| { @@ -229,6 +277,8 @@ impl<R: Reader, W: Writer> Reader for TeeReader<R, W> { } /// Copies all data from a `Reader` to a `Writer`. +#[deprecated(since = "1.0.0", reason = "use std::io's copy function instead")] +#[unstable(feature = "old_io")] pub fn copy<R: Reader, W: Writer>(r: &mut R, w: &mut W) -> old_io::IoResult<()> { let mut buf = [0; super::DEFAULT_BUF_SIZE]; loop { @@ -418,7 +468,7 @@ mod test { #[test] fn test_iter_reader() { - let mut r = IterReader::new(0u8..8); + let mut r = IterReader::new(0..8); let mut buf = [0, 0, 0]; let len = r.read(&mut buf).unwrap(); assert_eq!(len, 3); @@ -437,7 +487,7 @@ mod test { #[test] fn iter_reader_zero_length() { - let mut r = IterReader::new(0u8..8); + let mut r = IterReader::new(0..8); let mut buf = []; assert_eq!(Ok(0), r.read(&mut buf)); } diff --git a/src/libstd/old_path/windows.rs b/src/libstd/old_path/windows.rs index 31a8cbe572a..5f2f1728be1 100644 --- a/src/libstd/old_path/windows.rs +++ b/src/libstd/old_path/windows.rs @@ -1324,7 +1324,7 @@ mod tests { } #[test] - #[should_fail] + #[should_panic] fn test_not_utf8_panics() { Path::new(b"hello\x80.txt"); } diff --git a/src/libstd/path.rs b/src/libstd/path.rs index b85a0dcec81..ad8e17fed24 100755..100644 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -90,7 +90,7 @@ //! * Repeated separators are ignored: `a/b` and `a//b` both have components `a` //! and `b`. //! -//! * Paths ending in a separator are treated as if they has a current directory +//! * Paths ending in a separator are treated as if they have a current directory //! component at the end (or, in verbatim paths, an empty component). For //! example, while `a/b` has components `a` and `b`, the paths `a/b/` and //! `a/b/.` both have components `a`, `b`, and `.` (current directory). The @@ -872,10 +872,10 @@ impl PathBuf { // `path` is a pure relative path } else if need_sep { - self.inner.push_os_str(OsStr::from_str(MAIN_SEP_STR)); + self.inner.push(MAIN_SEP_STR); } - self.inner.push_os_str(path.as_os_str()); + self.inner.push(path); } /// Truncate `self` to `self.parent()`. @@ -937,8 +937,8 @@ impl PathBuf { let extension = extension.as_os_str(); if os_str_as_u8_slice(extension).len() > 0 { - stem.push_os_str(OsStr::from_str(".")); - stem.push_os_str(extension.as_os_str()); + stem.push("."); + stem.push(extension); } self.set_file_name(&stem); @@ -1193,7 +1193,7 @@ impl Path { iter_after(self.components(), base.as_path().components()).is_some() } - /// Determines whether `base` is a suffix of `self`. + /// Determines whether `child` is a suffix of `self`. pub fn ends_with<P: ?Sized>(&self, child: &P) -> bool where P: AsPath { iter_after(self.components().rev(), child.as_path().components().rev()).is_some() } diff --git a/src/libstd/process.rs b/src/libstd/process.rs index b578b5e3d60..ec4fcec5556 100644 --- a/src/libstd/process.rs +++ b/src/libstd/process.rs @@ -264,7 +264,7 @@ impl Command { /// By default, stdin, stdout and stderr are captured (and used to /// provide the resulting output). /// - /// # Example + /// # Examples /// /// ``` /// # #![feature(process)] @@ -275,8 +275,8 @@ impl Command { /// }); /// /// 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> { @@ -803,17 +803,16 @@ mod tests { #[cfg(not(target_os="android"))] #[test] fn test_inherit_env() { - use os; + use std::env; if running_on_valgrind() { return; } let result = env_cmd().output().unwrap(); let output = String::from_utf8(result.stdout).unwrap(); - let r = os::env(); - for &(ref k, ref v) in &r { + 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); } @@ -831,12 +830,12 @@ mod tests { 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))); } } } diff --git a/src/libstd/rand/mod.rs b/src/libstd/rand/mod.rs index a49db012882..7382cc6e2eb 100644 --- a/src/libstd/rand/mod.rs +++ b/src/libstd/rand/mod.rs @@ -468,7 +468,7 @@ mod test { let lengths = [0, 1, 2, 3, 4, 5, 6, 7, 80, 81, 82, 83, 84, 85, 86, 87]; for &n in &lengths { - let mut v = repeat(0u8).take(n).collect::<Vec<_>>(); + let mut v = repeat(0).take(n).collect::<Vec<_>>(); r.fill_bytes(&mut v); // use this to get nicer error messages. @@ -500,14 +500,14 @@ mod test { } #[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); diff --git a/src/libstd/rand/os.rs b/src/libstd/rand/os.rs index c2ead267578..6cb3eb4d16e 100644 --- a/src/libstd/rand/os.rs +++ b/src/libstd/rand/os.rs @@ -80,13 +80,13 @@ mod imp { } fn getrandom_next_u32() -> u32 { - let mut buf: [u8; 4] = [0u8; 4]; + let mut buf: [u8; 4] = [0; 4]; getrandom_fill_bytes(&mut buf); unsafe { mem::transmute::<[u8; 4], u32>(buf) } } fn getrandom_next_u64() -> u64 { - let mut buf: [u8; 8] = [0u8; 8]; + let mut buf: [u8; 8] = [0; 8]; getrandom_fill_bytes(&mut buf); unsafe { mem::transmute::<[u8; 8], u64>(buf) } } @@ -231,12 +231,12 @@ mod imp { impl Rng for OsRng { fn next_u32(&mut self) -> u32 { - let mut v = [0u8; 4]; + let mut v = [0; 4]; self.fill_bytes(&mut v); unsafe { mem::transmute(v) } } fn next_u64(&mut self) -> u64 { - let mut v = [0u8; 8]; + let mut v = [0; 8]; self.fill_bytes(&mut v); unsafe { mem::transmute(v) } } @@ -318,12 +318,12 @@ mod imp { impl Rng for OsRng { fn next_u32(&mut self) -> u32 { - let mut v = [0u8; 4]; + let mut v = [0; 4]; self.fill_bytes(&mut v); unsafe { mem::transmute(v) } } fn next_u64(&mut self) -> u64 { - let mut v = [0u8; 8]; + let mut v = [0; 8]; self.fill_bytes(&mut v); unsafe { mem::transmute(v) } } @@ -366,7 +366,7 @@ mod test { r.next_u32(); r.next_u64(); - let mut v = [0u8; 1000]; + let mut v = [0; 1000]; r.fill_bytes(&mut v); } @@ -386,7 +386,7 @@ mod test { // as possible (XXX: is this a good test?) let mut r = OsRng::new().unwrap(); thread::yield_now(); - let mut v = [0u8; 1000]; + let mut v = [0; 1000]; for _ in 0..100 { r.next_u32(); diff --git a/src/libstd/rand/reader.rs b/src/libstd/rand/reader.rs index b71e8b4fd61..c56dc387b7f 100644 --- a/src/libstd/rand/reader.rs +++ b/src/libstd/rand/reader.rs @@ -84,28 +84,28 @@ mod test { #[test] fn test_reader_rng_u64() { // transmute from the target to avoid endianness concerns. - let v = vec![0u8, 0, 0, 0, 0, 0, 0, 1, + let v = vec![0, 0, 0, 0, 0, 0, 0, 1, 0 , 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3]; let mut rng = ReaderRng::new(MemReader::new(v)); - assert_eq!(rng.next_u64(), 1_u64.to_be()); - assert_eq!(rng.next_u64(), 2_u64.to_be()); - assert_eq!(rng.next_u64(), 3_u64.to_be()); + assert_eq!(rng.next_u64(), 1.to_be()); + assert_eq!(rng.next_u64(), 2.to_be()); + assert_eq!(rng.next_u64(), 3.to_be()); } #[test] fn test_reader_rng_u32() { - let v = vec![0u8, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3]; + let v = vec![0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3]; let mut rng = ReaderRng::new(MemReader::new(v)); - assert_eq!(rng.next_u32(), 1_u32.to_be()); - assert_eq!(rng.next_u32(), 2_u32.to_be()); - assert_eq!(rng.next_u32(), 3_u32.to_be()); + assert_eq!(rng.next_u32(), 1.to_be()); + assert_eq!(rng.next_u32(), 2.to_be()); + assert_eq!(rng.next_u32(), 3.to_be()); } #[test] fn test_reader_rng_fill_bytes() { - let v = [1u8, 2, 3, 4, 5, 6, 7, 8]; - let mut w = [0u8; 8]; + let v = [1, 2, 3, 4, 5, 6, 7, 8]; + let mut w = [0; 8]; let mut rng = ReaderRng::new(MemReader::new(v.to_vec())); rng.fill_bytes(&mut w); @@ -114,10 +114,10 @@ mod test { } #[test] - #[should_fail] + #[should_panic] fn test_reader_rng_insufficient_bytes() { let mut rng = ReaderRng::new(MemReader::new(vec!())); - let mut v = [0u8; 3]; + let mut v = [0; 3]; rng.fill_bytes(&mut v); } } diff --git a/src/libstd/rt/util.rs b/src/libstd/rt/util.rs index a304f1f844d..dc557403153 100644 --- a/src/libstd/rt/util.rs +++ b/src/libstd/rt/util.rs @@ -139,7 +139,7 @@ pub fn abort(args: fmt::Arguments) -> ! { } // Convert the arguments into a stack-allocated string - let mut msg = [0u8; 512]; + let mut msg = [0; 512]; let mut w = BufWriter { buf: &mut msg, pos: 0 }; let _ = write!(&mut w, "{}", args); let msg = str::from_utf8(&w.buf[..w.pos]).unwrap_or("aborted"); diff --git a/src/libstd/sync/condvar.rs b/src/libstd/sync/condvar.rs index e7ee9bd2066..3499675f542 100644 --- a/src/libstd/sync/condvar.rs +++ b/src/libstd/sync/condvar.rs @@ -479,7 +479,7 @@ mod tests { } #[test] - #[should_fail] + #[should_panic] fn two_mutexes() { static M1: StaticMutex = MUTEX_INIT; static M2: StaticMutex = MUTEX_INIT; diff --git a/src/libstd/sync/future.rs b/src/libstd/sync/future.rs index d60e2738808..ee9bcd3dd89 100644 --- a/src/libstd/sync/future.rs +++ b/src/libstd/sync/future.rs @@ -204,7 +204,7 @@ mod test { } #[test] - #[should_fail] + #[should_panic] fn test_future_panic() { let mut f = Future::spawn(move|| panic!()); let _x: String = f.get(); diff --git a/src/libstd/sync/mpsc/mod.rs b/src/libstd/sync/mpsc/mod.rs index 1a1e9e69e71..2ae1d4a9d50 100644 --- a/src/libstd/sync/mpsc/mod.rs +++ b/src/libstd/sync/mpsc/mod.rs @@ -318,6 +318,7 @@ use prelude::v1::*; use sync::Arc; +use error; use fmt; use mem; use cell::UnsafeCell; @@ -976,6 +977,18 @@ impl<T> fmt::Display for SendError<T> { } #[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 { match *self { @@ -1000,6 +1013,25 @@ impl<T> fmt::Display for TrySendError<T> { } #[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 { "receiving on a closed channel".fmt(f) @@ -1007,6 +1039,18 @@ impl fmt::Display for RecvError { } #[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 { match *self { @@ -1020,6 +1064,25 @@ impl fmt::Display for TryRecvError { } } +#[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::*; diff --git a/src/libstd/sync/task_pool.rs b/src/libstd/sync/task_pool.rs index efb6689e785..e41bc6d8683 100644 --- a/src/libstd/sync/task_pool.rs +++ b/src/libstd/sync/task_pool.rs @@ -164,7 +164,7 @@ mod test { } #[test] - #[should_fail] + #[should_panic] fn test_zero_tasks_panic() { TaskPool::new(0); } diff --git a/src/libstd/sys/common/net.rs b/src/libstd/sys/common/net.rs index 228362e3d62..344645dfc1a 100644 --- a/src/libstd/sys/common/net.rs +++ b/src/libstd/sys/common/net.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![allow(deprecated)] + use prelude::v1::*; use self::SocketStatus::*; use self::InAddr::*; diff --git a/src/libstd/sys/common/thread_local.rs b/src/libstd/sys/common/thread_local.rs index 27b8784e394..91de2662883 100644 --- a/src/libstd/sys/common/thread_local.rs +++ b/src/libstd/sys/common/thread_local.rs @@ -55,6 +55,7 @@ //! ``` #![allow(non_camel_case_types)] +#![unstable(feature = "thread_local_internals")] use prelude::v1::*; @@ -84,17 +85,14 @@ use sys::thread_local as imp; /// KEY.set(1 as *mut u8); /// } /// ``` -#[stable(feature = "rust1", since = "1.0.0")] pub struct StaticKey { /// Inner static TLS key (internals), created with by `INIT_INNER` in this /// module. - #[stable(feature = "rust1", since = "1.0.0")] pub inner: StaticKeyInner, /// Destructor for the TLS value. /// /// See `Key::new` for information about when the destructor runs and how /// it runs. - #[stable(feature = "rust1", since = "1.0.0")] pub dtor: Option<unsafe extern fn(*mut u8)>, } @@ -131,7 +129,6 @@ pub struct Key { /// Constant initialization value for static TLS keys. /// /// This value specifies no destructor by default. -#[stable(feature = "rust1", since = "1.0.0")] pub const INIT: StaticKey = StaticKey { inner: INIT_INNER, dtor: None, @@ -140,7 +137,6 @@ pub const INIT: StaticKey = StaticKey { /// Constant initialization value for the inner part of static TLS keys. /// /// This value allows specific configuration of the destructor for a TLS key. -#[stable(feature = "rust1", since = "1.0.0")] pub const INIT_INNER: StaticKeyInner = StaticKeyInner { key: atomic::ATOMIC_USIZE_INIT, }; diff --git a/src/libstd/sys/common/wtf8.rs b/src/libstd/sys/common/wtf8.rs index 31bdaee1e34..7a02df23b19 100644 --- a/src/libstd/sys/common/wtf8.rs +++ b/src/libstd/sys/common/wtf8.rs @@ -714,7 +714,7 @@ pub fn is_code_point_boundary(slice: &Wtf8, index: uint) -> bool { if index == slice.len() { return true; } match slice.bytes.get(index) { None => false, - Some(&b) => b < 128u8 || b >= 192u8, + Some(&b) => b < 128 || b >= 192, } } @@ -776,7 +776,7 @@ impl<'a> Iterator for EncodeWide<'a> { return Some(tmp); } - let mut buf = [0u16; 2]; + let mut buf = [0; 2]; self.code_points.next().map(|code_point| { let n = encode_utf16_raw(code_point.value, &mut buf) .unwrap_or(0); @@ -1030,14 +1030,14 @@ mod tests { } #[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 @@ mod tests { } #[test] - #[should_fail] + #[should_panic] fn wtf8_slice_not_code_point_boundary() { &Wtf8::from_str("aé 💩")[2.. 4]; } @@ -1144,7 +1144,7 @@ mod tests { } #[test] - #[should_fail] + #[should_panic] fn wtf8_slice_from_not_code_point_boundary() { &Wtf8::from_str("aé 💩")[2..]; } @@ -1155,7 +1155,7 @@ mod tests { } #[test] - #[should_fail] + #[should_panic] fn wtf8_slice_to_not_code_point_boundary() { &Wtf8::from_str("aé 💩")[5..]; } diff --git a/src/libstd/sys/unix/ext.rs b/src/libstd/sys/unix/ext.rs index 3f9da6e3c51..ca7f7c4c0ca 100644 --- a/src/libstd/sys/unix/ext.rs +++ b/src/libstd/sys/unix/ext.rs @@ -54,6 +54,7 @@ pub trait AsRawFd { fn as_raw_fd(&self) -> Fd; } +#[allow(deprecated)] impl AsRawFd for old_io::fs::File { fn as_raw_fd(&self) -> Fd { self.as_inner().fd() @@ -72,42 +73,49 @@ impl AsRawFd for old_io::pipe::PipeStream { } } +#[allow(deprecated)] impl AsRawFd for old_io::net::pipe::UnixStream { fn as_raw_fd(&self) -> Fd { self.as_inner().fd() } } +#[allow(deprecated)] impl AsRawFd for old_io::net::pipe::UnixListener { fn as_raw_fd(&self) -> Fd { self.as_inner().fd() } } +#[allow(deprecated)] impl AsRawFd for old_io::net::pipe::UnixAcceptor { fn as_raw_fd(&self) -> Fd { self.as_inner().fd() } } +#[allow(deprecated)] impl AsRawFd for old_io::net::tcp::TcpStream { fn as_raw_fd(&self) -> Fd { self.as_inner().fd() } } +#[allow(deprecated)] impl AsRawFd for old_io::net::tcp::TcpListener { fn as_raw_fd(&self) -> Fd { self.as_inner().fd() } } +#[allow(deprecated)] impl AsRawFd for old_io::net::tcp::TcpAcceptor { fn as_raw_fd(&self) -> Fd { self.as_inner().fd() } } +#[allow(deprecated)] impl AsRawFd for old_io::net::udp::UdpSocket { fn as_raw_fd(&self) -> Fd { self.as_inner().fd() diff --git a/src/libstd/sys/unix/fs.rs b/src/libstd/sys/unix/fs.rs index 71b6214460f..3d490380bfd 100644 --- a/src/libstd/sys/unix/fs.rs +++ b/src/libstd/sys/unix/fs.rs @@ -389,7 +389,7 @@ mod tests { let mut writer = FileDesc::new(writer, true); writer.write(b"test").ok().unwrap(); - let mut buf = [0u8; 4]; + let mut buf = [0; 4]; match reader.read(&mut buf) { Ok(4) => { assert_eq!(buf[0], 't' as u8); diff --git a/src/libstd/sys/unix/process.rs b/src/libstd/sys/unix/process.rs index 68c5c65e7cd..62a1799de94 100644 --- a/src/libstd/sys/unix/process.rs +++ b/src/libstd/sys/unix/process.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![allow(deprecated)] + use prelude::v1::*; use self::Req::*; diff --git a/src/libstd/sys/unix/tcp.rs b/src/libstd/sys/unix/tcp.rs index b08f6ef9b90..4fcaf504c3d 100644 --- a/src/libstd/sys/unix/tcp.rs +++ b/src/libstd/sys/unix/tcp.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![allow(deprecated)] + use prelude::v1::*; use old_io::net::ip; diff --git a/src/libstd/sys/windows/ext.rs b/src/libstd/sys/windows/ext.rs index ac1006e653f..b30aec08439 100644 --- a/src/libstd/sys/windows/ext.rs +++ b/src/libstd/sys/windows/ext.rs @@ -39,6 +39,7 @@ pub trait AsRawHandle { fn as_raw_handle(&self) -> Handle; } +#[allow(deprecated)] impl AsRawHandle for old_io::fs::File { fn as_raw_handle(&self) -> Handle { self.as_inner().handle() @@ -57,18 +58,21 @@ impl AsRawHandle for old_io::pipe::PipeStream { } } +#[allow(deprecated)] impl AsRawHandle for old_io::net::pipe::UnixStream { fn as_raw_handle(&self) -> Handle { self.as_inner().handle() } } +#[allow(deprecated)] impl AsRawHandle for old_io::net::pipe::UnixListener { fn as_raw_handle(&self) -> Handle { self.as_inner().handle() } } +#[allow(deprecated)] impl AsRawHandle for old_io::net::pipe::UnixAcceptor { fn as_raw_handle(&self) -> Handle { self.as_inner().handle() @@ -80,24 +84,28 @@ pub trait AsRawSocket { fn as_raw_socket(&self) -> Socket; } +#[allow(deprecated)] impl AsRawSocket for old_io::net::tcp::TcpStream { fn as_raw_socket(&self) -> Socket { self.as_inner().fd() } } +#[allow(deprecated)] impl AsRawSocket for old_io::net::tcp::TcpListener { fn as_raw_socket(&self) -> Socket { self.as_inner().socket() } } +#[allow(deprecated)] impl AsRawSocket for old_io::net::tcp::TcpAcceptor { fn as_raw_socket(&self) -> Socket { self.as_inner().socket() } } +#[allow(deprecated)] impl AsRawSocket for old_io::net::udp::UdpSocket { fn as_raw_socket(&self) -> Socket { self.as_inner().fd() diff --git a/src/libstd/sys/windows/process.rs b/src/libstd/sys/windows/process.rs index 334cafd3eb1..ca3ed54eb03 100644 --- a/src/libstd/sys/windows/process.rs +++ b/src/libstd/sys/windows/process.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![allow(deprecated)] + use prelude::v1::*; use collections; @@ -17,7 +19,7 @@ use hash::Hash; use libc::{pid_t, c_void}; use libc; use mem; -use old_io::fs::PathExtensions; +#[allow(deprecated)] use old_io::fs::PathExtensions; use old_io::process::{ProcessExit, ExitStatus}; use old_io::{IoResult, IoError}; use old_io; diff --git a/src/libstd/sys/windows/tcp.rs b/src/libstd/sys/windows/tcp.rs index 25b70918591..8547de145f8 100644 --- a/src/libstd/sys/windows/tcp.rs +++ b/src/libstd/sys/windows/tcp.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![allow(deprecated)] + use old_io::net::ip; use old_io::IoResult; use libc; diff --git a/src/libstd/thread.rs b/src/libstd/thread.rs index 9be77e78ed1..7d0df679591 100644 --- a/src/libstd/thread.rs +++ b/src/libstd/thread.rs @@ -284,7 +284,7 @@ impl Builder { 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( @@ -901,7 +901,7 @@ mod test { assert!(e.is::<T>()); let any = e.downcast::<T>().ok().unwrap(); assert!(any.is::<u16>()); - assert_eq!(*any.downcast::<u16>().ok().unwrap(), 413u16); + assert_eq!(*any.downcast::<u16>().ok().unwrap(), 413); } Ok(()) => panic!() } diff --git a/src/libstd/thread_local/mod.rs b/src/libstd/thread_local/mod.rs index 764c7d730cb..6bba73420d8 100644 --- a/src/libstd/thread_local/mod.rs +++ b/src/libstd/thread_local/mod.rs @@ -45,7 +45,7 @@ pub mod scoped; // Sure wish we had macro hygiene, no? #[doc(hidden)] -#[stable(feature = "rust1", since = "1.0.0")] +#[unstable(feature = "thread_local_internals")] pub mod __impl { pub use super::imp::Key as KeyInner; pub use super::imp::destroy_value; @@ -117,6 +117,7 @@ pub struct Key<T> { /// Declare a new thread local storage key of type `std::thread_local::Key`. #[macro_export] #[stable(feature = "rust1", since = "1.0.0")] +#[allow_internal_unstable] macro_rules! thread_local { (static $name:ident: $t:ty = $init:expr) => ( static $name: ::std::thread_local::Key<$t> = { @@ -176,6 +177,7 @@ macro_rules! thread_local { #[macro_export] #[doc(hidden)] +#[allow_internal_unstable] macro_rules! __thread_local_inner { (static $name:ident: $t:ty = $init:expr) => ( #[cfg_attr(all(any(target_os = "macos", target_os = "linux"), @@ -337,7 +339,7 @@ mod imp { use ptr; #[doc(hidden)] - #[stable(since = "1.0.0", feature = "rust1")] + #[unstable(feature = "thread_local_internals")] pub struct Key<T> { // Place the inner bits in an `UnsafeCell` to currently get around the // "only Sync statics" restriction. This allows any type to be placed in @@ -345,14 +347,14 @@ mod imp { // // Note that all access requires `T: 'static` so it can't be a type with // any borrowed pointers still. - #[stable(since = "1.0.0", feature = "rust1")] + #[unstable(feature = "thread_local_internals")] pub inner: UnsafeCell<T>, // Metadata to keep track of the state of the destructor. Remember that // these variables are thread-local, not global. - #[stable(since = "1.0.0", feature = "rust1")] + #[unstable(feature = "thread_local_internals")] pub dtor_registered: UnsafeCell<bool>, // should be Cell - #[stable(since = "1.0.0", feature = "rust1")] + #[unstable(feature = "thread_local_internals")] pub dtor_running: UnsafeCell<bool>, // should be Cell } @@ -455,7 +457,7 @@ mod imp { } #[doc(hidden)] - #[stable(feature = "rust1", since = "1.0.0")] + #[unstable(feature = "thread_local_internals")] pub unsafe extern fn destroy_value<T>(ptr: *mut u8) { let ptr = ptr as *mut Key<T>; // Right before we run the user destructor be sure to flag the @@ -477,15 +479,15 @@ mod imp { use sys_common::thread_local::StaticKey as OsStaticKey; #[doc(hidden)] - #[stable(since = "1.0.0", feature = "rust1")] + #[unstable(feature = "thread_local_internals")] pub struct Key<T> { // Statically allocated initialization expression, using an `UnsafeCell` // for the same reasons as above. - #[stable(since = "1.0.0", feature = "rust1")] + #[unstable(feature = "thread_local_internals")] pub inner: UnsafeCell<T>, // OS-TLS key that we'll use to key off. - #[stable(since = "1.0.0", feature = "rust1")] + #[unstable(feature = "thread_local_internals")] pub os: OsStaticKey, } @@ -528,7 +530,7 @@ mod imp { } #[doc(hidden)] - #[stable(feature = "rust1", since = "1.0.0")] + #[unstable(feature = "thread_local_internals")] pub unsafe extern fn destroy_value<T: 'static>(ptr: *mut u8) { // The OS TLS ensures that this key contains a NULL value when this // destructor starts to run. We set it back to a sentinel value of 1 to diff --git a/src/libstd/thread_local/scoped.rs b/src/libstd/thread_local/scoped.rs index d89d69e9497..a5339568e9e 100644 --- a/src/libstd/thread_local/scoped.rs +++ b/src/libstd/thread_local/scoped.rs @@ -65,6 +65,7 @@ pub struct Key<T> { #[doc(hidden)] pub inner: __impl::KeyInner<T> } /// This macro declares a `static` item on which methods are used to get and /// set the value stored within. #[macro_export] +#[allow_internal_unstable] macro_rules! scoped_thread_local { (static $name:ident: $t:ty) => ( __scoped_thread_local_inner!(static $name: $t); @@ -76,6 +77,7 @@ macro_rules! scoped_thread_local { #[macro_export] #[doc(hidden)] +#[allow_internal_unstable] macro_rules! __scoped_thread_local_inner { (static $name:ident: $t:ty) => ( #[cfg_attr(not(any(windows, diff --git a/src/libstd/time/duration.rs b/src/libstd/time/duration.rs index 42ef3459a0e..958417d864c 100644 --- a/src/libstd/time/duration.rs +++ b/src/libstd/time/duration.rs @@ -68,7 +68,7 @@ pub const MAX: Duration = Duration { impl Duration { /// Makes a new `Duration` with given number of weeks. - /// Equivalent to `Duration::seconds(weeks * 7 * 24 * 60 * 60), with overflow checks. + /// Equivalent to `Duration::seconds(weeks * 7 * 24 * 60 * 60)` with overflow checks. /// Panics when the duration is out of bounds. #[inline] #[unstable(feature = "std_misc")] diff --git a/src/libstd/tuple.rs b/src/libstd/tuple.rs index 988b13cd160..41b70889c9f 100644 --- a/src/libstd/tuple.rs +++ b/src/libstd/tuple.rs @@ -53,7 +53,7 @@ //! assert!(b == c); //! //! let d : (u32, f32) = Default::default(); -//! assert_eq!(d, (0u32, 0.0f32)); +//! assert_eq!(d, (0, 0.0f32)); //! ``` #![doc(primitive = "tuple")] diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 6d6fdffa950..550ce3bb8c8 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -58,9 +58,12 @@ pub use self::PathParameters::*; use codemap::{Span, Spanned, DUMMY_SP, ExpnId}; use abi::Abi; use ast_util; +use ext::base; +use ext::tt::macro_parser; use owned_slice::OwnedSlice; use parse::token::{InternedString, str_to_ident}; use parse::token; +use parse::lexer; use ptr::P; use std::fmt; @@ -960,6 +963,18 @@ impl TokenTree { TtSequence(span, _) => span, } } + + /// Use this token tree as a matcher to parse given tts. + pub fn parse(cx: &base::ExtCtxt, mtch: &[TokenTree], tts: &[TokenTree]) + -> macro_parser::NamedParseResult { + // `None` is because we're not interpolating + let arg_rdr = lexer::new_tt_reader_with_doc_flag(&cx.parse_sess().span_diagnostic, + None, + None, + tts.iter().cloned().collect(), + true); + macro_parser::parse(cx.parse_sess(), cx.cfg(), arg_rdr, mtch) + } } pub type Mac = Spanned<Mac_>; @@ -1249,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 (`[T; n]`) TyFixedLengthVec(P<Ty>, P<Expr>), /// A raw pointer (`*const T` or `*mut T`) TyPtr(MutTy), @@ -1728,6 +1743,7 @@ pub struct MacroDef { pub imported_from: Option<Ident>, pub export: bool, pub use_locally: bool, + pub allow_internal_unstable: bool, pub body: Vec<TokenTree>, } diff --git a/src/libsyntax/ast_map/mod.rs b/src/libsyntax/ast_map/mod.rs index 18b5d21318f..b96d735d92d 100644 --- a/src/libsyntax/ast_map/mod.rs +++ b/src/libsyntax/ast_map/mod.rs @@ -25,7 +25,7 @@ use visit::{self, Visitor}; use arena::TypedArena; use std::cell::RefCell; use std::fmt; -use std::old_io::IoResult; +use std::io; use std::iter::{self, repeat}; use std::mem; use std::slice; @@ -994,11 +994,11 @@ pub fn map_decoded_item<'ast, F: FoldOps>(map: &Map<'ast>, } pub trait NodePrinter { - fn print_node(&mut self, node: &Node) -> IoResult<()>; + fn print_node(&mut self, node: &Node) -> io::Result<()>; } impl<'a> NodePrinter for pprust::State<'a> { - fn print_node(&mut self, node: &Node) -> IoResult<()> { + fn print_node(&mut self, node: &Node) -> io::Result<()> { match *node { NodeItem(a) => self.print_item(&*a), NodeForeignItem(a) => self.print_foreign_item(&*a), diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index 264e05f5c8d..26d7562cdb2 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -159,10 +159,10 @@ pub fn int_ty_to_string(t: IntTy, val: Option<i64>) -> String { pub fn int_ty_max(t: IntTy) -> u64 { match t { - TyI8 => 0x80u64, - TyI16 => 0x8000u64, - TyIs(_) | TyI32 => 0x80000000u64, // actually ni about TyIs - TyI64 => 0x8000000000000000u64 + TyI8 => 0x80, + TyI16 => 0x8000, + TyIs(_) | TyI32 => 0x80000000, // actually ni about TyIs + TyI64 => 0x8000000000000000 } } @@ -185,10 +185,10 @@ pub fn uint_ty_to_string(t: UintTy, val: Option<u64>) -> String { pub fn uint_ty_max(t: UintTy) -> u64 { match t { - TyU8 => 0xffu64, - TyU16 => 0xffffu64, - TyUs(_) | TyU32 => 0xffffffffu64, // actually ni about TyUs - TyU64 => 0xffffffffffffffffu64 + TyU8 => 0xff, + TyU16 => 0xffff, + TyUs(_) | TyU32 => 0xffffffff, // actually ni about TyUs + TyU64 => 0xffffffffffffffff } } diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs index 099f6462942..7d2d4e53fe9 100644 --- a/src/libsyntax/codemap.rs +++ b/src/libsyntax/codemap.rs @@ -29,6 +29,11 @@ use std::rc::Rc; use libc::c_uint; use serialize::{Encodable, Decodable, Encoder, Decoder}; + +// _____________________________________________________________________________ +// Pos, BytePos, CharPos +// + pub trait Pos { fn from_usize(n: usize) -> Self; fn to_usize(&self) -> usize; @@ -69,6 +74,18 @@ impl Sub for BytePos { } } +impl Encodable for BytePos { + fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> { + s.emit_u32(self.0) + } +} + +impl Decodable for BytePos { + fn decode<D: Decoder>(d: &mut D) -> Result<BytePos, D::Error> { + Ok(BytePos(try!{ d.read_u32() })) + } +} + impl Pos for CharPos { fn from_usize(n: usize) -> CharPos { CharPos(n) } fn to_usize(&self) -> usize { let CharPos(n) = *self; n } @@ -90,6 +107,10 @@ impl Sub for CharPos { } } +// _____________________________________________________________________________ +// Span, Spanned +// + /// Spans represent a region of code, used for error reporting. Positions in spans /// are *absolute* positions from the beginning of the codemap, not positions /// relative to FileMaps. Methods on the CodeMap can be used to relate spans back @@ -126,15 +147,20 @@ impl PartialEq for Span { impl Eq for Span {} impl Encodable for Span { - /* Note #1972 -- spans are encoded but not decoded */ fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> { - s.emit_nil() + // Encode spans as a single u64 in order to cut down on tagging overhead + // added by the RBML metadata encoding. The should be solved differently + // altogether some time (FIXME #21482) + s.emit_u64( (self.lo.0 as u64) | ((self.hi.0 as u64) << 32) ) } } impl Decodable for Span { - fn decode<D: Decoder>(_d: &mut D) -> Result<Span, D::Error> { - Ok(DUMMY_SP) + fn decode<D: Decoder>(d: &mut D) -> Result<Span, D::Error> { + let lo_hi: u64 = try! { d.read_u64() }; + let lo = BytePos(lo_hi as u32); + let hi = BytePos((lo_hi >> 32) as u32); + Ok(mk_sp(lo, hi)) } } @@ -168,6 +194,10 @@ pub fn original_sp(cm: &CodeMap, sp: Span, enclosing_sp: Span) -> Span { } } +// _____________________________________________________________________________ +// Loc, LocWithOpt, FileMapAndLine, FileMapAndBytePos +// + /// A source code location used for error reporting pub struct Loc { /// Information about the original source @@ -192,6 +222,11 @@ pub struct LocWithOpt { pub struct FileMapAndLine { pub fm: Rc<FileMap>, pub line: usize } pub struct FileMapAndBytePos { pub fm: Rc<FileMap>, pub pos: BytePos } + +// _____________________________________________________________________________ +// MacroFormat, NameAndSpan, ExpnInfo, ExpnId +// + /// The syntax with which a macro was invoked. #[derive(Clone, Copy, Hash, Debug)] pub enum MacroFormat { @@ -208,6 +243,10 @@ pub struct NameAndSpan { pub name: String, /// The format with which the macro was invoked. pub format: MacroFormat, + /// Whether the macro is allowed to use #[unstable]/feature-gated + /// features internally without forcing the whole crate to opt-in + /// to them. + pub allow_internal_unstable: bool, /// The span of the macro definition itself. The macro may not /// have a sensible definition span (e.g. something defined /// completely inside libsyntax) in which case this is None. @@ -254,6 +293,10 @@ impl ExpnId { } } +// _____________________________________________________________________________ +// FileMap, MultiByteChar, FileName, FileLines +// + pub type FileName = String; pub struct FileLines { @@ -262,7 +305,7 @@ pub struct FileLines { } /// Identifies an offset of a multi-byte character in a FileMap -#[derive(Copy)] +#[derive(Copy, RustcEncodable, RustcDecodable, Eq, PartialEq)] pub struct MultiByteChar { /// The absolute offset of the character in the CodeMap pub pos: BytePos, @@ -277,13 +320,134 @@ pub struct FileMap { /// e.g. `<anon>` pub name: FileName, /// The complete source code - pub src: String, + pub src: Option<Rc<String>>, /// The start position of this source in the CodeMap pub start_pos: BytePos, + /// The end position of this source in the CodeMap + pub end_pos: BytePos, /// Locations of lines beginnings in the source code - pub lines: RefCell<Vec<BytePos> >, + pub lines: RefCell<Vec<BytePos>>, /// Locations of multi-byte characters in the source code - pub multibyte_chars: RefCell<Vec<MultiByteChar> >, + pub multibyte_chars: RefCell<Vec<MultiByteChar>>, +} + +impl Encodable for FileMap { + fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> { + s.emit_struct("FileMap", 5, |s| { + try! { s.emit_struct_field("name", 0, |s| self.name.encode(s)) }; + try! { s.emit_struct_field("start_pos", 1, |s| self.start_pos.encode(s)) }; + try! { s.emit_struct_field("end_pos", 2, |s| self.end_pos.encode(s)) }; + try! { s.emit_struct_field("lines", 3, |s| { + let lines = self.lines.borrow(); + // store the length + try! { s.emit_u32(lines.len() as u32) }; + + if lines.len() > 0 { + // In order to preserve some space, we exploit the fact that + // the lines list is sorted and individual lines are + // probably not that long. Because of that we can store lines + // as a difference list, using as little space as possible + // for the differences. + let max_line_length = if lines.len() == 1 { + 0 + } else { + lines.as_slice() + .windows(2) + .map(|w| w[1] - w[0]) + .map(|bp| bp.to_usize()) + .max() + .unwrap() + }; + + let bytes_per_diff: u8 = match max_line_length { + 0 ... 0xFF => 1, + 0x100 ... 0xFFFF => 2, + _ => 4 + }; + + // Encode the number of bytes used per diff. + try! { bytes_per_diff.encode(s) }; + + // Encode the first element. + try! { lines[0].encode(s) }; + + let diff_iter = (&lines[..]).windows(2) + .map(|w| (w[1] - w[0])); + + match bytes_per_diff { + 1 => for diff in diff_iter { try! { (diff.0 as u8).encode(s) } }, + 2 => for diff in diff_iter { try! { (diff.0 as u16).encode(s) } }, + 4 => for diff in diff_iter { try! { (diff.0 as u32).encode(s) } }, + _ => unreachable!() + } + } + + Ok(()) + }) + }; + s.emit_struct_field("multibyte_chars", 4, |s| { + (*self.multibyte_chars.borrow()).encode(s) + }) + }) + } +} + +impl Decodable for FileMap { + fn decode<D: Decoder>(d: &mut D) -> Result<FileMap, D::Error> { + + d.read_struct("FileMap", 5, |d| { + let name: String = try! { + d.read_struct_field("name", 0, |d| Decodable::decode(d)) + }; + let start_pos: BytePos = try! { + d.read_struct_field("start_pos", 1, |d| Decodable::decode(d)) + }; + let end_pos: BytePos = try! { + d.read_struct_field("end_pos", 2, |d| Decodable::decode(d)) + }; + let lines: Vec<BytePos> = try! { + d.read_struct_field("lines", 3, |d| { + let num_lines: u32 = try! { Decodable::decode(d) }; + let mut lines = Vec::with_capacity(num_lines as usize); + + if num_lines > 0 { + // Read the number of bytes used per diff. + let bytes_per_diff: u8 = try! { Decodable::decode(d) }; + + // Read the first element. + let mut line_start: BytePos = try! { Decodable::decode(d) }; + lines.push(line_start); + + for _ in 1..num_lines { + let diff = match bytes_per_diff { + 1 => try! { d.read_u8() } as u32, + 2 => try! { d.read_u16() } as u32, + 4 => try! { d.read_u32() }, + _ => unreachable!() + }; + + line_start = line_start + BytePos(diff); + + lines.push(line_start); + } + } + + Ok(lines) + }) + }; + let multibyte_chars: Vec<MultiByteChar> = try! { + d.read_struct_field("multibyte_chars", 4, |d| Decodable::decode(d)) + }; + Ok(FileMap { + name: name, + start_pos: start_pos, + end_pos: end_pos, + src: None, + lines: RefCell::new(lines), + multibyte_chars: RefCell::new(multibyte_chars) + }) + }) + } } impl FileMap { @@ -307,16 +471,21 @@ impl FileMap { /// get a line from the list of pre-computed line-beginnings /// pub fn get_line(&self, line_number: usize) -> Option<String> { - let lines = self.lines.borrow(); - lines.get(line_number).map(|&line| { - let begin: BytePos = line - self.start_pos; - let begin = begin.to_usize(); - let slice = &self.src[begin..]; - match slice.find('\n') { - Some(e) => &slice[..e], - None => slice - }.to_string() - }) + match self.src { + Some(ref src) => { + let lines = self.lines.borrow(); + lines.get(line_number).map(|&line| { + let begin: BytePos = line - self.start_pos; + let begin = begin.to_usize(); + let slice = &src[begin..]; + match slice.find('\n') { + Some(e) => &slice[..e], + None => slice + }.to_string() + }) + } + None => None + } } pub fn record_multibyte_char(&self, pos: BytePos, bytes: usize) { @@ -332,8 +501,17 @@ impl FileMap { !(self.name.starts_with("<") && self.name.ends_with(">")) } + + pub fn is_imported(&self) -> bool { + self.src.is_none() + } } + +// _____________________________________________________________________________ +// CodeMap +// + pub struct CodeMap { pub files: RefCell<Vec<Rc<FileMap>>>, expansions: RefCell<Vec<ExpnInfo>> @@ -351,7 +529,7 @@ impl CodeMap { let mut files = self.files.borrow_mut(); let start_pos = match files.last() { None => 0, - Some(last) => last.start_pos.to_usize() + last.src.len(), + Some(last) => last.end_pos.to_usize(), }; // Remove utf-8 BOM if any. @@ -372,10 +550,13 @@ impl CodeMap { src.push('\n'); } + let end_pos = start_pos + src.len(); + let filemap = Rc::new(FileMap { name: filename, - src: src.to_string(), + src: Some(Rc::new(src)), start_pos: Pos::from_usize(start_pos), + end_pos: Pos::from_usize(end_pos), lines: RefCell::new(Vec::new()), multibyte_chars: RefCell::new(Vec::new()), }); @@ -385,6 +566,45 @@ impl CodeMap { filemap } + /// Allocates a new FileMap representing a source file from an external + /// crate. The source code of such an "imported filemap" is not available, + /// but we still know enough to generate accurate debuginfo location + /// information for things inlined from other crates. + pub fn new_imported_filemap(&self, + filename: FileName, + source_len: usize, + file_local_lines: Vec<BytePos>, + file_local_multibyte_chars: Vec<MultiByteChar>) + -> Rc<FileMap> { + let mut files = self.files.borrow_mut(); + let start_pos = match files.last() { + None => 0, + Some(last) => last.end_pos.to_usize(), + }; + + let end_pos = Pos::from_usize(start_pos + source_len); + let start_pos = Pos::from_usize(start_pos); + + let lines = file_local_lines.map_in_place(|pos| pos + start_pos); + let multibyte_chars = file_local_multibyte_chars.map_in_place(|mbc| MultiByteChar { + pos: mbc.pos + start_pos, + bytes: mbc.bytes + }); + + let filemap = Rc::new(FileMap { + name: filename, + src: None, + start_pos: start_pos, + end_pos: end_pos, + lines: RefCell::new(lines), + multibyte_chars: RefCell::new(multibyte_chars), + }); + + files.push(filemap.clone()); + + filemap + } + pub fn mk_substr_filename(&self, sp: Span) -> String { let pos = self.lookup_char_pos(sp.lo); (format!("<{}:{}:{}>", @@ -442,30 +662,42 @@ impl CodeMap { return Err(SpanSnippetError::IllFormedSpan(sp)); } - let begin = self.lookup_byte_offset(sp.lo); - let end = self.lookup_byte_offset(sp.hi); + let local_begin = self.lookup_byte_offset(sp.lo); + let local_end = self.lookup_byte_offset(sp.hi); - if begin.fm.start_pos != end.fm.start_pos { + if local_begin.fm.start_pos != local_end.fm.start_pos { return Err(SpanSnippetError::DistinctSources(DistinctSources { - begin: (begin.fm.name.clone(), - begin.fm.start_pos), - end: (end.fm.name.clone(), - end.fm.start_pos) + begin: (local_begin.fm.name.clone(), + local_begin.fm.start_pos), + end: (local_end.fm.name.clone(), + local_end.fm.start_pos) })); } else { - let start = begin.pos.to_usize(); - let limit = end.pos.to_usize(); - if start > limit || limit > begin.fm.src.len() { - return Err(SpanSnippetError::MalformedForCodemap( - MalformedCodemapPositions { - name: begin.fm.name.clone(), - source_len: begin.fm.src.len(), - begin_pos: begin.pos, - end_pos: end.pos, - })); - } + match local_begin.fm.src { + Some(ref src) => { + let start_index = local_begin.pos.to_usize(); + let end_index = local_end.pos.to_usize(); + let source_len = (local_begin.fm.end_pos - + local_begin.fm.start_pos).to_usize(); + + if start_index > end_index || end_index > source_len { + return Err(SpanSnippetError::MalformedForCodemap( + MalformedCodemapPositions { + name: local_begin.fm.name.clone(), + source_len: source_len, + begin_pos: local_begin.pos, + end_pos: local_end.pos, + })); + } - return Ok((&begin.fm.src[start..limit]).to_string()) + return Ok((&src[start_index..end_index]).to_string()) + } + None => { + return Err(SpanSnippetError::SourceNotAvailable { + filename: local_begin.fm.name.clone() + }); + } + } } } @@ -478,6 +710,7 @@ impl CodeMap { panic!("asking for {} which we don't know about", filename); } + /// For a global BytePos compute the local offset within the containing FileMap pub fn lookup_byte_offset(&self, bpos: BytePos) -> FileMapAndBytePos { let idx = self.lookup_filemap_idx(bpos); let fm = (*self.files.borrow())[idx].clone(); @@ -601,49 +834,56 @@ impl CodeMap { } } - /// Check if a span is "internal" to a macro. This means that it is entirely generated by a - /// macro expansion and contains no code that was passed in as an argument. - pub fn span_is_internal(&self, span: Span) -> bool { - // first, check if the given expression was generated by a macro or not - // we need to go back the expn_info tree to check only the arguments - // of the initial macro call, not the nested ones. - let mut is_internal = false; - let mut expnid = span.expn_id; - while self.with_expn_info(expnid, |expninfo| { - match expninfo { - Some(ref info) => { - // save the parent expn_id for next loop iteration - expnid = info.call_site.expn_id; - if info.callee.name == "format_args" { - // This is a hack because the format_args builtin calls unstable APIs. - // I spent like 6 hours trying to solve this more generally but am stupid. - is_internal = true; - false - } else if info.callee.span.is_none() { - // it's a compiler built-in, we *really* don't want to mess with it - // so we skip it, unless it was called by a regular macro, in which case - // we will handle the caller macro next turn - is_internal = true; - true // continue looping + /// Check if a span is "internal" to a macro in which #[unstable] + /// items can be used (that is, a macro marked with + /// `#[allow_internal_unstable]`). + pub fn span_allows_unstable(&self, span: Span) -> bool { + debug!("span_allows_unstable(span = {:?})", span); + let mut allows_unstable = false; + let mut expn_id = span.expn_id; + loop { + let quit = self.with_expn_info(expn_id, |expninfo| { + debug!("span_allows_unstable: expninfo = {:?}", expninfo); + expninfo.map_or(/* hit the top level */ true, |info| { + + let span_comes_from_this_expansion = + info.callee.span.map_or(span == info.call_site, |mac_span| { + mac_span.lo <= span.lo && span.hi < mac_span.hi + }); + + debug!("span_allows_unstable: from this expansion? {}, allows unstable? {}", + span_comes_from_this_expansion, + info.callee.allow_internal_unstable); + if span_comes_from_this_expansion { + allows_unstable = info.callee.allow_internal_unstable; + // we've found the right place, stop looking + true } else { - // was this expression from the current macro arguments ? - is_internal = !( span.lo > info.call_site.lo && - span.hi < info.call_site.hi ); - true // continue looping + // not the right place, keep looking + expn_id = info.call_site.expn_id; + false } - }, - _ => false // stop looping + }) + }); + if quit { + break } - }) { /* empty while loop body */ } - return is_internal; + } + debug!("span_allows_unstable? {}", allows_unstable); + allows_unstable } } +// _____________________________________________________________________________ +// SpanSnippetError, DistinctSources, MalformedCodemapPositions +// + #[derive(Clone, PartialEq, Eq, Debug)] pub enum SpanSnippetError { IllFormedSpan(Span), DistinctSources(DistinctSources), MalformedForCodemap(MalformedCodemapPositions), + SourceNotAvailable { filename: String } } #[derive(Clone, PartialEq, Eq, Debug)] @@ -660,6 +900,11 @@ pub struct MalformedCodemapPositions { end_pos: BytePos } + +// _____________________________________________________________________________ +// Tests +// + #[cfg(test)] mod test { use super::*; @@ -677,7 +922,7 @@ mod test { } #[test] - #[should_fail] + #[should_panic] fn t2 () { let cm = CodeMap::new(); let fm = cm.new_filemap("blork.rs".to_string(), diff --git a/src/libsyntax/diagnostics/macros.rs b/src/libsyntax/diagnostics/macros.rs index 54689a1f77a..055ade46a3f 100644 --- a/src/libsyntax/diagnostics/macros.rs +++ b/src/libsyntax/diagnostics/macros.rs @@ -53,6 +53,13 @@ macro_rules! span_help { } #[macro_export] +macro_rules! fileline_help { + ($session:expr, $span:expr, $($message:tt)*) => ({ + ($session).fileline_help($span, &format!($($message)*)) + }) +} + +#[macro_export] macro_rules! register_diagnostics { ($($code:tt),*) => ( $(register_diagnostic! { $code })* diff --git a/src/libsyntax/ext/asm.rs b/src/libsyntax/ext/asm.rs index e58a3de41c0..d256698b885 100644 --- a/src/libsyntax/ext/asm.rs +++ b/src/libsyntax/ext/asm.rs @@ -214,6 +214,7 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) name: "asm".to_string(), format: codemap::MacroBang, span: None, + allow_internal_unstable: false, }, }); diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index ad5ca627a93..8aeafe419da 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -1,4 +1,4 @@ -// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT +// 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. // @@ -430,12 +430,15 @@ pub enum SyntaxExtension { /// A normal, function-like syntax extension. /// /// `bytes!` is a `NormalTT`. - NormalTT(Box<TTMacroExpander + 'static>, Option<Span>), + /// + /// The `bool` dictates whether the contents of the macro can + /// directly use `#[unstable]` things (true == yes). + NormalTT(Box<TTMacroExpander + 'static>, Option<Span>, bool), /// A function-like syntax extension that has an extra ident before /// the block. /// - IdentTT(Box<IdentMacroExpander + 'static>, Option<Span>), + IdentTT(Box<IdentMacroExpander + 'static>, Option<Span>, bool), /// Represents `macro_rules!` itself. MacroRulesTT, @@ -465,14 +468,14 @@ fn initial_syntax_expander_table<'feat>(ecfg: &expand::ExpansionConfig<'feat>) -> SyntaxEnv { // utility function to simplify creating NormalTT syntax extensions fn builtin_normal_expander(f: MacroExpanderFn) -> SyntaxExtension { - NormalTT(Box::new(f), None) + NormalTT(Box::new(f), None, false) } let mut syntax_expanders = SyntaxEnv::new(); syntax_expanders.insert(intern("macro_rules"), MacroRulesTT); syntax_expanders.insert(intern("format_args"), - builtin_normal_expander( - ext::format::expand_format_args)); + // format_args uses `unstable` things internally. + NormalTT(Box::new(ext::format::expand_format_args), None, true)); syntax_expanders.insert(intern("env"), builtin_normal_expander( ext::env::expand_env)); @@ -488,10 +491,8 @@ fn initial_syntax_expander_table<'feat>(ecfg: &expand::ExpansionConfig<'feat>) syntax_expanders.insert(intern("log_syntax"), builtin_normal_expander( ext::log_syntax::expand_syntax_ext)); - syntax_expanders.insert(intern("derive"), - Decorator(Box::new(ext::deriving::expand_meta_derive))); - syntax_expanders.insert(intern("deriving"), - Decorator(Box::new(ext::deriving::expand_deprecated_deriving))); + + ext::deriving::register_all(&mut syntax_expanders); if ecfg.enable_quotes() { // Quasi-quoting expanders @@ -519,6 +520,12 @@ fn initial_syntax_expander_table<'feat>(ecfg: &expand::ExpansionConfig<'feat>) syntax_expanders.insert(intern("quote_stmt"), builtin_normal_expander( ext::quote::expand_quote_stmt)); + syntax_expanders.insert(intern("quote_matcher"), + builtin_normal_expander( + ext::quote::expand_quote_matcher)); + syntax_expanders.insert(intern("quote_attr"), + builtin_normal_expander( + ext::quote::expand_quote_attr)); } syntax_expanders.insert(intern("line"), @@ -747,6 +754,10 @@ impl<'a> ExtCtxt<'a> { self.print_backtrace(); self.parse_sess.span_diagnostic.span_help(sp, msg); } + pub fn fileline_help(&self, sp: Span, msg: &str) { + self.print_backtrace(); + self.parse_sess.span_diagnostic.fileline_help(sp, msg); + } pub fn bug(&self, msg: &str) -> ! { self.print_backtrace(); self.parse_sess.span_diagnostic.handler().bug(msg); diff --git a/src/libsyntax/ext/deriving/bounds.rs b/src/libsyntax/ext/deriving/bounds.rs index 93098484ae0..e408c99935d 100644 --- a/src/libsyntax/ext/deriving/bounds.rs +++ b/src/libsyntax/ext/deriving/bounds.rs @@ -8,47 +8,34 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use ast::{MetaItem, MetaWord, Item}; +use ast::{MetaItem, Item}; use codemap::Span; use ext::base::ExtCtxt; use ext::deriving::generic::*; use ext::deriving::generic::ty::*; use ptr::P; -pub fn expand_deriving_bound<F>(cx: &mut ExtCtxt, - span: Span, - mitem: &MetaItem, - item: &Item, - push: F) where +pub fn expand_deriving_unsafe_bound<F>(cx: &mut ExtCtxt, + span: Span, + _: &MetaItem, + _: &Item, + _: F) where F: FnOnce(P<Item>), { - let name = match mitem.node { - MetaWord(ref tname) => { - match &tname[..] { - "Copy" => "Copy", - "Send" | "Sync" => { - return cx.span_err(span, - &format!("{} is an unsafe trait and it \ - should be implemented explicitly", - *tname)) - } - ref tname => { - cx.span_bug(span, - &format!("expected built-in trait name but \ - found {}", *tname)) - } - } - }, - _ => { - return cx.span_err(span, "unexpected value in deriving, expected \ - a trait") - } - }; + cx.span_err(span, "this unsafe trait should be implemented explicitly"); +} +pub fn expand_deriving_copy<F>(cx: &mut ExtCtxt, + span: Span, + mitem: &MetaItem, + item: &Item, + push: F) where + F: FnOnce(P<Item>), +{ let path = Path::new(vec![ if cx.use_std { "std" } else { "core" }, "marker", - name + "Copy", ]); let trait_def = TraitDef { diff --git a/src/libsyntax/ext/deriving/generic/mod.rs b/src/libsyntax/ext/deriving/generic/mod.rs index a36d3a155b8..9cd965a8138 100644 --- a/src/libsyntax/ext/deriving/generic/mod.rs +++ b/src/libsyntax/ext/deriving/generic/mod.rs @@ -1216,7 +1216,8 @@ impl<'a> TraitDef<'a> { callee: codemap::NameAndSpan { name: format!("derive({})", trait_name), format: codemap::MacroAttribute, - span: Some(self.span) + span: Some(self.span), + allow_internal_unstable: false, } }); to_set diff --git a/src/libsyntax/ext/deriving/mod.rs b/src/libsyntax/ext/deriving/mod.rs index 973c8f5fa1e..2631c28cf2f 100644 --- a/src/libsyntax/ext/deriving/mod.rs +++ b/src/libsyntax/ext/deriving/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2012-2013 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. // @@ -13,9 +13,13 @@ //! FIXME (#2810): hygiene. Search for "__" strings (in other files too). We also assume "extra" is //! the standard library, and "std" is the core library. -use ast::{Item, MetaItem, MetaList, MetaNameValue, MetaWord}; -use ext::base::ExtCtxt; +use ast::{Item, MetaItem, MetaWord}; +use attr::AttrMetaMethods; +use ext::base::{ExtCtxt, SyntaxEnv, Decorator, ItemDecorator, Modifier}; +use ext::build::AstBuilder; +use feature_gate; use codemap::Span; +use parse::token::{intern, intern_and_get_ident}; use ptr::P; macro_rules! pathvec { @@ -74,101 +78,133 @@ pub mod totalord; pub mod generic; -pub fn expand_deprecated_deriving(cx: &mut ExtCtxt, - span: Span, - _: &MetaItem, - _: &Item, - _: &mut FnMut(P<Item>)) { +fn expand_deprecated_deriving(cx: &mut ExtCtxt, + span: Span, + _: &MetaItem, + _: &Item, + _: &mut FnMut(P<Item>)) { cx.span_err(span, "`deriving` has been renamed to `derive`"); } -pub fn expand_meta_derive(cx: &mut ExtCtxt, - _span: Span, - mitem: &MetaItem, - item: &Item, - push: &mut FnMut(P<Item>)) { - match mitem.node { - MetaNameValue(_, ref l) => { - cx.span_err(l.span, "unexpected value in `derive`"); +fn expand_derive(cx: &mut ExtCtxt, + _: Span, + mitem: &MetaItem, + item: P<Item>) -> P<Item> { + item.map(|mut item| { + if mitem.value_str().is_some() { + cx.span_err(mitem.span, "unexpected value in `derive`"); } - MetaWord(_) => { + + let traits = mitem.meta_item_list().unwrap_or(&[]); + if traits.is_empty() { cx.span_warn(mitem.span, "empty trait list in `derive`"); } - MetaList(_, ref titems) if titems.len() == 0 => { - cx.span_warn(mitem.span, "empty trait list in `derive`"); + + for titem in traits.iter().rev() { + let tname = match titem.node { + MetaWord(ref tname) => tname, + _ => { + cx.span_err(titem.span, "malformed `derive` entry"); + continue; + } + }; + + if !(is_builtin_trait(tname) || cx.ecfg.enable_custom_derive()) { + feature_gate::emit_feature_err(&cx.parse_sess.span_diagnostic, + "custom_derive", + titem.span, + feature_gate::EXPLAIN_CUSTOM_DERIVE); + continue; + } + + // #[derive(Foo, Bar)] expands to #[derive_Foo] #[derive_Bar] + item.attrs.push(cx.attribute(titem.span, cx.meta_word(titem.span, + intern_and_get_ident(&format!("derive_{}", tname))))); } - MetaList(_, ref titems) => { - for titem in titems.iter().rev() { - match titem.node { - MetaNameValue(ref tname, _) | - MetaList(ref tname, _) | - MetaWord(ref tname) => { - macro_rules! expand { - ($func:path) => ($func(cx, titem.span, &**titem, item, - |i| push(i))) - } - - match &tname[..] { - "Clone" => expand!(clone::expand_deriving_clone), - - "Hash" => expand!(hash::expand_deriving_hash), - - "RustcEncodable" => { - expand!(encodable::expand_deriving_rustc_encodable) - } - "RustcDecodable" => { - expand!(decodable::expand_deriving_rustc_decodable) - } - "Encodable" => { - cx.span_warn(titem.span, - "derive(Encodable) is deprecated \ - in favor of derive(RustcEncodable)"); - - expand!(encodable::expand_deriving_encodable) - } - "Decodable" => { - cx.span_warn(titem.span, - "derive(Decodable) is deprecated \ - in favor of derive(RustcDecodable)"); - - expand!(decodable::expand_deriving_decodable) - } - - "PartialEq" => expand!(eq::expand_deriving_eq), - "Eq" => expand!(totaleq::expand_deriving_totaleq), - "PartialOrd" => expand!(ord::expand_deriving_ord), - "Ord" => expand!(totalord::expand_deriving_totalord), - - "Rand" => expand!(rand::expand_deriving_rand), - - "Show" => { - cx.span_warn(titem.span, - "derive(Show) is deprecated \ - in favor of derive(Debug)"); - - expand!(show::expand_deriving_show) - }, - - "Debug" => expand!(show::expand_deriving_show), - - "Default" => expand!(default::expand_deriving_default), - - "FromPrimitive" => expand!(primitive::expand_deriving_from_primitive), - - "Send" => expand!(bounds::expand_deriving_bound), - "Sync" => expand!(bounds::expand_deriving_bound), - "Copy" => expand!(bounds::expand_deriving_bound), - - ref tname => { - cx.span_err(titem.span, - &format!("unknown `derive` \ - trait: `{}`", - *tname)); - } - }; + + item + }) +} + +macro_rules! derive_traits { + ($( $name:expr => $func:path, )*) => { + pub fn register_all(env: &mut SyntaxEnv) { + // Define the #[derive_*] extensions. + $({ + struct DeriveExtension; + + impl ItemDecorator for DeriveExtension { + fn expand(&self, + ecx: &mut ExtCtxt, + sp: Span, + mitem: &MetaItem, + item: &Item, + push: &mut FnMut(P<Item>)) { + warn_if_deprecated(ecx, sp, $name); + $func(ecx, sp, mitem, item, |i| push(i)); } } + + env.insert(intern(concat!("derive_", $name)), + Decorator(Box::new(DeriveExtension))); + })* + + env.insert(intern("derive"), + Modifier(Box::new(expand_derive))); + env.insert(intern("deriving"), + Decorator(Box::new(expand_deprecated_deriving))); + } + + fn is_builtin_trait(name: &str) -> bool { + match name { + $( $name )|* => true, + _ => false, } } } } + +derive_traits! { + "Clone" => clone::expand_deriving_clone, + + "Hash" => hash::expand_deriving_hash, + + "RustcEncodable" => encodable::expand_deriving_rustc_encodable, + + "RustcDecodable" => decodable::expand_deriving_rustc_decodable, + + "PartialEq" => eq::expand_deriving_eq, + "Eq" => totaleq::expand_deriving_totaleq, + "PartialOrd" => ord::expand_deriving_ord, + "Ord" => totalord::expand_deriving_totalord, + + "Rand" => rand::expand_deriving_rand, + + "Debug" => show::expand_deriving_show, + + "Default" => default::expand_deriving_default, + + "FromPrimitive" => primitive::expand_deriving_from_primitive, + + "Send" => bounds::expand_deriving_unsafe_bound, + "Sync" => bounds::expand_deriving_unsafe_bound, + "Copy" => bounds::expand_deriving_copy, + + // deprecated + "Show" => show::expand_deriving_show, + "Encodable" => encodable::expand_deriving_encodable, + "Decodable" => decodable::expand_deriving_decodable, +} + +#[inline] // because `name` is a compile-time constant +fn warn_if_deprecated(ecx: &mut ExtCtxt, sp: Span, name: &str) { + if let Some(replacement) = match name { + "Show" => Some("Debug"), + "Encodable" => Some("RustcEncodable"), + "Decodable" => Some("RustcDecodable"), + _ => None, + } { + ecx.span_warn(sp, &format!("derive({}) is deprecated in favor of derive({})", + name, replacement)); + } +} diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index bea57ae14e4..98c7aefcd8a 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -22,7 +22,7 @@ use attr::AttrMetaMethods; use codemap; use codemap::{Span, Spanned, ExpnInfo, NameAndSpan, MacroBang, MacroAttribute}; use ext::base::*; -use feature_gate::{Features}; +use feature_gate::{self, Features}; use fold; use fold::*; use parse; @@ -395,13 +395,14 @@ fn expand_mac_invoc<T, F, G>(mac: ast::Mac, span: codemap::Span, None } Some(rc) => match *rc { - NormalTT(ref expandfun, exp_span) => { + NormalTT(ref expandfun, exp_span, allow_internal_unstable) => { fld.cx.bt_push(ExpnInfo { call_site: span, callee: NameAndSpan { name: extnamestr.to_string(), format: MacroBang, span: exp_span, + allow_internal_unstable: allow_internal_unstable, }, }); let fm = fresh_mark(); @@ -530,6 +531,9 @@ fn expand_item_modifiers(mut it: P<ast::Item>, fld: &mut MacroExpander) name: mname.to_string(), format: MacroAttribute, span: None, + // attributes can do whatever they like, + // for now + allow_internal_unstable: true, } }); it = mac.expand(fld.cx, attr.span, &*attr.node.value, it); @@ -571,7 +575,7 @@ fn contains_macro_use(fld: &mut MacroExpander, attrs: &[ast::Attribute]) -> bool fld.cx.span_warn(attr.span, "macro_escape is a deprecated synonym for macro_use"); is_use = true; if let ast::AttrInner = attr.node.style { - fld.cx.span_help(attr.span, "consider an outer attribute, \ + fld.cx.fileline_help(attr.span, "consider an outer attribute, \ #[macro_use] mod ..."); } }; @@ -614,7 +618,7 @@ pub fn expand_item_mac(it: P<ast::Item>, } Some(rc) => match *rc { - NormalTT(ref expander, span) => { + NormalTT(ref expander, span, allow_internal_unstable) => { if it.ident.name != parse::token::special_idents::invalid.name { fld.cx .span_err(path_span, @@ -628,14 +632,15 @@ pub fn expand_item_mac(it: P<ast::Item>, callee: NameAndSpan { name: extnamestr.to_string(), format: MacroBang, - span: span + span: span, + allow_internal_unstable: allow_internal_unstable, } }); // mark before expansion: let marked_before = mark_tts(&tts[..], fm); expander.expand(fld.cx, it.span, &marked_before[..]) } - IdentTT(ref expander, span) => { + IdentTT(ref expander, span, allow_internal_unstable) => { if it.ident.name == parse::token::special_idents::invalid.name { fld.cx.span_err(path_span, &format!("macro {}! expects an ident argument", @@ -647,7 +652,8 @@ pub fn expand_item_mac(it: P<ast::Item>, callee: NameAndSpan { name: extnamestr.to_string(), format: MacroBang, - span: span + span: span, + allow_internal_unstable: allow_internal_unstable, } }); // mark before expansion: @@ -661,16 +667,35 @@ pub fn expand_item_mac(it: P<ast::Item>, ); return SmallVector::zero(); } + fld.cx.bt_push(ExpnInfo { call_site: it.span, callee: NameAndSpan { name: extnamestr.to_string(), format: MacroBang, span: None, + // `macro_rules!` doesn't directly allow + // unstable (this is orthogonal to whether + // the macro it creates allows it) + allow_internal_unstable: false, } }); // DON'T mark before expansion. + let allow_internal_unstable = attr::contains_name(&it.attrs, + "allow_internal_unstable"); + + // ensure any #[allow_internal_unstable]s are + // detected (including nested macro definitions + // etc.) + if allow_internal_unstable && !fld.cx.ecfg.enable_allow_internal_unstable() { + feature_gate::emit_feature_err( + &fld.cx.parse_sess.span_diagnostic, + "allow_internal_unstable", + it.span, + feature_gate::EXPLAIN_ALLOW_INTERNAL_UNSTABLE) + } + let def = ast::MacroDef { ident: it.ident, attrs: it.attrs.clone(), @@ -679,6 +704,7 @@ pub fn expand_item_mac(it: P<ast::Item>, imported_from: None, export: attr::contains_name(&it.attrs, "macro_export"), use_locally: true, + allow_internal_unstable: allow_internal_unstable, body: tts, }; fld.cx.insert_macro(def); @@ -959,13 +985,14 @@ fn expand_pat(p: P<ast::Pat>, fld: &mut MacroExpander) -> P<ast::Pat> { } Some(rc) => match *rc { - NormalTT(ref expander, tt_span) => { + NormalTT(ref expander, tt_span, allow_internal_unstable) => { fld.cx.bt_push(ExpnInfo { call_site: span, callee: NameAndSpan { name: extnamestr.to_string(), format: MacroBang, - span: tt_span + span: tt_span, + allow_internal_unstable: allow_internal_unstable, } }); @@ -1094,7 +1121,10 @@ fn expand_annotatable(a: Annotatable, callee: NameAndSpan { name: mname.to_string(), format: MacroAttribute, - span: None + span: None, + // attributes can do whatever they like, + // for now. + allow_internal_unstable: true, } }); @@ -1244,6 +1274,9 @@ fn expand_item_multi_modifier(mut it: Annotatable, name: mname.to_string(), format: MacroAttribute, span: None, + // attributes can do whatever they like, + // for now + allow_internal_unstable: true, } }); it = mac.expand(fld.cx, attr.span, &*attr.node.value, it); @@ -1414,6 +1447,19 @@ pub struct ExpansionConfig<'feat> { pub recursion_limit: usize, } +macro_rules! feature_tests { + ($( fn $getter:ident = $field:ident, )*) => { + $( + pub fn $getter(&self) -> bool { + match self.features { + Some(&Features { $field: true, .. }) => true, + _ => false, + } + } + )* + } +} + impl<'feat> ExpansionConfig<'feat> { pub fn default(crate_name: String) -> ExpansionConfig<'static> { ExpansionConfig { @@ -1423,39 +1469,14 @@ impl<'feat> ExpansionConfig<'feat> { } } - pub fn enable_quotes(&self) -> bool { - match self.features { - Some(&Features { allow_quote: true, .. }) => true, - _ => false, - } - } - - pub fn enable_asm(&self) -> bool { - match self.features { - Some(&Features { allow_asm: true, .. }) => true, - _ => false, - } - } - - pub fn enable_log_syntax(&self) -> bool { - match self.features { - Some(&Features { allow_log_syntax: true, .. }) => true, - _ => false, - } - } - - pub fn enable_concat_idents(&self) -> bool { - match self.features { - Some(&Features { allow_concat_idents: true, .. }) => true, - _ => false, - } - } - - pub fn enable_trace_macros(&self) -> bool { - match self.features { - Some(&Features { allow_trace_macros: true, .. }) => true, - _ => false, - } + feature_tests! { + fn enable_quotes = allow_quote, + fn enable_asm = allow_asm, + fn enable_log_syntax = allow_log_syntax, + fn enable_concat_idents = allow_concat_idents, + fn enable_trace_macros = allow_trace_macros, + fn enable_allow_internal_unstable = allow_internal_unstable, + fn enable_custom_derive = allow_custom_derive, } } @@ -1635,7 +1656,7 @@ mod test { } // 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(); @@ -1649,7 +1670,7 @@ mod test { } // 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(); diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs index 544fb15dcde..737648cd90c 100644 --- a/src/libsyntax/ext/quote.rs +++ b/src/libsyntax/ext/quote.rs @@ -1,4 +1,4 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// 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. // @@ -401,7 +401,7 @@ pub fn expand_quote_tokens<'cx>(cx: &'cx mut ExtCtxt, tts: &[ast::TokenTree]) -> Box<base::MacResult+'cx> { let (cx_expr, expr) = expand_tts(cx, sp, tts); - let expanded = expand_wrapper(cx, sp, cx_expr, expr); + let expanded = expand_wrapper(cx, sp, cx_expr, expr, &[&["syntax", "ext", "quote", "rt"]]); base::MacEager::expr(expanded) } @@ -465,6 +465,32 @@ pub fn expand_quote_stmt(cx: &mut ExtCtxt, base::MacEager::expr(expanded) } +pub fn expand_quote_attr(cx: &mut ExtCtxt, + sp: Span, + tts: &[ast::TokenTree]) + -> Box<base::MacResult+'static> { + let expanded = expand_parse_call(cx, sp, "parse_attribute", + vec!(cx.expr_bool(sp, true)), tts); + + base::MacEager::expr(expanded) +} + +pub fn expand_quote_matcher(cx: &mut ExtCtxt, + sp: Span, + tts: &[ast::TokenTree]) + -> Box<base::MacResult+'static> { + let (cx_expr, tts) = parse_arguments_to_quote(cx, tts); + let mut vector = mk_stmts_let(cx, sp); + vector.extend(statements_mk_tts(cx, &tts[..], true).into_iter()); + let block = cx.expr_block( + cx.block_all(sp, + vector, + Some(cx.expr_ident(sp, id_ext("tt"))))); + + let expanded = expand_wrapper(cx, sp, cx_expr, block, &[&["syntax", "ext", "quote", "rt"]]); + base::MacEager::expr(expanded) +} + fn ids_ext(strs: Vec<String> ) -> Vec<ast::Ident> { strs.iter().map(|str| str_to_ident(&(*str))).collect() } @@ -527,7 +553,7 @@ fn mk_delim(cx: &ExtCtxt, sp: Span, delim: token::DelimToken) -> P<ast::Expr> { } #[allow(non_upper_case_globals)] -fn mk_token(cx: &ExtCtxt, sp: Span, tok: &token::Token) -> P<ast::Expr> { +fn expr_mk_token(cx: &ExtCtxt, sp: Span, tok: &token::Token) -> P<ast::Expr> { macro_rules! mk_lit { ($name: expr, $suffix: expr, $($args: expr),*) => {{ let inner = cx.expr_call(sp, mk_token_path(cx, sp, $name), vec![$($args),*]); @@ -606,6 +632,21 @@ fn mk_token(cx: &ExtCtxt, sp: Span, tok: &token::Token) -> P<ast::Expr> { vec!(mk_name(cx, sp, ident.ident()))); } + token::MatchNt(name, kind, namep, kindp) => { + return cx.expr_call(sp, + mk_token_path(cx, sp, "MatchNt"), + vec!(mk_ident(cx, sp, name), + mk_ident(cx, sp, kind), + match namep { + ModName => mk_token_path(cx, sp, "ModName"), + Plain => mk_token_path(cx, sp, "Plain"), + }, + match kindp { + ModName => mk_token_path(cx, sp, "ModName"), + Plain => mk_token_path(cx, sp, "Plain"), + })); + } + token::Interpolated(_) => panic!("quote! with interpolated token"), _ => () @@ -635,14 +676,15 @@ fn mk_token(cx: &ExtCtxt, sp: Span, tok: &token::Token) -> P<ast::Expr> { token::FatArrow => "FatArrow", token::Pound => "Pound", token::Dollar => "Dollar", + token::Question => "Question", token::Underscore => "Underscore", token::Eof => "Eof", - _ => panic!(), + _ => panic!("unhandled token in quote!"), }; mk_token_path(cx, sp, name) } -fn mk_tt(cx: &ExtCtxt, tt: &ast::TokenTree) -> Vec<P<ast::Stmt>> { +fn statements_mk_tt(cx: &ExtCtxt, tt: &ast::TokenTree, matcher: bool) -> Vec<P<ast::Stmt>> { match *tt { ast::TtToken(sp, SubstNt(ident, _)) => { // tt.extend($ident.to_tokens(ext_cx).into_iter()) @@ -663,18 +705,18 @@ fn mk_tt(cx: &ExtCtxt, tt: &ast::TokenTree) -> Vec<P<ast::Stmt>> { vec!(cx.stmt_expr(e_push)) } - ref tt @ ast::TtToken(_, MatchNt(..)) => { + ref tt @ ast::TtToken(_, MatchNt(..)) if !matcher => { let mut seq = vec![]; for i in 0..tt.len() { seq.push(tt.get_tt(i)); } - mk_tts(cx, &seq[..]) + statements_mk_tts(cx, &seq[..], matcher) } ast::TtToken(sp, ref tok) => { let e_sp = cx.expr_ident(sp, id_ext("_sp")); let e_tok = cx.expr_call(sp, mk_ast_path(cx, sp, "TtToken"), - vec!(e_sp, mk_token(cx, sp, tok))); + vec!(e_sp, expr_mk_token(cx, sp, tok))); let e_push = cx.expr_method_call(sp, cx.expr_ident(sp, id_ext("tt")), @@ -683,27 +725,61 @@ fn mk_tt(cx: &ExtCtxt, tt: &ast::TokenTree) -> Vec<P<ast::Stmt>> { vec!(cx.stmt_expr(e_push)) }, ast::TtDelimited(_, ref delimed) => { - mk_tt(cx, &delimed.open_tt()).into_iter() - .chain(delimed.tts.iter().flat_map(|tt| mk_tt(cx, tt).into_iter())) - .chain(mk_tt(cx, &delimed.close_tt()).into_iter()) + statements_mk_tt(cx, &delimed.open_tt(), matcher).into_iter() + .chain(delimed.tts.iter() + .flat_map(|tt| statements_mk_tt(cx, tt, matcher).into_iter())) + .chain(statements_mk_tt(cx, &delimed.close_tt(), matcher).into_iter()) .collect() }, - ast::TtSequence(..) => panic!("TtSequence in quote!"), - } -} + ast::TtSequence(sp, ref seq) => { + if !matcher { + panic!("TtSequence in quote!"); + } -fn mk_tts(cx: &ExtCtxt, tts: &[ast::TokenTree]) -> Vec<P<ast::Stmt>> { - let mut ss = Vec::new(); - for tt in tts { - ss.extend(mk_tt(cx, tt).into_iter()); + let e_sp = cx.expr_ident(sp, id_ext("_sp")); + + let stmt_let_tt = cx.stmt_let(sp, true, id_ext("tt"), cx.expr_vec_ng(sp)); + let mut tts_stmts = vec![stmt_let_tt]; + tts_stmts.extend(statements_mk_tts(cx, &seq.tts[..], matcher).into_iter()); + let e_tts = cx.expr_block(cx.block(sp, tts_stmts, + Some(cx.expr_ident(sp, id_ext("tt"))))); + let e_separator = match seq.separator { + Some(ref sep) => cx.expr_some(sp, expr_mk_token(cx, sp, sep)), + None => cx.expr_none(sp), + }; + let e_op = match seq.op { + ast::ZeroOrMore => mk_ast_path(cx, sp, "ZeroOrMore"), + ast::OneOrMore => mk_ast_path(cx, sp, "OneOrMore"), + }; + let fields = vec![cx.field_imm(sp, id_ext("tts"), e_tts), + cx.field_imm(sp, id_ext("separator"), e_separator), + cx.field_imm(sp, id_ext("op"), e_op), + cx.field_imm(sp, id_ext("num_captures"), + cx.expr_usize(sp, seq.num_captures))]; + let seq_path = vec![id_ext("syntax"), id_ext("ast"), id_ext("SequenceRepetition")]; + let e_seq_struct = cx.expr_struct(sp, cx.path_global(sp, seq_path), fields); + let e_rc_new = cx.expr_call_global(sp, vec![id_ext("std"), + id_ext("rc"), + id_ext("Rc"), + id_ext("new")], + vec![e_seq_struct]); + let e_tok = cx.expr_call(sp, + mk_ast_path(cx, sp, "TtSequence"), + vec!(e_sp, e_rc_new)); + let e_push = + cx.expr_method_call(sp, + cx.expr_ident(sp, id_ext("tt")), + id_ext("push"), + vec!(e_tok)); + vec!(cx.stmt_expr(e_push)) + } } - ss } -fn expand_tts(cx: &ExtCtxt, sp: Span, tts: &[ast::TokenTree]) - -> (P<ast::Expr>, P<ast::Expr>) { +fn parse_arguments_to_quote(cx: &ExtCtxt, tts: &[ast::TokenTree]) + -> (P<ast::Expr>, Vec<ast::TokenTree>) { // NB: It appears that the main parser loses its mind if we consider - // $foo as a TtNonterminal during the main parse, so we have to re-parse + // $foo as a SubstNt during the main parse, so we have to re-parse // under quote_depth > 0. This is silly and should go away; the _guess_ is // it has to do with transition away from supporting old-style macros, so // try removing it when enough of them are gone. @@ -719,6 +795,10 @@ fn expand_tts(cx: &ExtCtxt, sp: Span, tts: &[ast::TokenTree]) let tts = p.parse_all_token_trees(); p.abort_if_errors(); + (cx_expr, tts) +} + +fn mk_stmts_let(cx: &ExtCtxt, sp: Span) -> Vec<P<ast::Stmt>> { // We also bind a single value, sp, to ext_cx.call_site() // // This causes every span in a token-tree quote to be attributed to the @@ -756,8 +836,23 @@ fn expand_tts(cx: &ExtCtxt, sp: Span, tts: &[ast::TokenTree]) let stmt_let_tt = cx.stmt_let(sp, true, id_ext("tt"), cx.expr_vec_ng(sp)); - let mut vector = vec!(stmt_let_sp, stmt_let_tt); - vector.extend(mk_tts(cx, &tts[..]).into_iter()); + vec!(stmt_let_sp, stmt_let_tt) +} + +fn statements_mk_tts(cx: &ExtCtxt, tts: &[ast::TokenTree], matcher: bool) -> Vec<P<ast::Stmt>> { + let mut ss = Vec::new(); + for tt in tts { + ss.extend(statements_mk_tt(cx, tt, matcher).into_iter()); + } + ss +} + +fn expand_tts(cx: &ExtCtxt, sp: Span, tts: &[ast::TokenTree]) + -> (P<ast::Expr>, P<ast::Expr>) { + let (cx_expr, tts) = parse_arguments_to_quote(cx, tts); + + let mut vector = mk_stmts_let(cx, sp); + vector.extend(statements_mk_tts(cx, &tts[..], false).into_iter()); let block = cx.expr_block( cx.block_all(sp, vector, @@ -769,14 +864,14 @@ fn expand_tts(cx: &ExtCtxt, sp: Span, tts: &[ast::TokenTree]) fn expand_wrapper(cx: &ExtCtxt, sp: Span, cx_expr: P<ast::Expr>, - expr: P<ast::Expr>) -> P<ast::Expr> { + expr: P<ast::Expr>, + imports: &[&[&str]]) -> P<ast::Expr> { // Explicitly borrow to avoid moving from the invoker (#16992) let cx_expr_borrow = cx.expr_addr_of(sp, cx.expr_deref(sp, cx_expr)); let stmt_let_ext_cx = cx.stmt_let(sp, false, id_ext("ext_cx"), cx_expr_borrow); - let stmts = [ - &["syntax", "ext", "quote", "rt"], - ].iter().map(|path| { + let stmts = imports.iter().map(|path| { + // make item: `use ...;` let path = path.iter().map(|s| s.to_string()).collect(); cx.stmt_item(sp, cx.item_use_glob(sp, ast::Inherited, ids_ext(path))) }).chain(Some(stmt_let_ext_cx).into_iter()).collect(); @@ -807,5 +902,10 @@ fn expand_parse_call(cx: &ExtCtxt, let expr = cx.expr_method_call(sp, new_parser_call, id_ext(parse_method), arg_exprs); - expand_wrapper(cx, sp, cx_expr, expr) + if parse_method == "parse_attribute" { + expand_wrapper(cx, sp, cx_expr, expr, &[&["syntax", "ext", "quote", "rt"], + &["syntax", "parse", "attr"]]) + } else { + expand_wrapper(cx, sp, cx_expr, expr, &[&["syntax", "ext", "quote", "rt"]]) + } } diff --git a/src/libsyntax/ext/source_util.rs b/src/libsyntax/ext/source_util.rs index ba3743cdb33..62d98be8b85 100644 --- a/src/libsyntax/ext/source_util.rs +++ b/src/libsyntax/ext/source_util.rs @@ -20,7 +20,9 @@ use print::pprust; use ptr::P; use util::small_vector::SmallVector; -use std::old_io::File; +use std::fs::File; +use std::io::prelude::*; +use std::path::{Path, PathBuf}; use std::rc::Rc; // These macros all relate to the file system; they either return @@ -97,7 +99,7 @@ pub fn expand_include<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree cx.cfg(), &res_rel_file(cx, sp, - &Path::new(file)), + Path::new(&file)), true, None, sp); @@ -136,8 +138,10 @@ pub fn expand_include_str(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) Some(f) => f, None => return DummyResult::expr(sp) }; - let file = res_rel_file(cx, sp, &Path::new(file)); - let bytes = match File::open(&file).read_to_end() { + let file = res_rel_file(cx, sp, Path::new(&file)); + let mut bytes = Vec::new(); + match File::open(&file).and_then(|mut f| f.read_to_end(&mut bytes)) { + Ok(..) => {} Err(e) => { cx.span_err(sp, &format!("couldn't read {}: {}", @@ -145,7 +149,6 @@ pub fn expand_include_str(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) e)); return DummyResult::expr(sp); } - Ok(bytes) => bytes, }; match String::from_utf8(bytes) { Ok(src) => { @@ -172,15 +175,15 @@ pub fn expand_include_bytes(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) Some(f) => f, None => return DummyResult::expr(sp) }; - let file = res_rel_file(cx, sp, &Path::new(file)); - match File::open(&file).read_to_end() { + let file = res_rel_file(cx, sp, Path::new(&file)); + let mut bytes = Vec::new(); + match File::open(&file).and_then(|mut f| f.read_to_end(&mut bytes)) { Err(e) => { cx.span_err(sp, &format!("couldn't read {}: {}", file.display(), e)); return DummyResult::expr(sp); } - Ok(bytes) => { - let bytes = bytes.iter().cloned().collect(); + Ok(..) => { base::MacEager::expr(cx.expr_lit(sp, ast::LitBinary(Rc::new(bytes)))) } } @@ -188,14 +191,18 @@ pub fn expand_include_bytes(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) // resolve a file-system path to an absolute file-system path (if it // isn't already) -fn res_rel_file(cx: &mut ExtCtxt, sp: codemap::Span, arg: &Path) -> Path { +fn res_rel_file(cx: &mut ExtCtxt, sp: codemap::Span, arg: &Path) -> PathBuf { // NB: relative paths are resolved relative to the compilation unit if !arg.is_absolute() { - let mut cu = Path::new(cx.codemap().span_to_filename(sp)); - cu.pop(); + let mut cu = PathBuf::new(&cx.codemap().span_to_filename(sp)); + if cu.parent().is_some() { + cu.pop(); + } else { + cu = PathBuf::new(""); + } cu.push(arg); cu } else { - arg.clone() + arg.to_path_buf() } } diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs index 0ac78209b6f..eb15d708232 100644 --- a/src/libsyntax/ext/tt/macro_parser.rs +++ b/src/libsyntax/ext/tt/macro_parser.rs @@ -243,12 +243,15 @@ pub fn nameize(p_s: &ParseSess, ms: &[TokenTree], res: &[Rc<NamedMatch>]) ret_val } -pub enum ParseResult { - Success(HashMap<Ident, Rc<NamedMatch>>), +pub enum ParseResult<T> { + Success(T), Failure(codemap::Span, String), Error(codemap::Span, String) } +pub type NamedParseResult = ParseResult<HashMap<Ident, Rc<NamedMatch>>>; +pub type PositionalParseResult = ParseResult<Vec<Rc<NamedMatch>>>; + pub fn parse_or_else(sess: &ParseSess, cfg: ast::CrateConfig, rdr: TtReader, @@ -280,7 +283,7 @@ pub fn parse(sess: &ParseSess, cfg: ast::CrateConfig, mut rdr: TtReader, ms: &[TokenTree]) - -> ParseResult { + -> NamedParseResult { let mut cur_eis = Vec::new(); cur_eis.push(initial_matcher_pos(Rc::new(ms.iter() .cloned() diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index db7db4b83ac..644c6cd7e28 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -15,7 +15,7 @@ use ext::base::{NormalTT, TTMacroExpander}; use ext::tt::macro_parser::{Success, Error, Failure}; use ext::tt::macro_parser::{NamedMatch, MatchedSeq, MatchedNonterminal}; use ext::tt::macro_parser::{parse, parse_or_else}; -use parse::lexer::{new_tt_reader, new_tt_reader_with_doc_flag}; +use parse::lexer::new_tt_reader; use parse::parser::Parser; use parse::attr::ParserAttr; use parse::token::{self, special_idents, gensym_ident, NtTT, Token}; @@ -154,15 +154,8 @@ fn generic_extension<'cx>(cx: &'cx ExtCtxt, TtDelimited(_, ref delim) => &delim.tts[..], _ => cx.span_fatal(sp, "malformed macro lhs") }; - // `None` is because we're not interpolating - let arg_rdr = new_tt_reader_with_doc_flag(&cx.parse_sess().span_diagnostic, - None, - None, - arg.iter() - .cloned() - .collect(), - true); - match parse(cx.parse_sess(), cx.cfg(), arg_rdr, lhs_tt) { + + match TokenTree::parse(cx, lhs_tt, arg) { Success(named_matches) => { let rhs = match *rhses[i] { // okay, what's your transcriber? @@ -274,7 +267,7 @@ pub fn compile<'cx>(cx: &'cx mut ExtCtxt, rhses: rhses, }; - NormalTT(exp, Some(def.span)) + NormalTT(exp, Some(def.span), def.allow_internal_unstable) } fn check_lhs_nt_follows(cx: &mut ExtCtxt, lhs: &NamedMatch, sp: Span) { diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 18d3f85f4b5..c3bac0cf57c 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -137,11 +137,21 @@ const KNOWN_FEATURES: &'static [(&'static str, &'static str, Status)] = &[ // Allows the use of custom attributes; RFC 572 ("custom_attribute", "1.0.0", Active), + // Allows the use of #[derive(Anything)] as sugar for + // #[derive_Anything]. + ("custom_derive", "1.0.0", Active), + // Allows the use of rustc_* attributes; RFC 572 ("rustc_attrs", "1.0.0", Active), // Allows the use of `static_assert` ("static_assert", "1.0.0", Active), + + // Allows the use of #[allow_internal_unstable]. This is an + // attribute on macro_rules! and can't use the attribute handling + // below (it has to be checked before expansion possibly makes + // macros disappear). + ("allow_internal_unstable", "1.0.0", Active), ]; // (changing above list without updating src/doc/reference.md makes @cmr sad) @@ -190,6 +200,7 @@ pub const KNOWN_ATTRIBUTES: &'static [(&'static str, AttributeType)] = &[ ("no_mangle", Normal), ("no_link", Normal), ("derive", Normal), + ("deriving", Normal), // deprecation err in expansion ("should_fail", Normal), ("should_panic", Normal), ("ignore", Normal), @@ -229,6 +240,9 @@ pub const KNOWN_ATTRIBUTES: &'static [(&'static str, AttributeType)] = &[ "the `#[rustc_move_fragments]` attribute \ is an experimental feature")), + ("allow_internal_unstable", Gated("allow_internal_unstable", + EXPLAIN_ALLOW_INTERNAL_UNSTABLE)), + // FIXME: #14408 whitelist docs since rustdoc looks at them ("doc", Whitelisted), @@ -279,7 +293,7 @@ pub const KNOWN_ATTRIBUTES: &'static [(&'static str, AttributeType)] = &[ ("recursion_limit", CrateLevel), ]; -#[derive(PartialEq, Copy)] +#[derive(PartialEq, Copy, Debug)] pub enum AttributeType { /// Normal, builtin attribute that is consumed /// by the compiler before the unused_attribute check @@ -308,6 +322,8 @@ pub struct Features { pub allow_log_syntax: bool, pub allow_concat_idents: bool, pub allow_trace_macros: bool, + pub allow_internal_unstable: bool, + pub allow_custom_derive: bool, pub old_orphan_check: bool, pub simd_ffi: bool, pub unmarked_api: bool, @@ -328,6 +344,8 @@ impl Features { allow_log_syntax: false, allow_concat_idents: false, allow_trace_macros: false, + allow_internal_unstable: false, + allow_custom_derive: false, old_orphan_check: false, simd_ffi: false, unmarked_api: false, @@ -341,28 +359,62 @@ struct Context<'a> { features: Vec<&'static str>, span_handler: &'a SpanHandler, cm: &'a CodeMap, + do_warnings: bool, } impl<'a> Context<'a> { fn gate_feature(&self, feature: &str, span: Span, explain: &str) { - if !self.has_feature(feature) { + let has_feature = self.has_feature(feature); + debug!("gate_feature(feature = {:?}, span = {:?}); has? {}", feature, span, has_feature); + if !has_feature { emit_feature_err(self.span_handler, feature, span, explain); } } fn warn_feature(&self, feature: &str, span: Span, explain: &str) { - if !self.has_feature(feature) { + if !self.has_feature(feature) && self.do_warnings { emit_feature_warn(self.span_handler, feature, span, explain); } } fn has_feature(&self, feature: &str) -> bool { self.features.iter().any(|&n| n == feature) } + + fn check_attribute(&self, attr: &ast::Attribute) { + debug!("check_attribute(attr = {:?})", attr); + let name = &*attr.name(); + for &(n, ty) in KNOWN_ATTRIBUTES { + if n == name { + if let Gated(gate, desc) = ty { + self.gate_feature(gate, attr.span, desc); + } + debug!("check_attribute: {:?} is known, {:?}", name, ty); + return; + } + } + if name.starts_with("rustc_") { + self.gate_feature("rustc_attrs", attr.span, + "unless otherwise specified, attributes \ + with the prefix `rustc_` \ + are reserved for internal compiler diagnostics"); + } else if name.starts_with("derive_") { + self.gate_feature("custom_derive", attr.span, + "attributes of the form `#[derive_*]` are reserved + for the compiler"); + } else { + self.gate_feature("custom_attribute", attr.span, + &format!("The attribute `{}` is currently \ + unknown to the the compiler and \ + may have meaning \ + added to it in the future", + name)); + } + } } pub fn emit_feature_err(diag: &SpanHandler, feature: &str, span: Span, explain: &str) { diag.span_err(span, explain); - diag.span_help(span, &format!("add #![feature({})] to the \ + diag.fileline_help(span, &format!("add #![feature({})] to the \ crate attributes to enable", feature)); } @@ -370,7 +422,7 @@ pub fn emit_feature_err(diag: &SpanHandler, feature: &str, span: Span, explain: pub fn emit_feature_warn(diag: &SpanHandler, feature: &str, span: Span, explain: &str) { diag.span_warn(span, explain); if diag.handler.can_emit_warnings { - diag.span_help(span, &format!("add #![feature({})] to the \ + diag.fileline_help(span, &format!("add #![feature({})] to the \ crate attributes to silence this warning", feature)); } @@ -387,6 +439,11 @@ pub const EXPLAIN_CONCAT_IDENTS: &'static str = pub const EXPLAIN_TRACE_MACROS: &'static str = "`trace_macros` is not stable enough for use and is subject to change"; +pub const EXPLAIN_ALLOW_INTERNAL_UNSTABLE: &'static str = + "allow_internal_unstable side-steps feature gating and stability checks"; + +pub const EXPLAIN_CUSTOM_DERIVE: &'static str = + "`#[derive]` for custom traits is not stable enough for use and is subject to change"; struct MacroVisitor<'a> { context: &'a Context<'a> @@ -421,6 +478,10 @@ impl<'a, 'v> Visitor<'v> for MacroVisitor<'a> { self.context.gate_feature("concat_idents", path.span, EXPLAIN_CONCAT_IDENTS); } } + + fn visit_attribute(&mut self, attr: &'v ast::Attribute) { + self.context.check_attribute(attr); + } } struct PostExpansionVisitor<'a> { @@ -429,13 +490,19 @@ struct PostExpansionVisitor<'a> { impl<'a> PostExpansionVisitor<'a> { fn gate_feature(&self, feature: &str, span: Span, explain: &str) { - if !self.context.cm.span_is_internal(span) { + if !self.context.cm.span_allows_unstable(span) { self.context.gate_feature(feature, span, explain) } } } impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> { + fn visit_attribute(&mut self, attr: &ast::Attribute) { + if !self.context.cm.span_allows_unstable(attr.span) { + self.context.check_attribute(attr); + } + } + fn visit_name(&mut self, sp: Span, name: ast::Name) { if !token::get_name(name).is_ascii() { self.gate_feature("non_ascii_idents", sp, @@ -536,12 +603,6 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> { } fn visit_foreign_item(&mut self, i: &ast::ForeignItem) { - if attr::contains_name(&i.attrs, "linkage") { - self.gate_feature("linkage", i.span, - "the `linkage` attribute is experimental \ - and not portable across platforms") - } - let links_to_llvm = match attr::first_attr_value_str_by_name(&i.attrs, "link_name") { Some(val) => val.starts_with("llvm."), @@ -616,31 +677,6 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> { visit::walk_expr(self, e); } - fn visit_attribute(&mut self, attr: &ast::Attribute) { - let name = &*attr.name(); - for &(n, ty) in KNOWN_ATTRIBUTES { - if n == name { - if let Gated(gate, desc) = ty { - self.gate_feature(gate, attr.span, desc); - } - return; - } - } - if name.starts_with("rustc_") { - self.gate_feature("rustc_attrs", attr.span, - "unless otherwise specified, attributes \ - with the prefix `rustc_` \ - are reserved for internal compiler diagnostics"); - } else { - self.gate_feature("custom_attribute", attr.span, - format!("The attribute `{}` is currently \ - unknown to the the compiler and \ - may have meaning \ - added to it in the future", - name).as_slice()); - } - } - fn visit_pat(&mut self, pattern: &ast::Pat) { match pattern.node { ast::PatVec(_, Some(_), ref last) if !last.is_empty() => { @@ -679,6 +715,7 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> { } fn check_crate_inner<F>(cm: &CodeMap, span_handler: &SpanHandler, krate: &ast::Crate, + do_warnings: bool, check: F) -> Features where F: FnOnce(&mut Context, &ast::Crate) @@ -686,6 +723,7 @@ fn check_crate_inner<F>(cm: &CodeMap, span_handler: &SpanHandler, krate: &ast::C let mut cx = Context { features: Vec::new(), span_handler: span_handler, + do_warnings: do_warnings, cm: cm, }; @@ -754,6 +792,8 @@ fn check_crate_inner<F>(cm: &CodeMap, span_handler: &SpanHandler, krate: &ast::C allow_log_syntax: cx.has_feature("log_syntax"), allow_concat_idents: cx.has_feature("concat_idents"), allow_trace_macros: cx.has_feature("trace_macros"), + allow_internal_unstable: cx.has_feature("allow_internal_unstable"), + allow_custom_derive: cx.has_feature("custom_derive"), old_orphan_check: cx.has_feature("old_orphan_check"), simd_ffi: cx.has_feature("simd_ffi"), unmarked_api: cx.has_feature("unmarked_api"), @@ -764,13 +804,14 @@ fn check_crate_inner<F>(cm: &CodeMap, span_handler: &SpanHandler, krate: &ast::C pub fn check_crate_macros(cm: &CodeMap, span_handler: &SpanHandler, krate: &ast::Crate) -> Features { - check_crate_inner(cm, span_handler, krate, + check_crate_inner(cm, span_handler, krate, true, |ctx, krate| visit::walk_crate(&mut MacroVisitor { context: ctx }, krate)) } -pub fn check_crate(cm: &CodeMap, span_handler: &SpanHandler, krate: &ast::Crate) --> Features { - check_crate_inner(cm, span_handler, krate, +pub fn check_crate(cm: &CodeMap, span_handler: &SpanHandler, krate: &ast::Crate, + do_warnings: bool) -> Features +{ + check_crate_inner(cm, span_handler, krate, do_warnings, |ctx, krate| visit::walk_crate(&mut PostExpansionVisitor { context: ctx }, krate)) } diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index a556b2dfd2a..959e3bdb314 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -1432,7 +1432,7 @@ pub fn noop_fold_stmt<T: Folder>(Spanned {node, span}: Stmt, folder: &mut T) #[cfg(test)] mod test { - use std::old_io; + use std::io; use ast; use util::parser_testing::{string_to_crate, matches_codepattern}; use parse::token; @@ -1442,7 +1442,7 @@ mod test { // this version doesn't care about getting comments or docstrings in. fn fake_print_crate(s: &mut pprust::State, - krate: &ast::Crate) -> old_io::IoResult<()> { + krate: &ast::Crate) -> io::Result<()> { s.print_mod(&krate.module, &krate.attrs) } diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index 7acbd10ef03..ba3f495cdac 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -14,6 +14,8 @@ //! //! This API is completely unstable and subject to change. +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "syntax"] #![unstable(feature = "rustc_private")] #![staged_api] @@ -36,6 +38,9 @@ #![feature(staged_api)] #![feature(std_misc)] #![feature(unicode)] +#![feature(path)] +#![feature(io)] +#![feature(path_ext)] extern crate arena; extern crate fmt_macros; diff --git a/src/libsyntax/parse/attr.rs b/src/libsyntax/parse/attr.rs index a0e2b4dbf5a..db5583cf13a 100644 --- a/src/libsyntax/parse/attr.rs +++ b/src/libsyntax/parse/attr.rs @@ -77,7 +77,7 @@ impl<'a> ParserAttr for Parser<'a> { self.span_err(span, "an inner attribute is not permitted in \ this context"); - self.span_help(span, + self.fileline_help(span, "place inner attribute at the top of the module or block"); } ast::AttrInner diff --git a/src/libsyntax/parse/lexer/comments.rs b/src/libsyntax/parse/lexer/comments.rs index 3ad1d96a45d..fb9e0480ceb 100644 --- a/src/libsyntax/parse/lexer/comments.rs +++ b/src/libsyntax/parse/lexer/comments.rs @@ -19,9 +19,8 @@ use parse::lexer::is_block_doc_comment; use parse::lexer; use print::pprust; -use std::old_io; +use std::io::Read; use std::str; -use std::string::String; use std::usize; #[derive(Clone, Copy, PartialEq)] @@ -337,9 +336,10 @@ pub struct Literal { // probably not a good thing. pub fn gather_comments_and_literals(span_diagnostic: &diagnostic::SpanHandler, path: String, - srdr: &mut old_io::Reader) + srdr: &mut Read) -> (Vec<Comment>, Vec<Literal>) { - let src = srdr.read_to_end().unwrap(); + let mut src = Vec::new(); + srdr.read_to_end(&mut src).unwrap(); let src = String::from_utf8(src).unwrap(); let cm = CodeMap::new(); let filemap = cm.new_filemap(path, src); diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index bbe1ddfd4cf..f5781e0587d 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -76,6 +76,10 @@ pub struct StringReader<'a> { // are revised to go directly to token-trees. /// Is \x00<name>,<ctxt>\x00 is interpreted as encoded ast::Ident? read_embedded_ident: bool, + + // cache a direct reference to the source text, so that we don't have to + // retrieve it via `self.filemap.src.as_ref().unwrap()` all the time. + source_text: Rc<String> } impl<'a> Reader for StringReader<'a> { @@ -141,7 +145,14 @@ pub fn make_reader_with_embedded_idents<'b>(span_diagnostic: &'b SpanHandler, impl<'a> StringReader<'a> { /// For comments.rs, which hackily pokes into pos and curr pub fn new_raw<'b>(span_diagnostic: &'b SpanHandler, - filemap: Rc<codemap::FileMap>) -> StringReader<'b> { + filemap: Rc<codemap::FileMap>) -> StringReader<'b> { + if filemap.src.is_none() { + span_diagnostic.handler.bug(&format!("Cannot lex filemap without source: {}", + filemap.name)[..]); + } + + let source_text = (*filemap.src.as_ref().unwrap()).clone(); + let mut sr = StringReader { span_diagnostic: span_diagnostic, pos: filemap.start_pos, @@ -153,6 +164,7 @@ impl<'a> StringReader<'a> { peek_tok: token::Eof, peek_span: codemap::DUMMY_SP, read_embedded_ident: false, + source_text: source_text }; sr.bump(); sr @@ -213,7 +225,7 @@ impl<'a> StringReader<'a> { m.push_str(": "); let from = self.byte_offset(from_pos).to_usize(); let to = self.byte_offset(to_pos).to_usize(); - m.push_str(&self.filemap.src[from..to]); + m.push_str(&self.source_text[from..to]); self.fatal_span_(from_pos, to_pos, &m[..]); } @@ -270,9 +282,8 @@ impl<'a> StringReader<'a> { fn with_str_from_to<T, F>(&self, start: BytePos, end: BytePos, f: F) -> T where F: FnOnce(&str) -> T, { - f(&self.filemap.src[ - self.byte_offset(start).to_usize().. - self.byte_offset(end).to_usize()]) + f(&self.source_text[self.byte_offset(start).to_usize().. + self.byte_offset(end).to_usize()]) } /// Converts CRLF to LF in the given string, raising an error on bare CR. @@ -321,12 +332,10 @@ impl<'a> StringReader<'a> { pub fn bump(&mut self) { self.last_pos = self.pos; let current_byte_offset = self.byte_offset(self.pos).to_usize(); - if current_byte_offset < self.filemap.src.len() { + if current_byte_offset < self.source_text.len() { assert!(self.curr.is_some()); let last_char = self.curr.unwrap(); - let next = self.filemap - .src - .char_range_at(current_byte_offset); + let next = self.source_text.char_range_at(current_byte_offset); let byte_offset_diff = next.next - current_byte_offset; self.pos = self.pos + Pos::from_usize(byte_offset_diff); self.curr = Some(next.ch); @@ -346,8 +355,8 @@ impl<'a> StringReader<'a> { pub fn nextch(&self) -> Option<char> { let offset = self.byte_offset(self.pos).to_usize(); - if offset < self.filemap.src.len() { - Some(self.filemap.src.char_at(offset)) + if offset < self.source_text.len() { + Some(self.source_text.char_at(offset)) } else { None } @@ -359,7 +368,7 @@ impl<'a> StringReader<'a> { pub fn nextnextch(&self) -> Option<char> { let offset = self.byte_offset(self.pos).to_usize(); - let s = &*self.filemap.src; + let s = &self.source_text[..]; if offset >= s.len() { return None } let str::CharRange { next, .. } = s.char_range_at(offset); if next < s.len() { @@ -768,13 +777,6 @@ impl<'a> StringReader<'a> { } } - fn old_escape_warning(&mut self, sp: Span) { - self.span_diagnostic - .span_warn(sp, "\\U00ABCD12 and \\uABCD escapes are deprecated"); - self.span_diagnostic - .span_help(sp, "use \\u{ABCD12} escapes instead"); - } - /// Scan for a single (possibly escaped) byte or char /// in a byte, (non-raw) byte string, char, or (non-raw) string literal. /// `start` is the position of `first_source_char`, which is already consumed. @@ -794,21 +796,8 @@ impl<'a> StringReader<'a> { return match e { 'n' | 'r' | 't' | '\\' | '\'' | '"' | '0' => true, 'x' => self.scan_byte_escape(delim, !ascii_only), - 'u' if !ascii_only => { - if self.curr == Some('{') { - self.scan_unicode_escape(delim) - } else { - let res = self.scan_hex_digits(4, delim, false); - let sp = codemap::mk_sp(escaped_pos, self.last_pos); - self.old_escape_warning(sp); - res - } - } - 'U' if !ascii_only => { - let res = self.scan_hex_digits(8, delim, false); - let sp = codemap::mk_sp(escaped_pos, self.last_pos); - self.old_escape_warning(sp); - res + 'u' if self.curr_is('{') => { + self.scan_unicode_escape(delim) } '\n' if delim == '"' => { self.consume_whitespace(); diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index 4d099529cb4..fae305f9551 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -18,11 +18,13 @@ use parse::parser::Parser; use ptr::P; use std::cell::{Cell, RefCell}; -use std::old_io::File; -use std::rc::Rc; +use std::fs::File; +use std::io::Read; +use std::iter; use std::num::Int; +use std::path::{Path, PathBuf}; +use std::rc::Rc; use std::str; -use std::iter; #[macro_use] pub mod parser; @@ -39,7 +41,7 @@ pub mod obsolete; pub struct ParseSess { pub span_diagnostic: SpanHandler, // better be the same as the one in the reader! /// Used to determine and report recursive mod inclusions - included_mod_stack: RefCell<Vec<Path>>, + included_mod_stack: RefCell<Vec<PathBuf>>, pub node_id: Cell<ast::NodeId>, } @@ -250,24 +252,24 @@ pub fn file_to_filemap(sess: &ParseSess, path: &Path, spanopt: Option<Span>) None => sess.span_diagnostic.handler().fatal(msg), } }; - let bytes = match File::open(path).read_to_end() { - Ok(bytes) => bytes, + let mut bytes = Vec::new(); + match File::open(path).and_then(|mut f| f.read_to_end(&mut bytes)) { + Ok(..) => {} Err(e) => { - err(&format!("couldn't read {:?}: {}", - path.display(), e)); - unreachable!() + err(&format!("couldn't read {:?}: {}", path.display(), e)); + unreachable!(); } }; match str::from_utf8(&bytes[..]).ok() { Some(s) => { - return string_to_filemap(sess, s.to_string(), - path.as_str().unwrap().to_string()) + string_to_filemap(sess, s.to_string(), + path.to_str().unwrap().to_string()) } None => { - err(&format!("{:?} is not UTF-8 encoded", path.display())) + err(&format!("{:?} is not UTF-8 encoded", path.display())); + unreachable!(); } } - unreachable!() } /// Given a session and a string, add the string to @@ -722,7 +724,7 @@ pub fn integer_lit(s: &str, suffix: Option<&str>, sd: &SpanHandler, sp: Span) -> &suf[1..])); } else { sd.span_err(sp, &*format!("illegal suffix `{}` for numeric literal", suf)); - sd.span_help(sp, "the suffix must be one of the integral types \ + sd.fileline_help(sp, "the suffix must be one of the integral types \ (`u32`, `isize`, etc)"); } @@ -751,6 +753,7 @@ pub fn integer_lit(s: &str, suffix: Option<&str>, sd: &SpanHandler, sp: Span) -> #[cfg(test)] mod test { use super::*; + use std::rc::Rc; use serialize::json; use codemap::{Span, BytePos, Pos, Spanned, NO_EXPANSION}; use owned_slice::OwnedSlice; @@ -810,7 +813,7 @@ mod test { })) } - #[should_fail] + #[should_panic] #[test] fn bad_path_expr_1() { string_to_expr("::abc::def::return".to_string()); } @@ -855,117 +858,50 @@ mod test { } #[test] - fn string_to_tts_1 () { + fn string_to_tts_1() { let tts = string_to_tts("fn a (b : i32) { b; }".to_string()); - assert_eq!(json::encode(&tts).unwrap(), - "[\ - {\ - \"variant\":\"TtToken\",\ - \"fields\":[\ - null,\ - {\ - \"variant\":\"Ident\",\ - \"fields\":[\ - \"fn\",\ - \"Plain\"\ - ]\ - }\ - ]\ - },\ - {\ - \"variant\":\"TtToken\",\ - \"fields\":[\ - null,\ - {\ - \"variant\":\"Ident\",\ - \"fields\":[\ - \"a\",\ - \"Plain\"\ - ]\ - }\ - ]\ - },\ - {\ - \"variant\":\"TtDelimited\",\ - \"fields\":[\ - null,\ - {\ - \"delim\":\"Paren\",\ - \"open_span\":null,\ - \"tts\":[\ - {\ - \"variant\":\"TtToken\",\ - \"fields\":[\ - null,\ - {\ - \"variant\":\"Ident\",\ - \"fields\":[\ - \"b\",\ - \"Plain\"\ - ]\ - }\ - ]\ - },\ - {\ - \"variant\":\"TtToken\",\ - \"fields\":[\ - null,\ - \"Colon\"\ - ]\ - },\ - {\ - \"variant\":\"TtToken\",\ - \"fields\":[\ - null,\ - {\ - \"variant\":\"Ident\",\ - \"fields\":[\ - \"i32\",\ - \"Plain\"\ - ]\ - }\ - ]\ - }\ - ],\ - \"close_span\":null\ - }\ - ]\ - },\ - {\ - \"variant\":\"TtDelimited\",\ - \"fields\":[\ - null,\ - {\ - \"delim\":\"Brace\",\ - \"open_span\":null,\ - \"tts\":[\ - {\ - \"variant\":\"TtToken\",\ - \"fields\":[\ - null,\ - {\ - \"variant\":\"Ident\",\ - \"fields\":[\ - \"b\",\ - \"Plain\"\ - ]\ - }\ - ]\ - },\ - {\ - \"variant\":\"TtToken\",\ - \"fields\":[\ - null,\ - \"Semi\"\ - ]\ - }\ - ],\ - \"close_span\":null\ - }\ - ]\ - }\ -]" - ); + + let expected = vec![ + ast::TtToken(sp(0, 2), + token::Ident(str_to_ident("fn"), + token::IdentStyle::Plain)), + ast::TtToken(sp(3, 4), + token::Ident(str_to_ident("a"), + token::IdentStyle::Plain)), + ast::TtDelimited( + sp(5, 14), + Rc::new(ast::Delimited { + delim: token::DelimToken::Paren, + open_span: sp(5, 6), + tts: vec![ + ast::TtToken(sp(6, 7), + token::Ident(str_to_ident("b"), + token::IdentStyle::Plain)), + ast::TtToken(sp(8, 9), + token::Colon), + ast::TtToken(sp(10, 13), + token::Ident(str_to_ident("i32"), + token::IdentStyle::Plain)), + ], + close_span: sp(13, 14), + })), + ast::TtDelimited( + sp(15, 21), + Rc::new(ast::Delimited { + delim: token::DelimToken::Brace, + open_span: sp(15, 16), + tts: vec![ + ast::TtToken(sp(17, 18), + token::Ident(str_to_ident("b"), + token::IdentStyle::Plain)), + ast::TtToken(sp(18, 19), + token::Semi) + ], + close_span: sp(20, 21), + })) + ]; + + assert_eq!(tts, expected); } #[test] fn ret_expr() { diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index c1acee57cf8..28d757e9be9 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -78,10 +78,11 @@ use ptr::P; use owned_slice::OwnedSlice; use std::collections::HashSet; -use std::old_io::fs::PathExtensions; +use std::io::prelude::*; use std::iter; use std::mem; use std::num::Float; +use std::path::{Path, PathBuf}; use std::rc::Rc; use std::slice; @@ -973,7 +974,7 @@ impl<'a> Parser<'a> { } pub fn span_fatal_help(&self, sp: Span, m: &str, help: &str) -> ! { self.span_err(sp, m); - self.span_help(sp, help); + self.fileline_help(sp, help); panic!(diagnostic::FatalError); } pub fn span_note(&self, sp: Span, m: &str) { @@ -982,6 +983,9 @@ impl<'a> Parser<'a> { pub fn span_help(&self, sp: Span, m: &str) { self.sess.span_diagnostic.span_help(sp, m) } + pub fn fileline_help(&self, sp: Span, m: &str) { + self.sess.span_diagnostic.fileline_help(sp, m) + } pub fn bug(&self, m: &str) -> ! { self.sess.span_diagnostic.span_bug(self.span, m) } @@ -2531,7 +2535,7 @@ impl<'a> Parser<'a> { Some(f) => f, None => continue, }; - self.span_help(last_span, + self.fileline_help(last_span, &format!("try parenthesizing the first index; e.g., `(foo.{}){}`", float.trunc() as usize, &float.fract().to_string()[1..])); @@ -2942,7 +2946,7 @@ impl<'a> Parser<'a> { self.span_err(op_span, "chained comparison operators require parentheses"); if op.node == BiLt && outer_op == BiGt { - self.span_help(op_span, + self.fileline_help(op_span, "use `::<...>` instead of `<...>` if you meant to specify type arguments"); } } @@ -4698,7 +4702,7 @@ impl<'a> Parser<'a> { match visa { Public => { self.span_err(span, "can't qualify macro invocation with `pub`"); - self.span_help(span, "try adjusting the macro to put `pub` inside \ + self.fileline_help(span, "try adjusting the macro to put `pub` inside \ the invocation"); } Inherited => (), @@ -5248,14 +5252,23 @@ impl<'a> Parser<'a> { outer_attrs: &[ast::Attribute], id_sp: Span) -> (ast::Item_, Vec<ast::Attribute> ) { - let mut prefix = Path::new(self.sess.span_diagnostic.cm.span_to_filename(self.span)); - prefix.pop(); - let mod_path = Path::new(".").join_many(&self.mod_path_stack); - let dir_path = prefix.join(&mod_path); + let mut prefix = PathBuf::new(&self.sess.span_diagnostic.cm + .span_to_filename(self.span)); + // FIXME(acrichto): right now "a".pop() == "a", but need to confirm with + // aturon whether this is expected or not. + if prefix.parent().is_some() { + prefix.pop(); + } else { + prefix = PathBuf::new(""); + } + let mut dir_path = prefix; + for part in &self.mod_path_stack { + dir_path.push(&**part); + } let mod_string = token::get_ident(id); let (file_path, owns_directory) = match ::attr::first_attr_value_str_by_name( outer_attrs, "path") { - Some(d) => (dir_path.join(d), true), + Some(d) => (dir_path.join(&*d), true), None => { let mod_name = mod_string.to_string(); let default_path_str = format!("{}.rs", mod_name); @@ -5319,7 +5332,7 @@ impl<'a> Parser<'a> { } fn eval_src_mod_from_path(&mut self, - path: Path, + path: PathBuf, owns_directory: bool, name: String, id_sp: Span) -> (ast::Item_, Vec<ast::Attribute> ) { @@ -5329,10 +5342,10 @@ impl<'a> Parser<'a> { let mut err = String::from_str("circular modules: "); let len = included_mod_stack.len(); for p in &included_mod_stack[i.. len] { - err.push_str(&p.display().as_cow()); + err.push_str(&p.to_string_lossy()); err.push_str(" -> "); } - err.push_str(&path.display().as_cow()); + err.push_str(&path.to_string_lossy()); self.span_fatal(id_sp, &err[..]); } None => () @@ -5435,7 +5448,7 @@ impl<'a> Parser<'a> { if self.token.is_ident() { self.bump(); } self.span_err(span, "expected `;`, found `as`"); - self.span_help(span, + self.fileline_help(span, &format!("perhaps you meant to enclose the crate name `{}` in \ a string?", the_ident.as_str())); @@ -5746,7 +5759,7 @@ impl<'a> Parser<'a> { if self.eat_keyword(keywords::Mut) { let last_span = self.last_span; self.span_err(last_span, "const globals cannot be mutable"); - self.span_help(last_span, "did you mean to declare a static?"); + self.fileline_help(last_span, "did you mean to declare a static?"); } let (ident, item_, extra_attrs) = self.parse_item_const(None); let last_span = self.last_span; diff --git a/src/libsyntax/print/pp.rs b/src/libsyntax/print/pp.rs index 4cef7ed469f..640b7d1c91d 100644 --- a/src/libsyntax/print/pp.rs +++ b/src/libsyntax/print/pp.rs @@ -59,7 +59,7 @@ //! line (which it can't) and so naturally place the content on its own line to //! avoid combining it with other lines and making matters even worse. -use std::old_io; +use std::io; use std::string; use std::iter::repeat; @@ -161,7 +161,7 @@ pub struct PrintStackElem { const SIZE_INFINITY: isize = 0xffff; -pub fn mk_printer(out: Box<old_io::Writer+'static>, linewidth: usize) -> Printer { +pub fn mk_printer<'a>(out: Box<io::Write+'a>, linewidth: usize) -> Printer<'a> { // Yes 3, it makes the ring buffers big enough to never // fall behind. let n: usize = 3 * linewidth; @@ -265,8 +265,8 @@ pub fn mk_printer(out: Box<old_io::Writer+'static>, linewidth: usize) -> Printer /// In this implementation (following the paper, again) the SCAN process is /// the method called 'pretty_print', and the 'PRINT' process is the method /// called 'print'. -pub struct Printer { - pub out: Box<old_io::Writer+'static>, +pub struct Printer<'a> { + pub out: Box<io::Write+'a>, buf_len: usize, /// Width of lines we're constrained to margin: isize, @@ -303,7 +303,7 @@ pub struct Printer { pending_indentation: isize, } -impl Printer { +impl<'a> Printer<'a> { pub fn last_token(&mut self) -> Token { self.token[self.right].clone() } @@ -311,7 +311,7 @@ impl Printer { pub fn replace_last_token(&mut self, t: Token) { self.token[self.right] = t; } - pub fn pretty_print(&mut self, token: Token) -> old_io::IoResult<()> { + pub fn pretty_print(&mut self, token: Token) -> io::Result<()> { debug!("pp ~[{},{}]", self.left, self.right); match token { Token::Eof => { @@ -385,7 +385,7 @@ impl Printer { } } } - pub fn check_stream(&mut self) -> old_io::IoResult<()> { + pub fn check_stream(&mut self) -> io::Result<()> { debug!("check_stream ~[{}, {}] with left_total={}, right_total={}", self.left, self.right, self.left_total, self.right_total); if self.right_total - self.left_total > self.space { @@ -445,7 +445,7 @@ impl Printer { self.right %= self.buf_len; assert!((self.right != self.left)); } - pub fn advance_left(&mut self) -> old_io::IoResult<()> { + pub fn advance_left(&mut self) -> io::Result<()> { debug!("advance_left ~[{},{}], sizeof({})={}", self.left, self.right, self.left, self.size[self.left]); @@ -506,7 +506,7 @@ impl Printer { } } } - pub fn print_newline(&mut self, amount: isize) -> old_io::IoResult<()> { + pub fn print_newline(&mut self, amount: isize) -> io::Result<()> { debug!("NEWLINE {}", amount); let ret = write!(self.out, "\n"); self.pending_indentation = 0; @@ -529,14 +529,14 @@ impl Printer { } } } - pub fn print_str(&mut self, s: &str) -> old_io::IoResult<()> { + pub fn print_str(&mut self, s: &str) -> io::Result<()> { while self.pending_indentation > 0 { try!(write!(self.out, " ")); self.pending_indentation -= 1; } write!(self.out, "{}", s) } - pub fn print(&mut self, token: Token, l: isize) -> old_io::IoResult<()> { + pub fn print(&mut self, token: Token, l: isize) -> io::Result<()> { debug!("print {} {} (remaining line space={})", tok_str(&token), l, self.space); debug!("{}", buf_str(&self.token, @@ -620,61 +620,61 @@ impl Printer { // Convenience functions to talk to the printer. // // "raw box" -pub fn rbox(p: &mut Printer, indent: usize, b: Breaks) -> old_io::IoResult<()> { +pub fn rbox(p: &mut Printer, indent: usize, b: Breaks) -> io::Result<()> { p.pretty_print(Token::Begin(BeginToken { offset: indent as isize, breaks: b })) } -pub fn ibox(p: &mut Printer, indent: usize) -> old_io::IoResult<()> { +pub fn ibox(p: &mut Printer, indent: usize) -> io::Result<()> { rbox(p, indent, Breaks::Inconsistent) } -pub fn cbox(p: &mut Printer, indent: usize) -> old_io::IoResult<()> { +pub fn cbox(p: &mut Printer, indent: usize) -> io::Result<()> { rbox(p, indent, Breaks::Consistent) } -pub fn break_offset(p: &mut Printer, n: usize, off: isize) -> old_io::IoResult<()> { +pub fn break_offset(p: &mut Printer, n: usize, off: isize) -> io::Result<()> { p.pretty_print(Token::Break(BreakToken { offset: off, blank_space: n as isize })) } -pub fn end(p: &mut Printer) -> old_io::IoResult<()> { +pub fn end(p: &mut Printer) -> io::Result<()> { p.pretty_print(Token::End) } -pub fn eof(p: &mut Printer) -> old_io::IoResult<()> { +pub fn eof(p: &mut Printer) -> io::Result<()> { p.pretty_print(Token::Eof) } -pub fn word(p: &mut Printer, wrd: &str) -> old_io::IoResult<()> { +pub fn word(p: &mut Printer, wrd: &str) -> io::Result<()> { p.pretty_print(Token::String(/* bad */ wrd.to_string(), wrd.len() as isize)) } -pub fn huge_word(p: &mut Printer, wrd: &str) -> old_io::IoResult<()> { +pub fn huge_word(p: &mut Printer, wrd: &str) -> io::Result<()> { p.pretty_print(Token::String(/* bad */ wrd.to_string(), SIZE_INFINITY)) } -pub fn zero_word(p: &mut Printer, wrd: &str) -> old_io::IoResult<()> { +pub fn zero_word(p: &mut Printer, wrd: &str) -> io::Result<()> { p.pretty_print(Token::String(/* bad */ wrd.to_string(), 0)) } -pub fn spaces(p: &mut Printer, n: usize) -> old_io::IoResult<()> { +pub fn spaces(p: &mut Printer, n: usize) -> io::Result<()> { break_offset(p, n, 0) } -pub fn zerobreak(p: &mut Printer) -> old_io::IoResult<()> { +pub fn zerobreak(p: &mut Printer) -> io::Result<()> { spaces(p, 0) } -pub fn space(p: &mut Printer) -> old_io::IoResult<()> { +pub fn space(p: &mut Printer) -> io::Result<()> { spaces(p, 1) } -pub fn hardbreak(p: &mut Printer) -> old_io::IoResult<()> { +pub fn hardbreak(p: &mut Printer) -> io::Result<()> { spaces(p, SIZE_INFINITY as usize) } diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index af16e19c9f0..883c2295a36 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -30,7 +30,7 @@ use ptr::P; use std_inject; use std::{ascii, mem}; -use std::old_io::{self, IoResult}; +use std::io::{self, Write, Read}; use std::iter; pub enum AnnNode<'a> { @@ -43,8 +43,8 @@ pub enum AnnNode<'a> { } pub trait PpAnn { - fn pre(&self, _state: &mut State, _node: AnnNode) -> IoResult<()> { Ok(()) } - fn post(&self, _state: &mut State, _node: AnnNode) -> IoResult<()> { Ok(()) } + fn pre(&self, _state: &mut State, _node: AnnNode) -> io::Result<()> { Ok(()) } + fn post(&self, _state: &mut State, _node: AnnNode) -> io::Result<()> { Ok(()) } } #[derive(Copy)] @@ -59,7 +59,7 @@ pub struct CurrentCommentAndLiteral { } pub struct State<'a> { - pub s: pp::Printer, + pub s: pp::Printer<'a>, cm: Option<&'a CodeMap>, comments: Option<Vec<comments::Comment> >, literals: Option<Vec<comments::Literal> >, @@ -69,12 +69,12 @@ pub struct State<'a> { encode_idents_with_hygiene: bool, } -pub fn rust_printer(writer: Box<old_io::Writer+'static>) -> State<'static> { +pub fn rust_printer<'a>(writer: Box<Write+'a>) -> State<'a> { static NO_ANN: NoAnn = NoAnn; rust_printer_annotated(writer, &NO_ANN) } -pub fn rust_printer_annotated<'a>(writer: Box<old_io::Writer+'static>, +pub fn rust_printer_annotated<'a>(writer: Box<Write+'a>, ann: &'a PpAnn) -> State<'a> { State { s: pp::mk_printer(writer, default_columns), @@ -104,10 +104,10 @@ pub fn print_crate<'a>(cm: &'a CodeMap, span_diagnostic: &diagnostic::SpanHandler, krate: &ast::Crate, filename: String, - input: &mut old_io::Reader, - out: Box<old_io::Writer+'static>, + input: &mut Read, + out: Box<Write+'a>, ann: &'a PpAnn, - is_expanded: bool) -> IoResult<()> { + is_expanded: bool) -> io::Result<()> { let mut s = State::new_from_input(cm, span_diagnostic, filename, @@ -143,8 +143,8 @@ impl<'a> State<'a> { pub fn new_from_input(cm: &'a CodeMap, span_diagnostic: &diagnostic::SpanHandler, filename: String, - input: &mut old_io::Reader, - out: Box<old_io::Writer+'static>, + input: &mut Read, + out: Box<Write+'a>, ann: &'a PpAnn, is_expanded: bool) -> State<'a> { let (cmnts, lits) = comments::gather_comments_and_literals( @@ -164,7 +164,7 @@ impl<'a> State<'a> { } pub fn new(cm: &'a CodeMap, - out: Box<old_io::Writer+'static>, + out: Box<Write+'a>, ann: &'a PpAnn, comments: Option<Vec<comments::Comment>>, literals: Option<Vec<comments::Literal>>) -> State<'a> { @@ -185,14 +185,14 @@ impl<'a> State<'a> { } pub fn to_string<F>(f: F) -> String where - F: FnOnce(&mut State) -> IoResult<()>, + F: FnOnce(&mut State) -> io::Result<()>, { use std::raw::TraitObject; let mut s = rust_printer(box Vec::new()); f(&mut s).unwrap(); eof(&mut s.s).unwrap(); let wr = unsafe { - // FIXME(pcwalton): A nasty function to extract the string from an `old_io::Writer` + // FIXME(pcwalton): A nasty function to extract the string from an `Write` // that we "know" to be a `Vec<u8>` that works around the lack of checked // downcasts. let obj: &TraitObject = mem::transmute(&s.s.out); @@ -440,13 +440,13 @@ thing_to_string_impls! { to_string } pub mod with_hygiene { use abi; use ast; - use std::old_io::IoResult; + use std::io; use super::indent_unit; // This function is the trick that all the rest of the routines // hang on. pub fn to_string_hyg<F>(f: F) -> String where - F: FnOnce(&mut super::State) -> IoResult<()>, + F: FnOnce(&mut super::State) -> io::Result<()>, { super::to_string(move |s| { s.encode_idents_with_hygiene = true; @@ -474,44 +474,44 @@ fn needs_parentheses(expr: &ast::Expr) -> bool { } impl<'a> State<'a> { - pub fn ibox(&mut self, u: usize) -> IoResult<()> { + pub fn ibox(&mut self, u: usize) -> io::Result<()> { self.boxes.push(pp::Breaks::Inconsistent); pp::ibox(&mut self.s, u) } - pub fn end(&mut self) -> IoResult<()> { + pub fn end(&mut self) -> io::Result<()> { self.boxes.pop().unwrap(); pp::end(&mut self.s) } - pub fn cbox(&mut self, u: usize) -> IoResult<()> { + pub fn cbox(&mut self, u: usize) -> io::Result<()> { self.boxes.push(pp::Breaks::Consistent); pp::cbox(&mut self.s, u) } // "raw box" - pub fn rbox(&mut self, u: usize, b: pp::Breaks) -> IoResult<()> { + pub fn rbox(&mut self, u: usize, b: pp::Breaks) -> io::Result<()> { self.boxes.push(b); pp::rbox(&mut self.s, u, b) } - pub fn nbsp(&mut self) -> IoResult<()> { word(&mut self.s, " ") } + pub fn nbsp(&mut self) -> io::Result<()> { word(&mut self.s, " ") } - pub fn word_nbsp(&mut self, w: &str) -> IoResult<()> { + pub fn word_nbsp(&mut self, w: &str) -> io::Result<()> { try!(word(&mut self.s, w)); self.nbsp() } - pub fn word_space(&mut self, w: &str) -> IoResult<()> { + pub fn word_space(&mut self, w: &str) -> io::Result<()> { try!(word(&mut self.s, w)); space(&mut self.s) } - pub fn popen(&mut self) -> IoResult<()> { word(&mut self.s, "(") } + pub fn popen(&mut self) -> io::Result<()> { word(&mut self.s, "(") } - pub fn pclose(&mut self) -> IoResult<()> { word(&mut self.s, ")") } + pub fn pclose(&mut self) -> io::Result<()> { word(&mut self.s, ")") } - pub fn head(&mut self, w: &str) -> IoResult<()> { + pub fn head(&mut self, w: &str) -> io::Result<()> { // outer-box is consistent try!(self.cbox(indent_unit)); // head-box is inconsistent @@ -523,17 +523,17 @@ impl<'a> State<'a> { Ok(()) } - pub fn bopen(&mut self) -> IoResult<()> { + pub fn bopen(&mut self) -> io::Result<()> { try!(word(&mut self.s, "{")); self.end() // close the head-box } pub fn bclose_(&mut self, span: codemap::Span, - indented: usize) -> IoResult<()> { + indented: usize) -> io::Result<()> { self.bclose_maybe_open(span, indented, true) } pub fn bclose_maybe_open (&mut self, span: codemap::Span, - indented: usize, close_box: bool) -> IoResult<()> { + indented: usize, close_box: bool) -> io::Result<()> { try!(self.maybe_print_comment(span.hi)); try!(self.break_offset_if_not_bol(1, -(indented as isize))); try!(word(&mut self.s, "}")); @@ -542,7 +542,7 @@ impl<'a> State<'a> { } Ok(()) } - pub fn bclose(&mut self, span: codemap::Span) -> IoResult<()> { + pub fn bclose(&mut self, span: codemap::Span) -> io::Result<()> { self.bclose_(span, indent_unit) } @@ -572,18 +572,18 @@ impl<'a> State<'a> { } } - pub fn hardbreak_if_not_bol(&mut self) -> IoResult<()> { + pub fn hardbreak_if_not_bol(&mut self) -> io::Result<()> { if !self.is_bol() { try!(hardbreak(&mut self.s)) } Ok(()) } - pub fn space_if_not_bol(&mut self) -> IoResult<()> { + pub fn space_if_not_bol(&mut self) -> io::Result<()> { if !self.is_bol() { try!(space(&mut self.s)); } Ok(()) } pub fn break_offset_if_not_bol(&mut self, n: usize, - off: isize) -> IoResult<()> { + off: isize) -> io::Result<()> { if !self.is_bol() { break_offset(&mut self.s, n, off) } else { @@ -599,7 +599,7 @@ impl<'a> State<'a> { // Synthesizes a comment that was not textually present in the original source // file. - pub fn synth_comment(&mut self, text: String) -> IoResult<()> { + pub fn synth_comment(&mut self, text: String) -> io::Result<()> { try!(word(&mut self.s, "/*")); try!(space(&mut self.s)); try!(word(&mut self.s, &text[..])); @@ -607,8 +607,8 @@ impl<'a> State<'a> { word(&mut self.s, "*/") } - pub fn commasep<T, F>(&mut self, b: Breaks, elts: &[T], mut op: F) -> IoResult<()> where - F: FnMut(&mut State, &T) -> IoResult<()>, + pub fn commasep<T, F>(&mut self, b: Breaks, elts: &[T], mut op: F) -> io::Result<()> where + F: FnMut(&mut State, &T) -> io::Result<()>, { try!(self.rbox(0, b)); let mut first = true; @@ -624,8 +624,8 @@ impl<'a> State<'a> { b: Breaks, elts: &[T], mut op: F, - mut get_span: G) -> IoResult<()> where - F: FnMut(&mut State, &T) -> IoResult<()>, + mut get_span: G) -> io::Result<()> where + F: FnMut(&mut State, &T) -> io::Result<()>, G: FnMut(&T) -> codemap::Span, { try!(self.rbox(0, b)); @@ -646,12 +646,12 @@ impl<'a> State<'a> { } pub fn commasep_exprs(&mut self, b: Breaks, - exprs: &[P<ast::Expr>]) -> IoResult<()> { + exprs: &[P<ast::Expr>]) -> io::Result<()> { self.commasep_cmnt(b, exprs, |s, e| s.print_expr(&**e), |e| e.span) } pub fn print_mod(&mut self, _mod: &ast::Mod, - attrs: &[ast::Attribute]) -> IoResult<()> { + attrs: &[ast::Attribute]) -> io::Result<()> { try!(self.print_inner_attributes(attrs)); for item in &_mod.items { try!(self.print_item(&**item)); @@ -660,7 +660,7 @@ impl<'a> State<'a> { } pub fn print_foreign_mod(&mut self, nmod: &ast::ForeignMod, - attrs: &[ast::Attribute]) -> IoResult<()> { + attrs: &[ast::Attribute]) -> io::Result<()> { try!(self.print_inner_attributes(attrs)); for item in &nmod.items { try!(self.print_foreign_item(&**item)); @@ -669,7 +669,7 @@ impl<'a> State<'a> { } pub fn print_opt_lifetime(&mut self, - lifetime: &Option<ast::Lifetime>) -> IoResult<()> { + lifetime: &Option<ast::Lifetime>) -> io::Result<()> { if let Some(l) = *lifetime { try!(self.print_lifetime(&l)); try!(self.nbsp()); @@ -677,7 +677,7 @@ impl<'a> State<'a> { Ok(()) } - pub fn print_type(&mut self, ty: &ast::Ty) -> IoResult<()> { + pub fn print_type(&mut self, ty: &ast::Ty) -> io::Result<()> { try!(self.maybe_print_comment(ty.span.lo)); try!(self.ibox(0)); match ty.node { @@ -762,7 +762,7 @@ impl<'a> State<'a> { } pub fn print_foreign_item(&mut self, - item: &ast::ForeignItem) -> IoResult<()> { + item: &ast::ForeignItem) -> io::Result<()> { try!(self.hardbreak_if_not_bol()); try!(self.maybe_print_comment(item.span.lo)); try!(self.print_outer_attributes(&item.attrs)); @@ -791,7 +791,7 @@ impl<'a> State<'a> { } fn print_associated_type(&mut self, typedef: &ast::AssociatedType) - -> IoResult<()> + -> io::Result<()> { try!(self.print_outer_attributes(&typedef.attrs)); try!(self.word_space("type")); @@ -799,7 +799,7 @@ impl<'a> State<'a> { word(&mut self.s, ";") } - fn print_typedef(&mut self, typedef: &ast::Typedef) -> IoResult<()> { + fn print_typedef(&mut self, typedef: &ast::Typedef) -> io::Result<()> { try!(self.word_space("type")); try!(self.print_ident(typedef.ident)); try!(space(&mut self.s)); @@ -809,7 +809,7 @@ impl<'a> State<'a> { } /// Pretty-print an item - pub fn print_item(&mut self, item: &ast::Item) -> IoResult<()> { + pub fn print_item(&mut self, item: &ast::Item) -> io::Result<()> { try!(self.hardbreak_if_not_bol()); try!(self.maybe_print_comment(item.span.lo)); try!(self.print_outer_attributes(&item.attrs)); @@ -1032,11 +1032,11 @@ impl<'a> State<'a> { self.ann.post(self, NodeItem(item)) } - fn print_trait_ref(&mut self, t: &ast::TraitRef) -> IoResult<()> { + fn print_trait_ref(&mut self, t: &ast::TraitRef) -> io::Result<()> { self.print_path(&t.path, false, 0) } - fn print_formal_lifetime_list(&mut self, lifetimes: &[ast::LifetimeDef]) -> IoResult<()> { + fn print_formal_lifetime_list(&mut self, lifetimes: &[ast::LifetimeDef]) -> io::Result<()> { if !lifetimes.is_empty() { try!(word(&mut self.s, "for<")); let mut comma = false; @@ -1052,7 +1052,7 @@ impl<'a> State<'a> { Ok(()) } - fn print_poly_trait_ref(&mut self, t: &ast::PolyTraitRef) -> IoResult<()> { + fn print_poly_trait_ref(&mut self, t: &ast::PolyTraitRef) -> io::Result<()> { try!(self.print_formal_lifetime_list(&t.bound_lifetimes)); self.print_trait_ref(&t.trait_ref) } @@ -1060,7 +1060,7 @@ impl<'a> State<'a> { pub fn print_enum_def(&mut self, enum_definition: &ast::EnumDef, generics: &ast::Generics, ident: ast::Ident, span: codemap::Span, - visibility: ast::Visibility) -> IoResult<()> { + visibility: ast::Visibility) -> io::Result<()> { try!(self.head(&visibility_qualified(visibility, "enum"))); try!(self.print_ident(ident)); try!(self.print_generics(generics)); @@ -1071,7 +1071,7 @@ impl<'a> State<'a> { pub fn print_variants(&mut self, variants: &[P<ast::Variant>], - span: codemap::Span) -> IoResult<()> { + span: codemap::Span) -> io::Result<()> { try!(self.bopen()); for v in variants { try!(self.space_if_not_bol()); @@ -1086,7 +1086,7 @@ impl<'a> State<'a> { self.bclose(span) } - pub fn print_visibility(&mut self, vis: ast::Visibility) -> IoResult<()> { + pub fn print_visibility(&mut self, vis: ast::Visibility) -> io::Result<()> { match vis { ast::Public => self.word_nbsp("pub"), ast::Inherited => Ok(()) @@ -1097,7 +1097,7 @@ impl<'a> State<'a> { struct_def: &ast::StructDef, generics: &ast::Generics, ident: ast::Ident, - span: codemap::Span) -> IoResult<()> { + span: codemap::Span) -> io::Result<()> { try!(self.print_ident(ident)); try!(self.print_generics(generics)); if ast_util::struct_def_is_tuple_like(struct_def) { @@ -1155,7 +1155,7 @@ impl<'a> State<'a> { /// appropriate macro, transcribe back into the grammar we just parsed from, /// and then pretty-print the resulting AST nodes (so, e.g., we print /// expression arguments as expressions). It can be done! I think. - pub fn print_tt(&mut self, tt: &ast::TokenTree) -> IoResult<()> { + pub fn print_tt(&mut self, tt: &ast::TokenTree) -> io::Result<()> { match *tt { ast::TtToken(_, ref tk) => { try!(word(&mut self.s, &token_to_string(tk))); @@ -1193,7 +1193,7 @@ impl<'a> State<'a> { } } - pub fn print_tts(&mut self, tts: &[ast::TokenTree]) -> IoResult<()> { + pub fn print_tts(&mut self, tts: &[ast::TokenTree]) -> io::Result<()> { try!(self.ibox(0)); let mut suppress_space = false; for (i, tt) in tts.iter().enumerate() { @@ -1213,7 +1213,7 @@ impl<'a> State<'a> { self.end() } - pub fn print_variant(&mut self, v: &ast::Variant) -> IoResult<()> { + pub fn print_variant(&mut self, v: &ast::Variant) -> io::Result<()> { try!(self.print_visibility(v.node.vis)); match v.node.kind { ast::TupleVariantKind(ref args) => { @@ -1242,7 +1242,7 @@ impl<'a> State<'a> { } } - pub fn print_ty_method(&mut self, m: &ast::TypeMethod) -> IoResult<()> { + pub fn print_ty_method(&mut self, m: &ast::TypeMethod) -> io::Result<()> { try!(self.hardbreak_if_not_bol()); try!(self.maybe_print_comment(m.span.lo)); try!(self.print_outer_attributes(&m.attrs)); @@ -1256,7 +1256,7 @@ impl<'a> State<'a> { } pub fn print_trait_method(&mut self, - m: &ast::TraitItem) -> IoResult<()> { + m: &ast::TraitItem) -> io::Result<()> { match *m { RequiredMethod(ref ty_m) => self.print_ty_method(ty_m), ProvidedMethod(ref m) => self.print_method(&**m), @@ -1264,14 +1264,14 @@ impl<'a> State<'a> { } } - pub fn print_impl_item(&mut self, ii: &ast::ImplItem) -> IoResult<()> { + pub fn print_impl_item(&mut self, ii: &ast::ImplItem) -> io::Result<()> { match *ii { MethodImplItem(ref m) => self.print_method(&**m), TypeImplItem(ref td) => self.print_typedef(&**td), } } - pub fn print_method(&mut self, meth: &ast::Method) -> IoResult<()> { + pub fn print_method(&mut self, meth: &ast::Method) -> io::Result<()> { try!(self.hardbreak_if_not_bol()); try!(self.maybe_print_comment(meth.span.lo)); try!(self.print_outer_attributes(&meth.attrs)); @@ -1310,7 +1310,7 @@ impl<'a> State<'a> { } pub fn print_outer_attributes(&mut self, - attrs: &[ast::Attribute]) -> IoResult<()> { + attrs: &[ast::Attribute]) -> io::Result<()> { let mut count = 0; for attr in attrs { match attr.node.style { @@ -1328,7 +1328,7 @@ impl<'a> State<'a> { } pub fn print_inner_attributes(&mut self, - attrs: &[ast::Attribute]) -> IoResult<()> { + attrs: &[ast::Attribute]) -> io::Result<()> { let mut count = 0; for attr in attrs { match attr.node.style { @@ -1345,7 +1345,7 @@ impl<'a> State<'a> { Ok(()) } - pub fn print_attribute(&mut self, attr: &ast::Attribute) -> IoResult<()> { + pub fn print_attribute(&mut self, attr: &ast::Attribute) -> io::Result<()> { try!(self.hardbreak_if_not_bol()); try!(self.maybe_print_comment(attr.span.lo)); if attr.node.is_sugared_doc { @@ -1361,7 +1361,7 @@ impl<'a> State<'a> { } - pub fn print_stmt(&mut self, st: &ast::Stmt) -> IoResult<()> { + pub fn print_stmt(&mut self, st: &ast::Stmt) -> io::Result<()> { try!(self.maybe_print_comment(st.span.lo)); match st.node { ast::StmtDecl(ref decl, _) => { @@ -1395,22 +1395,22 @@ impl<'a> State<'a> { self.maybe_print_trailing_comment(st.span, None) } - pub fn print_block(&mut self, blk: &ast::Block) -> IoResult<()> { + pub fn print_block(&mut self, blk: &ast::Block) -> io::Result<()> { self.print_block_with_attrs(blk, &[]) } - pub fn print_block_unclosed(&mut self, blk: &ast::Block) -> IoResult<()> { + pub fn print_block_unclosed(&mut self, blk: &ast::Block) -> io::Result<()> { self.print_block_unclosed_indent(blk, indent_unit) } pub fn print_block_unclosed_indent(&mut self, blk: &ast::Block, - indented: usize) -> IoResult<()> { + indented: usize) -> io::Result<()> { self.print_block_maybe_unclosed(blk, indented, &[], false) } pub fn print_block_with_attrs(&mut self, blk: &ast::Block, - attrs: &[ast::Attribute]) -> IoResult<()> { + attrs: &[ast::Attribute]) -> io::Result<()> { self.print_block_maybe_unclosed(blk, indent_unit, attrs, true) } @@ -1418,7 +1418,7 @@ impl<'a> State<'a> { blk: &ast::Block, indented: usize, attrs: &[ast::Attribute], - close_box: bool) -> IoResult<()> { + close_box: bool) -> io::Result<()> { match blk.rules { ast::UnsafeBlock(..) => try!(self.word_space("unsafe")), ast::DefaultBlock => () @@ -1444,7 +1444,7 @@ impl<'a> State<'a> { self.ann.post(self, NodeBlock(blk)) } - fn print_else(&mut self, els: Option<&ast::Expr>) -> IoResult<()> { + fn print_else(&mut self, els: Option<&ast::Expr>) -> io::Result<()> { match els { Some(_else) => { match _else.node { @@ -1489,7 +1489,7 @@ impl<'a> State<'a> { } pub fn print_if(&mut self, test: &ast::Expr, blk: &ast::Block, - elseopt: Option<&ast::Expr>) -> IoResult<()> { + elseopt: Option<&ast::Expr>) -> io::Result<()> { try!(self.head("if")); try!(self.print_expr(test)); try!(space(&mut self.s)); @@ -1498,7 +1498,7 @@ impl<'a> State<'a> { } pub fn print_if_let(&mut self, pat: &ast::Pat, expr: &ast::Expr, blk: &ast::Block, - elseopt: Option<&ast::Expr>) -> IoResult<()> { + elseopt: Option<&ast::Expr>) -> io::Result<()> { try!(self.head("if let")); try!(self.print_pat(pat)); try!(space(&mut self.s)); @@ -1510,7 +1510,7 @@ impl<'a> State<'a> { } pub fn print_mac(&mut self, m: &ast::Mac, delim: token::DelimToken) - -> IoResult<()> { + -> io::Result<()> { match m.node { // I think it's reasonable to hide the ctxt here: ast::MacInvocTT(ref pth, ref tts, _) => { @@ -1532,13 +1532,13 @@ impl<'a> State<'a> { } - fn print_call_post(&mut self, args: &[P<ast::Expr>]) -> IoResult<()> { + fn print_call_post(&mut self, args: &[P<ast::Expr>]) -> io::Result<()> { try!(self.popen()); try!(self.commasep_exprs(Inconsistent, args)); self.pclose() } - pub fn print_expr_maybe_paren(&mut self, expr: &ast::Expr) -> IoResult<()> { + pub fn print_expr_maybe_paren(&mut self, expr: &ast::Expr) -> io::Result<()> { let needs_par = needs_parentheses(expr); if needs_par { try!(self.popen()); @@ -1552,7 +1552,7 @@ impl<'a> State<'a> { fn print_expr_box(&mut self, place: &Option<P<ast::Expr>>, - expr: &ast::Expr) -> IoResult<()> { + expr: &ast::Expr) -> io::Result<()> { try!(word(&mut self.s, "box")); try!(word(&mut self.s, "(")); try!(place.as_ref().map_or(Ok(()), |e|self.print_expr(&**e))); @@ -1560,7 +1560,7 @@ impl<'a> State<'a> { self.print_expr(expr) } - fn print_expr_vec(&mut self, exprs: &[P<ast::Expr>]) -> IoResult<()> { + fn print_expr_vec(&mut self, exprs: &[P<ast::Expr>]) -> io::Result<()> { try!(self.ibox(indent_unit)); try!(word(&mut self.s, "[")); try!(self.commasep_exprs(Inconsistent, &exprs[..])); @@ -1570,7 +1570,7 @@ impl<'a> State<'a> { fn print_expr_repeat(&mut self, element: &ast::Expr, - count: &ast::Expr) -> IoResult<()> { + count: &ast::Expr) -> io::Result<()> { try!(self.ibox(indent_unit)); try!(word(&mut self.s, "[")); try!(self.print_expr(element)); @@ -1583,7 +1583,7 @@ impl<'a> State<'a> { fn print_expr_struct(&mut self, path: &ast::Path, fields: &[ast::Field], - wth: &Option<P<ast::Expr>>) -> IoResult<()> { + wth: &Option<P<ast::Expr>>) -> io::Result<()> { try!(self.print_path(path, true, 0)); if !(fields.is_empty() && wth.is_none()) { try!(word(&mut self.s, "{")); @@ -1616,7 +1616,7 @@ impl<'a> State<'a> { Ok(()) } - fn print_expr_tup(&mut self, exprs: &[P<ast::Expr>]) -> IoResult<()> { + fn print_expr_tup(&mut self, exprs: &[P<ast::Expr>]) -> io::Result<()> { try!(self.popen()); try!(self.commasep_exprs(Inconsistent, &exprs[..])); if exprs.len() == 1 { @@ -1627,7 +1627,7 @@ impl<'a> State<'a> { fn print_expr_call(&mut self, func: &ast::Expr, - args: &[P<ast::Expr>]) -> IoResult<()> { + args: &[P<ast::Expr>]) -> io::Result<()> { try!(self.print_expr_maybe_paren(func)); self.print_call_post(args) } @@ -1635,7 +1635,7 @@ impl<'a> State<'a> { fn print_expr_method_call(&mut self, ident: ast::SpannedIdent, tys: &[P<ast::Ty>], - args: &[P<ast::Expr>]) -> IoResult<()> { + args: &[P<ast::Expr>]) -> io::Result<()> { let base_args = &args[1..]; try!(self.print_expr(&*args[0])); try!(word(&mut self.s, ".")); @@ -1652,7 +1652,7 @@ impl<'a> State<'a> { fn print_expr_binary(&mut self, op: ast::BinOp, lhs: &ast::Expr, - rhs: &ast::Expr) -> IoResult<()> { + rhs: &ast::Expr) -> io::Result<()> { try!(self.print_expr(lhs)); try!(space(&mut self.s)); try!(self.word_space(ast_util::binop_to_string(op.node))); @@ -1661,20 +1661,20 @@ impl<'a> State<'a> { fn print_expr_unary(&mut self, op: ast::UnOp, - expr: &ast::Expr) -> IoResult<()> { + expr: &ast::Expr) -> io::Result<()> { try!(word(&mut self.s, ast_util::unop_to_string(op))); self.print_expr_maybe_paren(expr) } fn print_expr_addr_of(&mut self, mutability: ast::Mutability, - expr: &ast::Expr) -> IoResult<()> { + expr: &ast::Expr) -> io::Result<()> { try!(word(&mut self.s, "&")); try!(self.print_mutability(mutability)); self.print_expr_maybe_paren(expr) } - pub fn print_expr(&mut self, expr: &ast::Expr) -> IoResult<()> { + pub fn print_expr(&mut self, expr: &ast::Expr) -> io::Result<()> { try!(self.maybe_print_comment(expr.span.lo)); try!(self.ibox(indent_unit)); try!(self.ann.pre(self, NodeExpr(expr))); @@ -1958,7 +1958,7 @@ impl<'a> State<'a> { self.end() } - pub fn print_local_decl(&mut self, loc: &ast::Local) -> IoResult<()> { + pub fn print_local_decl(&mut self, loc: &ast::Local) -> io::Result<()> { try!(self.print_pat(&*loc.pat)); if let Some(ref ty) = loc.ty { try!(self.word_space(":")); @@ -1967,7 +1967,7 @@ impl<'a> State<'a> { Ok(()) } - pub fn print_decl(&mut self, decl: &ast::Decl) -> IoResult<()> { + pub fn print_decl(&mut self, decl: &ast::Decl) -> io::Result<()> { try!(self.maybe_print_comment(decl.span.lo)); match decl.node { ast::DeclLocal(ref loc) => { @@ -1989,7 +1989,7 @@ impl<'a> State<'a> { } } - pub fn print_ident(&mut self, ident: ast::Ident) -> IoResult<()> { + pub fn print_ident(&mut self, ident: ast::Ident) -> io::Result<()> { if self.encode_idents_with_hygiene { let encoded = ident.encode_with_hygiene(); try!(word(&mut self.s, &encoded[..])) @@ -1999,17 +1999,17 @@ impl<'a> State<'a> { self.ann.post(self, NodeIdent(&ident)) } - pub fn print_usize(&mut self, i: usize) -> IoResult<()> { + pub fn print_usize(&mut self, i: usize) -> io::Result<()> { word(&mut self.s, &i.to_string()) } - pub fn print_name(&mut self, name: ast::Name) -> IoResult<()> { + pub fn print_name(&mut self, name: ast::Name) -> io::Result<()> { try!(word(&mut self.s, &token::get_name(name))); self.ann.post(self, NodeName(&name)) } pub fn print_for_decl(&mut self, loc: &ast::Local, - coll: &ast::Expr) -> IoResult<()> { + coll: &ast::Expr) -> io::Result<()> { try!(self.print_local_decl(loc)); try!(space(&mut self.s)); try!(self.word_space("in")); @@ -2020,7 +2020,7 @@ impl<'a> State<'a> { path: &ast::Path, colons_before_params: bool, depth: usize) - -> IoResult<()> + -> io::Result<()> { try!(self.maybe_print_comment(path.span.lo)); @@ -2044,7 +2044,7 @@ impl<'a> State<'a> { path: &ast::Path, qself: &ast::QSelf, colons_before_params: bool) - -> IoResult<()> + -> io::Result<()> { try!(word(&mut self.s, "<")); try!(self.print_type(&qself.ty)); @@ -2064,7 +2064,7 @@ impl<'a> State<'a> { fn print_path_parameters(&mut self, parameters: &ast::PathParameters, colons_before_params: bool) - -> IoResult<()> + -> io::Result<()> { if parameters.is_empty() { return Ok(()); @@ -2134,7 +2134,7 @@ impl<'a> State<'a> { Ok(()) } - pub fn print_pat(&mut self, pat: &ast::Pat) -> IoResult<()> { + pub fn print_pat(&mut self, pat: &ast::Pat) -> io::Result<()> { try!(self.maybe_print_comment(pat.span.lo)); try!(self.ann.pre(self, NodePat(pat))); /* Pat isn't normalized, but the beauty of it @@ -2253,7 +2253,7 @@ impl<'a> State<'a> { self.ann.post(self, NodePat(pat)) } - fn print_arm(&mut self, arm: &ast::Arm) -> IoResult<()> { + fn print_arm(&mut self, arm: &ast::Arm) -> io::Result<()> { // I have no idea why this check is necessary, but here it // is :( if arm.attrs.is_empty() { @@ -2302,7 +2302,7 @@ impl<'a> State<'a> { // Returns whether it printed anything fn print_explicit_self(&mut self, explicit_self: &ast::ExplicitSelf_, - mutbl: ast::Mutability) -> IoResult<bool> { + mutbl: ast::Mutability) -> io::Result<bool> { try!(self.print_mutability(mutbl)); match *explicit_self { ast::SelfStatic => { return Ok(false); } @@ -2331,7 +2331,7 @@ impl<'a> State<'a> { name: ast::Ident, generics: &ast::Generics, opt_explicit_self: Option<&ast::ExplicitSelf_>, - vis: ast::Visibility) -> IoResult<()> { + vis: ast::Visibility) -> io::Result<()> { try!(self.head("")); try!(self.print_fn_header_info(unsafety, abi, vis)); try!(self.nbsp()); @@ -2343,7 +2343,7 @@ impl<'a> State<'a> { pub fn print_fn_args(&mut self, decl: &ast::FnDecl, opt_explicit_self: Option<&ast::ExplicitSelf_>) - -> IoResult<()> { + -> io::Result<()> { // It is unfortunate to duplicate the commasep logic, but we want the // self type and the args all in the same box. try!(self.rbox(0, Inconsistent)); @@ -2376,7 +2376,7 @@ impl<'a> State<'a> { pub fn print_fn_args_and_ret(&mut self, decl: &ast::FnDecl, opt_explicit_self: Option<&ast::ExplicitSelf_>) - -> IoResult<()> { + -> io::Result<()> { try!(self.popen()); try!(self.print_fn_args(decl, opt_explicit_self)); if decl.variadic { @@ -2390,7 +2390,7 @@ impl<'a> State<'a> { pub fn print_fn_block_args( &mut self, decl: &ast::FnDecl) - -> IoResult<()> { + -> io::Result<()> { try!(word(&mut self.s, "|")); try!(self.print_fn_args(decl, None)); try!(word(&mut self.s, "|")); @@ -2415,7 +2415,7 @@ impl<'a> State<'a> { } pub fn print_capture_clause(&mut self, capture_clause: ast::CaptureClause) - -> IoResult<()> { + -> io::Result<()> { match capture_clause { ast::CaptureByValue => self.word_space("move"), ast::CaptureByRef => Ok(()), @@ -2425,7 +2425,7 @@ impl<'a> State<'a> { pub fn print_bounds(&mut self, prefix: &str, bounds: &[ast::TyParamBound]) - -> IoResult<()> { + -> io::Result<()> { if !bounds.is_empty() { try!(word(&mut self.s, prefix)); let mut first = true; @@ -2458,14 +2458,14 @@ impl<'a> State<'a> { pub fn print_lifetime(&mut self, lifetime: &ast::Lifetime) - -> IoResult<()> + -> io::Result<()> { self.print_name(lifetime.name) } pub fn print_lifetime_def(&mut self, lifetime: &ast::LifetimeDef) - -> IoResult<()> + -> io::Result<()> { try!(self.print_lifetime(&lifetime.lifetime)); let mut sep = ":"; @@ -2479,7 +2479,7 @@ impl<'a> State<'a> { pub fn print_generics(&mut self, generics: &ast::Generics) - -> IoResult<()> + -> io::Result<()> { let total = generics.lifetimes.len() + generics.ty_params.len(); if total == 0 { @@ -2508,7 +2508,7 @@ impl<'a> State<'a> { Ok(()) } - pub fn print_ty_param(&mut self, param: &ast::TyParam) -> IoResult<()> { + pub fn print_ty_param(&mut self, param: &ast::TyParam) -> io::Result<()> { try!(self.print_ident(param.ident)); try!(self.print_bounds(":", ¶m.bounds)); match param.default { @@ -2522,7 +2522,7 @@ impl<'a> State<'a> { } pub fn print_where_clause(&mut self, generics: &ast::Generics) - -> IoResult<()> { + -> io::Result<()> { if generics.where_clause.predicates.len() == 0 { return Ok(()) } @@ -2573,7 +2573,7 @@ impl<'a> State<'a> { Ok(()) } - pub fn print_meta_item(&mut self, item: &ast::MetaItem) -> IoResult<()> { + pub fn print_meta_item(&mut self, item: &ast::MetaItem) -> io::Result<()> { try!(self.ibox(indent_unit)); match item.node { ast::MetaWord(ref name) => { @@ -2596,7 +2596,7 @@ impl<'a> State<'a> { self.end() } - pub fn print_view_path(&mut self, vp: &ast::ViewPath) -> IoResult<()> { + pub fn print_view_path(&mut self, vp: &ast::ViewPath) -> io::Result<()> { match vp.node { ast::ViewPathSimple(ident, ref path) => { try!(self.print_path(path, false, 0)); @@ -2640,19 +2640,19 @@ impl<'a> State<'a> { } pub fn print_mutability(&mut self, - mutbl: ast::Mutability) -> IoResult<()> { + mutbl: ast::Mutability) -> io::Result<()> { match mutbl { ast::MutMutable => self.word_nbsp("mut"), ast::MutImmutable => Ok(()), } } - pub fn print_mt(&mut self, mt: &ast::MutTy) -> IoResult<()> { + pub fn print_mt(&mut self, mt: &ast::MutTy) -> io::Result<()> { try!(self.print_mutability(mt.mutbl)); self.print_type(&*mt.ty) } - pub fn print_arg(&mut self, input: &ast::Arg) -> IoResult<()> { + pub fn print_arg(&mut self, input: &ast::Arg) -> io::Result<()> { try!(self.ibox(indent_unit)); match input.ty.node { ast::TyInfer => try!(self.print_pat(&*input.pat)), @@ -2675,7 +2675,7 @@ impl<'a> State<'a> { self.end() } - pub fn print_fn_output(&mut self, decl: &ast::FnDecl) -> IoResult<()> { + pub fn print_fn_output(&mut self, decl: &ast::FnDecl) -> io::Result<()> { if let ast::DefaultReturn(..) = decl.output { return Ok(()); } @@ -2705,7 +2705,7 @@ impl<'a> State<'a> { id: Option<ast::Ident>, generics: &ast::Generics, opt_explicit_self: Option<&ast::ExplicitSelf_>) - -> IoResult<()> { + -> io::Result<()> { try!(self.ibox(indent_unit)); try!(self.print_fn_header_info(Some(unsafety), abi, ast::Inherited)); @@ -2726,7 +2726,7 @@ impl<'a> State<'a> { pub fn maybe_print_trailing_comment(&mut self, span: codemap::Span, next_pos: Option<BytePos>) - -> IoResult<()> { + -> io::Result<()> { let cm = match self.cm { Some(cm) => cm, _ => return Ok(()) @@ -2749,7 +2749,7 @@ impl<'a> State<'a> { Ok(()) } - pub fn print_remaining_comments(&mut self) -> IoResult<()> { + pub fn print_remaining_comments(&mut self) -> io::Result<()> { // If there aren't any remaining comments, then we need to manually // make sure there is a line break at the end. if self.next_comment().is_none() { @@ -2767,7 +2767,7 @@ impl<'a> State<'a> { Ok(()) } - pub fn print_literal(&mut self, lit: &ast::Lit) -> IoResult<()> { + pub fn print_literal(&mut self, lit: &ast::Lit) -> io::Result<()> { try!(self.maybe_print_comment(lit.span.lo)); match self.next_lit(lit.span.lo) { Some(ref ltrl) => { @@ -2848,7 +2848,7 @@ impl<'a> State<'a> { } } - pub fn maybe_print_comment(&mut self, pos: BytePos) -> IoResult<()> { + pub fn maybe_print_comment(&mut self, pos: BytePos) -> io::Result<()> { loop { match self.next_comment() { Some(ref cmnt) => { @@ -2864,7 +2864,7 @@ impl<'a> State<'a> { } pub fn print_comment(&mut self, - cmnt: &comments::Comment) -> IoResult<()> { + cmnt: &comments::Comment) -> io::Result<()> { match cmnt.style { comments::Mixed => { assert_eq!(cmnt.lines.len(), 1); @@ -2915,7 +2915,7 @@ impl<'a> State<'a> { } pub fn print_string(&mut self, st: &str, - style: ast::StrStyle) -> IoResult<()> { + style: ast::StrStyle) -> io::Result<()> { let st = match style { ast::CookedStr => { (format!("\"{}\"", st.escape_default())) @@ -2943,7 +2943,7 @@ impl<'a> State<'a> { } pub fn print_opt_unsafety(&mut self, - opt_unsafety: Option<ast::Unsafety>) -> IoResult<()> { + opt_unsafety: Option<ast::Unsafety>) -> io::Result<()> { match opt_unsafety { Some(unsafety) => self.print_unsafety(unsafety), None => Ok(()) @@ -2952,7 +2952,7 @@ impl<'a> State<'a> { pub fn print_opt_abi_and_extern_if_nondefault(&mut self, opt_abi: Option<abi::Abi>) - -> IoResult<()> { + -> io::Result<()> { match opt_abi { Some(abi::Rust) => Ok(()), Some(abi) => { @@ -2964,7 +2964,7 @@ impl<'a> State<'a> { } pub fn print_extern_opt_abi(&mut self, - opt_abi: Option<abi::Abi>) -> IoResult<()> { + opt_abi: Option<abi::Abi>) -> io::Result<()> { match opt_abi { Some(abi) => { try!(self.word_nbsp("extern")); @@ -2977,7 +2977,7 @@ impl<'a> State<'a> { pub fn print_fn_header_info(&mut self, opt_unsafety: Option<ast::Unsafety>, abi: abi::Abi, - vis: ast::Visibility) -> IoResult<()> { + vis: ast::Visibility) -> io::Result<()> { try!(word(&mut self.s, &visibility_qualified(vis, ""))); try!(self.print_opt_unsafety(opt_unsafety)); @@ -2989,7 +2989,7 @@ impl<'a> State<'a> { word(&mut self.s, "fn") } - pub fn print_unsafety(&mut self, s: ast::Unsafety) -> IoResult<()> { + pub fn print_unsafety(&mut self, s: ast::Unsafety) -> io::Result<()> { match s { ast::Unsafety::Normal => Ok(()), ast::Unsafety::Unsafe => self.word_nbsp("unsafe"), diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs index 5bada41badf..5e858d8a79f 100644 --- a/src/libsyntax/test.rs +++ b/src/libsyntax/test.rs @@ -37,7 +37,7 @@ use {ast, ast_util}; 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 @@ impl<'a> fold::Folder for TestHarnessGenerator<'a> { 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); @@ -256,7 +256,8 @@ fn generate_test_harness(sess: &ParseSess, callee: NameAndSpan { name: "test".to_string(), format: MacroAttribute, - span: None + span: None, + allow_internal_unstable: false, } }); @@ -288,7 +289,8 @@ fn ignored_span(cx: &TestCtxt, sp: Span) -> Span { callee: NameAndSpan { name: "test".to_string(), format: MacroAttribute, - span: None + span: None, + allow_internal_unstable: true, } }; let expn_id = cx.sess.span_diagnostic.cm.record_expansion(info); @@ -376,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, } } @@ -615,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), @@ -636,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 { diff --git a/src/libsyntax/util/interner.rs b/src/libsyntax/util/interner.rs index 5be45a2698f..7ae9e4646e5 100644 --- a/src/libsyntax/util/interner.rs +++ b/src/libsyntax/util/interner.rs @@ -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)); diff --git a/src/libsyntax/util/small_vector.rs b/src/libsyntax/util/small_vector.rs index 90df23882a1..5bd6591cfb0 100644 --- a/src/libsyntax/util/small_vector.rs +++ b/src/libsyntax/util/small_vector.rs @@ -236,13 +236,13 @@ mod test { } #[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(""); } diff --git a/src/libterm/lib.rs b/src/libterm/lib.rs index 756d67b5db1..1dad5d09092 100644 --- a/src/libterm/lib.rs +++ b/src/libterm/lib.rs @@ -38,6 +38,8 @@ //! [win]: http://msdn.microsoft.com/en-us/library/windows/desktop/ms682010%28v=vs.85%29.aspx //! [ti]: https://en.wikipedia.org/wiki/Terminfo +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "term"] #![unstable(feature = "rustc_private", reason = "use the crates.io `term` library instead")] @@ -53,13 +55,14 @@ #![feature(box_syntax)] #![feature(collections)] #![feature(int_uint)] +#![feature(io)] #![feature(old_io)] -#![feature(old_path)] +#![feature(path)] #![feature(rustc_private)] #![feature(staged_api)] -#![feature(unicode)] #![feature(std_misc)] -#![feature(os)] +#![feature(unicode)] +#![feature(path_ext)] #![cfg_attr(windows, feature(libc))] #[macro_use] extern crate log; @@ -153,23 +156,23 @@ pub mod color { /// Number for a terminal color pub type Color = u16; - pub const BLACK: Color = 0u16; - pub const RED: Color = 1u16; - pub const GREEN: Color = 2u16; - pub const YELLOW: Color = 3u16; - pub const BLUE: Color = 4u16; - pub const MAGENTA: Color = 5u16; - pub const CYAN: Color = 6u16; - pub const WHITE: Color = 7u16; - - pub const BRIGHT_BLACK: Color = 8u16; - pub const BRIGHT_RED: Color = 9u16; - pub const BRIGHT_GREEN: Color = 10u16; - pub const BRIGHT_YELLOW: Color = 11u16; - pub const BRIGHT_BLUE: Color = 12u16; - pub const BRIGHT_MAGENTA: Color = 13u16; - pub const BRIGHT_CYAN: Color = 14u16; - pub const BRIGHT_WHITE: Color = 15u16; + pub const BLACK: Color = 0; + pub const RED: Color = 1; + pub const GREEN: Color = 2; + pub const YELLOW: Color = 3; + pub const BLUE: Color = 4; + pub const MAGENTA: Color = 5; + pub const CYAN: Color = 6; + pub const WHITE: Color = 7; + + pub const BRIGHT_BLACK: Color = 8; + pub const BRIGHT_RED: Color = 9; + pub const BRIGHT_GREEN: Color = 10; + pub const BRIGHT_YELLOW: Color = 11; + pub const BRIGHT_BLUE: Color = 12; + pub const BRIGHT_MAGENTA: Color = 13; + pub const BRIGHT_CYAN: Color = 14; + pub const BRIGHT_WHITE: Color = 15; } /// Terminal attributes diff --git a/src/libterm/terminfo/parm.rs b/src/libterm/terminfo/parm.rs index 112525fcce9..30b732781db 100644 --- a/src/libterm/terminfo/parm.rs +++ b/src/libterm/terminfo/parm.rs @@ -128,7 +128,7 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables) // if c is 0, use 0200 (128) for ncurses compatibility Number(c) => { output.push(if c == 0 { - 128u8 + 128 } else { c as u8 }) @@ -647,7 +647,7 @@ mod test { #[test] fn test_comparison_ops() { - let v = [('<', [1u8, 0u8, 0u8]), ('=', [0u8, 1u8, 0u8]), ('>', [0u8, 0u8, 1u8])]; + let v = [('<', [1, 0, 0]), ('=', [0, 1, 0]), ('>', [0, 0, 1])]; for &(op, bs) in &v { let s = format!("%{{1}}%{{2}}%{}%d", op); let res = expand(s.as_bytes(), &[], &mut Variables::new()); diff --git a/src/libterm/terminfo/parser/compiled.rs b/src/libterm/terminfo/parser/compiled.rs index c147e6aa056..cc9a2880b5d 100644 --- a/src/libterm/terminfo/parser/compiled.rs +++ b/src/libterm/terminfo/parser/compiled.rs @@ -13,7 +13,8 @@ //! ncurses-compatible compiled terminfo format parsing (term(5)) use std::collections::HashMap; -use std::old_io; +use std::io::prelude::*; +use std::io; use super::super::TermInfo; // These are the orders ncurses uses in its compiled format (as of 5.9). Not sure if portable. @@ -158,7 +159,7 @@ pub static stringnames: &'static[&'static str] = &[ "cbt", "_", "cr", "csr", "tb "box1"]; /// Parse a compiled terminfo entry, using long capability names if `longnames` is true -pub fn parse(file: &mut old_io::Reader, longnames: bool) +pub fn parse(file: &mut Read, longnames: bool) -> Result<Box<TermInfo>, String> { macro_rules! try { ($e:expr) => ( match $e { @@ -182,17 +183,17 @@ pub fn parse(file: &mut old_io::Reader, longnames: bool) } // Check magic number - let magic = try!(file.read_le_u16()); + let magic = try!(read_le_u16(file)); if magic != 0x011A { return Err(format!("invalid magic number: expected {:x}, found {:x}", 0x011A as usize, magic as usize)); } - let names_bytes = try!(file.read_le_i16()) as int; - let bools_bytes = try!(file.read_le_i16()) as int; - let numbers_count = try!(file.read_le_i16()) as int; - let string_offsets_count = try!(file.read_le_i16()) as int; - let string_table_bytes = try!(file.read_le_i16()) as int; + let names_bytes = try!(read_le_u16(file)) as int; + let bools_bytes = try!(read_le_u16(file)) as int; + let numbers_count = try!(read_le_u16(file)) as int; + let string_offsets_count = try!(read_le_u16(file)) as int; + let string_table_bytes = try!(read_le_u16(file)) as int; assert!(names_bytes > 0); @@ -212,7 +213,7 @@ pub fn parse(file: &mut old_io::Reader, longnames: bool) } // don't read NUL - let bytes = try!(file.read_exact(names_bytes as uint - 1)); + let bytes = try!(read_exact(file, names_bytes as uint - 1)); let names_str = match String::from_utf8(bytes) { Ok(s) => s, Err(_) => return Err("input not utf-8".to_string()), @@ -222,12 +223,12 @@ pub fn parse(file: &mut old_io::Reader, longnames: bool) .map(|s| s.to_string()) .collect(); - try!(file.read_byte()); // consume NUL + try!(read_byte(file)); // consume NUL let mut bools_map = HashMap::new(); if bools_bytes != 0 { for i in 0..bools_bytes { - let b = try!(file.read_byte()); + let b = try!(read_byte(file)); if b == 1 { bools_map.insert(bnames[i as uint].to_string(), true); } @@ -235,13 +236,13 @@ pub fn parse(file: &mut old_io::Reader, longnames: bool) } if (bools_bytes + names_bytes) % 2 == 1 { - try!(file.read_byte()); // compensate for padding + try!(read_byte(file)); // compensate for padding } let mut numbers_map = HashMap::new(); if numbers_count != 0 { for i in 0..numbers_count { - let n = try!(file.read_le_u16()); + let n = try!(read_le_u16(file)); if n != 0xFFFF { numbers_map.insert(nnames[i as uint].to_string(), n); } @@ -253,10 +254,10 @@ pub fn parse(file: &mut old_io::Reader, longnames: bool) if string_offsets_count != 0 { let mut string_offsets = Vec::with_capacity(10); for _ in 0..string_offsets_count { - string_offsets.push(try!(file.read_le_u16())); + string_offsets.push(try!(read_le_u16(file))); } - let string_table = try!(file.read_exact(string_table_bytes as uint)); + let string_table = try!(read_exact(file, string_table_bytes as usize)); if string_table.len() != string_table_bytes as uint { return Err("error: hit EOF before end of string \ @@ -309,6 +310,25 @@ pub fn parse(file: &mut old_io::Reader, longnames: bool) }) } +fn read_le_u16<R: Read + ?Sized>(r: &mut R) -> io::Result<u16> { + let mut b = [0; 2]; + assert_eq!(try!(r.read(&mut b)), 2); + Ok((b[0] as u16) | ((b[1] as u16) << 8)) +} + +fn read_byte<R: Read + ?Sized>(r: &mut R) -> io::Result<u8> { + let mut b = [0; 1]; + assert_eq!(try!(r.read(&mut b)), 1); + Ok(b[0]) +} + +fn read_exact<R: Read + ?Sized>(r: &mut R, sz: usize) -> io::Result<Vec<u8>> { + let mut v = Vec::with_capacity(sz); + try!(r.take(sz as u64).read_to_end(&mut v)); + assert_eq!(v.len(), sz); + Ok(v) +} + /// Create a dummy TermInfo struct for msys terminals pub fn msys_terminfo() -> Box<TermInfo> { let mut strings = HashMap::new(); diff --git a/src/libterm/terminfo/searcher.rs b/src/libterm/terminfo/searcher.rs index a0cd7842070..f47921cbf5e 100644 --- a/src/libterm/terminfo/searcher.rs +++ b/src/libterm/terminfo/searcher.rs @@ -12,26 +12,27 @@ //! //! Does not support hashed database, only filesystem! -use std::old_io::File; -use std::old_io::fs::PathExtensions; use std::env; +use std::fs::File; +use std::io::prelude::*; +use std::path::PathBuf; /// Return path to database entry for `term` #[allow(deprecated)] -pub fn get_dbpath_for_term(term: &str) -> Option<Box<Path>> { +pub fn get_dbpath_for_term(term: &str) -> Option<Box<PathBuf>> { if term.len() == 0 { return None; } - let homedir = ::std::os::homedir(); + let homedir = env::home_dir(); let mut dirs_to_search = Vec::new(); let first_char = term.char_at(0); // Find search directory - match env::var("TERMINFO") { - Ok(dir) => dirs_to_search.push(Path::new(dir)), - Err(..) => { + match env::var_os("TERMINFO") { + Some(dir) => dirs_to_search.push(PathBuf::new(&dir)), + None => { if homedir.is_some() { // ncurses compatibility; dirs_to_search.push(homedir.unwrap().join(".terminfo")) @@ -39,9 +40,9 @@ pub fn get_dbpath_for_term(term: &str) -> Option<Box<Path>> { match env::var("TERMINFO_DIRS") { Ok(dirs) => for i in dirs.split(':') { if i == "" { - dirs_to_search.push(Path::new("/usr/share/terminfo")); + dirs_to_search.push(PathBuf::new("/usr/share/terminfo")); } else { - dirs_to_search.push(Path::new(i)); + dirs_to_search.push(PathBuf::new(i)); } }, // Found nothing in TERMINFO_DIRS, use the default paths: @@ -49,9 +50,9 @@ pub fn get_dbpath_for_term(term: &str) -> Option<Box<Path>> { // ~/.terminfo, ncurses will search /etc/terminfo, then // /lib/terminfo, and eventually /usr/share/terminfo. Err(..) => { - dirs_to_search.push(Path::new("/etc/terminfo")); - dirs_to_search.push(Path::new("/lib/terminfo")); - dirs_to_search.push(Path::new("/usr/share/terminfo")); + dirs_to_search.push(PathBuf::new("/etc/terminfo")); + dirs_to_search.push(PathBuf::new("/lib/terminfo")); + dirs_to_search.push(PathBuf::new("/usr/share/terminfo")); } } } @@ -61,13 +62,13 @@ pub fn get_dbpath_for_term(term: &str) -> Option<Box<Path>> { for p in &dirs_to_search { if p.exists() { let f = first_char.to_string(); - let newp = p.join_many(&[&f[..], term]); + let newp = p.join(&f).join(term); if newp.exists() { return Some(box newp); } // on some installations the dir is named after the hex of the char (e.g. OS X) let f = format!("{:x}", first_char as uint); - let newp = p.join_many(&[&f[..], term]); + let newp = p.join(&f).join(term); if newp.exists() { return Some(box newp); } @@ -96,17 +97,17 @@ pub fn open(term: &str) -> Result<File, String> { fn test_get_dbpath_for_term() { // woefully inadequate test coverage // note: current tests won't work with non-standard terminfo hierarchies (e.g. OS X's) - use std::os::{setenv, unsetenv}; + use std::env; // FIXME (#9639): This needs to handle non-utf8 paths fn x(t: &str) -> String { let p = get_dbpath_for_term(t).expect("no terminfo entry found"); - p.as_str().unwrap().to_string() + p.to_str().unwrap().to_string() }; assert!(x("screen") == "/usr/share/terminfo/s/screen"); assert!(get_dbpath_for_term("") == None); - setenv("TERMINFO_DIRS", ":"); + env::set_var("TERMINFO_DIRS", ":"); assert!(x("screen") == "/usr/share/terminfo/s/screen"); - unsetenv("TERMINFO_DIRS"); + env::remove_var("TERMINFO_DIRS"); } #[test] diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index a144904903e..1590291c88c 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -23,6 +23,8 @@ // running tests while providing a base that other test frameworks may // build off of. +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "test"] #![unstable(feature = "test")] #![staged_api] @@ -38,10 +40,11 @@ #![feature(core)] #![feature(int_uint)] #![feature(old_io)] -#![feature(old_path)] +#![feature(path)] #![feature(rustc_private)] #![feature(staged_api)] #![feature(std_misc)] +#![feature(io)] extern crate getopts; extern crate serialize; @@ -65,13 +68,16 @@ use term::color::{Color, RED, YELLOW, GREEN, CYAN}; use std::any::Any; use std::cmp; use std::collections::BTreeMap; +use std::env; use std::fmt; -use std::old_io::stdio::StdWriter; -use std::old_io::{File, ChanReader, ChanWriter}; -use std::old_io; +use std::fs::File; +use std::io::{self, Write}; use std::iter::repeat; use std::num::{Float, Int}; -use std::env; +use std::old_io::stdio::StdWriter; +use std::old_io::{ChanReader, ChanWriter}; +use std::old_io; +use std::path::{PathBuf}; use std::sync::mpsc::{channel, Sender}; use std::thread; use std::thunk::{Thunk, Invoke}; @@ -84,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; @@ -196,7 +202,7 @@ pub struct Bencher { } #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] -pub enum ShouldFail { +pub enum ShouldPanic { No, Yes(Option<&'static str>) } @@ -207,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 {} @@ -287,7 +293,7 @@ pub struct TestOpts { pub run_ignored: bool, pub run_tests: bool, pub run_benchmarks: bool, - pub logfile: Option<Path>, + pub logfile: Option<PathBuf>, pub nocapture: bool, pub color: ColorConfig, } @@ -345,10 +351,10 @@ Test Attributes: 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 @@ -376,7 +382,7 @@ pub fn parse_opts(args: &[String]) -> Option<OptRes> { let run_ignored = matches.opt_present("ignored"); let logfile = matches.opt_str("logfile"); - let logfile = logfile.map(|s| Path::new(s)); + let logfile = logfile.map(|s| PathBuf::new(&s)); let run_benchmarks = matches.opt_present("bench"); let run_tests = ! run_benchmarks || @@ -446,11 +452,19 @@ struct ConsoleTestState<T> { max_name_len: uint, // number of columns to fill when aligning names } +fn new2old(new: io::Error) -> old_io::IoError { + old_io::IoError { + kind: old_io::OtherIoError, + desc: "other error", + detail: Some(new.to_string()), + } +} + impl<T: Writer> ConsoleTestState<T> { pub fn new(opts: &TestOpts, _: Option<T>) -> old_io::IoResult<ConsoleTestState<StdWriter>> { let log_out = match opts.logfile { - Some(ref path) => Some(try!(File::create(path))), + Some(ref path) => Some(try!(File::create(path).map_err(new2old))), None => None }; let out = match term::stdout() { @@ -560,7 +574,7 @@ impl<T: Writer> ConsoleTestState<T> { } pub fn write_log(&mut self, test: &TestDesc, - result: &TestResult) -> old_io::IoResult<()> { + result: &TestResult) -> io::Result<()> { match self.log_out { None => Ok(()), Some(ref mut o) => { @@ -646,7 +660,7 @@ pub fn run_tests_console(opts: &TestOpts, tests: Vec<TestDescAndFn> ) -> old_io: TeFiltered(ref filtered_tests) => st.write_run_start(filtered_tests.len()), TeWait(ref test, padding) => st.write_test_start(test, padding), TeResult(test, result, stdout) => { - try!(st.write_log(&test, &result)); + try!(st.write_log(&test, &result).map_err(new2old)); try!(st.write_result(&result)); match result { TrOk => st.passed += 1, @@ -703,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 { @@ -732,8 +746,8 @@ fn should_sort_failures_before_printing_them() { Pretty(_) => unreachable!() }; - let apos = s.find_str("a").unwrap(); - let bpos = s.find_str("b").unwrap(); + let apos = s.find("a").unwrap(); + let bpos = s.find("b").unwrap(); assert!(apos < bpos); } @@ -939,10 +953,10 @@ pub fn run_test(opts: &TestOpts, } 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)) @@ -1011,7 +1025,7 @@ impl Bencher { pub fn iter<T, F>(&mut self, mut inner: F) where F: FnMut() -> T { self.dur = Duration::span(|| { let k = self.iterations; - for _ in 0u64..k { + for _ in 0..k { black_box(inner()); } }); @@ -1037,7 +1051,7 @@ impl Bencher { // This is a more statistics-driven benchmark algorithm pub fn auto_bench<F>(&mut self, mut f: F) -> stats::Summary<f64> where F: FnMut(&mut Bencher) { // Initial bench run to get ballpark figure. - let mut n = 1_u64; + let mut n = 1; self.bench_n(n, |x| f(x)); // Try to estimate iter count for 1ms falling back to 1m @@ -1095,7 +1109,14 @@ impl Bencher { 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, + }; } } } @@ -1130,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; @@ -1141,7 +1162,7 @@ mod tests { desc: TestDesc { name: StaticTestName("whatever"), ignore: true, - should_fail: ShouldFail::No, + should_panic: ShouldPanic::No, }, testfn: DynTestFn(Thunk::new(move|| f())), }; @@ -1158,7 +1179,7 @@ mod tests { desc: TestDesc { name: StaticTestName("whatever"), ignore: true, - should_fail: ShouldFail::No, + should_panic: ShouldPanic::No, }, testfn: DynTestFn(Thunk::new(move|| f())), }; @@ -1169,13 +1190,13 @@ mod tests { } #[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())), }; @@ -1186,13 +1207,13 @@ mod tests { } #[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())), }; @@ -1203,13 +1224,13 @@ mod tests { } #[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())), }; @@ -1220,13 +1241,13 @@ mod tests { } #[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())), }; @@ -1262,7 +1283,7 @@ mod tests { desc: TestDesc { name: StaticTestName("1"), ignore: true, - should_fail: ShouldFail::No, + should_panic: ShouldPanic::No, }, testfn: DynTestFn(Thunk::new(move|| {})), }, @@ -1270,7 +1291,7 @@ mod tests { desc: TestDesc { name: StaticTestName("2"), ignore: false, - should_fail: ShouldFail::No, + should_panic: ShouldPanic::No, }, testfn: DynTestFn(Thunk::new(move|| {})), }); @@ -1306,7 +1327,7 @@ mod tests { 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/lib.rs b/src/libunicode/lib.rs index 791886be1ce..2095b6921c8 100644 --- a/src/libunicode/lib.rs +++ b/src/libunicode/lib.rs @@ -20,6 +20,8 @@ //! provide for basic string-related manipulations. This crate does not //! (yet) aim to provide a full set of Unicode tables. +// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364) +#![cfg_attr(stage0, feature(custom_attribute))] #![crate_name = "unicode"] #![unstable(feature = "unicode")] #![feature(staged_api)] diff --git a/src/libunicode/tables.rs b/src/libunicode/tables.rs index 99a6b6aa180..1fb6ee7bc7c 100644 --- a/src/libunicode/tables.rs +++ b/src/libunicode/tables.rs @@ -115,27 +115,26 @@ pub mod general_category { '\u{2eff}'), ('\u{2fd6}', '\u{2fef}'), ('\u{2ffc}', '\u{2fff}'), ('\u{3040}', '\u{3040}'), ('\u{3097}', '\u{3098}'), ('\u{3100}', '\u{3104}'), ('\u{312e}', '\u{3130}'), ('\u{318f}', '\u{318f}'), ('\u{31bb}', '\u{31bf}'), ('\u{31e4}', '\u{31ef}'), ('\u{321f}', '\u{321f}'), - ('\u{32ff}', '\u{32ff}'), ('\u{3401}', '\u{4db4}'), ('\u{4db6}', '\u{4dbf}'), ('\u{4e01}', - '\u{9fcb}'), ('\u{9fcd}', '\u{9fff}'), ('\u{a48d}', '\u{a48f}'), ('\u{a4c7}', '\u{a4cf}'), - ('\u{a62c}', '\u{a63f}'), ('\u{a69e}', '\u{a69e}'), ('\u{a6f8}', '\u{a6ff}'), ('\u{a78f}', - '\u{a78f}'), ('\u{a7ae}', '\u{a7af}'), ('\u{a7b2}', '\u{a7f6}'), ('\u{a82c}', '\u{a82f}'), - ('\u{a83a}', '\u{a83f}'), ('\u{a878}', '\u{a87f}'), ('\u{a8c5}', '\u{a8cd}'), ('\u{a8da}', - '\u{a8df}'), ('\u{a8fc}', '\u{a8ff}'), ('\u{a954}', '\u{a95e}'), ('\u{a97d}', '\u{a97f}'), - ('\u{a9ce}', '\u{a9ce}'), ('\u{a9da}', '\u{a9dd}'), ('\u{a9ff}', '\u{a9ff}'), ('\u{aa37}', - '\u{aa3f}'), ('\u{aa4e}', '\u{aa4f}'), ('\u{aa5a}', '\u{aa5b}'), ('\u{aac3}', '\u{aada}'), - ('\u{aaf7}', '\u{ab00}'), ('\u{ab07}', '\u{ab08}'), ('\u{ab0f}', '\u{ab10}'), ('\u{ab17}', - '\u{ab1f}'), ('\u{ab27}', '\u{ab27}'), ('\u{ab2f}', '\u{ab2f}'), ('\u{ab60}', '\u{ab63}'), - ('\u{ab66}', '\u{abbf}'), ('\u{abee}', '\u{abef}'), ('\u{abfa}', '\u{abff}'), ('\u{ac01}', - '\u{d7a2}'), ('\u{d7a4}', '\u{d7af}'), ('\u{d7c7}', '\u{d7ca}'), ('\u{d7fc}', '\u{d7ff}'), - ('\u{e000}', '\u{f8ff}'), ('\u{fa6e}', '\u{fa6f}'), ('\u{fada}', '\u{faff}'), ('\u{fb07}', - '\u{fb12}'), ('\u{fb18}', '\u{fb1c}'), ('\u{fb37}', '\u{fb37}'), ('\u{fb3d}', '\u{fb3d}'), - ('\u{fb3f}', '\u{fb3f}'), ('\u{fb42}', '\u{fb42}'), ('\u{fb45}', '\u{fb45}'), ('\u{fbc2}', - '\u{fbd2}'), ('\u{fd40}', '\u{fd4f}'), ('\u{fd90}', '\u{fd91}'), ('\u{fdc8}', '\u{fdef}'), - ('\u{fdfe}', '\u{fdff}'), ('\u{fe1a}', '\u{fe1f}'), ('\u{fe2e}', '\u{fe2f}'), ('\u{fe53}', - '\u{fe53}'), ('\u{fe67}', '\u{fe67}'), ('\u{fe6c}', '\u{fe6f}'), ('\u{fe75}', '\u{fe75}'), - ('\u{fefd}', '\u{ff00}'), ('\u{ffbf}', '\u{ffc1}'), ('\u{ffc8}', '\u{ffc9}'), ('\u{ffd0}', - '\u{ffd1}'), ('\u{ffd8}', '\u{ffd9}'), ('\u{ffdd}', '\u{ffdf}'), ('\u{ffe7}', '\u{ffe7}'), - ('\u{ffef}', '\u{fffb}'), ('\u{fffe}', '\u{ffff}'), ('\u{1000c}', '\u{1000c}'), + ('\u{32ff}', '\u{32ff}'), ('\u{4db6}', '\u{4dbf}'), ('\u{9fcd}', '\u{9fff}'), ('\u{a48d}', + '\u{a48f}'), ('\u{a4c7}', '\u{a4cf}'), ('\u{a62c}', '\u{a63f}'), ('\u{a69e}', '\u{a69e}'), + ('\u{a6f8}', '\u{a6ff}'), ('\u{a78f}', '\u{a78f}'), ('\u{a7ae}', '\u{a7af}'), ('\u{a7b2}', + '\u{a7f6}'), ('\u{a82c}', '\u{a82f}'), ('\u{a83a}', '\u{a83f}'), ('\u{a878}', '\u{a87f}'), + ('\u{a8c5}', '\u{a8cd}'), ('\u{a8da}', '\u{a8df}'), ('\u{a8fc}', '\u{a8ff}'), ('\u{a954}', + '\u{a95e}'), ('\u{a97d}', '\u{a97f}'), ('\u{a9ce}', '\u{a9ce}'), ('\u{a9da}', '\u{a9dd}'), + ('\u{a9ff}', '\u{a9ff}'), ('\u{aa37}', '\u{aa3f}'), ('\u{aa4e}', '\u{aa4f}'), ('\u{aa5a}', + '\u{aa5b}'), ('\u{aac3}', '\u{aada}'), ('\u{aaf7}', '\u{ab00}'), ('\u{ab07}', '\u{ab08}'), + ('\u{ab0f}', '\u{ab10}'), ('\u{ab17}', '\u{ab1f}'), ('\u{ab27}', '\u{ab27}'), ('\u{ab2f}', + '\u{ab2f}'), ('\u{ab60}', '\u{ab63}'), ('\u{ab66}', '\u{abbf}'), ('\u{abee}', '\u{abef}'), + ('\u{abfa}', '\u{abff}'), ('\u{d7a4}', '\u{d7af}'), ('\u{d7c7}', '\u{d7ca}'), ('\u{d7fc}', + '\u{d7ff}'), ('\u{e000}', '\u{f8ff}'), ('\u{fa6e}', '\u{fa6f}'), ('\u{fada}', '\u{faff}'), + ('\u{fb07}', '\u{fb12}'), ('\u{fb18}', '\u{fb1c}'), ('\u{fb37}', '\u{fb37}'), ('\u{fb3d}', + '\u{fb3d}'), ('\u{fb3f}', '\u{fb3f}'), ('\u{fb42}', '\u{fb42}'), ('\u{fb45}', '\u{fb45}'), + ('\u{fbc2}', '\u{fbd2}'), ('\u{fd40}', '\u{fd4f}'), ('\u{fd90}', '\u{fd91}'), ('\u{fdc8}', + '\u{fdef}'), ('\u{fdfe}', '\u{fdff}'), ('\u{fe1a}', '\u{fe1f}'), ('\u{fe2e}', '\u{fe2f}'), + ('\u{fe53}', '\u{fe53}'), ('\u{fe67}', '\u{fe67}'), ('\u{fe6c}', '\u{fe6f}'), ('\u{fe75}', + '\u{fe75}'), ('\u{fefd}', '\u{ff00}'), ('\u{ffbf}', '\u{ffc1}'), ('\u{ffc8}', '\u{ffc9}'), + ('\u{ffd0}', '\u{ffd1}'), ('\u{ffd8}', '\u{ffd9}'), ('\u{ffdd}', '\u{ffdf}'), ('\u{ffe7}', + '\u{ffe7}'), ('\u{ffef}', '\u{fffb}'), ('\u{fffe}', '\u{ffff}'), ('\u{1000c}', '\u{1000c}'), ('\u{10027}', '\u{10027}'), ('\u{1003b}', '\u{1003b}'), ('\u{1003e}', '\u{1003e}'), ('\u{1004e}', '\u{1004f}'), ('\u{1005e}', '\u{1007f}'), ('\u{100fb}', '\u{100ff}'), ('\u{10103}', '\u{10106}'), ('\u{10134}', '\u{10136}'), ('\u{1018d}', '\u{1018f}'), @@ -210,9 +209,8 @@ pub mod general_category { ('\u{1f643}', '\u{1f644}'), ('\u{1f6d0}', '\u{1f6df}'), ('\u{1f6ed}', '\u{1f6ef}'), ('\u{1f6f4}', '\u{1f6ff}'), ('\u{1f774}', '\u{1f77f}'), ('\u{1f7d5}', '\u{1f7ff}'), ('\u{1f80c}', '\u{1f80f}'), ('\u{1f848}', '\u{1f84f}'), ('\u{1f85a}', '\u{1f85f}'), - ('\u{1f888}', '\u{1f88f}'), ('\u{1f8ae}', '\u{1ffff}'), ('\u{20001}', '\u{2a6d5}'), - ('\u{2a6d7}', '\u{2a6ff}'), ('\u{2a701}', '\u{2b733}'), ('\u{2b735}', '\u{2b73f}'), - ('\u{2b741}', '\u{2b81c}'), ('\u{2b81e}', '\u{2f7ff}'), ('\u{2fa1e}', '\u{e00ff}'), + ('\u{1f888}', '\u{1f88f}'), ('\u{1f8ae}', '\u{1ffff}'), ('\u{2a6d7}', '\u{2a6ff}'), + ('\u{2b735}', '\u{2b73f}'), ('\u{2b81e}', '\u{2f7ff}'), ('\u{2fa1e}', '\u{e00ff}'), ('\u{e01f0}', '\u{10ffff}') ]; @@ -319,112 +317,108 @@ pub mod general_category { ('\u{2e9a}', '\u{2e9a}'), ('\u{2ef4}', '\u{2eff}'), ('\u{2fd6}', '\u{2fef}'), ('\u{2ffc}', '\u{2fff}'), ('\u{3040}', '\u{3040}'), ('\u{3097}', '\u{3098}'), ('\u{3100}', '\u{3104}'), ('\u{312e}', '\u{3130}'), ('\u{318f}', '\u{318f}'), ('\u{31bb}', '\u{31bf}'), ('\u{31e4}', - '\u{31ef}'), ('\u{321f}', '\u{321f}'), ('\u{32ff}', '\u{32ff}'), ('\u{3401}', '\u{4db4}'), - ('\u{4db6}', '\u{4dbf}'), ('\u{4e01}', '\u{9fcb}'), ('\u{9fcd}', '\u{9fff}'), ('\u{a48d}', - '\u{a48f}'), ('\u{a4c7}', '\u{a4cf}'), ('\u{a62c}', '\u{a63f}'), ('\u{a69e}', '\u{a69e}'), - ('\u{a6f8}', '\u{a6ff}'), ('\u{a78f}', '\u{a78f}'), ('\u{a7ae}', '\u{a7af}'), ('\u{a7b2}', - '\u{a7f6}'), ('\u{a82c}', '\u{a82f}'), ('\u{a83a}', '\u{a83f}'), ('\u{a878}', '\u{a87f}'), - ('\u{a8c5}', '\u{a8cd}'), ('\u{a8da}', '\u{a8df}'), ('\u{a8fc}', '\u{a8ff}'), ('\u{a954}', - '\u{a95e}'), ('\u{a97d}', '\u{a97f}'), ('\u{a9ce}', '\u{a9ce}'), ('\u{a9da}', '\u{a9dd}'), - ('\u{a9ff}', '\u{a9ff}'), ('\u{aa37}', '\u{aa3f}'), ('\u{aa4e}', '\u{aa4f}'), ('\u{aa5a}', - '\u{aa5b}'), ('\u{aac3}', '\u{aada}'), ('\u{aaf7}', '\u{ab00}'), ('\u{ab07}', '\u{ab08}'), - ('\u{ab0f}', '\u{ab10}'), ('\u{ab17}', '\u{ab1f}'), ('\u{ab27}', '\u{ab27}'), ('\u{ab2f}', - '\u{ab2f}'), ('\u{ab60}', '\u{ab63}'), ('\u{ab66}', '\u{abbf}'), ('\u{abee}', '\u{abef}'), - ('\u{abfa}', '\u{abff}'), ('\u{ac01}', '\u{d7a2}'), ('\u{d7a4}', '\u{d7af}'), ('\u{d7c7}', - '\u{d7ca}'), ('\u{d7fc}', '\u{d7ff}'), ('\u{e001}', '\u{f8fe}'), ('\u{fa6e}', '\u{fa6f}'), - ('\u{fada}', '\u{faff}'), ('\u{fb07}', '\u{fb12}'), ('\u{fb18}', '\u{fb1c}'), ('\u{fb37}', - '\u{fb37}'), ('\u{fb3d}', '\u{fb3d}'), ('\u{fb3f}', '\u{fb3f}'), ('\u{fb42}', '\u{fb42}'), - ('\u{fb45}', '\u{fb45}'), ('\u{fbc2}', '\u{fbd2}'), ('\u{fd40}', '\u{fd4f}'), ('\u{fd90}', - '\u{fd91}'), ('\u{fdc8}', '\u{fdef}'), ('\u{fdfe}', '\u{fdff}'), ('\u{fe1a}', '\u{fe1f}'), - ('\u{fe2e}', '\u{fe2f}'), ('\u{fe53}', '\u{fe53}'), ('\u{fe67}', '\u{fe67}'), ('\u{fe6c}', - '\u{fe6f}'), ('\u{fe75}', '\u{fe75}'), ('\u{fefd}', '\u{fefe}'), ('\u{ff00}', '\u{ff00}'), - ('\u{ffbf}', '\u{ffc1}'), ('\u{ffc8}', '\u{ffc9}'), ('\u{ffd0}', '\u{ffd1}'), ('\u{ffd8}', - '\u{ffd9}'), ('\u{ffdd}', '\u{ffdf}'), ('\u{ffe7}', '\u{ffe7}'), ('\u{ffef}', '\u{fff8}'), - ('\u{fffe}', '\u{ffff}'), ('\u{1000c}', '\u{1000c}'), ('\u{10027}', '\u{10027}'), - ('\u{1003b}', '\u{1003b}'), ('\u{1003e}', '\u{1003e}'), ('\u{1004e}', '\u{1004f}'), - ('\u{1005e}', '\u{1007f}'), ('\u{100fb}', '\u{100ff}'), ('\u{10103}', '\u{10106}'), - ('\u{10134}', '\u{10136}'), ('\u{1018d}', '\u{1018f}'), ('\u{1019c}', '\u{1019f}'), - ('\u{101a1}', '\u{101cf}'), ('\u{101fe}', '\u{1027f}'), ('\u{1029d}', '\u{1029f}'), - ('\u{102d1}', '\u{102df}'), ('\u{102fc}', '\u{102ff}'), ('\u{10324}', '\u{1032f}'), - ('\u{1034b}', '\u{1034f}'), ('\u{1037b}', '\u{1037f}'), ('\u{1039e}', '\u{1039e}'), - ('\u{103c4}', '\u{103c7}'), ('\u{103d6}', '\u{103ff}'), ('\u{1049e}', '\u{1049f}'), - ('\u{104aa}', '\u{104ff}'), ('\u{10528}', '\u{1052f}'), ('\u{10564}', '\u{1056e}'), - ('\u{10570}', '\u{105ff}'), ('\u{10737}', '\u{1073f}'), ('\u{10756}', '\u{1075f}'), - ('\u{10768}', '\u{107ff}'), ('\u{10806}', '\u{10807}'), ('\u{10809}', '\u{10809}'), - ('\u{10836}', '\u{10836}'), ('\u{10839}', '\u{1083b}'), ('\u{1083d}', '\u{1083e}'), - ('\u{10856}', '\u{10856}'), ('\u{1089f}', '\u{108a6}'), ('\u{108b0}', '\u{108ff}'), - ('\u{1091c}', '\u{1091e}'), ('\u{1093a}', '\u{1093e}'), ('\u{10940}', '\u{1097f}'), - ('\u{109b8}', '\u{109bd}'), ('\u{109c0}', '\u{109ff}'), ('\u{10a04}', '\u{10a04}'), - ('\u{10a07}', '\u{10a0b}'), ('\u{10a14}', '\u{10a14}'), ('\u{10a18}', '\u{10a18}'), - ('\u{10a34}', '\u{10a37}'), ('\u{10a3b}', '\u{10a3e}'), ('\u{10a48}', '\u{10a4f}'), - ('\u{10a59}', '\u{10a5f}'), ('\u{10aa0}', '\u{10abf}'), ('\u{10ae7}', '\u{10aea}'), - ('\u{10af7}', '\u{10aff}'), ('\u{10b36}', '\u{10b38}'), ('\u{10b56}', '\u{10b57}'), - ('\u{10b73}', '\u{10b77}'), ('\u{10b92}', '\u{10b98}'), ('\u{10b9d}', '\u{10ba8}'), - ('\u{10bb0}', '\u{10bff}'), ('\u{10c49}', '\u{10e5f}'), ('\u{10e7f}', '\u{10fff}'), - ('\u{1104e}', '\u{11051}'), ('\u{11070}', '\u{1107e}'), ('\u{110c2}', '\u{110cf}'), - ('\u{110e9}', '\u{110ef}'), ('\u{110fa}', '\u{110ff}'), ('\u{11135}', '\u{11135}'), - ('\u{11144}', '\u{1114f}'), ('\u{11177}', '\u{1117f}'), ('\u{111c9}', '\u{111cc}'), - ('\u{111ce}', '\u{111cf}'), ('\u{111db}', '\u{111e0}'), ('\u{111f5}', '\u{111ff}'), - ('\u{11212}', '\u{11212}'), ('\u{1123e}', '\u{112af}'), ('\u{112eb}', '\u{112ef}'), - ('\u{112fa}', '\u{11300}'), ('\u{11304}', '\u{11304}'), ('\u{1130d}', '\u{1130e}'), - ('\u{11311}', '\u{11312}'), ('\u{11329}', '\u{11329}'), ('\u{11331}', '\u{11331}'), - ('\u{11334}', '\u{11334}'), ('\u{1133a}', '\u{1133b}'), ('\u{11345}', '\u{11346}'), - ('\u{11349}', '\u{1134a}'), ('\u{1134e}', '\u{11356}'), ('\u{11358}', '\u{1135c}'), - ('\u{11364}', '\u{11365}'), ('\u{1136d}', '\u{1136f}'), ('\u{11375}', '\u{1147f}'), - ('\u{114c8}', '\u{114cf}'), ('\u{114da}', '\u{1157f}'), ('\u{115b6}', '\u{115b7}'), - ('\u{115ca}', '\u{115ff}'), ('\u{11645}', '\u{1164f}'), ('\u{1165a}', '\u{1167f}'), - ('\u{116b8}', '\u{116bf}'), ('\u{116ca}', '\u{1189f}'), ('\u{118f3}', '\u{118fe}'), - ('\u{11900}', '\u{11abf}'), ('\u{11af9}', '\u{11fff}'), ('\u{12399}', '\u{123ff}'), - ('\u{1246f}', '\u{1246f}'), ('\u{12475}', '\u{12fff}'), ('\u{1342f}', '\u{167ff}'), - ('\u{16a39}', '\u{16a3f}'), ('\u{16a5f}', '\u{16a5f}'), ('\u{16a6a}', '\u{16a6d}'), - ('\u{16a70}', '\u{16acf}'), ('\u{16aee}', '\u{16aef}'), ('\u{16af6}', '\u{16aff}'), - ('\u{16b46}', '\u{16b4f}'), ('\u{16b5a}', '\u{16b5a}'), ('\u{16b62}', '\u{16b62}'), - ('\u{16b78}', '\u{16b7c}'), ('\u{16b90}', '\u{16eff}'), ('\u{16f45}', '\u{16f4f}'), - ('\u{16f7f}', '\u{16f8e}'), ('\u{16fa0}', '\u{1afff}'), ('\u{1b002}', '\u{1bbff}'), - ('\u{1bc6b}', '\u{1bc6f}'), ('\u{1bc7d}', '\u{1bc7f}'), ('\u{1bc89}', '\u{1bc8f}'), - ('\u{1bc9a}', '\u{1bc9b}'), ('\u{1bca4}', '\u{1cfff}'), ('\u{1d0f6}', '\u{1d0ff}'), - ('\u{1d127}', '\u{1d128}'), ('\u{1d1de}', '\u{1d1ff}'), ('\u{1d246}', '\u{1d2ff}'), - ('\u{1d357}', '\u{1d35f}'), ('\u{1d372}', '\u{1d3ff}'), ('\u{1d455}', '\u{1d455}'), - ('\u{1d49d}', '\u{1d49d}'), ('\u{1d4a0}', '\u{1d4a1}'), ('\u{1d4a3}', '\u{1d4a4}'), - ('\u{1d4a7}', '\u{1d4a8}'), ('\u{1d4ad}', '\u{1d4ad}'), ('\u{1d4ba}', '\u{1d4ba}'), - ('\u{1d4bc}', '\u{1d4bc}'), ('\u{1d4c4}', '\u{1d4c4}'), ('\u{1d506}', '\u{1d506}'), - ('\u{1d50b}', '\u{1d50c}'), ('\u{1d515}', '\u{1d515}'), ('\u{1d51d}', '\u{1d51d}'), - ('\u{1d53a}', '\u{1d53a}'), ('\u{1d53f}', '\u{1d53f}'), ('\u{1d545}', '\u{1d545}'), - ('\u{1d547}', '\u{1d549}'), ('\u{1d551}', '\u{1d551}'), ('\u{1d6a6}', '\u{1d6a7}'), - ('\u{1d7cc}', '\u{1d7cd}'), ('\u{1d800}', '\u{1e7ff}'), ('\u{1e8c5}', '\u{1e8c6}'), - ('\u{1e8d7}', '\u{1edff}'), ('\u{1ee04}', '\u{1ee04}'), ('\u{1ee20}', '\u{1ee20}'), - ('\u{1ee23}', '\u{1ee23}'), ('\u{1ee25}', '\u{1ee26}'), ('\u{1ee28}', '\u{1ee28}'), - ('\u{1ee33}', '\u{1ee33}'), ('\u{1ee38}', '\u{1ee38}'), ('\u{1ee3a}', '\u{1ee3a}'), - ('\u{1ee3c}', '\u{1ee41}'), ('\u{1ee43}', '\u{1ee46}'), ('\u{1ee48}', '\u{1ee48}'), - ('\u{1ee4a}', '\u{1ee4a}'), ('\u{1ee4c}', '\u{1ee4c}'), ('\u{1ee50}', '\u{1ee50}'), - ('\u{1ee53}', '\u{1ee53}'), ('\u{1ee55}', '\u{1ee56}'), ('\u{1ee58}', '\u{1ee58}'), - ('\u{1ee5a}', '\u{1ee5a}'), ('\u{1ee5c}', '\u{1ee5c}'), ('\u{1ee5e}', '\u{1ee5e}'), - ('\u{1ee60}', '\u{1ee60}'), ('\u{1ee63}', '\u{1ee63}'), ('\u{1ee65}', '\u{1ee66}'), - ('\u{1ee6b}', '\u{1ee6b}'), ('\u{1ee73}', '\u{1ee73}'), ('\u{1ee78}', '\u{1ee78}'), - ('\u{1ee7d}', '\u{1ee7d}'), ('\u{1ee7f}', '\u{1ee7f}'), ('\u{1ee8a}', '\u{1ee8a}'), - ('\u{1ee9c}', '\u{1eea0}'), ('\u{1eea4}', '\u{1eea4}'), ('\u{1eeaa}', '\u{1eeaa}'), - ('\u{1eebc}', '\u{1eeef}'), ('\u{1eef2}', '\u{1efff}'), ('\u{1f02c}', '\u{1f02f}'), - ('\u{1f094}', '\u{1f09f}'), ('\u{1f0af}', '\u{1f0b0}'), ('\u{1f0c0}', '\u{1f0c0}'), - ('\u{1f0d0}', '\u{1f0d0}'), ('\u{1f0f6}', '\u{1f0ff}'), ('\u{1f10d}', '\u{1f10f}'), - ('\u{1f12f}', '\u{1f12f}'), ('\u{1f16c}', '\u{1f16f}'), ('\u{1f19b}', '\u{1f1e5}'), - ('\u{1f203}', '\u{1f20f}'), ('\u{1f23b}', '\u{1f23f}'), ('\u{1f249}', '\u{1f24f}'), - ('\u{1f252}', '\u{1f2ff}'), ('\u{1f32d}', '\u{1f32f}'), ('\u{1f37e}', '\u{1f37f}'), - ('\u{1f3cf}', '\u{1f3d3}'), ('\u{1f3f8}', '\u{1f3ff}'), ('\u{1f4ff}', '\u{1f4ff}'), - ('\u{1f54b}', '\u{1f54f}'), ('\u{1f57a}', '\u{1f57a}'), ('\u{1f5a4}', '\u{1f5a4}'), - ('\u{1f643}', '\u{1f644}'), ('\u{1f6d0}', '\u{1f6df}'), ('\u{1f6ed}', '\u{1f6ef}'), - ('\u{1f6f4}', '\u{1f6ff}'), ('\u{1f774}', '\u{1f77f}'), ('\u{1f7d5}', '\u{1f7ff}'), - ('\u{1f80c}', '\u{1f80f}'), ('\u{1f848}', '\u{1f84f}'), ('\u{1f85a}', '\u{1f85f}'), - ('\u{1f888}', '\u{1f88f}'), ('\u{1f8ae}', '\u{1ffff}'), ('\u{20001}', '\u{2a6d5}'), - ('\u{2a6d7}', '\u{2a6ff}'), ('\u{2a701}', '\u{2b733}'), ('\u{2b735}', '\u{2b73f}'), - ('\u{2b741}', '\u{2b81c}'), ('\u{2b81e}', '\u{2f7ff}'), ('\u{2fa1e}', '\u{e0000}'), - ('\u{e0002}', '\u{e001f}'), ('\u{e0080}', '\u{e00ff}'), ('\u{e01f0}', '\u{effff}'), - ('\u{f0001}', '\u{ffffc}'), ('\u{ffffe}', '\u{fffff}'), ('\u{100001}', '\u{10fffc}'), - ('\u{10fffe}', '\u{10ffff}') + '\u{31ef}'), ('\u{321f}', '\u{321f}'), ('\u{32ff}', '\u{32ff}'), ('\u{4db6}', '\u{4dbf}'), + ('\u{9fcd}', '\u{9fff}'), ('\u{a48d}', '\u{a48f}'), ('\u{a4c7}', '\u{a4cf}'), ('\u{a62c}', + '\u{a63f}'), ('\u{a69e}', '\u{a69e}'), ('\u{a6f8}', '\u{a6ff}'), ('\u{a78f}', '\u{a78f}'), + ('\u{a7ae}', '\u{a7af}'), ('\u{a7b2}', '\u{a7f6}'), ('\u{a82c}', '\u{a82f}'), ('\u{a83a}', + '\u{a83f}'), ('\u{a878}', '\u{a87f}'), ('\u{a8c5}', '\u{a8cd}'), ('\u{a8da}', '\u{a8df}'), + ('\u{a8fc}', '\u{a8ff}'), ('\u{a954}', '\u{a95e}'), ('\u{a97d}', '\u{a97f}'), ('\u{a9ce}', + '\u{a9ce}'), ('\u{a9da}', '\u{a9dd}'), ('\u{a9ff}', '\u{a9ff}'), ('\u{aa37}', '\u{aa3f}'), + ('\u{aa4e}', '\u{aa4f}'), ('\u{aa5a}', '\u{aa5b}'), ('\u{aac3}', '\u{aada}'), ('\u{aaf7}', + '\u{ab00}'), ('\u{ab07}', '\u{ab08}'), ('\u{ab0f}', '\u{ab10}'), ('\u{ab17}', '\u{ab1f}'), + ('\u{ab27}', '\u{ab27}'), ('\u{ab2f}', '\u{ab2f}'), ('\u{ab60}', '\u{ab63}'), ('\u{ab66}', + '\u{abbf}'), ('\u{abee}', '\u{abef}'), ('\u{abfa}', '\u{abff}'), ('\u{d7a4}', '\u{d7af}'), + ('\u{d7c7}', '\u{d7ca}'), ('\u{d7fc}', '\u{d7ff}'), ('\u{fa6e}', '\u{fa6f}'), ('\u{fada}', + '\u{faff}'), ('\u{fb07}', '\u{fb12}'), ('\u{fb18}', '\u{fb1c}'), ('\u{fb37}', '\u{fb37}'), + ('\u{fb3d}', '\u{fb3d}'), ('\u{fb3f}', '\u{fb3f}'), ('\u{fb42}', '\u{fb42}'), ('\u{fb45}', + '\u{fb45}'), ('\u{fbc2}', '\u{fbd2}'), ('\u{fd40}', '\u{fd4f}'), ('\u{fd90}', '\u{fd91}'), + ('\u{fdc8}', '\u{fdef}'), ('\u{fdfe}', '\u{fdff}'), ('\u{fe1a}', '\u{fe1f}'), ('\u{fe2e}', + '\u{fe2f}'), ('\u{fe53}', '\u{fe53}'), ('\u{fe67}', '\u{fe67}'), ('\u{fe6c}', '\u{fe6f}'), + ('\u{fe75}', '\u{fe75}'), ('\u{fefd}', '\u{fefe}'), ('\u{ff00}', '\u{ff00}'), ('\u{ffbf}', + '\u{ffc1}'), ('\u{ffc8}', '\u{ffc9}'), ('\u{ffd0}', '\u{ffd1}'), ('\u{ffd8}', '\u{ffd9}'), + ('\u{ffdd}', '\u{ffdf}'), ('\u{ffe7}', '\u{ffe7}'), ('\u{ffef}', '\u{fff8}'), ('\u{fffe}', + '\u{ffff}'), ('\u{1000c}', '\u{1000c}'), ('\u{10027}', '\u{10027}'), ('\u{1003b}', + '\u{1003b}'), ('\u{1003e}', '\u{1003e}'), ('\u{1004e}', '\u{1004f}'), ('\u{1005e}', + '\u{1007f}'), ('\u{100fb}', '\u{100ff}'), ('\u{10103}', '\u{10106}'), ('\u{10134}', + '\u{10136}'), ('\u{1018d}', '\u{1018f}'), ('\u{1019c}', '\u{1019f}'), ('\u{101a1}', + '\u{101cf}'), ('\u{101fe}', '\u{1027f}'), ('\u{1029d}', '\u{1029f}'), ('\u{102d1}', + '\u{102df}'), ('\u{102fc}', '\u{102ff}'), ('\u{10324}', '\u{1032f}'), ('\u{1034b}', + '\u{1034f}'), ('\u{1037b}', '\u{1037f}'), ('\u{1039e}', '\u{1039e}'), ('\u{103c4}', + '\u{103c7}'), ('\u{103d6}', '\u{103ff}'), ('\u{1049e}', '\u{1049f}'), ('\u{104aa}', + '\u{104ff}'), ('\u{10528}', '\u{1052f}'), ('\u{10564}', '\u{1056e}'), ('\u{10570}', + '\u{105ff}'), ('\u{10737}', '\u{1073f}'), ('\u{10756}', '\u{1075f}'), ('\u{10768}', + '\u{107ff}'), ('\u{10806}', '\u{10807}'), ('\u{10809}', '\u{10809}'), ('\u{10836}', + '\u{10836}'), ('\u{10839}', '\u{1083b}'), ('\u{1083d}', '\u{1083e}'), ('\u{10856}', + '\u{10856}'), ('\u{1089f}', '\u{108a6}'), ('\u{108b0}', '\u{108ff}'), ('\u{1091c}', + '\u{1091e}'), ('\u{1093a}', '\u{1093e}'), ('\u{10940}', '\u{1097f}'), ('\u{109b8}', + '\u{109bd}'), ('\u{109c0}', '\u{109ff}'), ('\u{10a04}', '\u{10a04}'), ('\u{10a07}', + '\u{10a0b}'), ('\u{10a14}', '\u{10a14}'), ('\u{10a18}', '\u{10a18}'), ('\u{10a34}', + '\u{10a37}'), ('\u{10a3b}', '\u{10a3e}'), ('\u{10a48}', '\u{10a4f}'), ('\u{10a59}', + '\u{10a5f}'), ('\u{10aa0}', '\u{10abf}'), ('\u{10ae7}', '\u{10aea}'), ('\u{10af7}', + '\u{10aff}'), ('\u{10b36}', '\u{10b38}'), ('\u{10b56}', '\u{10b57}'), ('\u{10b73}', + '\u{10b77}'), ('\u{10b92}', '\u{10b98}'), ('\u{10b9d}', '\u{10ba8}'), ('\u{10bb0}', + '\u{10bff}'), ('\u{10c49}', '\u{10e5f}'), ('\u{10e7f}', '\u{10fff}'), ('\u{1104e}', + '\u{11051}'), ('\u{11070}', '\u{1107e}'), ('\u{110c2}', '\u{110cf}'), ('\u{110e9}', + '\u{110ef}'), ('\u{110fa}', '\u{110ff}'), ('\u{11135}', '\u{11135}'), ('\u{11144}', + '\u{1114f}'), ('\u{11177}', '\u{1117f}'), ('\u{111c9}', '\u{111cc}'), ('\u{111ce}', + '\u{111cf}'), ('\u{111db}', '\u{111e0}'), ('\u{111f5}', '\u{111ff}'), ('\u{11212}', + '\u{11212}'), ('\u{1123e}', '\u{112af}'), ('\u{112eb}', '\u{112ef}'), ('\u{112fa}', + '\u{11300}'), ('\u{11304}', '\u{11304}'), ('\u{1130d}', '\u{1130e}'), ('\u{11311}', + '\u{11312}'), ('\u{11329}', '\u{11329}'), ('\u{11331}', '\u{11331}'), ('\u{11334}', + '\u{11334}'), ('\u{1133a}', '\u{1133b}'), ('\u{11345}', '\u{11346}'), ('\u{11349}', + '\u{1134a}'), ('\u{1134e}', '\u{11356}'), ('\u{11358}', '\u{1135c}'), ('\u{11364}', + '\u{11365}'), ('\u{1136d}', '\u{1136f}'), ('\u{11375}', '\u{1147f}'), ('\u{114c8}', + '\u{114cf}'), ('\u{114da}', '\u{1157f}'), ('\u{115b6}', '\u{115b7}'), ('\u{115ca}', + '\u{115ff}'), ('\u{11645}', '\u{1164f}'), ('\u{1165a}', '\u{1167f}'), ('\u{116b8}', + '\u{116bf}'), ('\u{116ca}', '\u{1189f}'), ('\u{118f3}', '\u{118fe}'), ('\u{11900}', + '\u{11abf}'), ('\u{11af9}', '\u{11fff}'), ('\u{12399}', '\u{123ff}'), ('\u{1246f}', + '\u{1246f}'), ('\u{12475}', '\u{12fff}'), ('\u{1342f}', '\u{167ff}'), ('\u{16a39}', + '\u{16a3f}'), ('\u{16a5f}', '\u{16a5f}'), ('\u{16a6a}', '\u{16a6d}'), ('\u{16a70}', + '\u{16acf}'), ('\u{16aee}', '\u{16aef}'), ('\u{16af6}', '\u{16aff}'), ('\u{16b46}', + '\u{16b4f}'), ('\u{16b5a}', '\u{16b5a}'), ('\u{16b62}', '\u{16b62}'), ('\u{16b78}', + '\u{16b7c}'), ('\u{16b90}', '\u{16eff}'), ('\u{16f45}', '\u{16f4f}'), ('\u{16f7f}', + '\u{16f8e}'), ('\u{16fa0}', '\u{1afff}'), ('\u{1b002}', '\u{1bbff}'), ('\u{1bc6b}', + '\u{1bc6f}'), ('\u{1bc7d}', '\u{1bc7f}'), ('\u{1bc89}', '\u{1bc8f}'), ('\u{1bc9a}', + '\u{1bc9b}'), ('\u{1bca4}', '\u{1cfff}'), ('\u{1d0f6}', '\u{1d0ff}'), ('\u{1d127}', + '\u{1d128}'), ('\u{1d1de}', '\u{1d1ff}'), ('\u{1d246}', '\u{1d2ff}'), ('\u{1d357}', + '\u{1d35f}'), ('\u{1d372}', '\u{1d3ff}'), ('\u{1d455}', '\u{1d455}'), ('\u{1d49d}', + '\u{1d49d}'), ('\u{1d4a0}', '\u{1d4a1}'), ('\u{1d4a3}', '\u{1d4a4}'), ('\u{1d4a7}', + '\u{1d4a8}'), ('\u{1d4ad}', '\u{1d4ad}'), ('\u{1d4ba}', '\u{1d4ba}'), ('\u{1d4bc}', + '\u{1d4bc}'), ('\u{1d4c4}', '\u{1d4c4}'), ('\u{1d506}', '\u{1d506}'), ('\u{1d50b}', + '\u{1d50c}'), ('\u{1d515}', '\u{1d515}'), ('\u{1d51d}', '\u{1d51d}'), ('\u{1d53a}', + '\u{1d53a}'), ('\u{1d53f}', '\u{1d53f}'), ('\u{1d545}', '\u{1d545}'), ('\u{1d547}', + '\u{1d549}'), ('\u{1d551}', '\u{1d551}'), ('\u{1d6a6}', '\u{1d6a7}'), ('\u{1d7cc}', + '\u{1d7cd}'), ('\u{1d800}', '\u{1e7ff}'), ('\u{1e8c5}', '\u{1e8c6}'), ('\u{1e8d7}', + '\u{1edff}'), ('\u{1ee04}', '\u{1ee04}'), ('\u{1ee20}', '\u{1ee20}'), ('\u{1ee23}', + '\u{1ee23}'), ('\u{1ee25}', '\u{1ee26}'), ('\u{1ee28}', '\u{1ee28}'), ('\u{1ee33}', + '\u{1ee33}'), ('\u{1ee38}', '\u{1ee38}'), ('\u{1ee3a}', '\u{1ee3a}'), ('\u{1ee3c}', + '\u{1ee41}'), ('\u{1ee43}', '\u{1ee46}'), ('\u{1ee48}', '\u{1ee48}'), ('\u{1ee4a}', + '\u{1ee4a}'), ('\u{1ee4c}', '\u{1ee4c}'), ('\u{1ee50}', '\u{1ee50}'), ('\u{1ee53}', + '\u{1ee53}'), ('\u{1ee55}', '\u{1ee56}'), ('\u{1ee58}', '\u{1ee58}'), ('\u{1ee5a}', + '\u{1ee5a}'), ('\u{1ee5c}', '\u{1ee5c}'), ('\u{1ee5e}', '\u{1ee5e}'), ('\u{1ee60}', + '\u{1ee60}'), ('\u{1ee63}', '\u{1ee63}'), ('\u{1ee65}', '\u{1ee66}'), ('\u{1ee6b}', + '\u{1ee6b}'), ('\u{1ee73}', '\u{1ee73}'), ('\u{1ee78}', '\u{1ee78}'), ('\u{1ee7d}', + '\u{1ee7d}'), ('\u{1ee7f}', '\u{1ee7f}'), ('\u{1ee8a}', '\u{1ee8a}'), ('\u{1ee9c}', + '\u{1eea0}'), ('\u{1eea4}', '\u{1eea4}'), ('\u{1eeaa}', '\u{1eeaa}'), ('\u{1eebc}', + '\u{1eeef}'), ('\u{1eef2}', '\u{1efff}'), ('\u{1f02c}', '\u{1f02f}'), ('\u{1f094}', + '\u{1f09f}'), ('\u{1f0af}', '\u{1f0b0}'), ('\u{1f0c0}', '\u{1f0c0}'), ('\u{1f0d0}', + '\u{1f0d0}'), ('\u{1f0f6}', '\u{1f0ff}'), ('\u{1f10d}', '\u{1f10f}'), ('\u{1f12f}', + '\u{1f12f}'), ('\u{1f16c}', '\u{1f16f}'), ('\u{1f19b}', '\u{1f1e5}'), ('\u{1f203}', + '\u{1f20f}'), ('\u{1f23b}', '\u{1f23f}'), ('\u{1f249}', '\u{1f24f}'), ('\u{1f252}', + '\u{1f2ff}'), ('\u{1f32d}', '\u{1f32f}'), ('\u{1f37e}', '\u{1f37f}'), ('\u{1f3cf}', + '\u{1f3d3}'), ('\u{1f3f8}', '\u{1f3ff}'), ('\u{1f4ff}', '\u{1f4ff}'), ('\u{1f54b}', + '\u{1f54f}'), ('\u{1f57a}', '\u{1f57a}'), ('\u{1f5a4}', '\u{1f5a4}'), ('\u{1f643}', + '\u{1f644}'), ('\u{1f6d0}', '\u{1f6df}'), ('\u{1f6ed}', '\u{1f6ef}'), ('\u{1f6f4}', + '\u{1f6ff}'), ('\u{1f774}', '\u{1f77f}'), ('\u{1f7d5}', '\u{1f7ff}'), ('\u{1f80c}', + '\u{1f80f}'), ('\u{1f848}', '\u{1f84f}'), ('\u{1f85a}', '\u{1f85f}'), ('\u{1f888}', + '\u{1f88f}'), ('\u{1f8ae}', '\u{1ffff}'), ('\u{2a6d7}', '\u{2a6ff}'), ('\u{2b735}', + '\u{2b73f}'), ('\u{2b81e}', '\u{2f7ff}'), ('\u{2fa1e}', '\u{e0000}'), ('\u{e0002}', + '\u{e001f}'), ('\u{e0080}', '\u{e00ff}'), ('\u{e01f0}', '\u{effff}'), ('\u{ffffe}', + '\u{fffff}'), ('\u{10fffe}', '\u{10ffff}') ]; pub const Co_table: &'static [(char, char)] = &[ - ('\u{e000}', '\u{e000}'), ('\u{f8ff}', '\u{f8ff}'), ('\u{f0000}', '\u{f0000}'), - ('\u{ffffd}', '\u{ffffd}'), ('\u{100000}', '\u{100000}'), ('\u{10fffd}', '\u{10fffd}') + ('\u{e000}', '\u{f8ff}'), ('\u{f0000}', '\u{ffffd}'), ('\u{100000}', '\u{10fffd}') ]; pub const L_table: &'static [(char, char)] = &[ @@ -511,86 +505,84 @@ pub mod general_category { ('\u{2e2f}', '\u{2e2f}'), ('\u{3005}', '\u{3006}'), ('\u{3031}', '\u{3035}'), ('\u{303b}', '\u{303c}'), ('\u{3041}', '\u{3096}'), ('\u{309d}', '\u{309f}'), ('\u{30a1}', '\u{30fa}'), ('\u{30fc}', '\u{30ff}'), ('\u{3105}', '\u{312d}'), ('\u{3131}', '\u{318e}'), ('\u{31a0}', - '\u{31ba}'), ('\u{31f0}', '\u{31ff}'), ('\u{3400}', '\u{3400}'), ('\u{4db5}', '\u{4db5}'), - ('\u{4e00}', '\u{4e00}'), ('\u{9fcc}', '\u{9fcc}'), ('\u{a000}', '\u{a48c}'), ('\u{a4d0}', - '\u{a4fd}'), ('\u{a500}', '\u{a60c}'), ('\u{a610}', '\u{a61f}'), ('\u{a62a}', '\u{a62b}'), - ('\u{a640}', '\u{a66e}'), ('\u{a67f}', '\u{a69d}'), ('\u{a6a0}', '\u{a6e5}'), ('\u{a717}', - '\u{a71f}'), ('\u{a722}', '\u{a788}'), ('\u{a78b}', '\u{a78e}'), ('\u{a790}', '\u{a7ad}'), - ('\u{a7b0}', '\u{a7b1}'), ('\u{a7f7}', '\u{a801}'), ('\u{a803}', '\u{a805}'), ('\u{a807}', - '\u{a80a}'), ('\u{a80c}', '\u{a822}'), ('\u{a840}', '\u{a873}'), ('\u{a882}', '\u{a8b3}'), - ('\u{a8f2}', '\u{a8f7}'), ('\u{a8fb}', '\u{a8fb}'), ('\u{a90a}', '\u{a925}'), ('\u{a930}', - '\u{a946}'), ('\u{a960}', '\u{a97c}'), ('\u{a984}', '\u{a9b2}'), ('\u{a9cf}', '\u{a9cf}'), - ('\u{a9e0}', '\u{a9e4}'), ('\u{a9e6}', '\u{a9ef}'), ('\u{a9fa}', '\u{a9fe}'), ('\u{aa00}', - '\u{aa28}'), ('\u{aa40}', '\u{aa42}'), ('\u{aa44}', '\u{aa4b}'), ('\u{aa60}', '\u{aa76}'), - ('\u{aa7a}', '\u{aa7a}'), ('\u{aa7e}', '\u{aaaf}'), ('\u{aab1}', '\u{aab1}'), ('\u{aab5}', - '\u{aab6}'), ('\u{aab9}', '\u{aabd}'), ('\u{aac0}', '\u{aac0}'), ('\u{aac2}', '\u{aac2}'), - ('\u{aadb}', '\u{aadd}'), ('\u{aae0}', '\u{aaea}'), ('\u{aaf2}', '\u{aaf4}'), ('\u{ab01}', - '\u{ab06}'), ('\u{ab09}', '\u{ab0e}'), ('\u{ab11}', '\u{ab16}'), ('\u{ab20}', '\u{ab26}'), - ('\u{ab28}', '\u{ab2e}'), ('\u{ab30}', '\u{ab5a}'), ('\u{ab5c}', '\u{ab5f}'), ('\u{ab64}', - '\u{ab65}'), ('\u{abc0}', '\u{abe2}'), ('\u{ac00}', '\u{ac00}'), ('\u{d7a3}', '\u{d7a3}'), - ('\u{d7b0}', '\u{d7c6}'), ('\u{d7cb}', '\u{d7fb}'), ('\u{f900}', '\u{fa6d}'), ('\u{fa70}', - '\u{fad9}'), ('\u{fb00}', '\u{fb06}'), ('\u{fb13}', '\u{fb17}'), ('\u{fb1d}', '\u{fb1d}'), - ('\u{fb1f}', '\u{fb28}'), ('\u{fb2a}', '\u{fb36}'), ('\u{fb38}', '\u{fb3c}'), ('\u{fb3e}', - '\u{fb3e}'), ('\u{fb40}', '\u{fb41}'), ('\u{fb43}', '\u{fb44}'), ('\u{fb46}', '\u{fbb1}'), - ('\u{fbd3}', '\u{fd3d}'), ('\u{fd50}', '\u{fd8f}'), ('\u{fd92}', '\u{fdc7}'), ('\u{fdf0}', - '\u{fdfb}'), ('\u{fe70}', '\u{fe74}'), ('\u{fe76}', '\u{fefc}'), ('\u{ff21}', '\u{ff3a}'), - ('\u{ff41}', '\u{ff5a}'), ('\u{ff66}', '\u{ffbe}'), ('\u{ffc2}', '\u{ffc7}'), ('\u{ffca}', - '\u{ffcf}'), ('\u{ffd2}', '\u{ffd7}'), ('\u{ffda}', '\u{ffdc}'), ('\u{10000}', '\u{1000b}'), - ('\u{1000d}', '\u{10026}'), ('\u{10028}', '\u{1003a}'), ('\u{1003c}', '\u{1003d}'), - ('\u{1003f}', '\u{1004d}'), ('\u{10050}', '\u{1005d}'), ('\u{10080}', '\u{100fa}'), - ('\u{10280}', '\u{1029c}'), ('\u{102a0}', '\u{102d0}'), ('\u{10300}', '\u{1031f}'), - ('\u{10330}', '\u{10340}'), ('\u{10342}', '\u{10349}'), ('\u{10350}', '\u{10375}'), - ('\u{10380}', '\u{1039d}'), ('\u{103a0}', '\u{103c3}'), ('\u{103c8}', '\u{103cf}'), - ('\u{10400}', '\u{1049d}'), ('\u{10500}', '\u{10527}'), ('\u{10530}', '\u{10563}'), - ('\u{10600}', '\u{10736}'), ('\u{10740}', '\u{10755}'), ('\u{10760}', '\u{10767}'), - ('\u{10800}', '\u{10805}'), ('\u{10808}', '\u{10808}'), ('\u{1080a}', '\u{10835}'), - ('\u{10837}', '\u{10838}'), ('\u{1083c}', '\u{1083c}'), ('\u{1083f}', '\u{10855}'), - ('\u{10860}', '\u{10876}'), ('\u{10880}', '\u{1089e}'), ('\u{10900}', '\u{10915}'), - ('\u{10920}', '\u{10939}'), ('\u{10980}', '\u{109b7}'), ('\u{109be}', '\u{109bf}'), - ('\u{10a00}', '\u{10a00}'), ('\u{10a10}', '\u{10a13}'), ('\u{10a15}', '\u{10a17}'), - ('\u{10a19}', '\u{10a33}'), ('\u{10a60}', '\u{10a7c}'), ('\u{10a80}', '\u{10a9c}'), - ('\u{10ac0}', '\u{10ac7}'), ('\u{10ac9}', '\u{10ae4}'), ('\u{10b00}', '\u{10b35}'), - ('\u{10b40}', '\u{10b55}'), ('\u{10b60}', '\u{10b72}'), ('\u{10b80}', '\u{10b91}'), - ('\u{10c00}', '\u{10c48}'), ('\u{11003}', '\u{11037}'), ('\u{11083}', '\u{110af}'), - ('\u{110d0}', '\u{110e8}'), ('\u{11103}', '\u{11126}'), ('\u{11150}', '\u{11172}'), - ('\u{11176}', '\u{11176}'), ('\u{11183}', '\u{111b2}'), ('\u{111c1}', '\u{111c4}'), - ('\u{111da}', '\u{111da}'), ('\u{11200}', '\u{11211}'), ('\u{11213}', '\u{1122b}'), - ('\u{112b0}', '\u{112de}'), ('\u{11305}', '\u{1130c}'), ('\u{1130f}', '\u{11310}'), - ('\u{11313}', '\u{11328}'), ('\u{1132a}', '\u{11330}'), ('\u{11332}', '\u{11333}'), - ('\u{11335}', '\u{11339}'), ('\u{1133d}', '\u{1133d}'), ('\u{1135d}', '\u{11361}'), - ('\u{11480}', '\u{114af}'), ('\u{114c4}', '\u{114c5}'), ('\u{114c7}', '\u{114c7}'), - ('\u{11580}', '\u{115ae}'), ('\u{11600}', '\u{1162f}'), ('\u{11644}', '\u{11644}'), - ('\u{11680}', '\u{116aa}'), ('\u{118a0}', '\u{118df}'), ('\u{118ff}', '\u{118ff}'), - ('\u{11ac0}', '\u{11af8}'), ('\u{12000}', '\u{12398}'), ('\u{13000}', '\u{1342e}'), - ('\u{16800}', '\u{16a38}'), ('\u{16a40}', '\u{16a5e}'), ('\u{16ad0}', '\u{16aed}'), - ('\u{16b00}', '\u{16b2f}'), ('\u{16b40}', '\u{16b43}'), ('\u{16b63}', '\u{16b77}'), - ('\u{16b7d}', '\u{16b8f}'), ('\u{16f00}', '\u{16f44}'), ('\u{16f50}', '\u{16f50}'), - ('\u{16f93}', '\u{16f9f}'), ('\u{1b000}', '\u{1b001}'), ('\u{1bc00}', '\u{1bc6a}'), - ('\u{1bc70}', '\u{1bc7c}'), ('\u{1bc80}', '\u{1bc88}'), ('\u{1bc90}', '\u{1bc99}'), - ('\u{1d400}', '\u{1d454}'), ('\u{1d456}', '\u{1d49c}'), ('\u{1d49e}', '\u{1d49f}'), - ('\u{1d4a2}', '\u{1d4a2}'), ('\u{1d4a5}', '\u{1d4a6}'), ('\u{1d4a9}', '\u{1d4ac}'), - ('\u{1d4ae}', '\u{1d4b9}'), ('\u{1d4bb}', '\u{1d4bb}'), ('\u{1d4bd}', '\u{1d4c3}'), - ('\u{1d4c5}', '\u{1d505}'), ('\u{1d507}', '\u{1d50a}'), ('\u{1d50d}', '\u{1d514}'), - ('\u{1d516}', '\u{1d51c}'), ('\u{1d51e}', '\u{1d539}'), ('\u{1d53b}', '\u{1d53e}'), - ('\u{1d540}', '\u{1d544}'), ('\u{1d546}', '\u{1d546}'), ('\u{1d54a}', '\u{1d550}'), - ('\u{1d552}', '\u{1d6a5}'), ('\u{1d6a8}', '\u{1d6c0}'), ('\u{1d6c2}', '\u{1d6da}'), - ('\u{1d6dc}', '\u{1d6fa}'), ('\u{1d6fc}', '\u{1d714}'), ('\u{1d716}', '\u{1d734}'), - ('\u{1d736}', '\u{1d74e}'), ('\u{1d750}', '\u{1d76e}'), ('\u{1d770}', '\u{1d788}'), - ('\u{1d78a}', '\u{1d7a8}'), ('\u{1d7aa}', '\u{1d7c2}'), ('\u{1d7c4}', '\u{1d7cb}'), - ('\u{1e800}', '\u{1e8c4}'), ('\u{1ee00}', '\u{1ee03}'), ('\u{1ee05}', '\u{1ee1f}'), - ('\u{1ee21}', '\u{1ee22}'), ('\u{1ee24}', '\u{1ee24}'), ('\u{1ee27}', '\u{1ee27}'), - ('\u{1ee29}', '\u{1ee32}'), ('\u{1ee34}', '\u{1ee37}'), ('\u{1ee39}', '\u{1ee39}'), - ('\u{1ee3b}', '\u{1ee3b}'), ('\u{1ee42}', '\u{1ee42}'), ('\u{1ee47}', '\u{1ee47}'), - ('\u{1ee49}', '\u{1ee49}'), ('\u{1ee4b}', '\u{1ee4b}'), ('\u{1ee4d}', '\u{1ee4f}'), - ('\u{1ee51}', '\u{1ee52}'), ('\u{1ee54}', '\u{1ee54}'), ('\u{1ee57}', '\u{1ee57}'), - ('\u{1ee59}', '\u{1ee59}'), ('\u{1ee5b}', '\u{1ee5b}'), ('\u{1ee5d}', '\u{1ee5d}'), - ('\u{1ee5f}', '\u{1ee5f}'), ('\u{1ee61}', '\u{1ee62}'), ('\u{1ee64}', '\u{1ee64}'), - ('\u{1ee67}', '\u{1ee6a}'), ('\u{1ee6c}', '\u{1ee72}'), ('\u{1ee74}', '\u{1ee77}'), - ('\u{1ee79}', '\u{1ee7c}'), ('\u{1ee7e}', '\u{1ee7e}'), ('\u{1ee80}', '\u{1ee89}'), - ('\u{1ee8b}', '\u{1ee9b}'), ('\u{1eea1}', '\u{1eea3}'), ('\u{1eea5}', '\u{1eea9}'), - ('\u{1eeab}', '\u{1eebb}'), ('\u{20000}', '\u{20000}'), ('\u{2a6d6}', '\u{2a6d6}'), - ('\u{2a700}', '\u{2a700}'), ('\u{2b734}', '\u{2b734}'), ('\u{2b740}', '\u{2b740}'), - ('\u{2b81d}', '\u{2b81d}'), ('\u{2f800}', '\u{2fa1d}') + '\u{31ba}'), ('\u{31f0}', '\u{31ff}'), ('\u{3400}', '\u{4db5}'), ('\u{4e00}', '\u{9fcc}'), + ('\u{a000}', '\u{a48c}'), ('\u{a4d0}', '\u{a4fd}'), ('\u{a500}', '\u{a60c}'), ('\u{a610}', + '\u{a61f}'), ('\u{a62a}', '\u{a62b}'), ('\u{a640}', '\u{a66e}'), ('\u{a67f}', '\u{a69d}'), + ('\u{a6a0}', '\u{a6e5}'), ('\u{a717}', '\u{a71f}'), ('\u{a722}', '\u{a788}'), ('\u{a78b}', + '\u{a78e}'), ('\u{a790}', '\u{a7ad}'), ('\u{a7b0}', '\u{a7b1}'), ('\u{a7f7}', '\u{a801}'), + ('\u{a803}', '\u{a805}'), ('\u{a807}', '\u{a80a}'), ('\u{a80c}', '\u{a822}'), ('\u{a840}', + '\u{a873}'), ('\u{a882}', '\u{a8b3}'), ('\u{a8f2}', '\u{a8f7}'), ('\u{a8fb}', '\u{a8fb}'), + ('\u{a90a}', '\u{a925}'), ('\u{a930}', '\u{a946}'), ('\u{a960}', '\u{a97c}'), ('\u{a984}', + '\u{a9b2}'), ('\u{a9cf}', '\u{a9cf}'), ('\u{a9e0}', '\u{a9e4}'), ('\u{a9e6}', '\u{a9ef}'), + ('\u{a9fa}', '\u{a9fe}'), ('\u{aa00}', '\u{aa28}'), ('\u{aa40}', '\u{aa42}'), ('\u{aa44}', + '\u{aa4b}'), ('\u{aa60}', '\u{aa76}'), ('\u{aa7a}', '\u{aa7a}'), ('\u{aa7e}', '\u{aaaf}'), + ('\u{aab1}', '\u{aab1}'), ('\u{aab5}', '\u{aab6}'), ('\u{aab9}', '\u{aabd}'), ('\u{aac0}', + '\u{aac0}'), ('\u{aac2}', '\u{aac2}'), ('\u{aadb}', '\u{aadd}'), ('\u{aae0}', '\u{aaea}'), + ('\u{aaf2}', '\u{aaf4}'), ('\u{ab01}', '\u{ab06}'), ('\u{ab09}', '\u{ab0e}'), ('\u{ab11}', + '\u{ab16}'), ('\u{ab20}', '\u{ab26}'), ('\u{ab28}', '\u{ab2e}'), ('\u{ab30}', '\u{ab5a}'), + ('\u{ab5c}', '\u{ab5f}'), ('\u{ab64}', '\u{ab65}'), ('\u{abc0}', '\u{abe2}'), ('\u{ac00}', + '\u{d7a3}'), ('\u{d7b0}', '\u{d7c6}'), ('\u{d7cb}', '\u{d7fb}'), ('\u{f900}', '\u{fa6d}'), + ('\u{fa70}', '\u{fad9}'), ('\u{fb00}', '\u{fb06}'), ('\u{fb13}', '\u{fb17}'), ('\u{fb1d}', + '\u{fb1d}'), ('\u{fb1f}', '\u{fb28}'), ('\u{fb2a}', '\u{fb36}'), ('\u{fb38}', '\u{fb3c}'), + ('\u{fb3e}', '\u{fb3e}'), ('\u{fb40}', '\u{fb41}'), ('\u{fb43}', '\u{fb44}'), ('\u{fb46}', + '\u{fbb1}'), ('\u{fbd3}', '\u{fd3d}'), ('\u{fd50}', '\u{fd8f}'), ('\u{fd92}', '\u{fdc7}'), + ('\u{fdf0}', '\u{fdfb}'), ('\u{fe70}', '\u{fe74}'), ('\u{fe76}', '\u{fefc}'), ('\u{ff21}', + '\u{ff3a}'), ('\u{ff41}', '\u{ff5a}'), ('\u{ff66}', '\u{ffbe}'), ('\u{ffc2}', '\u{ffc7}'), + ('\u{ffca}', '\u{ffcf}'), ('\u{ffd2}', '\u{ffd7}'), ('\u{ffda}', '\u{ffdc}'), ('\u{10000}', + '\u{1000b}'), ('\u{1000d}', '\u{10026}'), ('\u{10028}', '\u{1003a}'), ('\u{1003c}', + '\u{1003d}'), ('\u{1003f}', '\u{1004d}'), ('\u{10050}', '\u{1005d}'), ('\u{10080}', + '\u{100fa}'), ('\u{10280}', '\u{1029c}'), ('\u{102a0}', '\u{102d0}'), ('\u{10300}', + '\u{1031f}'), ('\u{10330}', '\u{10340}'), ('\u{10342}', '\u{10349}'), ('\u{10350}', + '\u{10375}'), ('\u{10380}', '\u{1039d}'), ('\u{103a0}', '\u{103c3}'), ('\u{103c8}', + '\u{103cf}'), ('\u{10400}', '\u{1049d}'), ('\u{10500}', '\u{10527}'), ('\u{10530}', + '\u{10563}'), ('\u{10600}', '\u{10736}'), ('\u{10740}', '\u{10755}'), ('\u{10760}', + '\u{10767}'), ('\u{10800}', '\u{10805}'), ('\u{10808}', '\u{10808}'), ('\u{1080a}', + '\u{10835}'), ('\u{10837}', '\u{10838}'), ('\u{1083c}', '\u{1083c}'), ('\u{1083f}', + '\u{10855}'), ('\u{10860}', '\u{10876}'), ('\u{10880}', '\u{1089e}'), ('\u{10900}', + '\u{10915}'), ('\u{10920}', '\u{10939}'), ('\u{10980}', '\u{109b7}'), ('\u{109be}', + '\u{109bf}'), ('\u{10a00}', '\u{10a00}'), ('\u{10a10}', '\u{10a13}'), ('\u{10a15}', + '\u{10a17}'), ('\u{10a19}', '\u{10a33}'), ('\u{10a60}', '\u{10a7c}'), ('\u{10a80}', + '\u{10a9c}'), ('\u{10ac0}', '\u{10ac7}'), ('\u{10ac9}', '\u{10ae4}'), ('\u{10b00}', + '\u{10b35}'), ('\u{10b40}', '\u{10b55}'), ('\u{10b60}', '\u{10b72}'), ('\u{10b80}', + '\u{10b91}'), ('\u{10c00}', '\u{10c48}'), ('\u{11003}', '\u{11037}'), ('\u{11083}', + '\u{110af}'), ('\u{110d0}', '\u{110e8}'), ('\u{11103}', '\u{11126}'), ('\u{11150}', + '\u{11172}'), ('\u{11176}', '\u{11176}'), ('\u{11183}', '\u{111b2}'), ('\u{111c1}', + '\u{111c4}'), ('\u{111da}', '\u{111da}'), ('\u{11200}', '\u{11211}'), ('\u{11213}', + '\u{1122b}'), ('\u{112b0}', '\u{112de}'), ('\u{11305}', '\u{1130c}'), ('\u{1130f}', + '\u{11310}'), ('\u{11313}', '\u{11328}'), ('\u{1132a}', '\u{11330}'), ('\u{11332}', + '\u{11333}'), ('\u{11335}', '\u{11339}'), ('\u{1133d}', '\u{1133d}'), ('\u{1135d}', + '\u{11361}'), ('\u{11480}', '\u{114af}'), ('\u{114c4}', '\u{114c5}'), ('\u{114c7}', + '\u{114c7}'), ('\u{11580}', '\u{115ae}'), ('\u{11600}', '\u{1162f}'), ('\u{11644}', + '\u{11644}'), ('\u{11680}', '\u{116aa}'), ('\u{118a0}', '\u{118df}'), ('\u{118ff}', + '\u{118ff}'), ('\u{11ac0}', '\u{11af8}'), ('\u{12000}', '\u{12398}'), ('\u{13000}', + '\u{1342e}'), ('\u{16800}', '\u{16a38}'), ('\u{16a40}', '\u{16a5e}'), ('\u{16ad0}', + '\u{16aed}'), ('\u{16b00}', '\u{16b2f}'), ('\u{16b40}', '\u{16b43}'), ('\u{16b63}', + '\u{16b77}'), ('\u{16b7d}', '\u{16b8f}'), ('\u{16f00}', '\u{16f44}'), ('\u{16f50}', + '\u{16f50}'), ('\u{16f93}', '\u{16f9f}'), ('\u{1b000}', '\u{1b001}'), ('\u{1bc00}', + '\u{1bc6a}'), ('\u{1bc70}', '\u{1bc7c}'), ('\u{1bc80}', '\u{1bc88}'), ('\u{1bc90}', + '\u{1bc99}'), ('\u{1d400}', '\u{1d454}'), ('\u{1d456}', '\u{1d49c}'), ('\u{1d49e}', + '\u{1d49f}'), ('\u{1d4a2}', '\u{1d4a2}'), ('\u{1d4a5}', '\u{1d4a6}'), ('\u{1d4a9}', + '\u{1d4ac}'), ('\u{1d4ae}', '\u{1d4b9}'), ('\u{1d4bb}', '\u{1d4bb}'), ('\u{1d4bd}', + '\u{1d4c3}'), ('\u{1d4c5}', '\u{1d505}'), ('\u{1d507}', '\u{1d50a}'), ('\u{1d50d}', + '\u{1d514}'), ('\u{1d516}', '\u{1d51c}'), ('\u{1d51e}', '\u{1d539}'), ('\u{1d53b}', + '\u{1d53e}'), ('\u{1d540}', '\u{1d544}'), ('\u{1d546}', '\u{1d546}'), ('\u{1d54a}', + '\u{1d550}'), ('\u{1d552}', '\u{1d6a5}'), ('\u{1d6a8}', '\u{1d6c0}'), ('\u{1d6c2}', + '\u{1d6da}'), ('\u{1d6dc}', '\u{1d6fa}'), ('\u{1d6fc}', '\u{1d714}'), ('\u{1d716}', + '\u{1d734}'), ('\u{1d736}', '\u{1d74e}'), ('\u{1d750}', '\u{1d76e}'), ('\u{1d770}', + '\u{1d788}'), ('\u{1d78a}', '\u{1d7a8}'), ('\u{1d7aa}', '\u{1d7c2}'), ('\u{1d7c4}', + '\u{1d7cb}'), ('\u{1e800}', '\u{1e8c4}'), ('\u{1ee00}', '\u{1ee03}'), ('\u{1ee05}', + '\u{1ee1f}'), ('\u{1ee21}', '\u{1ee22}'), ('\u{1ee24}', '\u{1ee24}'), ('\u{1ee27}', + '\u{1ee27}'), ('\u{1ee29}', '\u{1ee32}'), ('\u{1ee34}', '\u{1ee37}'), ('\u{1ee39}', + '\u{1ee39}'), ('\u{1ee3b}', '\u{1ee3b}'), ('\u{1ee42}', '\u{1ee42}'), ('\u{1ee47}', + '\u{1ee47}'), ('\u{1ee49}', '\u{1ee49}'), ('\u{1ee4b}', '\u{1ee4b}'), ('\u{1ee4d}', + '\u{1ee4f}'), ('\u{1ee51}', '\u{1ee52}'), ('\u{1ee54}', '\u{1ee54}'), ('\u{1ee57}', + '\u{1ee57}'), ('\u{1ee59}', '\u{1ee59}'), ('\u{1ee5b}', '\u{1ee5b}'), ('\u{1ee5d}', + '\u{1ee5d}'), ('\u{1ee5f}', '\u{1ee5f}'), ('\u{1ee61}', '\u{1ee62}'), ('\u{1ee64}', + '\u{1ee64}'), ('\u{1ee67}', '\u{1ee6a}'), ('\u{1ee6c}', '\u{1ee72}'), ('\u{1ee74}', + '\u{1ee77}'), ('\u{1ee79}', '\u{1ee7c}'), ('\u{1ee7e}', '\u{1ee7e}'), ('\u{1ee80}', + '\u{1ee89}'), ('\u{1ee8b}', '\u{1ee9b}'), ('\u{1eea1}', '\u{1eea3}'), ('\u{1eea5}', + '\u{1eea9}'), ('\u{1eeab}', '\u{1eebb}'), ('\u{20000}', '\u{2a6d6}'), ('\u{2a700}', + '\u{2b734}'), ('\u{2b740}', '\u{2b81d}'), ('\u{2f800}', '\u{2fa1d}') ]; pub const LC_table: &'static [(char, char)] = &[ @@ -896,72 +888,71 @@ pub mod general_category { '\u{2dd6}'), ('\u{2dd8}', '\u{2dde}'), ('\u{3006}', '\u{3006}'), ('\u{303c}', '\u{303c}'), ('\u{3041}', '\u{3096}'), ('\u{309f}', '\u{309f}'), ('\u{30a1}', '\u{30fa}'), ('\u{30ff}', '\u{30ff}'), ('\u{3105}', '\u{312d}'), ('\u{3131}', '\u{318e}'), ('\u{31a0}', '\u{31ba}'), - ('\u{31f0}', '\u{31ff}'), ('\u{3400}', '\u{3400}'), ('\u{4db5}', '\u{4db5}'), ('\u{4e00}', - '\u{4e00}'), ('\u{9fcc}', '\u{9fcc}'), ('\u{a000}', '\u{a014}'), ('\u{a016}', '\u{a48c}'), - ('\u{a4d0}', '\u{a4f7}'), ('\u{a500}', '\u{a60b}'), ('\u{a610}', '\u{a61f}'), ('\u{a62a}', - '\u{a62b}'), ('\u{a66e}', '\u{a66e}'), ('\u{a6a0}', '\u{a6e5}'), ('\u{a7f7}', '\u{a7f7}'), - ('\u{a7fb}', '\u{a801}'), ('\u{a803}', '\u{a805}'), ('\u{a807}', '\u{a80a}'), ('\u{a80c}', - '\u{a822}'), ('\u{a840}', '\u{a873}'), ('\u{a882}', '\u{a8b3}'), ('\u{a8f2}', '\u{a8f7}'), - ('\u{a8fb}', '\u{a8fb}'), ('\u{a90a}', '\u{a925}'), ('\u{a930}', '\u{a946}'), ('\u{a960}', - '\u{a97c}'), ('\u{a984}', '\u{a9b2}'), ('\u{a9e0}', '\u{a9e4}'), ('\u{a9e7}', '\u{a9ef}'), - ('\u{a9fa}', '\u{a9fe}'), ('\u{aa00}', '\u{aa28}'), ('\u{aa40}', '\u{aa42}'), ('\u{aa44}', - '\u{aa4b}'), ('\u{aa60}', '\u{aa6f}'), ('\u{aa71}', '\u{aa76}'), ('\u{aa7a}', '\u{aa7a}'), - ('\u{aa7e}', '\u{aaaf}'), ('\u{aab1}', '\u{aab1}'), ('\u{aab5}', '\u{aab6}'), ('\u{aab9}', - '\u{aabd}'), ('\u{aac0}', '\u{aac0}'), ('\u{aac2}', '\u{aac2}'), ('\u{aadb}', '\u{aadc}'), - ('\u{aae0}', '\u{aaea}'), ('\u{aaf2}', '\u{aaf2}'), ('\u{ab01}', '\u{ab06}'), ('\u{ab09}', - '\u{ab0e}'), ('\u{ab11}', '\u{ab16}'), ('\u{ab20}', '\u{ab26}'), ('\u{ab28}', '\u{ab2e}'), - ('\u{abc0}', '\u{abe2}'), ('\u{ac00}', '\u{ac00}'), ('\u{d7a3}', '\u{d7a3}'), ('\u{d7b0}', - '\u{d7c6}'), ('\u{d7cb}', '\u{d7fb}'), ('\u{f900}', '\u{fa6d}'), ('\u{fa70}', '\u{fad9}'), - ('\u{fb1d}', '\u{fb1d}'), ('\u{fb1f}', '\u{fb28}'), ('\u{fb2a}', '\u{fb36}'), ('\u{fb38}', - '\u{fb3c}'), ('\u{fb3e}', '\u{fb3e}'), ('\u{fb40}', '\u{fb41}'), ('\u{fb43}', '\u{fb44}'), - ('\u{fb46}', '\u{fbb1}'), ('\u{fbd3}', '\u{fd3d}'), ('\u{fd50}', '\u{fd8f}'), ('\u{fd92}', - '\u{fdc7}'), ('\u{fdf0}', '\u{fdfb}'), ('\u{fe70}', '\u{fe74}'), ('\u{fe76}', '\u{fefc}'), - ('\u{ff66}', '\u{ff6f}'), ('\u{ff71}', '\u{ff9d}'), ('\u{ffa0}', '\u{ffbe}'), ('\u{ffc2}', - '\u{ffc7}'), ('\u{ffca}', '\u{ffcf}'), ('\u{ffd2}', '\u{ffd7}'), ('\u{ffda}', '\u{ffdc}'), - ('\u{10000}', '\u{1000b}'), ('\u{1000d}', '\u{10026}'), ('\u{10028}', '\u{1003a}'), - ('\u{1003c}', '\u{1003d}'), ('\u{1003f}', '\u{1004d}'), ('\u{10050}', '\u{1005d}'), - ('\u{10080}', '\u{100fa}'), ('\u{10280}', '\u{1029c}'), ('\u{102a0}', '\u{102d0}'), - ('\u{10300}', '\u{1031f}'), ('\u{10330}', '\u{10340}'), ('\u{10342}', '\u{10349}'), - ('\u{10350}', '\u{10375}'), ('\u{10380}', '\u{1039d}'), ('\u{103a0}', '\u{103c3}'), - ('\u{103c8}', '\u{103cf}'), ('\u{10450}', '\u{1049d}'), ('\u{10500}', '\u{10527}'), - ('\u{10530}', '\u{10563}'), ('\u{10600}', '\u{10736}'), ('\u{10740}', '\u{10755}'), - ('\u{10760}', '\u{10767}'), ('\u{10800}', '\u{10805}'), ('\u{10808}', '\u{10808}'), - ('\u{1080a}', '\u{10835}'), ('\u{10837}', '\u{10838}'), ('\u{1083c}', '\u{1083c}'), - ('\u{1083f}', '\u{10855}'), ('\u{10860}', '\u{10876}'), ('\u{10880}', '\u{1089e}'), - ('\u{10900}', '\u{10915}'), ('\u{10920}', '\u{10939}'), ('\u{10980}', '\u{109b7}'), - ('\u{109be}', '\u{109bf}'), ('\u{10a00}', '\u{10a00}'), ('\u{10a10}', '\u{10a13}'), - ('\u{10a15}', '\u{10a17}'), ('\u{10a19}', '\u{10a33}'), ('\u{10a60}', '\u{10a7c}'), - ('\u{10a80}', '\u{10a9c}'), ('\u{10ac0}', '\u{10ac7}'), ('\u{10ac9}', '\u{10ae4}'), - ('\u{10b00}', '\u{10b35}'), ('\u{10b40}', '\u{10b55}'), ('\u{10b60}', '\u{10b72}'), - ('\u{10b80}', '\u{10b91}'), ('\u{10c00}', '\u{10c48}'), ('\u{11003}', '\u{11037}'), - ('\u{11083}', '\u{110af}'), ('\u{110d0}', '\u{110e8}'), ('\u{11103}', '\u{11126}'), - ('\u{11150}', '\u{11172}'), ('\u{11176}', '\u{11176}'), ('\u{11183}', '\u{111b2}'), - ('\u{111c1}', '\u{111c4}'), ('\u{111da}', '\u{111da}'), ('\u{11200}', '\u{11211}'), - ('\u{11213}', '\u{1122b}'), ('\u{112b0}', '\u{112de}'), ('\u{11305}', '\u{1130c}'), - ('\u{1130f}', '\u{11310}'), ('\u{11313}', '\u{11328}'), ('\u{1132a}', '\u{11330}'), - ('\u{11332}', '\u{11333}'), ('\u{11335}', '\u{11339}'), ('\u{1133d}', '\u{1133d}'), - ('\u{1135d}', '\u{11361}'), ('\u{11480}', '\u{114af}'), ('\u{114c4}', '\u{114c5}'), - ('\u{114c7}', '\u{114c7}'), ('\u{11580}', '\u{115ae}'), ('\u{11600}', '\u{1162f}'), - ('\u{11644}', '\u{11644}'), ('\u{11680}', '\u{116aa}'), ('\u{118ff}', '\u{118ff}'), - ('\u{11ac0}', '\u{11af8}'), ('\u{12000}', '\u{12398}'), ('\u{13000}', '\u{1342e}'), - ('\u{16800}', '\u{16a38}'), ('\u{16a40}', '\u{16a5e}'), ('\u{16ad0}', '\u{16aed}'), - ('\u{16b00}', '\u{16b2f}'), ('\u{16b63}', '\u{16b77}'), ('\u{16b7d}', '\u{16b8f}'), - ('\u{16f00}', '\u{16f44}'), ('\u{16f50}', '\u{16f50}'), ('\u{1b000}', '\u{1b001}'), - ('\u{1bc00}', '\u{1bc6a}'), ('\u{1bc70}', '\u{1bc7c}'), ('\u{1bc80}', '\u{1bc88}'), - ('\u{1bc90}', '\u{1bc99}'), ('\u{1e800}', '\u{1e8c4}'), ('\u{1ee00}', '\u{1ee03}'), - ('\u{1ee05}', '\u{1ee1f}'), ('\u{1ee21}', '\u{1ee22}'), ('\u{1ee24}', '\u{1ee24}'), - ('\u{1ee27}', '\u{1ee27}'), ('\u{1ee29}', '\u{1ee32}'), ('\u{1ee34}', '\u{1ee37}'), - ('\u{1ee39}', '\u{1ee39}'), ('\u{1ee3b}', '\u{1ee3b}'), ('\u{1ee42}', '\u{1ee42}'), - ('\u{1ee47}', '\u{1ee47}'), ('\u{1ee49}', '\u{1ee49}'), ('\u{1ee4b}', '\u{1ee4b}'), - ('\u{1ee4d}', '\u{1ee4f}'), ('\u{1ee51}', '\u{1ee52}'), ('\u{1ee54}', '\u{1ee54}'), - ('\u{1ee57}', '\u{1ee57}'), ('\u{1ee59}', '\u{1ee59}'), ('\u{1ee5b}', '\u{1ee5b}'), - ('\u{1ee5d}', '\u{1ee5d}'), ('\u{1ee5f}', '\u{1ee5f}'), ('\u{1ee61}', '\u{1ee62}'), - ('\u{1ee64}', '\u{1ee64}'), ('\u{1ee67}', '\u{1ee6a}'), ('\u{1ee6c}', '\u{1ee72}'), - ('\u{1ee74}', '\u{1ee77}'), ('\u{1ee79}', '\u{1ee7c}'), ('\u{1ee7e}', '\u{1ee7e}'), - ('\u{1ee80}', '\u{1ee89}'), ('\u{1ee8b}', '\u{1ee9b}'), ('\u{1eea1}', '\u{1eea3}'), - ('\u{1eea5}', '\u{1eea9}'), ('\u{1eeab}', '\u{1eebb}'), ('\u{20000}', '\u{20000}'), - ('\u{2a6d6}', '\u{2a6d6}'), ('\u{2a700}', '\u{2a700}'), ('\u{2b734}', '\u{2b734}'), - ('\u{2b740}', '\u{2b740}'), ('\u{2b81d}', '\u{2b81d}'), ('\u{2f800}', '\u{2fa1d}') + ('\u{31f0}', '\u{31ff}'), ('\u{3400}', '\u{4db5}'), ('\u{4e00}', '\u{9fcc}'), ('\u{a000}', + '\u{a014}'), ('\u{a016}', '\u{a48c}'), ('\u{a4d0}', '\u{a4f7}'), ('\u{a500}', '\u{a60b}'), + ('\u{a610}', '\u{a61f}'), ('\u{a62a}', '\u{a62b}'), ('\u{a66e}', '\u{a66e}'), ('\u{a6a0}', + '\u{a6e5}'), ('\u{a7f7}', '\u{a7f7}'), ('\u{a7fb}', '\u{a801}'), ('\u{a803}', '\u{a805}'), + ('\u{a807}', '\u{a80a}'), ('\u{a80c}', '\u{a822}'), ('\u{a840}', '\u{a873}'), ('\u{a882}', + '\u{a8b3}'), ('\u{a8f2}', '\u{a8f7}'), ('\u{a8fb}', '\u{a8fb}'), ('\u{a90a}', '\u{a925}'), + ('\u{a930}', '\u{a946}'), ('\u{a960}', '\u{a97c}'), ('\u{a984}', '\u{a9b2}'), ('\u{a9e0}', + '\u{a9e4}'), ('\u{a9e7}', '\u{a9ef}'), ('\u{a9fa}', '\u{a9fe}'), ('\u{aa00}', '\u{aa28}'), + ('\u{aa40}', '\u{aa42}'), ('\u{aa44}', '\u{aa4b}'), ('\u{aa60}', '\u{aa6f}'), ('\u{aa71}', + '\u{aa76}'), ('\u{aa7a}', '\u{aa7a}'), ('\u{aa7e}', '\u{aaaf}'), ('\u{aab1}', '\u{aab1}'), + ('\u{aab5}', '\u{aab6}'), ('\u{aab9}', '\u{aabd}'), ('\u{aac0}', '\u{aac0}'), ('\u{aac2}', + '\u{aac2}'), ('\u{aadb}', '\u{aadc}'), ('\u{aae0}', '\u{aaea}'), ('\u{aaf2}', '\u{aaf2}'), + ('\u{ab01}', '\u{ab06}'), ('\u{ab09}', '\u{ab0e}'), ('\u{ab11}', '\u{ab16}'), ('\u{ab20}', + '\u{ab26}'), ('\u{ab28}', '\u{ab2e}'), ('\u{abc0}', '\u{abe2}'), ('\u{ac00}', '\u{d7a3}'), + ('\u{d7b0}', '\u{d7c6}'), ('\u{d7cb}', '\u{d7fb}'), ('\u{f900}', '\u{fa6d}'), ('\u{fa70}', + '\u{fad9}'), ('\u{fb1d}', '\u{fb1d}'), ('\u{fb1f}', '\u{fb28}'), ('\u{fb2a}', '\u{fb36}'), + ('\u{fb38}', '\u{fb3c}'), ('\u{fb3e}', '\u{fb3e}'), ('\u{fb40}', '\u{fb41}'), ('\u{fb43}', + '\u{fb44}'), ('\u{fb46}', '\u{fbb1}'), ('\u{fbd3}', '\u{fd3d}'), ('\u{fd50}', '\u{fd8f}'), + ('\u{fd92}', '\u{fdc7}'), ('\u{fdf0}', '\u{fdfb}'), ('\u{fe70}', '\u{fe74}'), ('\u{fe76}', + '\u{fefc}'), ('\u{ff66}', '\u{ff6f}'), ('\u{ff71}', '\u{ff9d}'), ('\u{ffa0}', '\u{ffbe}'), + ('\u{ffc2}', '\u{ffc7}'), ('\u{ffca}', '\u{ffcf}'), ('\u{ffd2}', '\u{ffd7}'), ('\u{ffda}', + '\u{ffdc}'), ('\u{10000}', '\u{1000b}'), ('\u{1000d}', '\u{10026}'), ('\u{10028}', + '\u{1003a}'), ('\u{1003c}', '\u{1003d}'), ('\u{1003f}', '\u{1004d}'), ('\u{10050}', + '\u{1005d}'), ('\u{10080}', '\u{100fa}'), ('\u{10280}', '\u{1029c}'), ('\u{102a0}', + '\u{102d0}'), ('\u{10300}', '\u{1031f}'), ('\u{10330}', '\u{10340}'), ('\u{10342}', + '\u{10349}'), ('\u{10350}', '\u{10375}'), ('\u{10380}', '\u{1039d}'), ('\u{103a0}', + '\u{103c3}'), ('\u{103c8}', '\u{103cf}'), ('\u{10450}', '\u{1049d}'), ('\u{10500}', + '\u{10527}'), ('\u{10530}', '\u{10563}'), ('\u{10600}', '\u{10736}'), ('\u{10740}', + '\u{10755}'), ('\u{10760}', '\u{10767}'), ('\u{10800}', '\u{10805}'), ('\u{10808}', + '\u{10808}'), ('\u{1080a}', '\u{10835}'), ('\u{10837}', '\u{10838}'), ('\u{1083c}', + '\u{1083c}'), ('\u{1083f}', '\u{10855}'), ('\u{10860}', '\u{10876}'), ('\u{10880}', + '\u{1089e}'), ('\u{10900}', '\u{10915}'), ('\u{10920}', '\u{10939}'), ('\u{10980}', + '\u{109b7}'), ('\u{109be}', '\u{109bf}'), ('\u{10a00}', '\u{10a00}'), ('\u{10a10}', + '\u{10a13}'), ('\u{10a15}', '\u{10a17}'), ('\u{10a19}', '\u{10a33}'), ('\u{10a60}', + '\u{10a7c}'), ('\u{10a80}', '\u{10a9c}'), ('\u{10ac0}', '\u{10ac7}'), ('\u{10ac9}', + '\u{10ae4}'), ('\u{10b00}', '\u{10b35}'), ('\u{10b40}', '\u{10b55}'), ('\u{10b60}', + '\u{10b72}'), ('\u{10b80}', '\u{10b91}'), ('\u{10c00}', '\u{10c48}'), ('\u{11003}', + '\u{11037}'), ('\u{11083}', '\u{110af}'), ('\u{110d0}', '\u{110e8}'), ('\u{11103}', + '\u{11126}'), ('\u{11150}', '\u{11172}'), ('\u{11176}', '\u{11176}'), ('\u{11183}', + '\u{111b2}'), ('\u{111c1}', '\u{111c4}'), ('\u{111da}', '\u{111da}'), ('\u{11200}', + '\u{11211}'), ('\u{11213}', '\u{1122b}'), ('\u{112b0}', '\u{112de}'), ('\u{11305}', + '\u{1130c}'), ('\u{1130f}', '\u{11310}'), ('\u{11313}', '\u{11328}'), ('\u{1132a}', + '\u{11330}'), ('\u{11332}', '\u{11333}'), ('\u{11335}', '\u{11339}'), ('\u{1133d}', + '\u{1133d}'), ('\u{1135d}', '\u{11361}'), ('\u{11480}', '\u{114af}'), ('\u{114c4}', + '\u{114c5}'), ('\u{114c7}', '\u{114c7}'), ('\u{11580}', '\u{115ae}'), ('\u{11600}', + '\u{1162f}'), ('\u{11644}', '\u{11644}'), ('\u{11680}', '\u{116aa}'), ('\u{118ff}', + '\u{118ff}'), ('\u{11ac0}', '\u{11af8}'), ('\u{12000}', '\u{12398}'), ('\u{13000}', + '\u{1342e}'), ('\u{16800}', '\u{16a38}'), ('\u{16a40}', '\u{16a5e}'), ('\u{16ad0}', + '\u{16aed}'), ('\u{16b00}', '\u{16b2f}'), ('\u{16b63}', '\u{16b77}'), ('\u{16b7d}', + '\u{16b8f}'), ('\u{16f00}', '\u{16f44}'), ('\u{16f50}', '\u{16f50}'), ('\u{1b000}', + '\u{1b001}'), ('\u{1bc00}', '\u{1bc6a}'), ('\u{1bc70}', '\u{1bc7c}'), ('\u{1bc80}', + '\u{1bc88}'), ('\u{1bc90}', '\u{1bc99}'), ('\u{1e800}', '\u{1e8c4}'), ('\u{1ee00}', + '\u{1ee03}'), ('\u{1ee05}', '\u{1ee1f}'), ('\u{1ee21}', '\u{1ee22}'), ('\u{1ee24}', + '\u{1ee24}'), ('\u{1ee27}', '\u{1ee27}'), ('\u{1ee29}', '\u{1ee32}'), ('\u{1ee34}', + '\u{1ee37}'), ('\u{1ee39}', '\u{1ee39}'), ('\u{1ee3b}', '\u{1ee3b}'), ('\u{1ee42}', + '\u{1ee42}'), ('\u{1ee47}', '\u{1ee47}'), ('\u{1ee49}', '\u{1ee49}'), ('\u{1ee4b}', + '\u{1ee4b}'), ('\u{1ee4d}', '\u{1ee4f}'), ('\u{1ee51}', '\u{1ee52}'), ('\u{1ee54}', + '\u{1ee54}'), ('\u{1ee57}', '\u{1ee57}'), ('\u{1ee59}', '\u{1ee59}'), ('\u{1ee5b}', + '\u{1ee5b}'), ('\u{1ee5d}', '\u{1ee5d}'), ('\u{1ee5f}', '\u{1ee5f}'), ('\u{1ee61}', + '\u{1ee62}'), ('\u{1ee64}', '\u{1ee64}'), ('\u{1ee67}', '\u{1ee6a}'), ('\u{1ee6c}', + '\u{1ee72}'), ('\u{1ee74}', '\u{1ee77}'), ('\u{1ee79}', '\u{1ee7c}'), ('\u{1ee7e}', + '\u{1ee7e}'), ('\u{1ee80}', '\u{1ee89}'), ('\u{1ee8b}', '\u{1ee9b}'), ('\u{1eea1}', + '\u{1eea3}'), ('\u{1eea5}', '\u{1eea9}'), ('\u{1eeab}', '\u{1eebb}'), ('\u{20000}', + '\u{2a6d6}'), ('\u{2a700}', '\u{2b734}'), ('\u{2b740}', '\u{2b81d}'), ('\u{2f800}', + '\u{2fa1d}') ]; pub const Lt_table: &'static [(char, char)] = &[ diff --git a/src/libunicode/u_str.rs b/src/libunicode/u_str.rs index 38cbe5c7dea..57439addeaa 100644 --- a/src/libunicode/u_str.rs +++ b/src/libunicode/u_str.rs @@ -525,7 +525,7 @@ impl<I> Iterator for Utf16Encoder<I> where I: Iterator<Item=char> { return Some(tmp); } - let mut buf = [0u16; 2]; + let mut buf = [0; 2]; self.chars.next().map(|ch| { let n = CharExt::encode_utf16(ch, &mut buf).unwrap_or(0); if n == 2 { self.extra = buf[1]; } diff --git a/src/llvm b/src/llvm -Subproject b89c3f039b61edbb077771eda2ee8a718dbec7e +Subproject bff69076975642c64e76dbeaa53476bfa721208 diff --git a/src/rustbook/book.rs b/src/rustbook/book.rs index 8900b60d191..ac7f2f824cb 100644 --- a/src/rustbook/book.rs +++ b/src/rustbook/book.rs @@ -10,14 +10,16 @@ //! Basic data structures for representing a book. -use std::old_io::BufferedReader; +use std::io::prelude::*; +use std::io::BufReader; use std::iter; use std::iter::AdditiveIterator; +use std::path::{Path, PathBuf}; pub struct BookItem { pub title: String, - pub path: Path, - pub path_to_root: Path, + pub path: PathBuf, + pub path_to_root: PathBuf, pub children: Vec<BookItem>, } @@ -76,7 +78,7 @@ impl Book { } /// Construct a book by parsing a summary (markdown table of contents). -pub fn parse_summary<R: Reader>(input: R, src: &Path) -> Result<Book, Vec<String>> { +pub fn parse_summary(input: &mut Read, src: &Path) -> Result<Book, Vec<String>> { fn collapse(stack: &mut Vec<BookItem>, top_items: &mut Vec<BookItem>, to_level: usize) { @@ -100,16 +102,16 @@ pub fn parse_summary<R: Reader>(input: R, src: &Path) -> Result<Book, Vec<String // always include the introduction top_items.push(BookItem { title: "Introduction".to_string(), - path: Path::new("README.md"), - path_to_root: Path::new("."), + path: PathBuf::new("README.md"), + path_to_root: PathBuf::new("."), children: vec!(), }); - for line_result in BufferedReader::new(input).lines() { + for line_result in BufReader::new(input).lines() { let line = match line_result { Ok(line) => line, Err(err) => { - errors.push(err.desc.to_string()); // FIXME: include detail + errors.push(err.to_string()); return Err(errors); } }; @@ -125,16 +127,16 @@ pub fn parse_summary<R: Reader>(input: R, src: &Path) -> Result<Book, Vec<String let title = line[start_bracket + 1..end_bracket].to_string(); let indent = &line[..star_idx]; - let path_from_root = match src.join(given_path).path_relative_from(src) { - Some(p) => p, + let path_from_root = match src.join(given_path).relative_from(src) { + Some(p) => p.to_path_buf(), None => { errors.push(format!("paths in SUMMARY.md must be relative, \ but path '{}' for section '{}' is not.", given_path, title)); - Path::new("") + PathBuf::new("") } }; - let path_to_root = Path::new(iter::repeat("../") + let path_to_root = PathBuf::new(&iter::repeat("../") .take(path_from_root.components().count() - 1) .collect::<String>()); let item = BookItem { diff --git a/src/rustbook/build.rs b/src/rustbook/build.rs index f36d97d6d12..731773917e0 100644 --- a/src/rustbook/build.rs +++ b/src/rustbook/build.rs @@ -11,13 +11,15 @@ //! Implementation of the `build` subcommand, used to compile a book. use std::env; -use std::os; -use std::old_io; -use std::old_io::{fs, File, BufferedWriter, TempDir, IoResult}; +use std::fs::{self, File}; +use std::io::prelude::*; +use std::io::{self, BufWriter}; +use std::path::{Path, PathBuf}; +use rustc_back::tempdir::TempDir; use subcommand::Subcommand; use term::Term; -use error::{Error, CliResult, CommandResult}; +use error::{err, CliResult, CommandResult}; use book; use book::{Book, BookItem}; use css; @@ -29,17 +31,17 @@ struct Build; pub fn parse_cmd(name: &str) -> Option<Box<Subcommand>> { if name == "build" { - Some(box Build as Box<Subcommand>) + Some(Box::new(Build)) } else { None } } -fn write_toc(book: &Book, path_to_root: &Path, out: &mut Writer) -> IoResult<()> { +fn write_toc(book: &Book, path_to_root: &Path, out: &mut Write) -> io::Result<()> { fn walk_items(items: &[BookItem], section: &str, path_to_root: &Path, - out: &mut Writer) -> IoResult<()> { + out: &mut Write) -> io::Result<()> { for (i, item) in items.iter().enumerate() { try!(walk_item(item, &format!("{}{}.", section, i + 1)[..], path_to_root, out)); } @@ -48,9 +50,9 @@ fn write_toc(book: &Book, path_to_root: &Path, out: &mut Writer) -> IoResult<()> fn walk_item(item: &BookItem, section: &str, path_to_root: &Path, - out: &mut Writer) -> IoResult<()> { + out: &mut Write) -> io::Result<()> { try!(writeln!(out, "<li><a href='{}'><b>{}</b> {}</a>", - path_to_root.join(item.path.with_extension("html")).display(), + path_to_root.join(&item.path.with_extension("html")).display(), section, item.title)); if !item.children.is_empty() { @@ -75,30 +77,35 @@ fn write_toc(book: &Book, path_to_root: &Path, out: &mut Writer) -> IoResult<()> fn render(book: &Book, tgt: &Path) -> CliResult<()> { let tmp = try!(TempDir::new("rust-book")); - for (section, item) in book.iter() { - println!("{} {}", section, item.title); - - let out_path = tgt.join(item.path.dirname()); + for (_section, item) in book.iter() { + let out_path = match item.path.parent() { + Some(p) => tgt.join(p), + None => tgt.to_path_buf(), + }; let src; if env::args().len() < 3 { - src = os::getcwd().unwrap().clone(); + src = env::current_dir().unwrap().clone(); } else { - src = Path::new(env::args().nth(2).unwrap().clone()); + src = PathBuf::new(&env::args().nth(2).unwrap()); } // preprocess the markdown, rerouting markdown references to html references - let markdown_data = try!(File::open(&src.join(&item.path)).read_to_string()); - let preprocessed_path = tmp.path().join(item.path.filename().unwrap()); + let mut markdown_data = String::new(); + try!(File::open(&src.join(&item.path)).and_then(|mut f| { + f.read_to_string(&mut markdown_data) + })); + let preprocessed_path = tmp.path().join(item.path.file_name().unwrap()); { let urls = markdown_data.replace(".md)", ".html)"); - try!(File::create(&preprocessed_path) - .write_str(&urls[..])); + try!(File::create(&preprocessed_path).and_then(|mut f| { + f.write_all(urls.as_bytes()) + })); } // write the prelude to a temporary HTML file for rustdoc inclusion let prelude = tmp.path().join("prelude.html"); { - let mut toc = BufferedWriter::new(try!(File::create(&prelude))); + let mut toc = BufWriter::new(try!(File::create(&prelude))); try!(writeln!(&mut toc, r#"<div id="nav"> <button id="toggle-nav"> <span class="sr-only">Toggle navigation</span> @@ -115,12 +122,12 @@ fn render(book: &Book, tgt: &Path) -> CliResult<()> { // write the postlude to a temporary HTML file for rustdoc inclusion let postlude = tmp.path().join("postlude.html"); { - let mut toc = BufferedWriter::new(try!(File::create(&postlude))); - try!(toc.write_str(javascript::JAVASCRIPT)); + let mut toc = BufWriter::new(try!(File::create(&postlude))); + try!(toc.write_all(javascript::JAVASCRIPT.as_bytes())); try!(writeln!(&mut toc, "</div></div>")); } - try!(fs::mkdir_recursive(&out_path, old_io::USER_DIR)); + try!(fs::create_dir_all(&out_path)); let rustdoc_args: &[String] = &[ "".to_string(), @@ -135,7 +142,7 @@ fn render(book: &Book, tgt: &Path) -> CliResult<()> { if output_result != 0 { let message = format!("Could not execute `rustdoc` with {:?}: {}", rustdoc_args, output_result); - return Err(box message as Box<Error>); + return Err(err(&message)); } } @@ -150,28 +157,30 @@ impl Subcommand for Build { } fn usage(&self) {} fn execute(&mut self, term: &mut Term) -> CommandResult<()> { - let cwd = os::getcwd().unwrap(); + let cwd = env::current_dir().unwrap(); let src; let tgt; if env::args().len() < 3 { src = cwd.clone(); } else { - src = Path::new(env::args().nth(2).unwrap().clone()); + src = PathBuf::new(&env::args().nth(2).unwrap()); } if env::args().len() < 4 { tgt = cwd.join("_book"); } else { - tgt = Path::new(env::args().nth(3).unwrap().clone()); + tgt = PathBuf::new(&env::args().nth(3).unwrap()); } - try!(fs::mkdir(&tgt, old_io::USER_DIR)); + try!(fs::create_dir(&tgt)); - try!(File::create(&tgt.join("rust-book.css")).write_str(css::STYLE)); + try!(File::create(&tgt.join("rust-book.css")).and_then(|mut f| { + f.write_all(css::STYLE.as_bytes()) + })); - let summary = try!(File::open(&src.join("SUMMARY.md"))); - match book::parse_summary(summary, &src) { + let mut summary = try!(File::open(&src.join("SUMMARY.md"))); + match book::parse_summary(&mut summary, &src) { Ok(book) => { // execute rustdoc on the whole book render(&book, &tgt) @@ -182,7 +191,7 @@ impl Subcommand for Build { term.err(&format!("error: {}", err)[..]); } - Err(box format!("{} errors occurred", n) as Box<Error>) + Err(err(&format!("{} errors occurred", n))) } } } diff --git a/src/rustbook/error.rs b/src/rustbook/error.rs index 43c882c7d5b..294b4e55669 100644 --- a/src/rustbook/error.rs +++ b/src/rustbook/error.rs @@ -10,10 +10,8 @@ //! Error handling utilities. WIP. +use std::error::Error; use std::fmt; -use std::fmt::{Debug, Formatter}; - -use std::old_io::IoError; pub type CliError = Box<Error + 'static>; pub type CliResult<T> = Result<T, CliError>; @@ -21,63 +19,17 @@ pub type CliResult<T> = Result<T, CliError>; pub type CommandError = Box<Error + 'static>; pub type CommandResult<T> = Result<T, CommandError>; -pub trait Error { - fn description(&self) -> &str; - - fn detail(&self) -> Option<&str> { None } - fn cause(&self) -> Option<&Error> { None } -} - -pub trait FromError<E> { - fn from_err(err: E) -> Self; -} - -impl Debug for Box<Error + 'static> { - fn fmt(&self, f: &mut Formatter) -> fmt::Result { - write!(f, "{}", self.description()) - } -} - -impl<E: Error + 'static> FromError<E> for Box<Error + 'static> { - fn from_err(err: E) -> Box<Error + 'static> { - box err as Box<Error> - } -} +pub fn err(s: &str) -> CliError { + struct E(String); -impl<'a> Error for &'a str { - fn description<'b>(&'b self) -> &'b str { - *self + impl Error for E { + fn description(&self) -> &str { &self.0 } } -} - -impl Error for String { - fn description<'a>(&'a self) -> &'a str { - &self[..] + impl fmt::Display for E { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.0.fmt(f) + } } -} - -impl<'a> Error for Box<Error + 'a> { - fn description(&self) -> &str { (**self).description() } - fn detail(&self) -> Option<&str> { (**self).detail() } - fn cause(&self) -> Option<&Error> { (**self).cause() } -} - -impl FromError<()> for () { - fn from_err(_: ()) -> () { () } -} -impl FromError<IoError> for IoError { - fn from_err(error: IoError) -> IoError { error } + Box::new(E(s.to_string())) } - -impl Error for IoError { - fn description(&self) -> &str { - self.desc - } - fn detail(&self) -> Option<&str> { - self.detail.as_ref().map(|s| &s[..]) - } -} - - -//fn iter_map_err<T, U, E, I: Iterator<Result<T,E>>>(iter: I, diff --git a/src/rustbook/help.rs b/src/rustbook/help.rs index 7fd8214f731..995d2f2494a 100644 --- a/src/rustbook/help.rs +++ b/src/rustbook/help.rs @@ -19,7 +19,7 @@ struct Help; pub fn parse_cmd(name: &str) -> Option<Box<Subcommand>> { match name { - "help" | "--help" | "-h" | "-?" => Some(box Help as Box<Subcommand>), + "help" | "--help" | "-h" | "-?" => Some(Box::new(Help)), _ => None } } diff --git a/src/rustbook/main.rs b/src/rustbook/main.rs index b9fc011e8b9..8df622b0b5d 100644 --- a/src/rustbook/main.rs +++ b/src/rustbook/main.rs @@ -8,31 +8,24 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(box_syntax)] -#![feature(collections)] +#![deny(warnings)] + #![feature(core)] +#![feature(exit_status)] +#![feature(io)] #![feature(old_io)] -#![feature(env)] -#![feature(os)] -#![feature(old_path)] +#![feature(path)] #![feature(rustdoc)] +#![feature(rustc_private)] extern crate rustdoc; +extern crate rustc_back; use std::env; +use std::error::Error; use subcommand::Subcommand; use term::Term; -macro_rules! try ( - ($expr:expr) => ({ - use error; - match $expr { - Ok(val) => val, - Err(err) => return Err(error::FromError::from_err(err)) - } - }) -); - mod term; mod error; mod book; @@ -56,15 +49,12 @@ fn main() { } else { match subcommand::parse_name(&cmd[1][..]) { Some(mut subcmd) => { - match subcmd.parse_args(cmd.tail()) { + match subcmd.parse_args(&cmd[..cmd.len()-1]) { Ok(_) => { match subcmd.execute(&mut term) { Ok(_) => (), Err(err) => { - term.err(&format!("error: {}", err.description())[..]); - err.detail().map(|detail| { - term.err(&format!("detail: {}", detail)[..]); - }); + term.err(&format!("error: {}", err)); } } } diff --git a/src/rustbook/serve.rs b/src/rustbook/serve.rs index 808527dcef9..2fa7b7eed7b 100644 --- a/src/rustbook/serve.rs +++ b/src/rustbook/serve.rs @@ -19,7 +19,7 @@ struct Serve; pub fn parse_cmd(name: &str) -> Option<Box<Subcommand>> { if name == "serve" { - Some(box Serve as Box<Subcommand>) + Some(Box::new(Serve)) } else { None } diff --git a/src/rustbook/term.rs b/src/rustbook/term.rs index 98aa3fca184..06595cb0455 100644 --- a/src/rustbook/term.rs +++ b/src/rustbook/term.rs @@ -21,7 +21,7 @@ pub struct Term { impl Term { pub fn new() -> Term { Term { - err: box stdio::stderr() as Box<Writer>, + err: Box::new(stdio::stderr()) } } diff --git a/src/rustbook/test.rs b/src/rustbook/test.rs index 727a385a8f0..72df0768e7b 100644 --- a/src/rustbook/test.rs +++ b/src/rustbook/test.rs @@ -11,19 +11,19 @@ //! Implementation of the `test` subcommand. Just a stub for now. use subcommand::Subcommand; -use error::CliResult; -use error::CommandResult; -use error::Error; +use error::{err, CliResult, CommandResult}; use term::Term; use book; -use std::old_io::{Command, File}; -use std::os; + +use std::fs::File; +use std::env; +use std::process::Command; struct Test; pub fn parse_cmd(name: &str) -> Option<Box<Subcommand>> { if name == "test" { - Some(box Test as Box<Subcommand>) + Some(Box::new(Test)) } else { None } @@ -35,11 +35,11 @@ impl Subcommand for Test { } fn usage(&self) {} fn execute(&mut self, term: &mut Term) -> CommandResult<()> { - let cwd = os::getcwd().unwrap(); + let cwd = env::current_dir().unwrap(); let src = cwd.clone(); - let summary = File::open(&src.join("SUMMARY.md")); - match book::parse_summary(summary, &src) { + let mut summary = try!(File::open(&src.join("SUMMARY.md"))); + match book::parse_summary(&mut summary, &src) { Ok(book) => { for (_, item) in book.iter() { let output_result = Command::new("rustdoc") @@ -50,15 +50,15 @@ impl Subcommand for Test { Ok(output) => { if !output.status.success() { term.err(&format!("{}\n{}", - String::from_utf8_lossy(&output.output[..]), - String::from_utf8_lossy(&output.error[..]))[..]); - return Err(box "Some tests failed." as Box<Error>); + String::from_utf8_lossy(&output.stdout), + String::from_utf8_lossy(&output.stderr))); + return Err(err("some tests failed")); } } Err(e) => { - let message = format!("Could not execute `rustdoc`: {}", e); - return Err(box message as Box<Error>); + let message = format!("could not execute `rustdoc`: {}", e); + return Err(err(&message)) } } } @@ -67,7 +67,7 @@ impl Subcommand for Test { for err in errors { term.err(&err[..]); } - return Err(box "There was an error." as Box<Error>); + return Err(err("there was an error")) } } Ok(()) // lol diff --git a/src/rustllvm/llvm-auto-clean-trigger b/src/rustllvm/llvm-auto-clean-trigger index 2cd7ed6c155..1ea40fc46a5 100644 --- a/src/rustllvm/llvm-auto-clean-trigger +++ b/src/rustllvm/llvm-auto-clean-trigger @@ -1,4 +1,4 @@ # If this file is modified, then llvm will be forcibly cleaned and then rebuilt. # The actual contents of this file do not matter, but to trigger a change on the # build bots then the contents should be changed so git updates the mtime. -2015-02-19 +2015-03-04 diff --git a/src/snapshots.txt b/src/snapshots.txt index 318f66b9465..35f46ca6d32 100644 --- a/src/snapshots.txt +++ b/src/snapshots.txt @@ -1,4 +1,14 @@ +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 linux-i386 3278ebbce8cb269acc0614dac5ddac07eab6a99c linux-x86_64 72287d0d88de3e5a53bae78ac0d958e1a7637d73 diff --git a/src/test/auxiliary/cci_class_3.rs b/src/test/auxiliary/cci_class_3.rs index 98881eb09bf..44d3a69fde4 100644 --- a/src/test/auxiliary/cci_class_3.rs +++ b/src/test/auxiliary/cci_class_3.rs @@ -16,7 +16,7 @@ pub mod kitties { } impl cat { - pub fn speak(&mut self) { self.meows += 1_usize; } + pub fn speak(&mut self) { self.meows += 1; } pub fn meow_count(&mut self) -> uint { self.meows } } diff --git a/src/test/auxiliary/cci_class_4.rs b/src/test/auxiliary/cci_class_4.rs index 9d7905cdebd..c10ef805a65 100644 --- a/src/test/auxiliary/cci_class_4.rs +++ b/src/test/auxiliary/cci_class_4.rs @@ -34,8 +34,8 @@ pub mod kitties { impl cat { pub fn meow(&mut self) { println!("Meow"); - self.meows += 1_usize; - if self.meows % 5_usize == 0_usize { + self.meows += 1; + if self.meows % 5 == 0 { self.how_hungry += 1; } } diff --git a/src/test/auxiliary/cci_class_cast.rs b/src/test/auxiliary/cci_class_cast.rs index 96a06968c5f..28fa354fef3 100644 --- a/src/test/auxiliary/cci_class_cast.rs +++ b/src/test/auxiliary/cci_class_cast.rs @@ -26,8 +26,8 @@ pub mod kitty { impl cat { fn meow(&mut self) { println!("Meow"); - self.meows += 1_usize; - if self.meows % 5_usize == 0_usize { + self.meows += 1; + if self.meows % 5 == 0 { self.how_hungry += 1; } } diff --git a/src/test/auxiliary/cci_impl_lib.rs b/src/test/auxiliary/cci_impl_lib.rs index 6ee497370e8..a650b30e593 100644 --- a/src/test/auxiliary/cci_impl_lib.rs +++ b/src/test/auxiliary/cci_impl_lib.rs @@ -20,7 +20,7 @@ impl uint_helpers for uint { let mut i = *self; while i < v { f(i); - i += 1_usize; + i += 1; } } } diff --git a/src/test/auxiliary/cci_iter_lib.rs b/src/test/auxiliary/cci_iter_lib.rs index 8e00b0dc7be..07d03b4c759 100644 --- a/src/test/auxiliary/cci_iter_lib.rs +++ b/src/test/auxiliary/cci_iter_lib.rs @@ -12,10 +12,10 @@ #[inline] pub fn iter<T, F>(v: &[T], mut f: F) where F: FnMut(&T) { - let mut i = 0_usize; + let mut i = 0; let n = v.len(); while i < n { f(&v[i]); - i += 1_usize; + i += 1; } } diff --git a/src/test/auxiliary/cci_no_inline_lib.rs b/src/test/auxiliary/cci_no_inline_lib.rs index ce041118906..f3ad2a3aeb9 100644 --- a/src/test/auxiliary/cci_no_inline_lib.rs +++ b/src/test/auxiliary/cci_no_inline_lib.rs @@ -13,10 +13,10 @@ // same as cci_iter_lib, more-or-less, but not marked inline pub fn iter<F>(v: Vec<uint> , mut f: F) where F: FnMut(uint) { - let mut i = 0_usize; + let mut i = 0; let n = v.len(); while i < n { f(v[i]); - i += 1_usize; + i += 1; } } diff --git a/src/test/auxiliary/cross_crate_spans.rs b/src/test/auxiliary/cross_crate_spans.rs new file mode 100644 index 00000000000..22c206836ee --- /dev/null +++ b/src/test/auxiliary/cross_crate_spans.rs @@ -0,0 +1,26 @@ +// Copyright 2013-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. + +#![crate_type = "rlib"] +#![omit_gdb_pretty_printer_section] + +// no-prefer-dynamic +// compile-flags:-g + +pub fn generic_function<T: Clone>(val: T) -> (T, T) { + let result = (val.clone(), val.clone()); + let a_variable: u32 = 123456789; + let another_variable: f64 = 123456789.5; + zzz(); + result +} + +#[inline(never)] +fn zzz() {()} \ No newline at end of file diff --git a/src/test/auxiliary/custom_derive_plugin.rs b/src/test/auxiliary/custom_derive_plugin.rs new file mode 100644 index 00000000000..e2688964804 --- /dev/null +++ b/src/test/auxiliary/custom_derive_plugin.rs @@ -0,0 +1,74 @@ +// 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. + +// force-host + +#![feature(plugin_registrar)] +#![feature(box_syntax)] +#![feature(rustc_private)] + +extern crate syntax; +extern crate rustc; + +use syntax::ast; +use syntax::codemap::Span; +use syntax::ext::base::{Decorator, ExtCtxt}; +use syntax::ext::build::AstBuilder; +use syntax::ext::deriving::generic::{cs_fold, TraitDef, MethodDef, combine_substructure}; +use syntax::ext::deriving::generic::ty::{Literal, LifetimeBounds, Path, borrowed_explicit_self}; +use syntax::parse::token; +use syntax::ptr::P; +use rustc::plugin::Registry; + +#[plugin_registrar] +pub fn plugin_registrar(reg: &mut Registry) { + reg.register_syntax_extension( + token::intern("derive_TotalSum"), + Decorator(box expand)); +} + +fn expand(cx: &mut ExtCtxt, + span: Span, + mitem: &ast::MetaItem, + item: &ast::Item, + push: &mut FnMut(P<ast::Item>)) { + let trait_def = TraitDef { + span: span, + attributes: vec![], + path: Path::new(vec!["TotalSum"]), + additional_bounds: vec![], + generics: LifetimeBounds::empty(), + associated_types: vec![], + methods: vec![ + MethodDef { + name: "total_sum", + generics: LifetimeBounds::empty(), + explicit_self: borrowed_explicit_self(), + args: vec![], + ret_ty: Literal(Path::new_local("isize")), + attributes: vec![], + combine_substructure: combine_substructure(box |cx, span, substr| { + let zero = cx.expr_int(span, 0); + cs_fold(false, + |cx, span, subexpr, field, _| { + cx.expr_binary(span, ast::BiAdd, subexpr, + cx.expr_method_call(span, field, + token::str_to_ident("total_sum"), vec![])) + }, + zero, + box |cx, span, _, _| { cx.span_bug(span, "wtf??"); }, + cx, span, substr) + }), + }, + ], + }; + + trait_def.expand(cx, mitem, item, |i| push(i)) +} diff --git a/src/test/auxiliary/internal_unstable.rs b/src/test/auxiliary/internal_unstable.rs new file mode 100644 index 00000000000..3d59b8e9009 --- /dev/null +++ b/src/test/auxiliary/internal_unstable.rs @@ -0,0 +1,60 @@ +// 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(staged_api, allow_internal_unstable)] +#![staged_api] +#![stable(feature = "stable", since = "1.0.0")] + +#[unstable(feature = "function")] +pub fn unstable() {} + + +#[stable(feature = "stable", since = "1.0.0")] +pub struct Foo { + #[unstable(feature = "struct_field")] + pub x: u8 +} + +#[allow_internal_unstable] +#[macro_export] +macro_rules! call_unstable_allow { + () => { $crate::unstable() } +} + +#[allow_internal_unstable] +#[macro_export] +macro_rules! construct_unstable_allow { + ($e: expr) => { + $crate::Foo { x: $e } + } +} + +#[allow_internal_unstable] +#[macro_export] +macro_rules! pass_through_allow { + ($e: expr) => { $e } +} + +#[macro_export] +macro_rules! call_unstable_noallow { + () => { $crate::unstable() } +} + +#[macro_export] +macro_rules! construct_unstable_noallow { + ($e: expr) => { + $crate::Foo { x: $e } + } +} + +#[macro_export] +macro_rules! pass_through_noallow { + ($e: expr) => { $e } +} diff --git a/src/test/auxiliary/lint_output_format.rs b/src/test/auxiliary/lint_output_format.rs index 1977e2aad28..1977e2aad28 100755..100644 --- a/src/test/auxiliary/lint_output_format.rs +++ b/src/test/auxiliary/lint_output_format.rs diff --git a/src/test/auxiliary/macro_reexport_1.rs b/src/test/auxiliary/macro_reexport_1.rs index 9c72cb1a680..aaeccc6e898 100644 --- a/src/test/auxiliary/macro_reexport_1.rs +++ b/src/test/auxiliary/macro_reexport_1.rs @@ -11,5 +11,5 @@ #![crate_type = "dylib"] #[macro_export] macro_rules! reexported { - () => ( 3_usize ) + () => ( 3 ) } diff --git a/src/test/auxiliary/plugin_args.rs b/src/test/auxiliary/plugin_args.rs index 20c84c4ba5b..30b18a3618f 100644 --- a/src/test/auxiliary/plugin_args.rs +++ b/src/test/auxiliary/plugin_args.rs @@ -47,5 +47,5 @@ pub fn plugin_registrar(reg: &mut Registry) { let args = reg.args().clone(); reg.register_syntax_extension(token::intern("plugin_args"), // FIXME (#22405): Replace `Box::new` with `box` here when/if possible. - NormalTT(Box::new(Expander { args: args, }), None)); + NormalTT(Box::new(Expander { args: args, }), None, false)); } diff --git a/src/test/auxiliary/procedural_mbe_matching.rs b/src/test/auxiliary/procedural_mbe_matching.rs new file mode 100644 index 00000000000..d9a2b06e039 --- /dev/null +++ b/src/test/auxiliary/procedural_mbe_matching.rs @@ -0,0 +1,69 @@ +// 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. + +// force-host + +#![crate_type="dylib"] +#![feature(plugin_registrar, quote)] + +extern crate syntax; +extern crate rustc; + +use syntax::codemap::Span; +use syntax::parse::token::{self, str_to_ident, NtExpr, NtPat}; +use syntax::ast::{TokenTree, TtToken, Pat}; +use syntax::ext::base::{ExtCtxt, MacResult, DummyResult, MacEager}; +use syntax::ext::build::AstBuilder; +use syntax::ext::tt::macro_parser::{MatchedSeq, MatchedNonterminal}; +use syntax::ext::tt::macro_parser::{Success, Failure, Error}; +use syntax::ptr::P; +use rustc::plugin::Registry; + +fn expand_mbe_matches(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree]) + -> Box<MacResult + 'static> { + + let mbe_matcher = quote_matcher!(cx, $matched:expr, $($pat:pat)|+); + + let mac_expr = match TokenTree::parse(cx, &mbe_matcher[..], args) { + Success(map) => { + match (&*map[str_to_ident("matched")], &*map[str_to_ident("pat")]) { + (&MatchedNonterminal(NtExpr(ref matched_expr)), + &MatchedSeq(ref pats, seq_sp)) => { + let pats: Vec<P<Pat>> = pats.iter().map(|pat_nt| + if let &MatchedNonterminal(NtPat(ref pat)) = &**pat_nt { + pat.clone() + } else { + unreachable!() + } + ).collect(); + let arm = cx.arm(seq_sp, pats, cx.expr_bool(seq_sp, true)); + + quote_expr!(cx, + match $matched_expr { + $arm + _ => false + } + ) + } + _ => unreachable!() + } + } + Failure(_, s) | Error(_, s) => { + panic!("expected Success, but got Error/Failure: {}", s); + } + }; + + MacEager::expr(mac_expr) +} + +#[plugin_registrar] +pub fn plugin_registrar(reg: &mut Registry) { + reg.register_macro("matches", expand_mbe_matches); +} diff --git a/src/test/auxiliary/roman_numerals.rs b/src/test/auxiliary/roman_numerals.rs index e5c42111105..0ea7c000570 100644 --- a/src/test/auxiliary/roman_numerals.rs +++ b/src/test/auxiliary/roman_numerals.rs @@ -47,7 +47,7 @@ fn expand_rn(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree]) }; let mut text = &*text; - let mut total = 0_usize; + let mut total = 0; while !text.is_empty() { match NUMERALS.iter().find(|&&(rn, _)| text.starts_with(rn)) { Some(&(rn, val)) => { 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 index 00000000000..506e7a00c75 --- /dev/null +++ b/src/test/auxiliary/typeck-default-trait-impl-cross-crate-coherence-lib.rs @@ -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/auxiliary/unboxed-closures-cross-crate.rs b/src/test/auxiliary/unboxed-closures-cross-crate.rs index a5178c03443..26925a35067 100644 --- a/src/test/auxiliary/unboxed-closures-cross-crate.rs +++ b/src/test/auxiliary/unboxed-closures-cross-crate.rs @@ -14,9 +14,9 @@ use std::ops::Add; #[inline] pub fn has_closures() -> uint { - let x = 1_usize; + let x = 1; let mut f = move || x; - let y = 1_usize; + let y = 1; let g = || y; f() + g() } diff --git a/src/test/bench/noise.rs b/src/test/bench/noise.rs index 53c52ae3019..de88c7733b3 100644 --- a/src/test/bench/noise.rs +++ b/src/test/bench/noise.rs @@ -49,7 +49,7 @@ impl Noise2DContext { *x = random_gradient(&mut rng); } - let mut permutations = [0i32; 256]; + let mut permutations = [0; 256]; for (i, x) in permutations.iter_mut().enumerate() { *x = i as i32; } diff --git a/src/test/bench/shootout-chameneos-redux.rs b/src/test/bench/shootout-chameneos-redux.rs index 73e7c8eb073..4a8bb24270d 100644 --- a/src/test/bench/shootout-chameneos-redux.rs +++ b/src/test/bench/shootout-chameneos-redux.rs @@ -145,7 +145,7 @@ fn creature( to_rendezvous: Sender<CreatureInfo>, to_rendezvous_log: Sender<String> ) { - let mut creatures_met = 0i32; + let mut creatures_met = 0; let mut evil_clones_met = 0; let mut rendezvous = from_rendezvous.iter(); diff --git a/src/test/bench/shootout-fannkuch-redux.rs b/src/test/bench/shootout-fannkuch-redux.rs index f7de935d08f..3688c224a7d 100644 --- a/src/test/bench/shootout-fannkuch-redux.rs +++ b/src/test/bench/shootout-fannkuch-redux.rs @@ -91,7 +91,7 @@ impl Perm { } fn get(&mut self, mut idx: i32) -> P { - let mut pp = [0u8; 16]; + let mut pp = [0; 16]; self.permcount = idx as u32; for (i, place) in self.perm.p.iter_mut().enumerate() { *place = i as i32 + 1; @@ -183,7 +183,7 @@ fn main() { let n = std::env::args() .nth(1) .and_then(|arg| arg.parse().ok()) - .unwrap_or(2i32); + .unwrap_or(2); let (checksum, maxflips) = fannkuch(n); println!("{}\nPfannkuchen({}) = {}", checksum, n, maxflips); diff --git a/src/test/bench/shootout-fasta-redux.rs b/src/test/bench/shootout-fasta-redux.rs index 277c3ee73df..9cee75757aa 100644 --- a/src/test/bench/shootout-fasta-redux.rs +++ b/src/test/bench/shootout-fasta-redux.rs @@ -121,7 +121,7 @@ impl<'a, W: Writer> RepeatFasta<'a, W> { fn make(&mut self, n: usize) -> IoResult<()> { let alu_len = self.alu.len(); - let mut buf = repeat(0u8).take(alu_len + LINE_LEN).collect::<Vec<_>>(); + let mut buf = repeat(0).take(alu_len + LINE_LEN).collect::<Vec<_>>(); let alu: &[u8] = self.alu.as_bytes(); copy_memory(&mut buf, alu); diff --git a/src/test/bench/shootout-fasta.rs b/src/test/bench/shootout-fasta.rs index 2c640c4b092..e15f9d99ff6 100644 --- a/src/test/bench/shootout-fasta.rs +++ b/src/test/bench/shootout-fasta.rs @@ -89,7 +89,7 @@ fn make_fasta<W: Writer, I: Iterator<Item=u8>>( -> std::old_io::IoResult<()> { try!(wr.write(header.as_bytes())); - let mut line = [0u8; LINE_LENGTH + 1]; + let mut line = [0; LINE_LENGTH + 1]; while n > 0 { let nb = min(LINE_LENGTH, n); for i in 0..nb { diff --git a/src/test/bench/shootout-k-nucleotide.rs b/src/test/bench/shootout-k-nucleotide.rs index 5cfe62d967c..9e5885041b6 100644 --- a/src/test/bench/shootout-k-nucleotide.rs +++ b/src/test/bench/shootout-k-nucleotide.rs @@ -78,11 +78,11 @@ impl Code { } fn rotate(&self, c: u8, frame: usize) -> Code { - Code(self.push_char(c).hash() & ((1u64 << (2 * frame)) - 1)) + Code(self.push_char(c).hash() & ((1 << (2 * frame)) - 1)) } fn pack(string: &str) -> Code { - string.bytes().fold(Code(0u64), |a, b| a.push_char(b)) + string.bytes().fold(Code(0), |a, b| a.push_char(b)) } fn unpack(&self, frame: usize) -> String { diff --git a/src/test/bench/shootout-meteor.rs b/src/test/bench/shootout-meteor.rs index a94fe0ccd95..79a5245a408 100644 --- a/src/test/bench/shootout-meteor.rs +++ b/src/test/bench/shootout-meteor.rs @@ -169,7 +169,7 @@ fn make_masks() -> Vec<Vec<Vec<u64> > > { .map(|(id, p)| transform(p, id != 3)) .collect(); - (0i32..50).map(|yx| { + (0..50).map(|yx| { transforms.iter().enumerate().map(|(id, t)| { t.iter().filter_map(|p| mask(yx / 5, yx % 5, id, p)).collect() }).collect() @@ -211,7 +211,7 @@ fn filter_masks(masks: &mut Vec<Vec<Vec<u64>>>) { // Gets the identifier of a mask. fn get_id(m: u64) -> u8 { - for id in 0u8..10 { + for id in 0..10 { if m & (1 << (id + 50) as usize) != 0 {return id;} } panic!("{:016x} does not have a valid identifier", m); diff --git a/src/test/bench/sudoku.rs b/src/test/bench/sudoku.rs index f308743ad13..9a82614510e 100644 --- a/src/test/bench/sudoku.rs +++ b/src/test/bench/sudoku.rs @@ -60,7 +60,7 @@ impl Sudoku { reader.read_line(&mut s).unwrap(); assert_eq!(s, "9,9\n"); - let mut g = repeat(vec![0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8]) + let mut g = repeat(vec![0, 0, 0, 0, 0, 0, 0, 0, 0]) .take(10).collect::<Vec<_>>(); for line in reader.lines() { let line = line.unwrap(); @@ -94,10 +94,10 @@ impl Sudoku { // solve sudoku grid pub fn solve(&mut self) { let mut work: Vec<(u8, u8)> = Vec::new(); /* queue of uncolored fields */ - for row in 0u8..9u8 { - for col in 0u8..9u8 { + for row in 0..9 { + for col in 0..9 { let color = self.grid[row as usize][col as usize]; - if color == 0u8 { + if color == 0 { work.push((row, col)); } } @@ -122,7 +122,7 @@ impl Sudoku { } fn next_color(&mut self, row: u8, col: u8, start_color: u8) -> bool { - if start_color < 10u8 { + if start_color < 10 { // colors not yet used let mut avail: Box<_> = box Colors::new(start_color); @@ -132,15 +132,15 @@ impl Sudoku { // find first remaining color that is available let next = avail.next(); self.grid[row as usize][col as usize] = next; - return 0u8 != next; + return 0 != next; } - self.grid[row as usize][col as usize] = 0u8; + self.grid[row as usize][col as usize] = 0; return false; } // find colors available in neighbourhood of (row, col) fn drop_colors(&mut self, avail: &mut Colors, row: u8, col: u8) { - for idx in 0u8..9u8 { + for idx in 0..9 { /* check same column fields */ avail.remove(self.grid[idx as usize][col as usize]); /* check same row fields */ @@ -148,10 +148,10 @@ impl Sudoku { } // check same block fields - let row0 = (row / 3u8) * 3u8; - let col0 = (col / 3u8) * 3u8; - for alt_row in row0..row0 + 3u8 { - for alt_col in col0..col0 + 3u8 { + let row0 = (row / 3) * 3; + let col0 = (col / 3) * 3; + for alt_row in row0..row0 + 3 { + for alt_col in col0..col0 + 3 { avail.remove(self.grid[alt_row as usize][alt_col as usize]); } } @@ -161,29 +161,29 @@ impl Sudoku { // Stores available colors as simple bitfield, bit 0 is always unset struct Colors(u16); -static HEADS: u16 = (1u16 << 10) - 1; /* bits 9..0 */ +static HEADS: u16 = (1 << 10) - 1; /* bits 9..0 */ impl Colors { fn new(start_color: u8) -> Colors { // Sets bits 9..start_color - let tails = !0u16 << start_color as usize; + let tails = !0 << start_color as usize; return Colors(HEADS & tails); } fn next(&self) -> u8 { let Colors(c) = *self; let val = c & HEADS; - if 0u16 == val { - return 0u8; + if 0 == val { + return 0; } else { return val.trailing_zeros() as u8 } } fn remove(&mut self, color: u8) { - if color != 0u8 { + if color != 0 { let Colors(val) = *self; - let mask = !(1u16 << color as usize); + let mask = !(1 << color as usize); *self = Colors(val & mask); } } @@ -191,57 +191,57 @@ impl Colors { static DEFAULT_SUDOKU: [[u8;9];9] = [ /* 0 1 2 3 4 5 6 7 8 */ - /* 0 */ [0u8, 4u8, 0u8, 6u8, 0u8, 0u8, 0u8, 3u8, 2u8], - /* 1 */ [0u8, 0u8, 8u8, 0u8, 2u8, 0u8, 0u8, 0u8, 0u8], - /* 2 */ [7u8, 0u8, 0u8, 8u8, 0u8, 0u8, 0u8, 0u8, 0u8], - /* 3 */ [0u8, 0u8, 0u8, 5u8, 0u8, 0u8, 0u8, 0u8, 0u8], - /* 4 */ [0u8, 5u8, 0u8, 0u8, 0u8, 3u8, 6u8, 0u8, 0u8], - /* 5 */ [6u8, 8u8, 0u8, 0u8, 0u8, 0u8, 0u8, 9u8, 0u8], - /* 6 */ [0u8, 9u8, 5u8, 0u8, 0u8, 6u8, 0u8, 7u8, 0u8], - /* 7 */ [0u8, 0u8, 0u8, 0u8, 4u8, 0u8, 0u8, 6u8, 0u8], - /* 8 */ [4u8, 0u8, 0u8, 0u8, 0u8, 7u8, 2u8, 0u8, 3u8] + /* 0 */ [0, 4, 0, 6, 0, 0, 0, 3, 2], + /* 1 */ [0, 0, 8, 0, 2, 0, 0, 0, 0], + /* 2 */ [7, 0, 0, 8, 0, 0, 0, 0, 0], + /* 3 */ [0, 0, 0, 5, 0, 0, 0, 0, 0], + /* 4 */ [0, 5, 0, 0, 0, 3, 6, 0, 0], + /* 5 */ [6, 8, 0, 0, 0, 0, 0, 9, 0], + /* 6 */ [0, 9, 5, 0, 0, 6, 0, 7, 0], + /* 7 */ [0, 0, 0, 0, 4, 0, 0, 6, 0], + /* 8 */ [4, 0, 0, 0, 0, 7, 2, 0, 3] ]; #[cfg(test)] static DEFAULT_SOLUTION: [[u8;9];9] = [ /* 0 1 2 3 4 5 6 7 8 */ - /* 0 */ [1u8, 4u8, 9u8, 6u8, 7u8, 5u8, 8u8, 3u8, 2u8], - /* 1 */ [5u8, 3u8, 8u8, 1u8, 2u8, 9u8, 7u8, 4u8, 6u8], - /* 2 */ [7u8, 2u8, 6u8, 8u8, 3u8, 4u8, 1u8, 5u8, 9u8], - /* 3 */ [9u8, 1u8, 4u8, 5u8, 6u8, 8u8, 3u8, 2u8, 7u8], - /* 4 */ [2u8, 5u8, 7u8, 4u8, 9u8, 3u8, 6u8, 1u8, 8u8], - /* 5 */ [6u8, 8u8, 3u8, 7u8, 1u8, 2u8, 5u8, 9u8, 4u8], - /* 6 */ [3u8, 9u8, 5u8, 2u8, 8u8, 6u8, 4u8, 7u8, 1u8], - /* 7 */ [8u8, 7u8, 2u8, 3u8, 4u8, 1u8, 9u8, 6u8, 5u8], - /* 8 */ [4u8, 6u8, 1u8, 9u8, 5u8, 7u8, 2u8, 8u8, 3u8] + /* 0 */ [1, 4, 9, 6, 7, 5, 8, 3, 2], + /* 1 */ [5, 3, 8, 1, 2, 9, 7, 4, 6], + /* 2 */ [7, 2, 6, 8, 3, 4, 1, 5, 9], + /* 3 */ [9, 1, 4, 5, 6, 8, 3, 2, 7], + /* 4 */ [2, 5, 7, 4, 9, 3, 6, 1, 8], + /* 5 */ [6, 8, 3, 7, 1, 2, 5, 9, 4], + /* 6 */ [3, 9, 5, 2, 8, 6, 4, 7, 1], + /* 7 */ [8, 7, 2, 3, 4, 1, 9, 6, 5], + /* 8 */ [4, 6, 1, 9, 5, 7, 2, 8, 3] ]; #[test] fn colors_new_works() { - assert_eq!(*Colors::new(1), 1022u16); - assert_eq!(*Colors::new(2), 1020u16); - assert_eq!(*Colors::new(3), 1016u16); - assert_eq!(*Colors::new(4), 1008u16); - assert_eq!(*Colors::new(5), 992u16); - assert_eq!(*Colors::new(6), 960u16); - assert_eq!(*Colors::new(7), 896u16); - assert_eq!(*Colors::new(8), 768u16); - assert_eq!(*Colors::new(9), 512u16); + assert_eq!(*Colors::new(1), 1022); + assert_eq!(*Colors::new(2), 1020); + assert_eq!(*Colors::new(3), 1016); + assert_eq!(*Colors::new(4), 1008); + assert_eq!(*Colors::new(5), 992); + assert_eq!(*Colors::new(6), 960); + assert_eq!(*Colors::new(7), 896); + assert_eq!(*Colors::new(8), 768); + assert_eq!(*Colors::new(9), 512); } #[test] fn colors_next_works() { - assert_eq!(Colors(0).next(), 0u8); - assert_eq!(Colors(2).next(), 1u8); - assert_eq!(Colors(4).next(), 2u8); - assert_eq!(Colors(8).next(), 3u8); - assert_eq!(Colors(16).next(), 4u8); - assert_eq!(Colors(32).next(), 5u8); - assert_eq!(Colors(64).next(), 6u8); - assert_eq!(Colors(128).next(), 7u8); - assert_eq!(Colors(256).next(), 8u8); - assert_eq!(Colors(512).next(), 9u8); - assert_eq!(Colors(1024).next(), 0u8); + assert_eq!(Colors(0).next(), 0); + assert_eq!(Colors(2).next(), 1); + assert_eq!(Colors(4).next(), 2); + assert_eq!(Colors(8).next(), 3); + assert_eq!(Colors(16).next(), 4); + assert_eq!(Colors(32).next(), 5); + assert_eq!(Colors(64).next(), 6); + assert_eq!(Colors(128).next(), 7); + assert_eq!(Colors(256).next(), 8); + assert_eq!(Colors(512).next(), 9); + assert_eq!(Colors(1024).next(), 0); } #[test] @@ -253,7 +253,7 @@ fn colors_remove_works() { colors.remove(1); // THEN - assert_eq!(colors.next(), 2u8); + assert_eq!(colors.next(), 2); } #[test] diff --git a/src/test/compile-fail-fulldeps/gated-quote.rs b/src/test/compile-fail-fulldeps/gated-quote.rs new file mode 100644 index 00000000000..6a5cd88a591 --- /dev/null +++ b/src/test/compile-fail-fulldeps/gated-quote.rs @@ -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-fulldeps/issue-18986.rs b/src/test/compile-fail-fulldeps/issue-18986.rs index 9b696e05c50..06fc3db58c1 100644 --- a/src/test/compile-fail-fulldeps/issue-18986.rs +++ b/src/test/compile-fail-fulldeps/issue-18986.rs @@ -15,6 +15,6 @@ pub use use_from_trait_xc::Trait; fn main() { match () { - Trait { x: 42_usize } => () //~ ERROR use of trait `Trait` in a struct pattern + Trait { x: 42 } => () //~ ERROR use of trait `Trait` in a struct pattern } } diff --git a/src/test/compile-fail/array-not-vector.rs b/src/test/compile-fail/array-not-vector.rs index 7111c00d124..6c9b8f81b2f 100644 --- a/src/test/compile-fail/array-not-vector.rs +++ b/src/test/compile-fail/array-not-vector.rs @@ -9,14 +9,14 @@ // except according to those terms. fn main() { - let _x: i32 = [1i32, 2, 3]; + let _x: i32 = [1, 2, 3]; //~^ ERROR mismatched types //~| expected `i32` - //~| found `[i32; 3]` + //~| found `[_; 3]` //~| expected i32 //~| found array of 3 elements - let x: &[i32] = &[1i32, 2, 3]; + let x: &[i32] = &[1, 2, 3]; let _y: &i32 = x; //~^ ERROR mismatched types //~| expected `&i32` diff --git a/src/test/compile-fail/asm-in-bad-modifier.rs b/src/test/compile-fail/asm-in-bad-modifier.rs index 01481af817b..3cb608a9c5e 100644 --- a/src/test/compile-fail/asm-in-bad-modifier.rs +++ b/src/test/compile-fail/asm-in-bad-modifier.rs @@ -20,8 +20,8 @@ pub fn main() { let x: isize; let y: isize; unsafe { - asm!("mov $1, $0" : "=r"(x) : "=r"(5_usize)); //~ ERROR operand constraint contains '=' - asm!("mov $1, $0" : "=r"(y) : "+r"(5_usize)); //~ ERROR operand constraint contains '+' + asm!("mov $1, $0" : "=r"(x) : "=r"(5)); //~ ERROR operand constraint contains '=' + asm!("mov $1, $0" : "=r"(y) : "+r"(5)); //~ ERROR operand constraint contains '+' } foo(x); foo(y); diff --git a/src/test/compile-fail/asm-out-assign-imm.rs b/src/test/compile-fail/asm-out-assign-imm.rs index ff56fb14f7d..8c8451623d5 100644 --- a/src/test/compile-fail/asm-out-assign-imm.rs +++ b/src/test/compile-fail/asm-out-assign-imm.rs @@ -21,7 +21,7 @@ pub fn main() { x = 1; //~ NOTE prior assignment occurs here foo(x); unsafe { - asm!("mov $1, $0" : "=r"(x) : "r"(5_usize)); + asm!("mov $1, $0" : "=r"(x) : "r"(5)); //~^ ERROR re-assignment of immutable variable `x` } foo(x); diff --git a/src/test/compile-fail/asm-out-no-modifier.rs b/src/test/compile-fail/asm-out-no-modifier.rs index 17c19c77ab9..9cf43bebe65 100644 --- a/src/test/compile-fail/asm-out-no-modifier.rs +++ b/src/test/compile-fail/asm-out-no-modifier.rs @@ -19,7 +19,7 @@ fn foo(x: isize) { println!("{}", x); } pub fn main() { let x: isize; unsafe { - asm!("mov $1, $0" : "r"(x) : "r"(5_usize)); //~ ERROR output operand constraint lacks '=' + asm!("mov $1, $0" : "r"(x) : "r"(5)); //~ ERROR output operand constraint lacks '=' } foo(x); } diff --git a/src/test/compile-fail/assign-to-method.rs b/src/test/compile-fail/assign-to-method.rs index d32ea327d0a..4518ce36b6d 100644 --- a/src/test/compile-fail/assign-to-method.rs +++ b/src/test/compile-fail/assign-to-method.rs @@ -15,7 +15,7 @@ struct cat { } impl cat { - pub fn speak(&self) { self.meows += 1_usize; } + pub fn speak(&self) { self.meows += 1; } } fn cat(in_x : usize, in_y : isize) -> cat { @@ -26,6 +26,6 @@ fn cat(in_x : usize, in_y : isize) -> cat { } fn main() { - let nyan : cat = cat(52_usize, 99); + let nyan : cat = cat(52, 99); nyan.speak = || println!("meow"); //~ ERROR attempted to take value of method } diff --git a/src/test/compile-fail/bad-bang-ann-3.rs b/src/test/compile-fail/bad-bang-ann-3.rs index 58a8314af21..de315a41361 100644 --- a/src/test/compile-fail/bad-bang-ann-3.rs +++ b/src/test/compile-fail/bad-bang-ann-3.rs @@ -11,7 +11,7 @@ // Tests that a function with a ! annotation always actually fails fn bad_bang(i: usize) -> ! { - return 7_usize; //~ ERROR `return` in a function declared as diverging [E0166] + return 7; //~ ERROR `return` in a function declared as diverging [E0166] } fn main() { bad_bang(5); } diff --git a/src/test/compile-fail/bad-bang-ann.rs b/src/test/compile-fail/bad-bang-ann.rs index 03c24c2fa3d..f0ecf31fd10 100644 --- a/src/test/compile-fail/bad-bang-ann.rs +++ b/src/test/compile-fail/bad-bang-ann.rs @@ -11,7 +11,7 @@ // Tests that a function with a ! annotation always actually fails fn bad_bang(i: usize) -> ! { //~ ERROR computation may converge in a function marked as diverging - if i < 0_usize { } else { panic!(); } + if i < 0 { } else { panic!(); } } fn main() { bad_bang(5); } diff --git a/src/test/compile-fail/bad-const-type.rs b/src/test/compile-fail/bad-const-type.rs index 7e3c356b870..a9e5c957b89 100644 --- a/src/test/compile-fail/bad-const-type.rs +++ b/src/test/compile-fail/bad-const-type.rs @@ -8,10 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -static i: String = 10i32; +static i: String = 10; //~^ ERROR mismatched types //~| expected `collections::string::String` -//~| found `i32` +//~| found `_` //~| expected struct `collections::string::String` -//~| found i32 +//~| found integral variable fn main() { println!("{}", i); } diff --git a/src/test/compile-fail/bad-method-typaram-kind.rs b/src/test/compile-fail/bad-method-typaram-kind.rs index a97cf5d41e8..2129d4fbd50 100644 --- a/src/test/compile-fail/bad-method-typaram-kind.rs +++ b/src/test/compile-fail/bad-method-typaram-kind.rs @@ -9,7 +9,7 @@ // except according to those terms. fn foo<T:'static>() { - 1_usize.bar::<T>(); //~ ERROR `core::marker::Send` is not implemented + 1.bar::<T>(); //~ ERROR `core::marker::Send` is not implemented } trait bar { diff --git a/src/test/compile-fail/binop-logic-int.rs b/src/test/compile-fail/binop-logic-int.rs index 2217cf5e4da..d5dd9e00902 100644 --- a/src/test/compile-fail/binop-logic-int.rs +++ b/src/test/compile-fail/binop-logic-int.rs @@ -8,6 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// error-pattern:`&&` cannot be applied to type `i32` +// error-pattern:`&&` cannot be applied to type `_` -fn main() { let x = 1i32 && 2i32; } +fn main() { let x = 1 && 2; } diff --git a/src/test/compile-fail/borrow-immutable-upvar-mutation.rs b/src/test/compile-fail/borrow-immutable-upvar-mutation.rs index a82aa12dc80..00f51973a41 100644 --- a/src/test/compile-fail/borrow-immutable-upvar-mutation.rs +++ b/src/test/compile-fail/borrow-immutable-upvar-mutation.rs @@ -21,25 +21,25 @@ fn to_fn_mut<A,F:FnMut<A>>(f: F) -> F { f } fn main() { // By-ref captures { - let mut x = 0_usize; + let mut x = 0; let _f = to_fn(|| x = 42); //~ ERROR cannot assign - let mut y = 0_usize; + let mut y = 0; let _g = to_fn(|| set(&mut y)); //~ ERROR cannot borrow - let mut z = 0_usize; + let mut z = 0; let _h = to_fn_mut(|| { set(&mut z); to_fn(|| z = 42); }); //~ ERROR cannot assign } // By-value captures { - let mut x = 0_usize; + let mut x = 0; let _f = to_fn(move || x = 42); //~ ERROR cannot assign - let mut y = 0_usize; + let mut y = 0; let _g = to_fn(move || set(&mut y)); //~ ERROR cannot borrow - let mut z = 0_usize; + let mut z = 0; let _h = to_fn_mut(move || { set(&mut z); to_fn(move || z = 42); }); //~ ERROR cannot assign } } diff --git a/src/test/compile-fail/borrowck-move-error-with-note.rs b/src/test/compile-fail/borrowck-move-error-with-note.rs index 2d82c8be519..e4b9fb26711 100644 --- a/src/test/compile-fail/borrowck-move-error-with-note.rs +++ b/src/test/compile-fail/borrowck-move-error-with-note.rs @@ -17,7 +17,7 @@ enum Foo { } fn blah() { - let f = &Foo::Foo1(box 1u32, box 2u32); + let f = &Foo::Foo1(box 1, box 2); match *f { //~ ERROR cannot move out of Foo::Foo1(num1, //~ NOTE attempting to move value to here num2) => (), //~ NOTE and here diff --git a/src/test/compile-fail/borrowck-report-with-custom-diagnostic.rs b/src/test/compile-fail/borrowck-report-with-custom-diagnostic.rs index 21637370724..61bf2c11a1f 100644 --- a/src/test/compile-fail/borrowck-report-with-custom-diagnostic.rs +++ b/src/test/compile-fail/borrowck-report-with-custom-diagnostic.rs @@ -11,7 +11,7 @@ #![allow(dead_code)] fn main() { // Original borrow ends at end of function - let mut x = 1_usize; + let mut x = 1; let y = &mut x; let z = &x; //~ ERROR cannot borrow } @@ -21,7 +21,7 @@ fn foo() { match true { true => { // Original borrow ends at end of match arm - let mut x = 1_usize; + let mut x = 1; let y = &x; let z = &mut x; //~ ERROR cannot borrow } @@ -33,7 +33,7 @@ fn foo() { fn bar() { // Original borrow ends at end of closure || { - let mut x = 1_usize; + let mut x = 1; let y = &mut x; let z = &mut x; //~ ERROR cannot borrow }; diff --git a/src/test/run-pass/lint-cstack.rs b/src/test/compile-fail/cfg-attr-unknown-attribute-macro-expansion.rs index f180ffcd4e8..afcb896b43c 100644 --- a/src/test/run-pass/lint-cstack.rs +++ b/src/test/compile-fail/cfg-attr-unknown-attribute-macro-expansion.rs @@ -1,4 +1,4 @@ -// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// 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. // @@ -8,19 +8,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -extern crate libc; - -extern { - fn rust_get_test_int() -> libc::intptr_t; -} - -trait A { - fn foo(&self) { - unsafe { - rust_get_test_int(); - } +macro_rules! foo { + () => { + #[cfg_attr(all(), unknown)] //~ ERROR `unknown` is currently unknown + fn foo() {} } } -pub fn main() { -} +foo!(); + +fn main() {} diff --git a/src/test/compile-fail/class-method-missing.rs b/src/test/compile-fail/class-method-missing.rs index ada45e8c1fc..46b100a4d39 100644 --- a/src/test/compile-fail/class-method-missing.rs +++ b/src/test/compile-fail/class-method-missing.rs @@ -27,5 +27,5 @@ fn cat(in_x : usize) -> cat { } fn main() { - let nyan = cat(0_usize); + let nyan = cat(0); } diff --git a/src/test/compile-fail/class-missing-self.rs b/src/test/compile-fail/class-missing-self.rs index f25b2e65388..ab76af1cbe6 100644 --- a/src/test/compile-fail/class-missing-self.rs +++ b/src/test/compile-fail/class-missing-self.rs @@ -16,7 +16,7 @@ impl cat { fn sleep(&self) { loop{} } fn meow(&self) { println!("Meow"); - meows += 1_usize; //~ ERROR unresolved name + meows += 1; //~ ERROR unresolved name sleep(); //~ ERROR unresolved name } diff --git a/src/test/compile-fail/coercion-slice.rs b/src/test/compile-fail/coercion-slice.rs index aac180f9ad7..bb4d1693af7 100644 --- a/src/test/compile-fail/coercion-slice.rs +++ b/src/test/compile-fail/coercion-slice.rs @@ -11,10 +11,10 @@ // Tests that we forbid coercion from `[T; n]` to `&[T]` fn main() { - let _: &[i32] = [0i32]; + let _: &[i32] = [0]; //~^ ERROR mismatched types //~| expected `&[i32]` - //~| found `[i32; 1]` + //~| found `[_; 1]` //~| expected &-ptr //~| found array of 1 elements } diff --git a/src/test/compile-fail/coherence-impls-copy.rs b/src/test/compile-fail/coherence-impls-copy.rs new file mode 100644 index 00000000000..3034be177ca --- /dev/null +++ b/src/test/compile-fail/coherence-impls-copy.rs @@ -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-builtin.rs b/src/test/compile-fail/coherence-impls-send.rs index 3e132dcb11f..b05c1ff0f0b 100644 --- a/src/test/compile-fail/coherence-impls-builtin.rs +++ b/src/test/compile-fail/coherence-impls-send.rs @@ -10,7 +10,7 @@ #![feature(optin_builtin_traits)] -use std::marker::Send; +use std::marker::Copy; enum TestE { A @@ -24,20 +24,17 @@ 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 +//~^ ERROR E0321 unsafe impl Send for &'static NotSync {} -//~^ ERROR builtin traits can only be implemented on structs or enums +//~^ ERROR E0321 unsafe impl Send for [MyType] {} -//~^ ERROR builtin traits can only be implemented on structs or enums +//~^ ERROR E0321 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>() {} +//~^ ERROR E0321 +//~| ERROR conflicting implementations fn main() { - is_send::<(MyType, TestE)>(); } diff --git a/src/test/compile-fail/coherence-impls-sized.rs b/src/test/compile-fail/coherence-impls-sized.rs new file mode 100644 index 00000000000..a9a3ebaffb7 --- /dev/null +++ b/src/test/compile-fail/coherence-impls-sized.rs @@ -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() { +} diff --git a/src/test/compile-fail/coherence-orphan.rs b/src/test/compile-fail/coherence-orphan.rs index d7cd68e73c3..97dffec2dd9 100644 --- a/src/test/compile-fail/coherence-orphan.rs +++ b/src/test/compile-fail/coherence-orphan.rs @@ -19,13 +19,15 @@ use lib::TheTrait; 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/const-block-non-item-statement.rs b/src/test/compile-fail/const-block-non-item-statement.rs index fa63b16afa6..5ccfb1ddec7 100644 --- a/src/test/compile-fail/const-block-non-item-statement.rs +++ b/src/test/compile-fail/const-block-non-item-statement.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -const A: usize = { 1_usize; 2 }; +const A: usize = { 1; 2 }; //~^ ERROR: blocks in constants are limited to items and tail expressions const B: usize = { { } 2 }; @@ -19,7 +19,7 @@ macro_rules! foo { } const C: usize = { foo!(); 2 }; -const D: usize = { let x = 4_usize; 2 }; +const D: usize = { let x = 4; 2 }; //~^ ERROR: blocks in constants are limited to items and tail expressions pub fn main() { diff --git a/src/test/compile-fail/cycle-projection-based-on-where-clause.rs b/src/test/compile-fail/cycle-projection-based-on-where-clause.rs index abcbf567d44..5ca0700ce6e 100644 --- a/src/test/compile-fail/cycle-projection-based-on-where-clause.rs +++ b/src/test/compile-fail/cycle-projection-based-on-where-clause.rs @@ -25,7 +25,7 @@ trait Trait { type Item; } struct A<T> where T : Trait, T : Add<T::Item> - //~^ ERROR illegal recursive type + //~^ ERROR unsupported cyclic reference between types/traits detected { data: T } diff --git a/src/test/compile-fail/cycle-trait-default-type-trait.rs b/src/test/compile-fail/cycle-trait-default-type-trait.rs new file mode 100644 index 00000000000..e6caeb34a8c --- /dev/null +++ b/src/test/compile-fail/cycle-trait-default-type-trait.rs @@ -0,0 +1,18 @@ +// 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 a cycle where a type parameter on a trait has a default that +// again references the trait. + +trait Foo<X = Box<Foo>> { + //~^ ERROR unsupported cyclic reference +} + +fn main() { } diff --git a/src/test/compile-fail/cycle-trait-supertrait-indirect.rs b/src/test/compile-fail/cycle-trait-supertrait-indirect.rs index 6ebd9a1bcb6..c9bfde3f4ed 100644 --- a/src/test/compile-fail/cycle-trait-supertrait-indirect.rs +++ b/src/test/compile-fail/cycle-trait-supertrait-indirect.rs @@ -12,9 +12,12 @@ // a direct participant in the cycle. trait A: B { + //~^ ERROR unsupported cyclic reference } -trait B: C { } +trait B: C { + //~^ ERROR unsupported cyclic reference +} trait C: B { } //~^ ERROR unsupported cyclic reference diff --git a/src/test/compile-fail/deprecated-phase.rs b/src/test/compile-fail/deprecated-phase.rs index 1401494d987..22fc4a94cd2 100644 --- a/src/test/compile-fail/deprecated-phase.rs +++ b/src/test/compile-fail/deprecated-phase.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![feature(custom_attribute)] + #[phase(blah)] //~^ ERROR #[phase] is deprecated extern crate foo; diff --git a/src/test/compile-fail/deriving-bounds.rs b/src/test/compile-fail/deriving-bounds.rs index c0bcbb284a1..72d06274de4 100644 --- a/src/test/compile-fail/deriving-bounds.rs +++ b/src/test/compile-fail/deriving-bounds.rs @@ -8,12 +8,12 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[derive(Copy(Bad))] -//~^ ERROR unexpected value in deriving, expected a trait +#[derive(Send)] +//~^ ERROR this unsafe trait should be implemented explicitly struct Test; #[derive(Sync)] -//~^ ERROR Sync is an unsafe trait and it should be implemented explicitly +//~^ ERROR this unsafe trait should be implemented explicitly struct Test1; pub fn main() {} diff --git a/src/test/compile-fail/deriving-meta-unknown-trait.rs b/src/test/compile-fail/deriving-meta-unknown-trait.rs index 6b85656bdd9..e2234994693 100644 --- a/src/test/compile-fail/deriving-meta-unknown-trait.rs +++ b/src/test/compile-fail/deriving-meta-unknown-trait.rs @@ -8,7 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[derive(Eqr)] //~ ERROR unknown `derive` trait: `Eqr` +#[derive(Eqr)] +//~^ ERROR `#[derive]` for custom traits is not stable enough for use and is subject to change struct Foo; pub fn main() {} diff --git a/src/test/compile-fail/deriving-non-type.rs b/src/test/compile-fail/deriving-non-type.rs index 966e28a789c..5b215f3ccd9 100644 --- a/src/test/compile-fail/deriving-non-type.rs +++ b/src/test/compile-fail/deriving-non-type.rs @@ -22,10 +22,10 @@ impl S { } impl T for S { } #[derive(PartialEq)] //~ ERROR: `derive` may only be applied to structs and enums -static s: usize = 0_usize; +static s: usize = 0; #[derive(PartialEq)] //~ ERROR: `derive` may only be applied to structs and enums -const c: usize = 0_usize; +const c: usize = 0; #[derive(PartialEq)] //~ ERROR: `derive` may only be applied to structs and enums mod m { } diff --git a/src/test/compile-fail/destructor-restrictions.rs b/src/test/compile-fail/destructor-restrictions.rs index 0836cd1695d..22f615cafd7 100644 --- a/src/test/compile-fail/destructor-restrictions.rs +++ b/src/test/compile-fail/destructor-restrictions.rs @@ -14,8 +14,8 @@ use std::cell::RefCell; fn main() { let b = { - let a = Box::new(RefCell::new(4i8)); - *a.borrow() + 1i8 //~ ERROR `*a` does not live long enough + let a = Box::new(RefCell::new(4)); + *a.borrow() + 1 //~ ERROR `*a` does not live long enough }; println!("{}", b); } diff --git a/src/test/compile-fail/empty-extern-arg.rs b/src/test/compile-fail/empty-extern-arg.rs index 9b7df81a5dc..8791481d9e7 100644 --- a/src/test/compile-fail/empty-extern-arg.rs +++ b/src/test/compile-fail/empty-extern-arg.rs @@ -9,6 +9,6 @@ // except according to those terms. // compile-flags: --extern std= -// error-pattern: is not a file +// error-pattern: can't find crate for `std` fn main() {} diff --git a/src/test/compile-fail/feature-gate-allow-internal-unstable-nested-macro.rs b/src/test/compile-fail/feature-gate-allow-internal-unstable-nested-macro.rs new file mode 100644 index 00000000000..c9251c925cc --- /dev/null +++ b/src/test/compile-fail/feature-gate-allow-internal-unstable-nested-macro.rs @@ -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. + +macro_rules! bar { + () => { + // more layers don't help: + #[allow_internal_unstable] + macro_rules! baz { //~ ERROR allow_internal_unstable side-steps + () => {} + } + } +} + +bar!(); + +fn main() {} diff --git a/src/test/compile-fail/feature-gate-allow-internal-unstable.rs b/src/test/compile-fail/feature-gate-allow-internal-unstable.rs new file mode 100644 index 00000000000..8a2d8dddac0 --- /dev/null +++ b/src/test/compile-fail/feature-gate-allow-internal-unstable.rs @@ -0,0 +1,16 @@ +// 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. + +#[allow_internal_unstable] //~ ERROR allow_internal_unstable side-steps +macro_rules! foo { + () => {} +} + +fn main() {} diff --git a/src/test/compile-fail/feature-gate-intrinsics-and-lang-items.rs b/src/test/compile-fail/feature-gate-intrinsics.rs index 986d52b1787..a4c09b21c90 100644 --- a/src/test/compile-fail/feature-gate-intrinsics-and-lang-items.rs +++ b/src/test/compile-fail/feature-gate-intrinsics.rs @@ -8,9 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[lang="foo"] //~ ERROR language items are subject to change -trait Foo {} - extern "rust-intrinsic" { //~ ERROR intrinsics are subject to change fn bar(); } @@ -20,4 +17,3 @@ extern "rust-intrinsic" fn baz() { //~ ERROR intrinsics are subject to change fn main() { } - diff --git a/src/test/compile-fail/duplicate-trait-bounds.rs b/src/test/compile-fail/feature-gate-lang-items.rs index d9aa9d9dfcc..0435ff4c332 100644 --- a/src/test/compile-fail/duplicate-trait-bounds.rs +++ b/src/test/compile-fail/feature-gate-lang-items.rs @@ -8,8 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#[lang="foo"] //~ ERROR language items are subject to change trait Foo {} -fn foo<T: Foo + Foo>() {} //~ ERROR `Foo` already appears in the list of bounds - -fn main() {} +fn main() { +} diff --git a/src/test/compile-fail/feature-gated-feature-in-macro-arg.rs b/src/test/compile-fail/feature-gated-feature-in-macro-arg.rs index 1e15e67876e..54bdaf011c8 100644 --- a/src/test/compile-fail/feature-gated-feature-in-macro-arg.rs +++ b/src/test/compile-fail/feature-gated-feature-in-macro-arg.rs @@ -21,7 +21,7 @@ // test. Not ideal, but oh well :( fn main() { - let a = &[1i32, 2, 3]; + let a = &[1, 2, 3]; println!("{}", { extern "rust-intrinsic" { //~ ERROR intrinsics are subject to change fn atomic_fence(); diff --git a/src/test/compile-fail/gated-link-args.rs b/src/test/compile-fail/gated-link-args.rs new file mode 100644 index 00000000000..c8845ced2fc --- /dev/null +++ b/src/test/compile-fail/gated-link-args.rs @@ -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 index 00000000000..716ea9f8dba --- /dev/null +++ b/src/test/compile-fail/gated-link-llvm-intrinsics.rs @@ -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(){ +} diff --git a/src/test/compile-fail/gated-plugin_registrar.rs b/src/test/compile-fail/gated-plugin_registrar.rs index f6e11ffd9e5..d716c53e1d1 100644 --- a/src/test/compile-fail/gated-plugin_registrar.rs +++ b/src/test/compile-fail/gated-plugin_registrar.rs @@ -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 index 00000000000..f355c6562c8 --- /dev/null +++ b/src/test/compile-fail/gated-thread-local.rs @@ -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 index 00000000000..6024fef9fb8 --- /dev/null +++ b/src/test/compile-fail/gated-unsafe-destructor.rs @@ -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/import-glob-circular.rs b/src/test/compile-fail/import-glob-circular.rs index f38172db444..67834a99969 100644 --- a/src/test/compile-fail/import-glob-circular.rs +++ b/src/test/compile-fail/import-glob-circular.rs @@ -13,13 +13,13 @@ mod circ1 { pub use circ2::f2; pub fn f1() { println!("f1"); } - pub fn common() -> usize { return 0_usize; } + pub fn common() -> usize { return 0; } } mod circ2 { pub use circ1::f1; pub fn f2() { println!("f2"); } - pub fn common() -> usize { return 1_usize; } + pub fn common() -> usize { return 1; } } mod test { diff --git a/src/test/compile-fail/index-bot.rs b/src/test/compile-fail/index-bot.rs index b28f2a746fd..70c362303ae 100644 --- a/src/test/compile-fail/index-bot.rs +++ b/src/test/compile-fail/index-bot.rs @@ -9,5 +9,5 @@ // except according to those terms. fn main() { - (return)[0_usize]; //~ ERROR the type of this value must be known in this context + (return)[0]; //~ ERROR the type of this value must be known in this context } diff --git a/src/test/compile-fail/infinite-instantiation.rs b/src/test/compile-fail/infinite-instantiation.rs index d39efa3c2ab..559e0e9a292 100644 --- a/src/test/compile-fail/infinite-instantiation.rs +++ b/src/test/compile-fail/infinite-instantiation.rs @@ -32,13 +32,13 @@ impl<T:Clone> ToOpt for Option<T> { } fn function<T:ToOpt + Clone>(counter: usize, t: T) { - if counter > 0_usize { - function(counter - 1_usize, t.to_option()); + if counter > 0 { + function(counter - 1, t.to_option()); // FIXME(#4287) Error message should be here. It should be // a type error to instantiate `test` at a type other than T. } } fn main() { - function(22_usize, 22_usize); + function(22, 22); } diff --git a/src/test/compile-fail/infinite-vec-type-recursion.rs b/src/test/compile-fail/infinite-vec-type-recursion.rs index 5bcba350b2e..e5120840f76 100644 --- a/src/test/compile-fail/infinite-vec-type-recursion.rs +++ b/src/test/compile-fail/infinite-vec-type-recursion.rs @@ -8,9 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// error-pattern: illegal recursive type - - type x = Vec<x>; +//~^ ERROR unsupported cyclic reference fn main() { let b: x = Vec::new(); } diff --git a/src/test/compile-fail/internal-unstable-noallow.rs b/src/test/compile-fail/internal-unstable-noallow.rs new file mode 100644 index 00000000000..4e296198be8 --- /dev/null +++ b/src/test/compile-fail/internal-unstable-noallow.rs @@ -0,0 +1,30 @@ +// 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. + +// this has to be separate to internal-unstable.rs because these tests +// have error messages pointing deep into the internals of the +// cross-crate macros, and hence need to use error-pattern instead of +// the // ~ form. + +// aux-build:internal_unstable.rs +// error-pattern:use of unstable library feature 'function' +// error-pattern:use of unstable library feature 'struct_field' +// error-pattern:compilation successful +#![feature(rustc_attrs)] + +#[macro_use] +extern crate internal_unstable; + +#[rustc_error] +fn main() { + call_unstable_noallow!(); + + construct_unstable_noallow!(0); +} diff --git a/src/test/compile-fail/internal-unstable-thread-local.rs b/src/test/compile-fail/internal-unstable-thread-local.rs new file mode 100644 index 00000000000..ff158497546 --- /dev/null +++ b/src/test/compile-fail/internal-unstable-thread-local.rs @@ -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. + +// aux-build:internal_unstable.rs + +#![feature(rustc_attrs)] +#![allow(dead_code)] + +extern crate internal_unstable; + + +thread_local!(static FOO: () = ()); +thread_local!(static BAR: () = internal_unstable::unstable()); //~ WARN use of unstable + +#[rustc_error] +fn main() {} //~ ERROR diff --git a/src/test/compile-fail/internal-unstable.rs b/src/test/compile-fail/internal-unstable.rs new file mode 100755 index 00000000000..8674e8ab5b2 --- /dev/null +++ b/src/test/compile-fail/internal-unstable.rs @@ -0,0 +1,51 @@ +// 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:internal_unstable.rs + +#![feature(rustc_attrs, allow_internal_unstable)] + +#[macro_use] +extern crate internal_unstable; + +macro_rules! foo { + ($e: expr, $f: expr) => {{ + $e; + $f; + internal_unstable::unstable(); //~ WARN use of unstable + }} +} + +#[allow_internal_unstable] +macro_rules! bar { + ($e: expr) => {{ + foo!($e, + internal_unstable::unstable()); + internal_unstable::unstable(); + }} +} + +#[rustc_error] +fn main() { //~ ERROR + // ok, the instability is contained. + call_unstable_allow!(); + construct_unstable_allow!(0); + + // bad. + pass_through_allow!(internal_unstable::unstable()); //~ WARN use of unstable + + pass_through_noallow!(internal_unstable::unstable()); //~ WARN use of unstable + + + + println!("{:?}", internal_unstable::unstable()); //~ WARN use of unstable + + bar!(internal_unstable::unstable()); //~ WARN use of unstable +} diff --git a/src/test/compile-fail/issue-11714.rs b/src/test/compile-fail/issue-11714.rs index d307352517f..998576097a0 100644 --- a/src/test/compile-fail/issue-11714.rs +++ b/src/test/compile-fail/issue-11714.rs @@ -9,7 +9,7 @@ // except according to those terms. fn blah() -> i32 { //~ ERROR not all control paths return a value - 1i32 + 1 ; //~ HELP consider removing this semicolon: } diff --git a/src/test/compile-fail/issue-13058.rs b/src/test/compile-fail/issue-13058.rs index 06f14158b91..50c4ac94d90 100644 --- a/src/test/compile-fail/issue-13058.rs +++ b/src/test/compile-fail/issue-13058.rs @@ -24,7 +24,7 @@ fn check<'r, I: Iterator<Item=usize>, T: Itble<'r, usize, I>>(cont: &T) -> bool { let cont_iter = cont.iter(); //~^ ERROR cannot infer an appropriate lifetime for autoref due to conflicting requirements - let result = cont_iter.fold(Some(0u16), |state, val| { + let result = cont_iter.fold(Some(0), |state, val| { state.map_or(None, |mask| { let bit = 1 << val; if mask & bit == 0 {Some(mask|bit)} else {None} @@ -34,10 +34,10 @@ fn check<'r, I: Iterator<Item=usize>, T: Itble<'r, usize, I>>(cont: &T) -> bool } fn main() { - check((3_usize, 5_usize)); + check((3, 5)); //~^ ERROR mismatched types //~| expected `&_` -//~| found `(usize, usize)` +//~| found `(_, _)` //~| expected &-ptr //~| found tuple } diff --git a/src/test/compile-fail/issue-13466.rs b/src/test/compile-fail/issue-13466.rs index 16128e52d64..a29a83c4306 100644 --- a/src/test/compile-fail/issue-13466.rs +++ b/src/test/compile-fail/issue-13466.rs @@ -14,17 +14,17 @@ pub fn main() { // The expected arm type `Option<T>` has one type parameter, while // the actual arm `Result<T, E>` has two. typeck should not be // tricked into looking up a non-existing second type parameter. - let _x: usize = match Some(1_usize) { + let _x: usize = match Some(1) { Ok(u) => u, //~^ ERROR mismatched types - //~| expected `core::option::Option<usize>` + //~| expected `core::option::Option<_>` //~| found `core::result::Result<_, _>` //~| expected enum `core::option::Option` //~| found enum `core::result::Result` Err(e) => panic!(e) //~^ ERROR mismatched types - //~| expected `core::option::Option<usize>` + //~| expected `core::option::Option<_>` //~| found `core::result::Result<_, _>` //~| expected enum `core::option::Option` //~| found enum `core::result::Result` diff --git a/src/test/compile-fail/issue-14845.rs b/src/test/compile-fail/issue-14845.rs index d7ff6f2fe63..d7bb806999c 100644 --- a/src/test/compile-fail/issue-14845.rs +++ b/src/test/compile-fail/issue-14845.rs @@ -22,11 +22,11 @@ fn main() { //~| expected u8 //~| found array of 1 elements - let local = [0u8]; + let local = [0]; let _v = &local as *mut u8; //~^ ERROR mismatched types //~| expected `*mut u8` - //~| found `&[u8; 1]` + //~| found `&[_; 1]` //~| expected u8, //~| found array of 1 elements } diff --git a/src/test/compile-fail/issue-16747.rs b/src/test/compile-fail/issue-16747.rs index a213234b89b..64334fe4392 100644 --- a/src/test/compile-fail/issue-16747.rs +++ b/src/test/compile-fail/issue-16747.rs @@ -18,11 +18,10 @@ trait Collection { fn len(&self) -> usize; } struct List<'a, T: ListItem<'a>> { //~^ ERROR the parameter type `T` may not live long enough -//~^^ HELP consider adding an explicit lifetime bound -//~^^^ NOTE ...so that the reference type `&'a [T]` does not outlive the data it points at +//~^^ NOTE ...so that the reference type `&'a [T]` does not outlive the data it points at slice: &'a [T] } - +//~^ HELP consider adding an explicit lifetime bound impl<'a, T: ListItem<'a>> Collection for List<'a, T> { fn len(&self) -> usize { 0 diff --git a/src/test/compile-fail/issue-17283.rs b/src/test/compile-fail/issue-17283.rs index 65731379094..a481fec6bf9 100644 --- a/src/test/compile-fail/issue-17283.rs +++ b/src/test/compile-fail/issue-17283.rs @@ -16,7 +16,7 @@ struct Foo { } fn main() { - let x = 1_usize; + let x = 1; let y: Foo; // `x { ... }` should not be interpreted as a struct literal here diff --git a/src/test/compile-fail/issue-17651.rs b/src/test/compile-fail/issue-17651.rs index d6471ca018d..8ebf80a8db0 100644 --- a/src/test/compile-fail/issue-17651.rs +++ b/src/test/compile-fail/issue-17651.rs @@ -13,6 +13,6 @@ fn main() { // FIXME (#22405): Replace `Box::new` with `box` here when/if possible. - (|| Box::new(*[0_usize].as_slice()))(); - //~^ ERROR the trait `core::marker::Sized` is not implemented for the type `[usize]` + (|| Box::new(*[0].as_slice()))(); + //~^ ERROR the trait `core::marker::Sized` is not implemented for the type `[_]` } diff --git a/src/test/compile-fail/issue-17718-patterns.rs b/src/test/compile-fail/issue-17718-patterns.rs index b7f58791bfc..4e63f667d26 100644 --- a/src/test/compile-fail/issue-17718-patterns.rs +++ b/src/test/compile-fail/issue-17718-patterns.rs @@ -13,7 +13,7 @@ static mut A2: usize = 1; const A3: usize = 1; fn main() { - match 1_usize { + match 1 { A1 => {} //~ ERROR: static variables cannot be referenced in a pattern A2 => {} //~ ERROR: static variables cannot be referenced in a pattern A3 => {} diff --git a/src/test/compile-fail/issue-17933.rs b/src/test/compile-fail/issue-17933.rs index bd047408498..657b31fa83c 100644 --- a/src/test/compile-fail/issue-17933.rs +++ b/src/test/compile-fail/issue-17933.rs @@ -8,10 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -pub static X: usize = 1_usize; +pub static X: usize = 1; fn main() { - match 1_usize { + match 1 { self::X => { }, //~^ ERROR static variables cannot be referenced in a pattern, use a `const` instead _ => { }, diff --git a/src/test/compile-fail/issue-18107.rs b/src/test/compile-fail/issue-18107.rs index d5fb22bdebd..60ab616d598 100644 --- a/src/test/compile-fail/issue-18107.rs +++ b/src/test/compile-fail/issue-18107.rs @@ -16,7 +16,7 @@ fn _create_render(_: &()) -> AbstractRenderer //~^ ERROR: the trait `core::marker::Sized` is not implemented { - match 0_usize { + match 0 { _ => unimplemented!() } } diff --git a/src/test/compile-fail/issue-18252.rs b/src/test/compile-fail/issue-18252.rs index 54c51405bd7..e3e56c7f97a 100644 --- a/src/test/compile-fail/issue-18252.rs +++ b/src/test/compile-fail/issue-18252.rs @@ -13,5 +13,5 @@ enum Foo { } fn main() { - let f = Foo::Variant(42_usize); //~ ERROR uses it like a function + let f = Foo::Variant(42); //~ ERROR uses it like a function } diff --git a/src/test/compile-fail/issue-18389.rs b/src/test/compile-fail/issue-18389.rs index 9065a5b9605..271c31bd375 100644 --- a/src/test/compile-fail/issue-18389.rs +++ b/src/test/compile-fail/issue-18389.rs @@ -12,18 +12,17 @@ use std::any::Any; use std::any::TypeId; +use std::marker::MarkerTrait; -pub trait Pt {} -pub trait Rt {} +pub trait Pt : MarkerTrait {} +pub trait Rt : MarkerTrait {} trait Private<P: Pt, R: Rt> { fn call(&self, p: P, r: R); } -pub trait Public: Private< +pub trait Public: Private< //~ ERROR private trait in exported type parameter bound <Self as Public>::P, -//~^ ERROR illegal recursive type; insert an enum or struct in the cycle, if this is desired <Self as Public>::R -//~^ ERROR unsupported cyclic reference between types/traits detected > { type P; type R; diff --git a/src/test/compile-fail/issue-18566.rs b/src/test/compile-fail/issue-18566.rs index dd3844b1a0e..41e82d0cd89 100644 --- a/src/test/compile-fail/issue-18566.rs +++ b/src/test/compile-fail/issue-18566.rs @@ -28,7 +28,7 @@ impl Tr for usize { } fn main() { - let s = &mut 1_usize; + let s = &mut 1; MyPtr(s).poke(s); //~^ ERROR cannot borrow `*s` as mutable more than once at a time diff --git a/src/test/compile-fail/issue-18783.rs b/src/test/compile-fail/issue-18783.rs index f6a3da81857..5eb3c439df2 100644 --- a/src/test/compile-fail/issue-18783.rs +++ b/src/test/compile-fail/issue-18783.rs @@ -13,7 +13,7 @@ use std::cell::RefCell; // FIXME (#22405): Replace `Box::new` with `box` here when/if possible. fn main() { - let mut y = 1_usize; + let mut y = 1; let c = RefCell::new(vec![]); c.push(Box::new(|| y = 0)); c.push(Box::new(|| y = 0)); @@ -21,7 +21,7 @@ fn main() { } fn ufcs() { - let mut y = 1_usize; + let mut y = 1; let c = RefCell::new(vec![]); Push::push(&c, Box::new(|| y = 0)); diff --git a/src/test/compile-fail/issue-18959.rs b/src/test/compile-fail/issue-18959.rs index 8fb543fb967..ebda2481803 100644 --- a/src/test/compile-fail/issue-18959.rs +++ b/src/test/compile-fail/issue-18959.rs @@ -19,7 +19,7 @@ impl Foo for Thing { #[inline(never)] fn foo(b: &Bar) { - b.foo(&0usize) + b.foo(&0) //~^ ERROR the trait `Foo` is not implemented for the type `Bar` } diff --git a/src/test/compile-fail/issue-19991.rs b/src/test/compile-fail/issue-19991.rs index 2d73b98ec1e..6c9b0004f77 100644 --- a/src/test/compile-fail/issue-19991.rs +++ b/src/test/compile-fail/issue-19991.rs @@ -14,9 +14,9 @@ fn main() { if let Some(homura) = Some("madoka") { //~ ERROR missing an else clause //~| expected `()` - //~| found `i32` + //~| found `_` //~| expected () - //~| found i32 - 765i32 + //~| found integral variable + 765 }; } diff --git a/src/test/compile-fail/issue-20801.rs b/src/test/compile-fail/issue-20801.rs index 929c8ec0fd6..fe7807042e5 100644 --- a/src/test/compile-fail/issue-20801.rs +++ b/src/test/compile-fail/issue-20801.rs @@ -25,11 +25,11 @@ fn mut_ref() -> &'static mut T { } fn mut_ptr() -> *mut T { - unsafe { 0u8 as *mut T } + unsafe { 0 as *mut T } } fn const_ptr() -> *const T { - unsafe { 0u8 as *const T } + unsafe { 0 as *const T } } pub fn main() { diff --git a/src/test/compile-fail/issue-2150.rs b/src/test/compile-fail/issue-2150.rs index 505885e6c41..8b109b0a5c0 100644 --- a/src/test/compile-fail/issue-2150.rs +++ b/src/test/compile-fail/issue-2150.rs @@ -15,7 +15,7 @@ fn fail_len(v: Vec<isize> ) -> usize { let mut i = 3; panic!(); - for x in &v { i += 1_usize; } + for x in &v { i += 1; } //~^ ERROR: unreachable statement return i; } diff --git a/src/test/compile-fail/issue-23080-2.rs b/src/test/compile-fail/issue-23080-2.rs new file mode 100644 index 00000000000..ff5ac9de8d9 --- /dev/null +++ b/src/test/compile-fail/issue-23080-2.rs @@ -0,0 +1,29 @@ +// 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. + +// ignore-tidy-linelength + +#![feature(optin_builtin_traits)] + +use std::marker::MarkerTrait; + +unsafe trait Trait: MarkerTrait { +//~^ error: traits with default impls (`e.g. unsafe impl Trait for ..`) must have no methods or associated items + type Output; +} + +unsafe impl Trait for .. {} + +fn call_method<T: Trait>(x: T) {} + +fn main() { + // ICE + call_method(()); +} diff --git a/src/test/compile-fail/issue-23080.rs b/src/test/compile-fail/issue-23080.rs new file mode 100644 index 00000000000..99373a69697 --- /dev/null +++ b/src/test/compile-fail/issue-23080.rs @@ -0,0 +1,31 @@ +// 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. + +// ignore-tidy-linelength + +#![feature(optin_builtin_traits)] + +unsafe trait Trait { +//~^ error: traits with default impls (`e.g. unsafe impl Trait for ..`) must have no methods or associated items + fn method(&self) { + println!("Hello"); + } +} + +unsafe impl Trait for .. {} + +fn call_method<T: Trait>(x: T) { + x.method(); +} + +fn main() { + // ICE + call_method(()); +} diff --git a/src/test/compile-fail/issue-3953.rs b/src/test/compile-fail/issue-3953.rs deleted file mode 100644 index 0f1dd2d7fd6..00000000000 --- a/src/test/compile-fail/issue-3953.rs +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// ignore-tidy-linelength - -use std::cmp::PartialEq; - -trait Hahaha: PartialEq + PartialEq { - //~^ ERROR trait `PartialEq` already appears in the list of bounds -} - -struct Lol(isize); - -impl Hahaha for Lol { } - -impl PartialEq for Lol { - fn eq(&self, other: &Lol) -> bool { **self != **other } - fn ne(&self, other: &Lol) -> bool { **self == **other } -} - -fn main() { - if Lol(2) == Lol(4) { - println!("2 == 4"); - } else { - println!("2 != 4"); - } -} diff --git a/src/test/compile-fail/issue-4517.rs b/src/test/compile-fail/issue-4517.rs index 6d4777be40b..a1804b5a268 100644 --- a/src/test/compile-fail/issue-4517.rs +++ b/src/test/compile-fail/issue-4517.rs @@ -11,7 +11,7 @@ fn bar(int_param: usize) {} fn main() { - let foo: [u8; 4] = [1u8; 4_usize]; + let foo: [u8; 4] = [1; 4]; bar(foo); //~^ ERROR mismatched types //~| expected `usize` diff --git a/src/test/compile-fail/issue-7575.rs b/src/test/compile-fail/issue-7575.rs index b6643f43952..9c019f6ec47 100644 --- a/src/test/compile-fail/issue-7575.rs +++ b/src/test/compile-fail/issue-7575.rs @@ -32,17 +32,17 @@ trait UnusedTrait : MarkerTrait { impl CtxtFn for usize { fn f8(self, i: usize) -> usize { - i * 4_usize + i * 4 } fn f9(i: usize) -> usize { - i * 4_usize + i * 4 } } impl OtherTrait for usize { fn f9(i: usize) -> usize { - i * 8_usize + i * 8 } } diff --git a/src/test/compile-fail/issue-7867.rs b/src/test/compile-fail/issue-7867.rs index 7bb4aac23d6..400806c3a5f 100644 --- a/src/test/compile-fail/issue-7867.rs +++ b/src/test/compile-fail/issue-7867.rs @@ -23,16 +23,16 @@ fn main() { _ => () } - match &Some(42i32) { + match &Some(42) { Some(x) => (), //~^ ERROR mismatched types - //~| expected `&core::option::Option<i32>` + //~| expected `&core::option::Option<_>` //~| found `core::option::Option<_>` //~| expected &-ptr //~| found enum `core::option::Option` None => () //~^ ERROR mismatched types - //~| expected `&core::option::Option<i32>` + //~| expected `&core::option::Option<_>` //~| found `core::option::Option<_>` //~| expected &-ptr //~| found enum `core::option::Option` diff --git a/src/test/compile-fail/kindck-nonsendable-1.rs b/src/test/compile-fail/kindck-nonsendable-1.rs index e6041cddead..c370aa4b8fb 100644 --- a/src/test/compile-fail/kindck-nonsendable-1.rs +++ b/src/test/compile-fail/kindck-nonsendable-1.rs @@ -16,7 +16,7 @@ fn foo(_x: Rc<usize>) {} fn bar<F:FnOnce() + Send>(_: F) { } fn main() { - let x = Rc::new(3_usize); + let x = Rc::new(3); bar(move|| foo(x)); //~^ ERROR `core::marker::Send` is not implemented } diff --git a/src/test/compile-fail/lifetime-inference-give-expl-lifetime-param-2.rs b/src/test/compile-fail/lifetime-inference-give-expl-lifetime-param-2.rs index fac518c7635..0a8e4514b43 100644 --- a/src/test/compile-fail/lifetime-inference-give-expl-lifetime-param-2.rs +++ b/src/test/compile-fail/lifetime-inference-give-expl-lifetime-param-2.rs @@ -24,7 +24,7 @@ impl<'r> Itble<'r, usize, Range<usize>> for (usize, usize) { fn check<'r, I: Iterator<Item=usize>, T: Itble<'r, usize, I>>(cont: &T) -> bool { //~^ HELP: consider using an explicit lifetime parameter as shown: fn check<'r, I: Iterator<Item = usize>, T: Itble<'r, usize, I>>(cont: &'r T) let cont_iter = cont.iter(); //~ ERROR: cannot infer - let result = cont_iter.fold(Some(0u16), |state, val| { + let result = cont_iter.fold(Some(0), |state, val| { state.map_or(None, |mask| { let bit = 1 << val; if mask & bit == 0 {Some(mask|bit)} else {None} diff --git a/src/test/compile-fail/linkage1.rs b/src/test/compile-fail/linkage1.rs index 35f93c13fb5..555cc2b9a7a 100644 --- a/src/test/compile-fail/linkage1.rs +++ b/src/test/compile-fail/linkage1.rs @@ -11,5 +11,4 @@ extern { #[linkage = "extern_weak"] static foo: isize; //~^ ERROR: the `linkage` attribute is experimental and not portable - //~^^ ERROR: the `linkage` attribute is experimental and not portable } diff --git a/src/test/compile-fail/lint-dead-code-4.rs b/src/test/compile-fail/lint-dead-code-4.rs index f304c26efb5..8441fb3ade9 100644 --- a/src/test/compile-fail/lint-dead-code-4.rs +++ b/src/test/compile-fail/lint-dead-code-4.rs @@ -63,6 +63,6 @@ fn field_match_in_let(f: Bar) -> bool { fn main() { field_read(Foo { x: 1, b: false, marker: std::marker::NoCopy }); field_match_in_patterns(XYZ::Z); - field_match_in_let(Bar { x: 42_usize, b: true, _guard: () }); + field_match_in_let(Bar { x: 42, b: true, _guard: () }); let _ = Baz { x: 0 }; } diff --git a/src/test/compile-fail/liveness-return-last-stmt-semi.rs b/src/test/compile-fail/liveness-return-last-stmt-semi.rs index 57252dd58d7..a4eb1630afe 100644 --- a/src/test/compile-fail/liveness-return-last-stmt-semi.rs +++ b/src/test/compile-fail/liveness-return-last-stmt-semi.rs @@ -10,7 +10,7 @@ // // regression test for #8005 -macro_rules! test { () => { fn foo() -> i32 { 1i32; } } } +macro_rules! test { () => { fn foo() -> i32 { 1; } } } //~^ ERROR not all control paths return a value //~^^ HELP consider removing this semicolon diff --git a/src/test/compile-fail/macro-no-implicit-reexport.rs b/src/test/compile-fail/macro-no-implicit-reexport.rs index 13dbab12b77..e8d9f444cef 100644 --- a/src/test/compile-fail/macro-no-implicit-reexport.rs +++ b/src/test/compile-fail/macro-no-implicit-reexport.rs @@ -16,5 +16,5 @@ extern crate macro_non_reexport_2; fn main() { - assert_eq!(reexported!(), 3_usize); //~ ERROR macro undefined + assert_eq!(reexported!(), 3); //~ ERROR macro undefined } diff --git a/src/test/compile-fail/macro-reexport-not-locally-visible.rs b/src/test/compile-fail/macro-reexport-not-locally-visible.rs index dc8f4fadc76..26de51a7cf8 100644 --- a/src/test/compile-fail/macro-reexport-not-locally-visible.rs +++ b/src/test/compile-fail/macro-reexport-not-locally-visible.rs @@ -18,5 +18,5 @@ extern crate macro_reexport_1; fn main() { - assert_eq!(reexported!(), 3_usize); //~ ERROR macro undefined + assert_eq!(reexported!(), 3); //~ ERROR macro undefined } diff --git a/src/test/compile-fail/malformed-derive-entry.rs b/src/test/compile-fail/malformed-derive-entry.rs new file mode 100644 index 00000000000..62dbc21495a --- /dev/null +++ b/src/test/compile-fail/malformed-derive-entry.rs @@ -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. + +#[derive(Copy(Bad))] +//~^ ERROR malformed `derive` entry +struct Test1; + +#[derive(Copy="bad")] +//~^ ERROR malformed `derive` entry +struct Test2; + +#[derive()] +//~^ WARNING empty trait list +struct Test3; + +#[derive] +//~^ WARNING empty trait list +struct Test4; diff --git a/src/test/compile-fail/malformed-plugin-1.rs b/src/test/compile-fail/malformed-plugin-1.rs index 254a797ef1c..214a5e5e3eb 100644 --- a/src/test/compile-fail/malformed-plugin-1.rs +++ b/src/test/compile-fail/malformed-plugin-1.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![feature(plugin)] #![plugin] //~ ERROR malformed plugin attribute fn main() {} diff --git a/src/test/compile-fail/malformed-plugin-2.rs b/src/test/compile-fail/malformed-plugin-2.rs index 884087b7bc5..1b112608bee 100644 --- a/src/test/compile-fail/malformed-plugin-2.rs +++ b/src/test/compile-fail/malformed-plugin-2.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![feature(plugin)] #![plugin="bleh"] //~ ERROR malformed plugin attribute fn main() {} diff --git a/src/test/compile-fail/malformed-plugin-3.rs b/src/test/compile-fail/malformed-plugin-3.rs index 4885bb901df..0c948831de2 100644 --- a/src/test/compile-fail/malformed-plugin-3.rs +++ b/src/test/compile-fail/malformed-plugin-3.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![feature(plugin)] #![plugin(foo="bleh")] //~ ERROR malformed plugin attribute fn main() {} diff --git a/src/test/compile-fail/method-self-arg-1.rs b/src/test/compile-fail/method-self-arg-1.rs index 7b6868af805..57a96bb9a26 100644 --- a/src/test/compile-fail/method-self-arg-1.rs +++ b/src/test/compile-fail/method-self-arg-1.rs @@ -23,9 +23,9 @@ fn main() { //~| found `Foo` //~| expected &-ptr //~| found struct `Foo` - Foo::bar(&42i32); //~ ERROR mismatched types + Foo::bar(&42); //~ ERROR mismatched types //~| expected `&Foo` - //~| found `&i32` + //~| found `&_` //~| expected struct `Foo` - //~| found i32 + //~| found integral variable } diff --git a/src/test/compile-fail/mut-pattern-mismatched.rs b/src/test/compile-fail/mut-pattern-mismatched.rs index 6de69a9adb0..9eb24c81960 100644 --- a/src/test/compile-fail/mut-pattern-mismatched.rs +++ b/src/test/compile-fail/mut-pattern-mismatched.rs @@ -9,21 +9,21 @@ // except according to those terms. fn main() { - let foo = &mut 1i32; + let foo = &mut 1; // (separate lines to ensure the spans are accurate) let &_ //~ ERROR mismatched types - //~| expected `&mut i32` + //~| expected `&mut _` //~| found `&_` //~| values differ in mutability = foo; let &mut _ = foo; - let bar = &1i32; + let bar = &1; let &_ = bar; let &mut _ //~ ERROR mismatched types - //~| expected `&i32` + //~| expected `&_` //~| found `&mut _` //~| values differ in mutability = bar; diff --git a/src/test/compile-fail/mutable-class-fields-2.rs b/src/test/compile-fail/mutable-class-fields-2.rs index b6744d4b33a..46af3a862c2 100644 --- a/src/test/compile-fail/mutable-class-fields-2.rs +++ b/src/test/compile-fail/mutable-class-fields-2.rs @@ -29,6 +29,6 @@ fn cat(in_x : usize, in_y : isize) -> cat { } fn main() { - let nyan : cat = cat(52_usize, 99); + let nyan : cat = cat(52, 99); nyan.eat(); } diff --git a/src/test/compile-fail/mutable-class-fields.rs b/src/test/compile-fail/mutable-class-fields.rs index 94b1047f85e..c163dc2b4d2 100644 --- a/src/test/compile-fail/mutable-class-fields.rs +++ b/src/test/compile-fail/mutable-class-fields.rs @@ -21,6 +21,6 @@ fn cat(in_x : usize, in_y : isize) -> cat { } fn main() { - let nyan : cat = cat(52_usize, 99); + let nyan : cat = cat(52, 99); nyan.how_hungry = 0; //~ ERROR cannot assign } diff --git a/src/test/compile-fail/non-exhaustive-pattern-witness.rs b/src/test/compile-fail/non-exhaustive-pattern-witness.rs index 0eb91e0419a..3ed91459ae9 100644 --- a/src/test/compile-fail/non-exhaustive-pattern-witness.rs +++ b/src/test/compile-fail/non-exhaustive-pattern-witness.rs @@ -27,7 +27,7 @@ fn struct_with_a_nested_enum_and_vector() { Foo { first: true, second: None } => (), Foo { first: true, second: Some(_) } => (), Foo { first: false, second: None } => (), - Foo { first: false, second: Some([1_usize, 2_usize, 3_usize, 4_usize]) } => () + Foo { first: false, second: Some([1, 2, 3, 4]) } => () } } diff --git a/src/test/compile-fail/or-patter-mismatch.rs b/src/test/compile-fail/or-patter-mismatch.rs index 4b261d89888..59508d6ac95 100644 --- a/src/test/compile-fail/or-patter-mismatch.rs +++ b/src/test/compile-fail/or-patter-mismatch.rs @@ -12,4 +12,4 @@ enum blah { a(isize, isize, usize), b(isize, isize), } -fn main() { match blah::a(1, 1, 2_usize) { blah::a(_, x, y) | blah::b(x, y) => { } } } +fn main() { match blah::a(1, 1, 2) { blah::a(_, x, y) | blah::b(x, y) => { } } } diff --git a/src/test/compile-fail/phantom-oibit.rs b/src/test/compile-fail/phantom-oibit.rs new file mode 100644 index 00000000000..c912d084daa --- /dev/null +++ b/src/test/compile-fail/phantom-oibit.rs @@ -0,0 +1,41 @@ +// 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. + +// Ensure that OIBIT checks `T` when it encounters a `PhantomData<T>` field, instead of checking +// the `PhantomData<T>` type itself (which almost always implements a "default" trait +// (`impl Trait for ..`)) + +#![feature(optin_builtin_traits)] + +use std::marker::{MarkerTrait, PhantomData}; + +unsafe trait Zen: MarkerTrait {} + +unsafe impl Zen for .. {} + +unsafe impl<'a, T: 'a> Zen for &'a T where T: Sync {} + +struct Guard<'a, T: 'a> { + _marker: PhantomData<&'a T>, +} + +struct Nested<T>(T); + +fn is_zen<T: Zen>(_: T) {} + +fn not_sync<T>(x: Guard<T>) { + is_zen(x) //~ error: the trait `core::marker::Sync` is not implemented for the type `T` +} + +fn nested_not_sync<T>(x: Nested<Guard<T>>) { + is_zen(x) //~ error: the trait `core::marker::Sync` is not implemented for the type `T` +} + +fn main() {} diff --git a/src/test/compile-fail/plugin-extern-crate-attr-deprecated.rs b/src/test/compile-fail/plugin-extern-crate-attr-deprecated.rs index ccda5cbdceb..efa352e386d 100644 --- a/src/test/compile-fail/plugin-extern-crate-attr-deprecated.rs +++ b/src/test/compile-fail/plugin-extern-crate-attr-deprecated.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![feature(plugin)] + #[plugin] //~ ERROR #[plugin] on `extern crate` is deprecated //~^ HELP use a crate attribute instead, i.e. #![plugin(std)] extern crate std; diff --git a/src/test/compile-fail/privacy5.rs b/src/test/compile-fail/privacy5.rs index df570fd4647..a7f6a514b96 100644 --- a/src/test/compile-fail/privacy5.rs +++ b/src/test/compile-fail/privacy5.rs @@ -9,7 +9,6 @@ // except according to those terms. // aux-build:privacy-tuple-struct.rs -// ignore-fast extern crate "privacy-tuple-struct" as other; diff --git a/src/test/compile-fail/private-method.rs b/src/test/compile-fail/private-method.rs index ccbdd52a983..16510c2c8c9 100644 --- a/src/test/compile-fail/private-method.rs +++ b/src/test/compile-fail/private-method.rs @@ -30,6 +30,6 @@ mod kitties { } fn main() { - let nyan : kitties::cat = kitties::cat(52_usize, 99); + let nyan : kitties::cat = kitties::cat(52, 99); nyan.nap(); } diff --git a/src/test/compile-fail/private-struct-field-cross-crate.rs b/src/test/compile-fail/private-struct-field-cross-crate.rs index 243d835d46e..fb4491a6375 100644 --- a/src/test/compile-fail/private-struct-field-cross-crate.rs +++ b/src/test/compile-fail/private-struct-field-cross-crate.rs @@ -13,7 +13,7 @@ extern crate cci_class; use cci_class::kitties::cat; fn main() { - let nyan : cat = cat(52_usize, 99); - assert!((nyan.meows == 52_usize)); + let nyan : cat = cat(52, 99); + assert!((nyan.meows == 52)); //~^ ERROR field `meows` of struct `cci_class::kitties::cat` is private } diff --git a/src/test/compile-fail/range-1.rs b/src/test/compile-fail/range-1.rs index a8b6e399418..e7b34d6d1bc 100644 --- a/src/test/compile-fail/range-1.rs +++ b/src/test/compile-fail/range-1.rs @@ -20,7 +20,7 @@ pub fn main() { //~^ ERROR the trait `core::num::Int` is not implemented for the type `f32` // Unsized type. - let arr: &[_] = &[1u32, 2, 3]; + let arr: &[_] = &[1, 2, 3]; let range = *arr..; //~^ ERROR the trait `core::marker::Sized` is not implemented } diff --git a/src/test/compile-fail/regions-addr-of-self.rs b/src/test/compile-fail/regions-addr-of-self.rs index 45e468b3ab0..04ee0526403 100644 --- a/src/test/compile-fail/regions-addr-of-self.rs +++ b/src/test/compile-fail/regions-addr-of-self.rs @@ -15,18 +15,18 @@ struct dog { impl dog { pub fn chase_cat(&mut self) { let p: &'static mut usize = &mut self.cats_chased; //~ ERROR cannot infer - *p += 1_usize; + *p += 1; } pub fn chase_cat_2(&mut self) { let p: &mut usize = &mut self.cats_chased; - *p += 1_usize; + *p += 1; } } fn dog() -> dog { dog { - cats_chased: 0_usize + cats_chased: 0 } } diff --git a/src/test/compile-fail/regions-addr-of-upvar-self.rs b/src/test/compile-fail/regions-addr-of-upvar-self.rs index 8cc2dd6afc6..28491f1155c 100644 --- a/src/test/compile-fail/regions-addr-of-upvar-self.rs +++ b/src/test/compile-fail/regions-addr-of-upvar-self.rs @@ -18,7 +18,7 @@ impl dog { pub fn chase_cat(&mut self) { let _f = || { let p: &'static mut usize = &mut self.food; //~ ERROR cannot infer - *p = 3_usize; + *p = 3; }; } } diff --git a/src/test/compile-fail/regions-creating-enums.rs b/src/test/compile-fail/regions-creating-enums.rs index 4c361427bf3..ad2dc28afef 100644 --- a/src/test/compile-fail/regions-creating-enums.rs +++ b/src/test/compile-fail/regions-creating-enums.rs @@ -14,8 +14,8 @@ enum ast<'a> { } fn build() { - let x = ast::num(3_usize); - let y = ast::num(4_usize); + let x = ast::num(3); + let y = ast::num(4); let z = ast::add(&x, &y); compute(&z); } diff --git a/src/test/compile-fail/regions-pattern-typing-issue-19997.rs b/src/test/compile-fail/regions-pattern-typing-issue-19997.rs index da839d72172..ae9ceb600d4 100644 --- a/src/test/compile-fail/regions-pattern-typing-issue-19997.rs +++ b/src/test/compile-fail/regions-pattern-typing-issue-19997.rs @@ -9,8 +9,8 @@ // except according to those terms. fn main() { - let a0 = 0u8; - let f = 1u8; + let a0 = 0; + let f = 1; let mut a1 = &a0; match (&a1,) { (&ref b0,) => { diff --git a/src/test/compile-fail/regions-return-ref-to-upvar-issue-17403.rs b/src/test/compile-fail/regions-return-ref-to-upvar-issue-17403.rs index aa20efa5a12..1e2224eafae 100644 --- a/src/test/compile-fail/regions-return-ref-to-upvar-issue-17403.rs +++ b/src/test/compile-fail/regions-return-ref-to-upvar-issue-17403.rs @@ -15,7 +15,7 @@ fn main() { // Unboxed closure case { - let mut x = 0_usize; + let mut x = 0; let mut f = || &mut x; //~ ERROR cannot infer let x = f(); let y = f(); diff --git a/src/test/compile-fail/regions-trait-1.rs b/src/test/compile-fail/regions-trait-1.rs index b45a37d26e5..01439ce5e68 100644 --- a/src/test/compile-fail/regions-trait-1.rs +++ b/src/test/compile-fail/regions-trait-1.rs @@ -34,7 +34,7 @@ fn get_v(gc: Box<get_ctxt>) -> usize { } fn main() { - let ctxt = ctxt { v: 22_usize }; + let ctxt = ctxt { v: 22 }; let hc = has_ctxt { c: &ctxt }; - assert_eq!(get_v(box hc as Box<get_ctxt>), 22_usize); + assert_eq!(get_v(box hc as Box<get_ctxt>), 22); } diff --git a/src/test/compile-fail/reserved-attr-on-macro.rs b/src/test/compile-fail/reserved-attr-on-macro.rs new file mode 100644 index 00000000000..db8f82a70e1 --- /dev/null +++ b/src/test/compile-fail/reserved-attr-on-macro.rs @@ -0,0 +1,18 @@ +// 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. + +#[rustc_attribute_should_be_reserved] //~ ERROR attributes with the prefix `rustc_` are reserved +macro_rules! foo { + () => (()); +} + +fn main() { + foo!(); +} diff --git a/src/test/compile-fail/send-is-not-static-ensures-scoping.rs b/src/test/compile-fail/send-is-not-static-ensures-scoping.rs index fe03ca8353d..fe03ca8353d 100755..100644 --- a/src/test/compile-fail/send-is-not-static-ensures-scoping.rs +++ b/src/test/compile-fail/send-is-not-static-ensures-scoping.rs diff --git a/src/test/compile-fail/single-derive-attr.rs b/src/test/compile-fail/single-derive-attr.rs new file mode 100644 index 00000000000..0b1b3141f5b --- /dev/null +++ b/src/test/compile-fail/single-derive-attr.rs @@ -0,0 +1,15 @@ +// 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. + +#[derive_Clone] +//~^ ERROR attributes of the form `#[derive_*]` are reserved +struct Test; + +pub fn main() {} diff --git a/src/test/compile-fail/structure-constructor-type-mismatch.rs b/src/test/compile-fail/structure-constructor-type-mismatch.rs index c276228b18e..ea6d63ca540 100644 --- a/src/test/compile-fail/structure-constructor-type-mismatch.rs +++ b/src/test/compile-fail/structure-constructor-type-mismatch.rs @@ -26,40 +26,40 @@ fn main() { let pt = PointF { //~^ ERROR structure constructor specifies a structure of type //~| expected f32 - //~| found i32 - x: 1i32, - y: 2i32, + //~| found integral variable + x: 1, + y: 2, }; let pt2 = Point::<f32> { //~^ ERROR structure constructor specifies a structure of type //~| expected f32 - //~| found i32 - x: 3i32, - y: 4i32, + //~| found integral variable + x: 3, + y: 4, }; let pair = PairF { //~^ ERROR structure constructor specifies a structure of type //~| expected f32 - //~| found i32 - x: 5i32, - y: 6i32, + //~| found integral variable + x: 5, + y: 6, }; let pair2 = PairF::<i32> { //~^ ERROR structure constructor specifies a structure of type //~| expected f32 - //~| found i32 - x: 7i32, - y: 8i32, + //~| found integral variable + x: 7, + y: 8, }; let pt3 = PointF::<i32> { //~^ ERROR wrong number of type arguments //~| ERROR structure constructor specifies a structure of type - x: 9i32, - y: 10i32, + x: 9, + y: 10, }; } diff --git a/src/test/compile-fail/tail-typeck.rs b/src/test/compile-fail/tail-typeck.rs index 9c1d318d588..5c1270aa0e4 100644 --- a/src/test/compile-fail/tail-typeck.rs +++ b/src/test/compile-fail/tail-typeck.rs @@ -12,6 +12,6 @@ fn f() -> isize { return g(); } -fn g() -> usize { return 0_usize; } +fn g() -> usize { return 0; } fn main() { let y = f(); } diff --git a/src/test/compile-fail/traits-assoc-type-in-supertrait-bad.rs b/src/test/compile-fail/traits-assoc-type-in-supertrait-bad.rs new file mode 100644 index 00000000000..971869ba85b --- /dev/null +++ b/src/test/compile-fail/traits-assoc-type-in-supertrait-bad.rs @@ -0,0 +1,26 @@ +// 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 case where an associated type is referenced from within the +// supertrait definition, and the impl makes the wrong +// associations. Issue #20220. + +use std::vec::IntoIter; + +pub trait Foo: Iterator<Item=<Self as Foo>::Key> { + type Key; +} + +impl Foo for IntoIter<i32> { //~ ERROR type mismatch + type Key = u32; +} + +fn main() { +} diff --git a/src/test/compile-fail/traits-issue-23003-overflow.rs b/src/test/compile-fail/traits-issue-23003-overflow.rs new file mode 100644 index 00000000000..ea41775f310 --- /dev/null +++ b/src/test/compile-fail/traits-issue-23003-overflow.rs @@ -0,0 +1,38 @@ +// 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. + +// A variant of traits-issue-23003 in which an infinite series of +// types are required. This currently creates an overflow. This test +// is included to ensure that some controlled failure, at least, +// results -- but it might be that we should adjust the rules somewhat +// to make this legal. -nmatsakis + +use std::marker::PhantomData; + +trait Async { + type Cancel; +} + +struct Receipt<A:Async> { + marker: PhantomData<A>, +} + +struct Complete<B> { + core: Option<B>, +} + +impl<B> Async for Complete<B> { + type Cancel = Receipt<Complete<Option<B>>>; +} + +fn foo(r: Receipt<Complete<()>>) { } +//~^ ERROR overflow + +fn main() { } diff --git a/src/test/compile-fail/traits-multidispatch-convert-ambig-dest.rs b/src/test/compile-fail/traits-multidispatch-convert-ambig-dest.rs index 0a5aa1b7bd3..8fe1f4d2371 100644 --- a/src/test/compile-fail/traits-multidispatch-convert-ambig-dest.rs +++ b/src/test/compile-fail/traits-multidispatch-convert-ambig-dest.rs @@ -33,7 +33,7 @@ where T : Convert<U> } fn a() { - test(22_i32, std::default::Default::default()); //~ ERROR type annotations required + test(22, std::default::Default::default()); //~ ERROR type annotations required } fn main() {} diff --git a/src/test/compile-fail/traits-repeated-supertrait-ambig.rs b/src/test/compile-fail/traits-repeated-supertrait-ambig.rs new file mode 100644 index 00000000000..d61ac6f08d9 --- /dev/null +++ b/src/test/compile-fail/traits-repeated-supertrait-ambig.rs @@ -0,0 +1,53 @@ +// 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 a case of a trait which extends the same supertrait twice, but +// with difference type parameters. Test then that when we don't give +// enough information to pick between these, no selection is made. In +// this particular case, the two choices are i64/u64 -- so when we use +// an integer literal, we wind up falling this literal back to i32. +// See also `run-pass/trait-repeated-supertrait.rs`. + +trait CompareTo<T> { + fn same_as(&self, t: T) -> bool; +} + +trait CompareToInts : CompareTo<i64> + CompareTo<u64> { +} + +impl CompareTo<i64> for i64 { + fn same_as(&self, t: i64) -> bool { *self == t } +} + +impl CompareTo<u64> for i64 { + fn same_as(&self, t: u64) -> bool { *self == (t as i64) } +} + +impl CompareToInts for i64 { } + +fn with_obj(c: &CompareToInts) -> bool { + c.same_as(22) //~ ERROR `CompareTo<i32>` is not implemented +} + +fn with_trait<C:CompareToInts>(c: &C) -> bool { + c.same_as(22) //~ ERROR `CompareTo<i32>` is not implemented +} + +fn with_ufcs1<C:CompareToInts>(c: &C) -> bool { + CompareToInts::same_as(c, 22) //~ ERROR `CompareTo<i32>` is not implemented +} + +fn with_ufcs2<C:CompareToInts>(c: &C) -> bool { + CompareTo::same_as(c, 22) //~ ERROR `CompareTo<i32>` is not implemented +} + +fn main() { + assert_eq!(22_i64.same_as(22), true); //~ ERROR `CompareTo<i32>` is not implemented +} diff --git a/src/test/compile-fail/tuple-index-out-of-bounds.rs b/src/test/compile-fail/tuple-index-out-of-bounds.rs index 54b8d551f20..c2c41fbbb2a 100644 --- a/src/test/compile-fail/tuple-index-out-of-bounds.rs +++ b/src/test/compile-fail/tuple-index-out-of-bounds.rs @@ -11,14 +11,14 @@ struct Point(i32, i32); fn main() { - let origin = Point(0i32, 0i32); + let origin = Point(0, 0); origin.0; origin.1; origin.2; //~^ ERROR attempted out-of-bounds tuple index `2` on type `Point` - let tuple = (0i32, 0i32); + let tuple = (0, 0); tuple.0; tuple.1; tuple.2; - //~^ ERROR attempted out-of-bounds tuple index `2` on type `(i32, i32)` + //~^ ERROR attempted out-of-bounds tuple index `2` on type `(_, _)` } diff --git a/src/test/compile-fail/type-mismatch-multiple.rs b/src/test/compile-fail/type-mismatch-multiple.rs index 3bf0896d990..627300a0377 100644 --- a/src/test/compile-fail/type-mismatch-multiple.rs +++ b/src/test/compile-fail/type-mismatch-multiple.rs @@ -10,12 +10,12 @@ // Checking that the compiler reports multiple type errors at once -fn main() { let a: bool = 1i32; let b: i32 = true; } +fn main() { let a: bool = 1; let b: i32 = true; } //~^ ERROR mismatched types //~| expected `bool` -//~| found `i32` +//~| found `_` //~| expected bool -//~| found i32 +//~| found integral variable //~| ERROR mismatched types //~| expected `i32` //~| found `bool` diff --git a/src/test/compile-fail/type-params-in-different-spaces-1.rs b/src/test/compile-fail/type-params-in-different-spaces-1.rs index de9623de7cd..88d8788d63a 100644 --- a/src/test/compile-fail/type-params-in-different-spaces-1.rs +++ b/src/test/compile-fail/type-params-in-different-spaces-1.rs @@ -23,7 +23,7 @@ trait BrokenAdd: Int { impl<T: Int> BrokenAdd for T {} pub fn main() { - let foo: u8 = 0u8; + let foo: u8 = 0; let x: u8 = foo.broken_add("hello darkness my old friend".to_string()); println!("{}", x); } 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 index 00000000000..3a29bb9c227 --- /dev/null +++ b/src/test/compile-fail/typeck-default-trait-impl-cross-crate-coherence.rs @@ -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() { } diff --git a/src/test/compile-fail/typeck-default-trait-impl-outside-crate.rs b/src/test/compile-fail/typeck-default-trait-impl-outside-crate.rs index 10ba8c74164..a345bd1b65c 100644 --- a/src/test/compile-fail/typeck-default-trait-impl-outside-crate.rs +++ b/src/test/compile-fail/typeck-default-trait-impl-outside-crate.rs @@ -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() {} diff --git a/src/test/compile-fail/typeck_type_placeholder_item.rs b/src/test/compile-fail/typeck_type_placeholder_item.rs index 5bfad94867e..d4f3cdfd8b7 100644 --- a/src/test/compile-fail/typeck_type_placeholder_item.rs +++ b/src/test/compile-fail/typeck_type_placeholder_item.rs @@ -21,7 +21,7 @@ fn test2() -> (_, _) { (5, 5) } static TEST3: _ = "test"; //~^ ERROR the type placeholder `_` is not allowed within types on item signatures -static TEST4: _ = 145u16; +static TEST4: _ = 145; //~^ ERROR the type placeholder `_` is not allowed within types on item signatures static TEST5: (_, _) = (1, 2); @@ -74,7 +74,7 @@ pub fn main() { static FN_TEST3: _ = "test"; //~^ ERROR the type placeholder `_` is not allowed within types on item signatures - static FN_TEST4: _ = 145u16; + static FN_TEST4: _ = 145; //~^ ERROR the type placeholder `_` is not allowed within types on item signatures static FN_TEST5: (_, _) = (1, 2); diff --git a/src/test/compile-fail/unboxed-closure-illegal-move.rs b/src/test/compile-fail/unboxed-closure-illegal-move.rs index 86e326f3c5a..564b1b4669f 100644 --- a/src/test/compile-fail/unboxed-closure-illegal-move.rs +++ b/src/test/compile-fail/unboxed-closure-illegal-move.rs @@ -23,28 +23,28 @@ fn to_fn_once<A,F:FnOnce<A>>(f: F) -> F { f } fn main() { // By-ref cases { - let x = Box::new(0_usize); + let x = Box::new(0); let f = to_fn(|| drop(x)); //~ ERROR cannot move } { - let x = Box::new(0_usize); + let x = Box::new(0); let f = to_fn_mut(|| drop(x)); //~ ERROR cannot move } { - let x = Box::new(0_usize); + let x = Box::new(0); let f = to_fn_once(|| drop(x)); // OK -- FnOnce } // By-value cases { - let x = Box::new(0_usize); + let x = Box::new(0); let f = to_fn(move || drop(x)); //~ ERROR cannot move } { - let x = Box::new(0_usize); + let x = Box::new(0); let f = to_fn_mut(move || drop(x)); //~ ERROR cannot move } { - let x = Box::new(0_usize); + let x = Box::new(0); let f = to_fn_once(move || drop(x)); // this one is ok } } diff --git a/src/test/compile-fail/unboxed-closure-immutable-capture.rs b/src/test/compile-fail/unboxed-closure-immutable-capture.rs index b40a91181ad..5be2738b47e 100644 --- a/src/test/compile-fail/unboxed-closure-immutable-capture.rs +++ b/src/test/compile-fail/unboxed-closure-immutable-capture.rs @@ -17,7 +17,7 @@ fn set(x: &mut usize) { *x = 0; } fn main() { - let x = 0_usize; + let x = 0; move || x = 1; //~ ERROR cannot assign move || set(&mut x); //~ ERROR cannot borrow move || x = 1; //~ ERROR cannot assign diff --git a/src/test/compile-fail/unboxed-closure-region.rs b/src/test/compile-fail/unboxed-closure-region.rs index 5f4bf0d33be..eee1b6ce30b 100644 --- a/src/test/compile-fail/unboxed-closure-region.rs +++ b/src/test/compile-fail/unboxed-closure-region.rs @@ -14,7 +14,7 @@ // reference cannot escape the region of that variable. fn main() { let _f = { - let x = 0_usize; + let x = 0; || x //~ ERROR `x` does not live long enough }; } diff --git a/src/test/compile-fail/unboxed-closures-borrow-conflict.rs b/src/test/compile-fail/unboxed-closures-borrow-conflict.rs index 1191cfa2600..372f3277931 100644 --- a/src/test/compile-fail/unboxed-closures-borrow-conflict.rs +++ b/src/test/compile-fail/unboxed-closures-borrow-conflict.rs @@ -14,7 +14,7 @@ // cause borrow conflicts. fn main() { - let mut x = 0_usize; + let mut x = 0; let f = || x += 1; let _y = x; //~ ERROR cannot use `x` because it was mutably borrowed } diff --git a/src/test/compile-fail/unboxed-closures-mutate-upvar.rs b/src/test/compile-fail/unboxed-closures-mutate-upvar.rs index 650bb17bb77..35052ec0bd5 100644 --- a/src/test/compile-fail/unboxed-closures-mutate-upvar.rs +++ b/src/test/compile-fail/unboxed-closures-mutate-upvar.rs @@ -20,21 +20,21 @@ fn to_fn<A,F:Fn<A>>(f: F) -> F { f } fn to_fn_mut<A,F:FnMut<A>>(f: F) -> F { f } fn a() { - let n = 0u8; + let n = 0; let mut f = to_fn_mut(|| { //~ ERROR closure cannot assign n += 1; }); } fn b() { - let mut n = 0u8; + let mut n = 0; let mut f = to_fn_mut(|| { n += 1; // OK }); } fn c() { - let n = 0u8; + let n = 0; let mut f = to_fn_mut(move || { // If we just did a straight-forward desugaring, this would // compile, but we do something a bit more subtle, and hence @@ -44,21 +44,21 @@ fn c() { } fn d() { - let mut n = 0u8; + let mut n = 0; let mut f = to_fn_mut(move || { n += 1; // OK }); } fn e() { - let n = 0u8; + let n = 0; let mut f = to_fn(move || { n += 1; //~ ERROR cannot assign }); } fn f() { - let mut n = 0u8; + let mut n = 0; let mut f = to_fn(move || { n += 1; //~ ERROR cannot assign }); diff --git a/src/test/compile-fail/unboxed-closures-mutated-upvar-from-fn-closure.rs b/src/test/compile-fail/unboxed-closures-mutated-upvar-from-fn-closure.rs index 2345a86595e..432c7fa5d1b 100644 --- a/src/test/compile-fail/unboxed-closures-mutated-upvar-from-fn-closure.rs +++ b/src/test/compile-fail/unboxed-closures-mutated-upvar-from-fn-closure.rs @@ -16,7 +16,7 @@ fn call<F>(f: F) where F : Fn() { } fn main() { - let mut counter = 0_u32; + let mut counter = 0; call(|| { counter += 1; //~^ ERROR cannot assign to data in a captured outer variable in an `Fn` closure diff --git a/src/test/compile-fail/unreachable-arm.rs b/src/test/compile-fail/unreachable-arm.rs index eb5ffeaf888..bc93b86a391 100644 --- a/src/test/compile-fail/unreachable-arm.rs +++ b/src/test/compile-fail/unreachable-arm.rs @@ -15,4 +15,4 @@ enum foo { a(Box<foo>, isize), b(usize), } -fn main() { match foo::b(1_usize) { foo::b(_) | foo::a(box _, 1) => { } foo::a(_, 1) => { } } } +fn main() { match foo::b(1) { foo::b(_) | foo::a(box _, 1) => { } foo::a(_, 1) => { } } } diff --git a/src/test/compile-fail/unsafe-fn-assign-deref-ptr.rs b/src/test/compile-fail/unsafe-fn-assign-deref-ptr.rs index 97908118e35..4ea7051775e 100644 --- a/src/test/compile-fail/unsafe-fn-assign-deref-ptr.rs +++ b/src/test/compile-fail/unsafe-fn-assign-deref-ptr.rs @@ -10,7 +10,7 @@ fn f(p: *const u8) { - *p = 0u8; //~ ERROR dereference of unsafe pointer requires unsafe function or block + *p = 0; //~ ERROR dereference of unsafe pointer requires unsafe function or block return; } diff --git a/src/test/compile-fail/variance-issue-20533.rs b/src/test/compile-fail/variance-issue-20533.rs index 0254f56bd1a..e5473f12bf2 100644 --- a/src/test/compile-fail/variance-issue-20533.rs +++ b/src/test/compile-fail/variance-issue-20533.rs @@ -33,19 +33,19 @@ struct AffineU32(u32); fn main() { { - let a = AffineU32(1_u32); + let a = AffineU32(1); let x = foo(&a); drop(a); //~ ERROR cannot move out of `a` drop(x); } { - let a = AffineU32(1_u32); + let a = AffineU32(1); let x = bar(&a); drop(a); //~ ERROR cannot move out of `a` drop(x); } { - let a = AffineU32(1_u32); + let a = AffineU32(1); let x = baz(&a); drop(a); //~ ERROR cannot move out of `a` drop(x); diff --git a/src/test/compile-fail/vtable-res-trait-param.rs b/src/test/compile-fail/vtable-res-trait-param.rs index cc6ff2d8ebc..654272f5bc6 100644 --- a/src/test/compile-fail/vtable-res-trait-param.rs +++ b/src/test/compile-fail/vtable-res-trait-param.rs @@ -23,7 +23,7 @@ impl TraitB for isize { } fn call_it<B:TraitB>(b: B) -> isize { - let y = 4_usize; + let y = 4; b.gimme_an_a(y) //~ ERROR the trait `TraitA` is not implemented } diff --git a/src/test/debuginfo/associated-types.rs b/src/test/debuginfo/associated-types.rs index 26117e7a13b..63132d91327 100644 --- a/src/test/debuginfo/associated-types.rs +++ b/src/test/debuginfo/associated-types.rs @@ -139,13 +139,13 @@ fn assoc_enum<T: TraitWithAssocType>(arg: Enum<T>) { } fn main() { - assoc_struct(Struct { b: -1i32, b1: 0i64 }); - assoc_local(1i32); - assoc_arg::<i32>(2i64); - assoc_return_value(3i32); - assoc_tuple((4i32, 5i64)); - assoc_enum(Enum::Variant1(6i32, 7i64)); - assoc_enum(Enum::Variant2(8i64, 9i32)); + assoc_struct(Struct { b: -1, b1: 0 }); + assoc_local(1); + assoc_arg::<i32>(2); + assoc_return_value(3); + assoc_tuple((4, 5)); + assoc_enum(Enum::Variant1(6, 7)); + assoc_enum(Enum::Variant2(8, 9)); } fn zzz() { () } diff --git a/src/test/debuginfo/constant-debug-locs.rs b/src/test/debuginfo/constant-debug-locs.rs new file mode 100644 index 00000000000..24332e31775 --- /dev/null +++ b/src/test/debuginfo/constant-debug-locs.rs @@ -0,0 +1,67 @@ +// Copyright 2013-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. + +// ignore-android: FIXME(#10381) +// min-lldb-version: 310 + +// compile-flags:-g + +#![allow(unused_variables)] +#![allow(dead_code)] +#![omit_gdb_pretty_printer_section] + +// This test makes sure that the compiler doesn't crash when trying to assign +// debug locations to const-expressions. + +use std::sync::MUTEX_INIT; +use std::cell::UnsafeCell; + +const CONSTANT: u64 = 3 + 4; + +struct Struct { + a: isize, + b: usize, +} +const STRUCT: Struct = Struct { a: 1, b: 2 }; + +struct TupleStruct(u32); +const TUPLE_STRUCT: TupleStruct = TupleStruct(4); + +enum Enum { + Variant1(char), + Variant2 { a: u8 }, + Variant3 +} + +const VARIANT1: Enum = Enum::Variant1('v'); +const VARIANT2: Enum = Enum::Variant2 { a: 2 }; +const VARIANT3: Enum = Enum::Variant3; + +const STRING: &'static str = "String"; + +const VEC: [u32; 8] = [0; 8]; + +const NESTED: (Struct, TupleStruct) = (STRUCT, TUPLE_STRUCT); + +const UNSAFE_CELL: UnsafeCell<bool> = UnsafeCell { value: false }; + +fn main() { + let mut _constant = CONSTANT; + let mut _struct = STRUCT; + let mut _tuple_struct = TUPLE_STRUCT; + let mut _variant1 = VARIANT1; + let mut _variant2 = VARIANT2; + let mut _variant3 = VARIANT3; + let mut _string = STRING; + let mut _vec = VEC; + let mut _nested = NESTED; + let mut _extern = MUTEX_INIT; + let mut _unsafe_cell = UNSAFE_CELL; +} diff --git a/src/test/debuginfo/cross-crate-spans.rs b/src/test/debuginfo/cross-crate-spans.rs new file mode 100644 index 00000000000..3aef9438a33 --- /dev/null +++ b/src/test/debuginfo/cross-crate-spans.rs @@ -0,0 +1,74 @@ +// Copyright 2013-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. + +#![omit_gdb_pretty_printer_section] + +// ignore-android: FIXME(#10381) +// min-lldb-version: 310 + +// aux-build:cross_crate_spans.rs +extern crate cross_crate_spans; + +// compile-flags:-g + + +// === GDB TESTS =================================================================================== + +// gdb-command:break cross_crate_spans.rs:21 +// gdb-command:run + +// gdb-command:print result +// gdb-check:$1 = {17, 17} +// gdb-command:print a_variable +// gdb-check:$2 = 123456789 +// gdb-command:print another_variable +// gdb-check:$3 = 123456789.5 +// gdb-command:continue + +// gdb-command:print result +// gdb-check:$4 = {1212, 1212} +// gdb-command:print a_variable +// gdb-check:$5 = 123456789 +// gdb-command:print another_variable +// gdb-check:$6 = 123456789.5 +// gdb-command:continue + + + +// === LLDB TESTS ================================================================================== + +// lldb-command:b cross_crate_spans.rs:21 +// lldb-command:run + +// lldb-command:print result +// lldb-check:[...]$0 = (17, 17) +// lldb-command:print a_variable +// lldb-check:[...]$1 = 123456789 +// lldb-command:print another_variable +// lldb-check:[...]$2 = 123456789.5 +// lldb-command:continue + +// lldb-command:print result +// lldb-check:[...]$3 = (1212, 1212) +// lldb-command:print a_variable +// lldb-check:[...]$4 = 123456789 +// lldb-command:print another_variable +// lldb-check:[...]$5 = 123456789.5 +// lldb-command:continue + + +// This test makes sure that we can break in functions inlined from other crates. + +fn main() { + + let _ = cross_crate_spans::generic_function(17u32); + let _ = cross_crate_spans::generic_function(1212i16); + +} diff --git a/src/test/debuginfo/extern-c-fn.rs b/src/test/debuginfo/extern-c-fn.rs new file mode 100644 index 00000000000..9e73417e7de --- /dev/null +++ b/src/test/debuginfo/extern-c-fn.rs @@ -0,0 +1,68 @@ +// Copyright 2013-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. + +// min-lldb-version: 310 + +// compile-flags:-g + +// === GDB TESTS =================================================================================== +// gdb-command:run + +// gdb-command:print s +// gdb-check:$1 = [...]"abcd" +// gdb-command:print len +// gdb-check:$2 = 20 +// gdb-command:print local0 +// gdb-check:$3 = 19 +// gdb-command:print local1 +// gdb-check:$4 = true +// gdb-command:print local2 +// gdb-check:$5 = 20.5 + +// gdb-command:continue + +// === LLDB TESTS ================================================================================== +// lldb-command:run + +// lldb-command:print len +// lldb-check:[...]$0 = 20 +// lldb-command:print local0 +// lldb-check:[...]$1 = 19 +// lldb-command:print local1 +// lldb-check:[...]$2 = true +// lldb-command:print local2 +// lldb-check:[...]$3 = 20.5 + +// lldb-command:continue + +#![allow(unused_variables)] +#![allow(dead_code)] +#![omit_gdb_pretty_printer_section] + + +#[no_mangle] +pub unsafe extern "C" fn fn_with_c_abi(s: *const u8, len: i32) -> i32 { + let local0 = len - 1; + let local1 = len > 2; + let local2 = (len as f64) + 0.5; + + zzz(); // #break + + return 0; +} + +fn main() { + unsafe { + fn_with_c_abi(b"abcd\0".as_ptr(), 20); + } +} + +#[inline(never)] +fn zzz() {()} diff --git a/src/test/debuginfo/recursive-struct.rs b/src/test/debuginfo/recursive-struct.rs index 3b1979337d5..25afd3514b0 100644 --- a/src/test/debuginfo/recursive-struct.rs +++ b/src/test/debuginfo/recursive-struct.rs @@ -128,10 +128,10 @@ fn main() { next: Val { val: box UniqueNode { next: Empty, - value: 1_u16, + value: 1, } }, - value: 0_u16, + value: 0, }; let unique_unique: Box<UniqueNode<u32>> = box UniqueNode { diff --git a/src/test/debuginfo/simd.rs b/src/test/debuginfo/simd.rs index 161392c94c8..12c7b146342 100644 --- a/src/test/debuginfo/simd.rs +++ b/src/test/debuginfo/simd.rs @@ -47,18 +47,18 @@ use std::simd::{i8x16, i16x8,i32x4,i64x2,u8x16,u16x8,u32x4,u64x2,f32x4,f64x2}; fn main() { - let vi8x16 = i8x16(0i8, 1i8, 2i8, 3i8, 4i8, 5i8, 6i8, 7i8, - 8i8, 9i8, 10i8, 11i8, 12i8, 13i8, 14i8, 15i8); - - let vi16x8 = i16x8(16i16, 17i16, 18i16, 19i16, 20i16, 21i16, 22i16, 23i16); - let vi32x4 = i32x4(24i32, 25i32, 26i32, 27i32); - let vi64x2 = i64x2(28i64, 29i64); - - let vu8x16 = u8x16(30u8, 31u8, 32u8, 33u8, 34u8, 35u8, 36u8, 37u8, - 38u8, 39u8, 40u8, 41u8, 42u8, 43u8, 44u8, 45u8); - let vu16x8 = u16x8(46u16, 47u16, 48u16, 49u16, 50u16, 51u16, 52u16, 53u16); - let vu32x4 = u32x4(54u32, 55u32, 56u32, 57u32); - let vu64x2 = u64x2(58u64, 59u64); + let vi8x16 = i8x16(0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15); + + let vi16x8 = i16x8(16, 17, 18, 19, 20, 21, 22, 23); + let vi32x4 = i32x4(24, 25, 26, 27); + let vi64x2 = i64x2(28, 29); + + let vu8x16 = u8x16(30, 31, 32, 33, 34, 35, 36, 37, + 38, 39, 40, 41, 42, 43, 44, 45); + let vu16x8 = u16x8(46, 47, 48, 49, 50, 51, 52, 53); + let vu32x4 = u32x4(54, 55, 56, 57); + let vu64x2 = u64x2(58, 59); let vf32x4 = f32x4(60.5f32, 61.5f32, 62.5f32, 63.5f32); let vf64x2 = f64x2(64.5f64, 65.5f64); diff --git a/src/test/parse-fail/circular_modules_main.rs b/src/test/parse-fail/circular_modules_main.rs index ac5ec1236ff..3e548981f1e 100644 --- a/src/test/parse-fail/circular_modules_main.rs +++ b/src/test/parse-fail/circular_modules_main.rs @@ -9,10 +9,10 @@ // except according to those terms. #[path = "circular_modules_hello.rs"] -mod circular_modules_hello; //~ERROR: circular modules +mod circular_modules_hello; //~ ERROR: circular modules pub fn hi_str() -> String { - "Hi!".to_string() + "Hi!".to_string() } fn main() { diff --git a/src/test/parse-fail/class-implements-bad-trait.rs b/src/test/parse-fail/class-implements-bad-trait.rs index d709ffdc3fc..7de51c1ea75 100644 --- a/src/test/parse-fail/class-implements-bad-trait.rs +++ b/src/test/parse-fail/class-implements-bad-trait.rs @@ -15,5 +15,5 @@ class cat : nonexistent { } fn main() { - let nyan = cat(0us); + let nyan = cat(0); } diff --git a/src/test/parse-fail/issue-5544-b.rs b/src/test/parse-fail/issue-5544-b.rs index afff5984b46..9c35d77baf0 100644 --- a/src/test/parse-fail/issue-5544-b.rs +++ b/src/test/parse-fail/issue-5544-b.rs @@ -9,6 +9,6 @@ // except according to those terms. fn main() { - let __isize = 0xff_ffff_ffff_ffff_ffff__isize; + let __isize = 0xff_ffff_ffff_ffff_ffff; //~^ ERROR int literal is too large } diff --git a/src/test/parse-fail/issue-5806.rs b/src/test/parse-fail/issue-5806.rs index 597366a1b35..09de97d71b8 100644 --- a/src/test/parse-fail/issue-5806.rs +++ b/src/test/parse-fail/issue-5806.rs @@ -8,15 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// Copyright 2013 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. +// ignore-windows +// ignore-freebsd +// ignore-openbsd #[path = "../compile-fail"] mod foo; //~ ERROR: a directory diff --git a/src/test/parse-fail/lex-bad-char-literals.rs b/src/test/parse-fail/lex-bad-char-literals.rs index fbe03e355ee..4aa01bcde69 100644 --- a/src/test/parse-fail/lex-bad-char-literals.rs +++ b/src/test/parse-fail/lex-bad-char-literals.rs @@ -8,36 +8,14 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -static c: char = - '\u539_' //~ ERROR: illegal character in numeric character escape - //~^ WARNING: \uABCD escapes are deprecated -; - -static c2: char = - '\Uffffffff' //~ ERROR: illegal numeric character escape - //~^ WARNING: \uABCD escapes are deprecated -; - static c3: char = '\x1' //~ ERROR: numeric character escape is too short ; -static c4: char = - '\u23q' //~ ERROR: illegal character in numeric character escape - //~^ WARNING: \uABCD escapes are deprecated -; -//~^^^ ERROR: numeric character escape is too short - static s: &'static str = "\x1" //~ ERROR: numeric character escape is too short ; -static s2: &'static str = - "\u23q" //~ ERROR: illegal character in numeric character escape - //~^ ERROR: numeric character escape is too short - //~^^ WARNING: \uABCD escapes are deprecated -; - static c: char = '\●' //~ ERROR: unknown character escape ; diff --git a/src/test/parse-fail/lex-bad-numeric-literals.rs b/src/test/parse-fail/lex-bad-numeric-literals.rs index 9a490be6a01..62b87e3f480 100644 --- a/src/test/parse-fail/lex-bad-numeric-literals.rs +++ b/src/test/parse-fail/lex-bad-numeric-literals.rs @@ -22,7 +22,7 @@ fn main() { 1e+; //~ ERROR: expected at least one digit in exponent 0x539.0; //~ ERROR: hexadecimal float literal is not supported 99999999999999999999999999999999; //~ ERROR: int literal is too large - 99999999999999999999999999999999u32; //~ ERROR: int literal is too large + 99999999999999999999999999999999; //~ ERROR: int literal is too large 0x; //~ ERROR: no valid digits 0xu32; //~ ERROR: no valid digits 0ou32; //~ ERROR: no valid digits diff --git a/src/test/parse-fail/regions-trait-2.rs b/src/test/parse-fail/regions-trait-2.rs index 8b36e87db3e..7a7113cd594 100644 --- a/src/test/parse-fail/regions-trait-2.rs +++ b/src/test/parse-fail/regions-trait-2.rs @@ -26,7 +26,7 @@ impl<'a> get_ctxt for has_ctxt<'a> { } fn make_gc() -> @get_ctxt { - let ctxt = ctxt { v: 22us }; + let ctxt = ctxt { v: 22 }; let hc = has_ctxt { c: &ctxt }; return @hc as @get_ctxt; //~^ ERROR source contains reference diff --git a/src/test/pretty/block-comment-wchar.pp b/src/test/pretty/block-comment-wchar.pp index 5a55cb4e561..a5d82277d2f 100644 --- a/src/test/pretty/block-comment-wchar.pp +++ b/src/test/pretty/block-comment-wchar.pp @@ -105,10 +105,11 @@ fn f() { fn main() { // Taken from http://www.unicode.org/Public/UNIDATA/PropList.txt let chars = - ['\x0A', '\x0B', '\x0C', '\x0D', '\x20', '\u0085', '\u00A0', '\u1680', - '\u2000', '\u2001', '\u2002', '\u2003', '\u2004', '\u2005', '\u2006', - '\u2007', '\u2008', '\u2009', '\u200A', '\u2028', '\u2029', '\u202F', - '\u205F', '\u3000']; + ['\x0A', '\x0B', '\x0C', '\x0D', '\x20', '\u{85}', '\u{A0}', + '\u{1680}', '\u{2000}', '\u{2001}', '\u{2002}', '\u{2003}', + '\u{2004}', '\u{2005}', '\u{2006}', '\u{2007}', '\u{2008}', + '\u{2009}', '\u{200A}', '\u{2028}', '\u{2029}', '\u{202F}', + '\u{205F}', '\u{3000}']; for c in &chars { let ws = c.is_whitespace(); println!("{} {}" , c , ws); diff --git a/src/test/pretty/block-comment-wchar.rs b/src/test/pretty/block-comment-wchar.rs index c82bdcd8dcb..eb6d2a4a0a1 100644 --- a/src/test/pretty/block-comment-wchar.rs +++ b/src/test/pretty/block-comment-wchar.rs @@ -99,10 +99,11 @@ fn f() { fn main() { // Taken from http://www.unicode.org/Public/UNIDATA/PropList.txt let chars = - ['\x0A', '\x0B', '\x0C', '\x0D', '\x20', '\u0085', '\u00A0', '\u1680', - '\u2000', '\u2001', '\u2002', '\u2003', '\u2004', '\u2005', '\u2006', - '\u2007', '\u2008', '\u2009', '\u200A', '\u2028', '\u2029', '\u202F', - '\u205F', '\u3000']; + ['\x0A', '\x0B', '\x0C', '\x0D', '\x20', '\u{85}', '\u{A0}', + '\u{1680}', '\u{2000}', '\u{2001}', '\u{2002}', '\u{2003}', + '\u{2004}', '\u{2005}', '\u{2006}', '\u{2007}', '\u{2008}', + '\u{2009}', '\u{200A}', '\u{2028}', '\u{2029}', '\u{202F}', + '\u{205F}', '\u{3000}']; for c in &chars { let ws = c.is_whitespace(); println!("{} {}", c , ws); diff --git a/src/test/pretty/empty-lines.rs b/src/test/pretty/empty-lines.rs index 58f6ae960b1..6a9cbef1015 100644 --- a/src/test/pretty/empty-lines.rs +++ b/src/test/pretty/empty-lines.rs @@ -13,5 +13,5 @@ fn a() -> uint { - 1usize + 1 } diff --git a/src/test/pretty/issue-4264.pp b/src/test/pretty/issue-4264.pp index 83ee2bd08f4..58cd19059c0 100644 --- a/src/test/pretty/issue-4264.pp +++ b/src/test/pretty/issue-4264.pp @@ -26,12 +26,12 @@ pub fn bar() { const FOO: usize = ((5 as usize) - (4 as usize) as usize); let _: [(); (FOO as usize)] = ([(() as ())] as [(); 1]); - let _: [(); (1usize as usize)] = ([(() as ())] as [(); 1]); + let _: [(); (1 as usize)] = ([(() as ())] as [(); 1]); let _ = (((&((([(1 as i32), (2 as i32), (3 as i32)] as [i32; 3])) as [i32; 3]) as &[i32; 3]) as *const _ as *const [i32; 3]) as - *const [i32; (3usize as usize)] as *const [i32; 3]); + *const [i32; (3 as usize)] as *const [i32; 3]); diff --git a/src/test/pretty/issue-4264.rs b/src/test/pretty/issue-4264.rs index 3aa2f4826b2..90757c92c4c 100644 --- a/src/test/pretty/issue-4264.rs +++ b/src/test/pretty/issue-4264.rs @@ -20,9 +20,9 @@ pub fn bar() { const FOO: usize = 5 - 4; let _: [(); FOO] = [()]; - let _ : [(); 1usize] = [()]; + let _ : [(); 1] = [()]; - let _ = &([1,2,3]) as *const _ as *const [i32; 3usize]; + let _ = &([1,2,3]) as *const _ as *const [i32; 3]; format!("test"); } diff --git a/src/test/run-fail/extern-panic.rs b/src/test/run-fail/extern-panic.rs index 225ce5a741b..127700e963a 100644 --- a/src/test/run-fail/extern-panic.rs +++ b/src/test/run-fail/extern-panic.rs @@ -26,10 +26,10 @@ mod rustrt { } extern fn cb(data: libc::uintptr_t) -> libc::uintptr_t { - if data == 1_usize { + if data == 1 { data } else { - count(data - 1_usize) + count(data - 1_usize) + count(data - 1) + count(data - 1) } } @@ -41,9 +41,9 @@ fn count(n: uint) -> uint { } fn main() { - for _ in 0..10_usize { + for _ in 0..10 { task::spawn(move|| { - let result = count(5_usize); + let result = count(5); println!("result = %?", result); panic!(); }); diff --git a/src/test/run-fail/if-check-panic.rs b/src/test/run-fail/if-check-panic.rs index 19a57db5ec7..e3af5b2bbf5 100644 --- a/src/test/run-fail/if-check-panic.rs +++ b/src/test/run-fail/if-check-panic.rs @@ -10,9 +10,9 @@ // error-pattern:Number is odd fn even(x: uint) -> bool { - if x < 2_usize { + if x < 2 { return false; - } else if x == 2_usize { return true; } else { return even(x - 2_usize); } + } else if x == 2 { return true; } else { return even(x - 2); } } fn foo(x: uint) { @@ -23,4 +23,4 @@ fn foo(x: uint) { } } -fn main() { foo(3_usize); } +fn main() { foo(3); } diff --git a/src/test/run-fail/overflowing-add.rs b/src/test/run-fail/overflowing-add.rs index 34a03e5f008..cd13b817c2b 100644 --- a/src/test/run-fail/overflowing-add.rs +++ b/src/test/run-fail/overflowing-add.rs @@ -9,6 +9,7 @@ // except according to those terms. // error-pattern:thread '<main>' panicked at 'arithmetic operation overflowed' +// compile-flags: -C debug-assertions // (Work around constant-evaluation) fn value() -> u8 { 200 } diff --git a/src/test/run-fail/overflowing-mul.rs b/src/test/run-fail/overflowing-mul.rs index b18d99cd232..5d2f5396240 100644 --- a/src/test/run-fail/overflowing-mul.rs +++ b/src/test/run-fail/overflowing-mul.rs @@ -9,6 +9,7 @@ // except according to those terms. // error-pattern:thread '<main>' panicked at 'arithmetic operation overflowed' +// compile-flags: -C debug-assertions // (Work around constant-evaluation) fn value() -> u8 { 200 } diff --git a/src/test/run-fail/overflowing-sub.rs b/src/test/run-fail/overflowing-sub.rs index ee32291eca6..b089dccbaa5 100644 --- a/src/test/run-fail/overflowing-sub.rs +++ b/src/test/run-fail/overflowing-sub.rs @@ -9,6 +9,7 @@ // except according to those terms. // error-pattern:thread '<main>' panicked at 'arithmetic operation overflowed' +// compile-flags: -C debug-assertions // (Work around constant-evaluation) fn value() -> u8 { 42 } diff --git a/src/test/run-fail/test-should-fail-bad-message.rs b/src/test/run-fail/test-should-fail-bad-message.rs index 5a5bb53a33a..e18c5d9631a 100644 --- a/src/test/run-fail/test-should-fail-bad-message.rs +++ b/src/test/run-fail/test-should-fail-bad-message.rs @@ -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 index 00000000000..97d09c837c1 --- /dev/null +++ b/src/test/run-make/bare-outfile/Makefile @@ -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 index 00000000000..63e747901ae --- /dev/null +++ b/src/test/run-make/bare-outfile/foo.rs @@ -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() { +} diff --git a/src/test/run-make/debug-assertions/Makefile b/src/test/run-make/debug-assertions/Makefile new file mode 100644 index 00000000000..71297562768 --- /dev/null +++ b/src/test/run-make/debug-assertions/Makefile @@ -0,0 +1,21 @@ +-include ../tools.mk + +all: + $(RUSTC) debug.rs -C debug-assertions=no + $(call RUN,debug) good + $(RUSTC) debug.rs -C opt-level=0 + $(call RUN,debug) bad + $(RUSTC) debug.rs -C opt-level=1 + $(call RUN,debug) good + $(RUSTC) debug.rs -C opt-level=2 + $(call RUN,debug) good + $(RUSTC) debug.rs -C opt-level=3 + $(call RUN,debug) good + $(RUSTC) debug.rs -O + $(call RUN,debug) good + $(RUSTC) debug.rs + $(call RUN,debug) bad + $(RUSTC) debug.rs -C debug-assertions=yes -O + $(call RUN,debug) bad + $(RUSTC) debug.rs -C debug-assertions=yes -C opt-level=1 + $(call RUN,debug) bad diff --git a/src/test/run-make/debug-assertions/debug.rs b/src/test/run-make/debug-assertions/debug.rs new file mode 100644 index 00000000000..a0ccc75afd0 --- /dev/null +++ b/src/test/run-make/debug-assertions/debug.rs @@ -0,0 +1,42 @@ +// 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. + +#![deny(warnings)] + +use std::env; +use std::thread; + +fn main() { + let should_fail = env::args().nth(1) == Some("bad".to_string()); + + assert_eq!(thread::spawn(debug_assert_eq).join().is_err(), should_fail); + assert_eq!(thread::spawn(debug_assert).join().is_err(), should_fail); + assert_eq!(thread::spawn(overflow).join().is_err(), should_fail); +} + +fn debug_assert_eq() { + let mut hit1 = false; + let mut hit2 = false; + debug_assert_eq!({ hit1 = true; 1 }, { hit2 = true; 2 }); + assert!(!hit1); + assert!(!hit2); +} + +fn debug_assert() { + let mut hit = false; + debug_assert!({ hit = true; false }); + assert!(!hit); +} + +fn overflow() { + fn add(a: u8, b: u8) -> u8 { a + b } + + add(200u8, 200u8); +} diff --git a/src/test/run-make/graphviz-flowgraph/f20.dot-expected.dot b/src/test/run-make/graphviz-flowgraph/f20.dot-expected.dot index b4ec986ef25..21e84fb858b 100644 --- a/src/test/run-make/graphviz-flowgraph/f20.dot-expected.dot +++ b/src/test/run-make/graphviz-flowgraph/f20.dot-expected.dot @@ -1,17 +1,17 @@ digraph block { N0[label="entry"]; N1[label="exit"]; - N2[label="expr 2usize"]; - N3[label="expr 0usize"]; - N4[label="expr 20usize"]; - N5[label="expr [2usize, 0usize, 20usize]"]; + N2[label="expr 2"]; + N3[label="expr 0"]; + N4[label="expr 20"]; + N5[label="expr [2, 0, 20]"]; N6[label="local v"]; - N7[label="stmt let v = [2usize, 0usize, 20usize];"]; + N7[label="stmt let v = [2, 0, 20];"]; N8[label="expr v"]; - N9[label="expr 20usize"]; - N10[label="expr v[20usize]"]; - N11[label="stmt v[20usize];"]; - N12[label="block { let v = [2usize, 0usize, 20usize]; v[20usize]; }"]; + N9[label="expr 20"]; + N10[label="expr v[20]"]; + N11[label="stmt v[20];"]; + N12[label="block { let v = [2, 0, 20]; v[20]; }"]; N0 -> N2; N2 -> N3; N3 -> N4; diff --git a/src/test/run-make/graphviz-flowgraph/f20.rs b/src/test/run-make/graphviz-flowgraph/f20.rs index d65de18b547..d7349932355 100644 --- a/src/test/run-make/graphviz-flowgraph/f20.rs +++ b/src/test/run-make/graphviz-flowgraph/f20.rs @@ -9,6 +9,6 @@ // except according to those terms. pub fn expr_index_20() { - let v = [2_usize, 0_usize, 20_usize]; - v[20_usize]; + let v = [2, 0, 20]; + v[20]; } diff --git a/src/test/run-make/issue-19371/foo.rs b/src/test/run-make/issue-19371/foo.rs index cff4d44910b..1ed816ed729 100644 --- a/src/test/run-make/issue-19371/foo.rs +++ b/src/test/run-make/issue-19371/foo.rs @@ -18,6 +18,8 @@ use rustc::session::config::{basic_options, build_configuration, Input, OutputTy use rustc_driver::driver::{compile_input, CompileController}; use syntax::diagnostics::registry::Registry; +use std::path::PathBuf; + fn main() { let src = r#" fn main() {} @@ -29,9 +31,9 @@ fn main() { panic!("expected rustc path"); } - let tmpdir = Path::new(&args[1]); + let tmpdir = PathBuf::new(&args[1]); - let mut sysroot = Path::new(&args[3]); + let mut sysroot = PathBuf::new(&args[3]); sysroot.pop(); sysroot.pop(); @@ -40,7 +42,7 @@ fn main() { compile(src.to_string(), tmpdir.join("out"), sysroot.clone()); } -fn basic_sess(sysroot: Path) -> Session { +fn basic_sess(sysroot: PathBuf) -> Session { let mut opts = basic_options(); opts.output_types = vec![OutputTypeExe]; opts.maybe_sysroot = Some(sysroot); @@ -51,7 +53,7 @@ fn basic_sess(sysroot: Path) -> Session { sess } -fn compile(code: String, output: Path, sysroot: Path) { +fn compile(code: String, output: PathBuf, sysroot: PathBuf) { let sess = basic_sess(sysroot); let cfg = build_configuration(&sess); let control = CompileController::basic(); diff --git a/src/test/run-make/mismatching-target-triples/bar.rs b/src/test/run-make/mismatching-target-triples/bar.rs index 8695ab58e5f..8695ab58e5f 100755..100644 --- a/src/test/run-make/mismatching-target-triples/bar.rs +++ b/src/test/run-make/mismatching-target-triples/bar.rs diff --git a/src/test/run-make/mismatching-target-triples/foo.rs b/src/test/run-make/mismatching-target-triples/foo.rs index afd4f298a97..afd4f298a97 100755..100644 --- a/src/test/run-make/mismatching-target-triples/foo.rs +++ b/src/test/run-make/mismatching-target-triples/foo.rs diff --git a/src/test/run-make/pretty-expanded-hygiene/input.pp.rs b/src/test/run-make/pretty-expanded-hygiene/input.pp.rs index 6aff4c9b3d5..6aff4c9b3d5 100755..100644 --- a/src/test/run-make/pretty-expanded-hygiene/input.pp.rs +++ b/src/test/run-make/pretty-expanded-hygiene/input.pp.rs diff --git a/src/test/run-make/pretty-expanded-hygiene/input.rs b/src/test/run-make/pretty-expanded-hygiene/input.rs index a46fa12ac05..a46fa12ac05 100755..100644 --- a/src/test/run-make/pretty-expanded-hygiene/input.rs +++ b/src/test/run-make/pretty-expanded-hygiene/input.rs diff --git a/src/test/run-make/save-analysis/foo.rs b/src/test/run-make/save-analysis/foo.rs index 7d94f4c7b17..2e2b8d2578e 100644 --- a/src/test/run-make/save-analysis/foo.rs +++ b/src/test/run-make/save-analysis/foo.rs @@ -39,17 +39,17 @@ static bob: Option<&'static [isize]> = None; // buglink test - see issue #1337. fn test_alias<I: Iterator>(i: Option<<I as Iterator>::Item>) { - let s = sub_struct{ field2: 45u32, }; + let s = sub_struct{ field2: 45, }; // import tests fn foo(x: &Float) {} let _: Option<u8> = from_i32(45); - let x = 42_usize; + let x = 42; myflate::deflate_bytes(&[]); - let x = (3, 4_usize); + let x = (3, 4); let y = x.1; } diff --git a/src/test/run-make/simd-ffi/simd.rs b/src/test/run-make/simd-ffi/simd.rs index f418d5d1fb7..f418d5d1fb7 100755..100644 --- a/src/test/run-make/simd-ffi/simd.rs +++ b/src/test/run-make/simd-ffi/simd.rs diff --git a/src/test/run-make/symbols-are-reasonable/lib.rs b/src/test/run-make/symbols-are-reasonable/lib.rs index e1f36ecda53..f81d4803f8f 100644 --- a/src/test/run-make/symbols-are-reasonable/lib.rs +++ b/src/test/run-make/symbols-are-reasonable/lib.rs @@ -16,5 +16,5 @@ impl Foo for uint {} pub fn dummy() { // force the vtable to be created - let _x = &1_usize as &Foo; + let _x = &1 as &Foo; } diff --git a/src/test/run-make/unicode-input/span_length.rs b/src/test/run-make/unicode-input/span_length.rs index ef6c799336b..a6cb9fe0324 100644 --- a/src/test/run-make/unicode-input/span_length.rs +++ b/src/test/run-make/unicode-input/span_length.rs @@ -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()); diff --git a/src/test/run-pass-fulldeps/compiler-calls.rs b/src/test/run-pass-fulldeps/compiler-calls.rs index 9e164522d77..75a968c3f81 100644 --- a/src/test/run-pass-fulldeps/compiler-calls.rs +++ b/src/test/run-pass-fulldeps/compiler-calls.rs @@ -25,6 +25,7 @@ use rustc::session::config::{self, Input}; use rustc_driver::{driver, CompilerCalls, Compilation}; use syntax::diagnostics; +use std::path::PathBuf; struct TestCalls { count: u32 @@ -43,14 +44,15 @@ impl<'a> CompilerCalls<'a> for TestCalls { _: &getopts::Matches, _: &Session, _: &Input, - _: &Option<Path>, - _: &Option<Path>) + _: &Option<PathBuf>, + _: &Option<PathBuf>) -> Compilation { self.count *= 3; Compilation::Stop } - fn some_input(&mut self, input: Input, input_path: Option<Path>) -> (Input, Option<Path>) { + fn some_input(&mut self, input: Input, input_path: Option<PathBuf>) + -> (Input, Option<PathBuf>) { self.count *= 5; (input, input_path) } @@ -58,10 +60,10 @@ impl<'a> CompilerCalls<'a> for TestCalls { fn no_input(&mut self, _: &getopts::Matches, _: &config::Options, - _: &Option<Path>, - _: &Option<Path>, + _: &Option<PathBuf>, + _: &Option<PathBuf>, _: &diagnostics::registry::Registry) - -> Option<(Input, Option<Path>)> { + -> Option<(Input, Option<PathBuf>)> { panic!("This shouldn't happen"); } diff --git a/src/test/run-pass-fulldeps/derive-totalsum.rs b/src/test/run-pass-fulldeps/derive-totalsum.rs new file mode 100644 index 00000000000..848b2425e44 --- /dev/null +++ b/src/test/run-pass-fulldeps/derive-totalsum.rs @@ -0,0 +1,59 @@ +// 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:custom_derive_plugin.rs +// ignore-stage1 + +#![feature(plugin, custom_derive)] +#![plugin(custom_derive_plugin)] + +trait TotalSum { + fn total_sum(&self) -> isize; +} + +impl TotalSum for isize { + fn total_sum(&self) -> isize { + *self + } +} + +struct Seven; + +impl TotalSum for Seven { + fn total_sum(&self) -> isize { + 7 + } +} + +#[derive(TotalSum)] +struct Foo { + seven: Seven, + bar: Bar, + baz: isize, +} + +#[derive(TotalSum)] +struct Bar { + quux: isize, + bleh: isize, +} + + +pub fn main() { + let v = Foo { + seven: Seven, + bar: Bar { + quux: 9, + bleh: 3, + }, + baz: 80, + }; + assert_eq!(v.total_sum(), 99); +} diff --git a/src/test/run-pass-fulldeps/macro-crate.rs b/src/test/run-pass-fulldeps/macro-crate.rs index 58ccd79b712..7a2846c31b6 100644 --- a/src/test/run-pass-fulldeps/macro-crate.rs +++ b/src/test/run-pass-fulldeps/macro-crate.rs @@ -11,7 +11,7 @@ // aux-build:macro_crate_test.rs // ignore-stage1 -#![feature(plugin)] +#![feature(plugin, custom_attribute)] #![plugin(macro_crate_test)] #[macro_use] #[no_link] diff --git a/src/test/run-pass-fulldeps/mbe_matching_test_macro.rs b/src/test/run-pass-fulldeps/mbe_matching_test_macro.rs new file mode 100644 index 00000000000..5383b11cf53 --- /dev/null +++ b/src/test/run-pass-fulldeps/mbe_matching_test_macro.rs @@ -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. + +// aux-build:procedural_mbe_matching.rs +// ignore-stage1 + +#![feature(plugin)] +#![plugin(procedural_mbe_matching)] + +#[no_link] +extern crate procedural_mbe_matching; + +pub fn main() { + let abc = 123u32; + assert_eq!(matches!(Some(123), None | Some(0)), false); + assert_eq!(matches!(Some(123), None | Some(123)), true); + assert_eq!(matches!(true, true), true); +} diff --git a/src/test/run-pass-fulldeps/qquote.rs b/src/test/run-pass-fulldeps/qquote.rs index 252d297d12d..92cb0d71e45 100644 --- a/src/test/run-pass-fulldeps/qquote.rs +++ b/src/test/run-pass-fulldeps/qquote.rs @@ -1,4 +1,4 @@ -// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT +// 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. // @@ -74,6 +74,9 @@ fn main() { let arm = quote_arm!(cx, (ref x, ref y) => (x, y)); check_pp(ext_cx, arm, pprust::print_stmt, "(ref x, ref y) = (x, y)".to_string()); + + let attr = quote_attr!(cx, #![cfg(foo = "bar")]); + check_pp(ext_cx, attr, pprust::print_attribute, "#![cfg(foo = "bar")]".to_string()); } fn check_pp<T>(cx: fake_ext_ctxt, diff --git a/src/test/run-pass-fulldeps/quote-tokens.rs b/src/test/run-pass-fulldeps/quote-tokens.rs index e76c379177b..a9b77419b9a 100644 --- a/src/test/run-pass-fulldeps/quote-tokens.rs +++ b/src/test/run-pass-fulldeps/quote-tokens.rs @@ -40,6 +40,11 @@ fn syntax_extension(cx: &ExtCtxt) { let _k: P<syntax::ast::Method> = quote_method!(cx, #[doc = "hello"] fn foo(&self) {}); let _l: P<syntax::ast::Ty> = quote_ty!(cx, &int); + + let _m: Vec<syntax::ast::TokenTree> = quote_matcher!(cx, $($foo:tt,)* bar); + let _n: syntax::ast::Attribute = quote_attr!(cx, #![cfg(foo, bar = "baz")]); + + let _o: Option<P<syntax::ast::Item>> = quote_item!(cx, fn foo<T: ?Sized>() {}); } fn main() { diff --git a/src/test/run-pass/alias-uninit-value.rs b/src/test/run-pass/alias-uninit-value.rs index b1bebf0b3e6..45dd213d71f 100644 --- a/src/test/run-pass/alias-uninit-value.rs +++ b/src/test/run-pass/alias-uninit-value.rs @@ -17,7 +17,7 @@ enum sty { ty_nil, } struct RawT {struct_: sty, cname: Option<String>, hash: uint} fn mk_raw_ty(st: sty, cname: Option<String>) -> RawT { - return RawT {struct_: st, cname: cname, hash: 0_usize}; + return RawT {struct_: st, cname: cname, hash: 0}; } pub fn main() { mk_raw_ty(sty::ty_nil, None::<String>); } diff --git a/src/test/run-pass/associated-types-constant-type.rs b/src/test/run-pass/associated-types-constant-type.rs index 57e9230336c..299225e3a47 100644 --- a/src/test/run-pass/associated-types-constant-type.rs +++ b/src/test/run-pass/associated-types-constant-type.rs @@ -35,5 +35,5 @@ fn get(x: int) -> <int as SignedUnsigned>::Opposite { fn main() { let x = get(22); - assert_eq!(22_usize, x); + assert_eq!(22, x); } diff --git a/src/test/run-pass/associated-types-return.rs b/src/test/run-pass/associated-types-return.rs index 8ae550be3fc..e7ab910bc95 100644 --- a/src/test/run-pass/associated-types-return.rs +++ b/src/test/run-pass/associated-types-return.rs @@ -43,7 +43,7 @@ fn foo2<I: Foo>(x: I) -> <I as Foo>::A { pub fn main() { let a = 42; - assert!(foo2(a) == 42_usize); + assert!(foo2(a) == 42); let a = Bar; assert!(foo2(a) == 43); diff --git a/src/test/run-pass/associated-types-struct-field-named.rs b/src/test/run-pass/associated-types-struct-field-named.rs index 8667f6c8430..a63274beb0e 100644 --- a/src/test/run-pass/associated-types-struct-field-named.rs +++ b/src/test/run-pass/associated-types-struct-field-named.rs @@ -36,8 +36,8 @@ impl UnifyKey for u32 { pub fn main() { let node: Node<i32> = Node { key: 1, value: Some(22) }; - assert_eq!(foo(&node), Some(22_u32)); + assert_eq!(foo(&node), Some(22)); let node: Node<u32> = Node { key: 1, value: Some(22) }; - assert_eq!(foo(&node), Some(22_i32)); + assert_eq!(foo(&node), Some(22)); } diff --git a/src/test/run-pass/associated-types-struct-field-numbered.rs b/src/test/run-pass/associated-types-struct-field-numbered.rs index 9503f78a71b..3be2623185b 100644 --- a/src/test/run-pass/associated-types-struct-field-numbered.rs +++ b/src/test/run-pass/associated-types-struct-field-numbered.rs @@ -33,8 +33,8 @@ impl UnifyKey for u32 { pub fn main() { let node: Node<i32> = Node(1, Some(22)); - assert_eq!(foo(&node), Some(22_u32)); + assert_eq!(foo(&node), Some(22)); let node: Node<u32> = Node(1, Some(22)); - assert_eq!(foo(&node), Some(22_i32)); + assert_eq!(foo(&node), Some(22)); } diff --git a/src/test/run-pass/associated-types-sugar-path.rs b/src/test/run-pass/associated-types-sugar-path.rs index c068065ac6a..7e7299961d8 100644 --- a/src/test/run-pass/associated-types-sugar-path.rs +++ b/src/test/run-pass/associated-types-sugar-path.rs @@ -41,5 +41,5 @@ impl<T: Foo> C for B<T> { } pub fn main() { - let z: uint = bar(2, 4_usize); + let z: uint = bar(2, 4); } diff --git a/src/test/run-pass/auto-encode.rs b/src/test/run-pass/auto-encode.rs index 7c126fc420a..2b84adcb15c 100644 --- a/src/test/run-pass/auto-encode.rs +++ b/src/test/run-pass/auto-encode.rs @@ -131,19 +131,19 @@ enum Quark<T> { enum CLike { A, B, C } pub fn main() { - let a = &Plus(@Minus(@Val(3_usize), @Val(10_usize)), @Plus(@Val(22_usize), @Val(5_usize))); + let a = &Plus(@Minus(@Val(3), @Val(10)), @Plus(@Val(22), @Val(5))); test_rbml(a); - let a = &Spanned {lo: 0_usize, hi: 5_usize, node: 22_usize}; + let a = &Spanned {lo: 0, hi: 5, node: 22}; test_rbml(a); - let a = &Point {x: 3_usize, y: 5_usize}; + let a = &Point {x: 3, y: 5}; test_rbml(a); - let a = &Top(22_usize); + let a = &Top(22); test_rbml(a); - let a = &Bottom(222_usize); + let a = &Bottom(222); test_rbml(a); let a = &A; diff --git a/src/test/run-pass/autoderef-method-on-trait.rs b/src/test/run-pass/autoderef-method-on-trait.rs index 8121edfd2cc..6a90fa47e58 100644 --- a/src/test/run-pass/autoderef-method-on-trait.rs +++ b/src/test/run-pass/autoderef-method-on-trait.rs @@ -16,10 +16,10 @@ trait double { } impl double for uint { - fn double(self: Box<uint>) -> uint { *self * 2_usize } + fn double(self: Box<uint>) -> uint { *self * 2 } } pub fn main() { - let x: Box<_> = box() (box 3_usize as Box<double>); - assert_eq!(x.double(), 6_usize); + let x: Box<_> = box() (box 3 as Box<double>); + assert_eq!(x.double(), 6); } diff --git a/src/test/run-pass/autoderef-method-priority.rs b/src/test/run-pass/autoderef-method-priority.rs index 537894bfd15..cadce45b18d 100644 --- a/src/test/run-pass/autoderef-method-priority.rs +++ b/src/test/run-pass/autoderef-method-priority.rs @@ -20,10 +20,10 @@ impl double for uint { } impl double for Box<uint> { - fn double(self) -> uint { *self * 2_usize } + fn double(self) -> uint { *self * 2 } } pub fn main() { - let x: Box<_> = box 3_usize; - assert_eq!(x.double(), 6_usize); + let x: Box<_> = box 3; + assert_eq!(x.double(), 6); } diff --git a/src/test/run-pass/autoderef-method-twice-but-not-thrice.rs b/src/test/run-pass/autoderef-method-twice-but-not-thrice.rs index 2ffdd576ffb..746107803c9 100644 --- a/src/test/run-pass/autoderef-method-twice-but-not-thrice.rs +++ b/src/test/run-pass/autoderef-method-twice-but-not-thrice.rs @@ -16,10 +16,10 @@ trait double { } impl double for Box<uint> { - fn double(self: Box<Box<uint>>) -> uint { **self * 2_usize } + fn double(self: Box<Box<uint>>) -> uint { **self * 2 } } pub fn main() { - let x: Box<Box<Box<Box<Box<_>>>>> = box box box box box 3_usize; - assert_eq!(x.double(), 6_usize); + let x: Box<Box<Box<Box<Box<_>>>>> = box box box box box 3; + assert_eq!(x.double(), 6); } diff --git a/src/test/run-pass/autoderef-method-twice.rs b/src/test/run-pass/autoderef-method-twice.rs index 82510aea162..51b5c98816a 100644 --- a/src/test/run-pass/autoderef-method-twice.rs +++ b/src/test/run-pass/autoderef-method-twice.rs @@ -16,10 +16,10 @@ trait double { } impl double for uint { - fn double(self: Box<uint>) -> uint { *self * 2_usize } + fn double(self: Box<uint>) -> uint { *self * 2 } } pub fn main() { - let x: Box<Box<_>> = box box 3_usize; - assert_eq!(x.double(), 6_usize); + let x: Box<Box<_>> = box box 3; + assert_eq!(x.double(), 6); } diff --git a/src/test/run-pass/autoderef-method.rs b/src/test/run-pass/autoderef-method.rs index c9aa1133101..61e704276af 100644 --- a/src/test/run-pass/autoderef-method.rs +++ b/src/test/run-pass/autoderef-method.rs @@ -16,10 +16,10 @@ trait double { } impl double for uint { - fn double(self: Box<uint>) -> uint { *self * 2_usize } + fn double(self: Box<uint>) -> uint { *self * 2 } } pub fn main() { - let x: Box<_> = box 3_usize; - assert_eq!(x.double(), 6_usize); + let x: Box<_> = box 3; + assert_eq!(x.double(), 6); } diff --git a/src/test/run-pass/autoref-intermediate-types-issue-3585.rs b/src/test/run-pass/autoref-intermediate-types-issue-3585.rs index 6e6e58a7ddf..86d6a91e75b 100644 --- a/src/test/run-pass/autoref-intermediate-types-issue-3585.rs +++ b/src/test/run-pass/autoref-intermediate-types-issue-3585.rs @@ -29,6 +29,6 @@ impl Foo for uint { } pub fn main() { - let x: Box<_> = box 3_usize; + let x: Box<_> = box 3; assert_eq!(x.foo(), "box 3".to_string()); } diff --git a/src/test/run-pass/big-literals.rs b/src/test/run-pass/big-literals.rs index 8afb33c7669..01ac2fc20bf 100644 --- a/src/test/run-pass/big-literals.rs +++ b/src/test/run-pass/big-literals.rs @@ -9,10 +9,10 @@ // except according to those terms. pub fn main() { - assert_eq!(0xffffffffu32, (-1 as u32)); - assert_eq!(4294967295u32, (-1 as u32)); - assert_eq!(0xffffffffffffffffu64, (-1 as u64)); - assert_eq!(18446744073709551615u64, (-1 as u64)); + assert_eq!(0xffffffff, (-1 as u32)); + assert_eq!(4294967295, (-1 as u32)); + assert_eq!(0xffffffffffffffff, (-1 as u64)); + assert_eq!(18446744073709551615, (-1 as u64)); - assert_eq!(-2147483648i32 - 1i32, 2147483647i32); + assert_eq!(-2147483648 - 1, 2147483647); } diff --git a/src/test/run-pass/block-arg-call-as.rs b/src/test/run-pass/block-arg-call-as.rs index d319aaa2f8e..8be6d1bd35a 100644 --- a/src/test/run-pass/block-arg-call-as.rs +++ b/src/test/run-pass/block-arg-call-as.rs @@ -13,6 +13,6 @@ fn asBlock<F>(f: F) -> uint where F: FnOnce() -> uint { } pub fn main() { - let x = asBlock(|| 22_usize); - assert_eq!(x, 22_usize); + let x = asBlock(|| 22); + assert_eq!(x, 22); } diff --git a/src/test/run-pass/block-iter-1.rs b/src/test/run-pass/block-iter-1.rs index d5d26f42ef0..7cbe8104deb 100644 --- a/src/test/run-pass/block-iter-1.rs +++ b/src/test/run-pass/block-iter-1.rs @@ -11,8 +11,8 @@ fn iter_vec<T, F>(v: Vec<T> , mut f: F) where F: FnMut(&T) { for x in &v { f(x); } } pub fn main() { - let v = vec![1i32, 2, 3, 4, 5, 6, 7]; - let mut odds = 0i32; + let v = vec![1, 2, 3, 4, 5, 6, 7]; + let mut odds = 0; iter_vec(v, |i| { if *i % 2 == 1 { odds += 1; diff --git a/src/test/run-pass/block-iter-2.rs b/src/test/run-pass/block-iter-2.rs index 8c079ca4b07..7701f6114ca 100644 --- a/src/test/run-pass/block-iter-2.rs +++ b/src/test/run-pass/block-iter-2.rs @@ -11,7 +11,7 @@ fn iter_vec<T, F>(v: Vec<T>, mut f: F) where F: FnMut(&T) { for x in &v { f(x); } } pub fn main() { - let v = vec![1i32, 2, 3, 4, 5]; + let v = vec![1, 2, 3, 4, 5]; let mut sum = 0; iter_vec(v.clone(), |i| { iter_vec(v.clone(), |j| { diff --git a/src/test/run-pass/borrowck-closures-two-imm.rs b/src/test/run-pass/borrowck-closures-two-imm.rs index c907778339e..75161d16bc0 100644 --- a/src/test/run-pass/borrowck-closures-two-imm.rs +++ b/src/test/run-pass/borrowck-closures-two-imm.rs @@ -15,7 +15,7 @@ // the closures are in scope. Issue #6801. fn a() -> i32 { - let mut x = 3i32; + let mut x = 3; x += 1; let c1 = || x * 4; let c2 = || x * 5; @@ -27,7 +27,7 @@ fn get(x: &i32) -> i32 { } fn b() -> i32 { - let mut x = 3i32; + let mut x = 3; x += 1; let c1 = || get(&x); let c2 = || get(&x); @@ -35,7 +35,7 @@ fn b() -> i32 { } fn c() -> i32 { - let mut x = 3i32; + let mut x = 3; x += 1; let c1 = || x * 5; let c2 = || get(&x); diff --git a/src/test/run-pass/borrowck-mut-uniq.rs b/src/test/run-pass/borrowck-mut-uniq.rs index 499650a6e51..d35600ef22e 100644 --- a/src/test/run-pass/borrowck-mut-uniq.rs +++ b/src/test/run-pass/borrowck-mut-uniq.rs @@ -26,7 +26,7 @@ fn add_int(x: &mut Ints, v: int) { fn iter_ints<F>(x: &Ints, mut f: F) -> bool where F: FnMut(&int) -> bool { let l = x.values.len(); - (0_usize..l).all(|i| f(&x.values[i])) + (0..l).all(|i| f(&x.values[i])) } pub fn main() { diff --git a/src/test/run-pass/c-stack-returning-int64.rs b/src/test/run-pass/c-stack-returning-int64.rs index 6246ee9c6c4..1de7520d2b1 100644 --- a/src/test/run-pass/c-stack-returning-int64.rs +++ b/src/test/run-pass/c-stack-returning-int64.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-fast doesn't like extern crate extern crate libc; diff --git a/src/test/run-pass/capture-clauses-unboxed-closures.rs b/src/test/run-pass/capture-clauses-unboxed-closures.rs index dd417f1a9eb..19316590c26 100644 --- a/src/test/run-pass/capture-clauses-unboxed-closures.rs +++ b/src/test/run-pass/capture-clauses-unboxed-closures.rs @@ -17,8 +17,8 @@ fn each<'a,T,F:FnMut(&'a T)>(x: &'a [T], mut f: F) { } fn main() { - let mut sum = 0_usize; - let elems = [ 1_usize, 2, 3, 4, 5 ]; + let mut sum = 0; + let elems = [ 1, 2, 3, 4, 5 ]; each(&elems, |val: &uint| sum += *val); assert_eq!(sum, 15); } diff --git a/src/test/run-pass/cast.rs b/src/test/run-pass/cast.rs index f8a680b2a97..fc71e6c59fc 100644 --- a/src/test/run-pass/cast.rs +++ b/src/test/run-pass/cast.rs @@ -16,6 +16,6 @@ pub fn main() { assert_eq!(u, 'Q' as u32); assert_eq!(i as u8, 'Q' as u8); assert_eq!(i as u8 as i8, 'Q' as u8 as i8); - assert_eq!(0x51u8 as char, 'Q'); + assert_eq!(0x51 as char, 'Q'); assert_eq!(0 as u32, false as u32); } diff --git a/src/test/run-pass/cci_borrow.rs b/src/test/run-pass/cci_borrow.rs index 89babb8f722..cd8f783a2e5 100644 --- a/src/test/run-pass/cci_borrow.rs +++ b/src/test/run-pass/cci_borrow.rs @@ -17,8 +17,8 @@ extern crate cci_borrow_lib; use cci_borrow_lib::foo; pub fn main() { - let p: Box<_> = box 22_usize; + let p: Box<_> = box 22; let r = foo(&*p); println!("r={}", r); - assert_eq!(r, 22_usize); + assert_eq!(r, 22); } diff --git a/src/test/run-pass/cci_impl_exe.rs b/src/test/run-pass/cci_impl_exe.rs index c4b55b9962f..bda3b73e29c 100644 --- a/src/test/run-pass/cci_impl_exe.rs +++ b/src/test/run-pass/cci_impl_exe.rs @@ -17,7 +17,7 @@ pub fn main() { //let bt0 = sys::frame_address(); //println!("%?", bt0); - 3_usize.to(10_usize, |i| { + 3.to(10, |i| { println!("{}", i); //let bt1 = sys::frame_address(); diff --git a/src/test/run-pass/cci_iter_exe.rs b/src/test/run-pass/cci_iter_exe.rs index e4b26ba74be..5b91af7a194 100644 --- a/src/test/run-pass/cci_iter_exe.rs +++ b/src/test/run-pass/cci_iter_exe.rs @@ -13,10 +13,10 @@ extern crate cci_iter_lib; pub fn main() { - //let bt0 = sys::rusti::frame_address(1u32); + //let bt0 = sys::rusti::frame_address(1); //println!("%?", bt0); cci_iter_lib::iter(&[1, 2, 3], |i| { println!("{}", *i); - //assert!(bt0 == sys::rusti::frame_address(2u32)); + //assert!(bt0 == sys::rusti::frame_address(2)); }) } diff --git a/src/test/run-pass/cci_no_inline_exe.rs b/src/test/run-pass/cci_no_inline_exe.rs index 2040bd7ad71..cc76ed530c4 100644 --- a/src/test/run-pass/cci_no_inline_exe.rs +++ b/src/test/run-pass/cci_no_inline_exe.rs @@ -21,7 +21,7 @@ pub fn main() { // actually working. //let bt0 = sys::frame_address(); //println!("%?", bt0); - iter(vec!(1_usize, 2_usize, 3_usize), |i| { + iter(vec!(1, 2, 3), |i| { println!("{}", i); //let bt1 = sys::frame_address(); diff --git a/src/test/run-pass/class-cast-to-trait-cross-crate-2.rs b/src/test/run-pass/class-cast-to-trait-cross-crate-2.rs index 9a388c9bc24..da51ad761c7 100644 --- a/src/test/run-pass/class-cast-to-trait-cross-crate-2.rs +++ b/src/test/run-pass/class-cast-to-trait-cross-crate-2.rs @@ -25,6 +25,6 @@ fn print_out(thing: Box<ToString>, expected: String) { } pub fn main() { - let nyan: Box<ToString> = box cat(0_usize, 2, "nyan".to_string()) as Box<ToString>; + let nyan: Box<ToString> = box cat(0, 2, "nyan".to_string()) as Box<ToString>; print_out(nyan, "nyan".to_string()); } diff --git a/src/test/run-pass/class-cast-to-trait.rs b/src/test/run-pass/class-cast-to-trait.rs index 476594c270e..01513ab6f47 100644 --- a/src/test/run-pass/class-cast-to-trait.rs +++ b/src/test/run-pass/class-cast-to-trait.rs @@ -42,8 +42,8 @@ impl cat { impl cat { fn meow(&mut self) { println!("Meow"); - self.meows += 1_usize; - if self.meows % 5_usize == 0_usize { + self.meows += 1; + if self.meows % 5 == 0 { self.how_hungry += 1; } } @@ -59,7 +59,7 @@ fn cat(in_x : uint, in_y : int, in_name: String) -> cat { pub fn main() { - let mut nyan = cat(0_usize, 2, "nyan".to_string()); + let mut nyan = cat(0, 2, "nyan".to_string()); let mut nyan: &mut noisy = &mut nyan; nyan.speak(); } diff --git a/src/test/run-pass/class-dtor.rs b/src/test/run-pass/class-dtor.rs index 14247ad7754..c98e53c8a95 100644 --- a/src/test/run-pass/class-dtor.rs +++ b/src/test/run-pass/class-dtor.rs @@ -21,7 +21,7 @@ impl Drop for cat { fn cat(done: extern fn(uint)) -> cat { cat { - meows: 0_usize, + meows: 0, done: done } } diff --git a/src/test/run-pass/class-exports.rs b/src/test/run-pass/class-exports.rs index 4c7d0e6951a..1cf4c35ee96 100644 --- a/src/test/run-pass/class-exports.rs +++ b/src/test/run-pass/class-exports.rs @@ -27,7 +27,7 @@ mod kitty { pub fn cat(in_name: String) -> cat { cat { name: in_name, - meows: 0_usize + meows: 0 } } } diff --git a/src/test/run-pass/class-method-cross-crate.rs b/src/test/run-pass/class-method-cross-crate.rs index 47cc500e44e..55acd2e040d 100644 --- a/src/test/run-pass/class-method-cross-crate.rs +++ b/src/test/run-pass/class-method-cross-crate.rs @@ -13,8 +13,8 @@ extern crate cci_class_2; use cci_class_2::kitties::cat; pub fn main() { - let nyan : cat = cat(52_usize, 99); - let kitty = cat(1000_usize, 2); + let nyan : cat = cat(52, 99); + let kitty = cat(1000, 2); assert_eq!(nyan.how_hungry, 99); assert_eq!(kitty.how_hungry, 2); nyan.speak(); diff --git a/src/test/run-pass/class-methods-cross-crate.rs b/src/test/run-pass/class-methods-cross-crate.rs index d62a726dcdd..34c309780b1 100644 --- a/src/test/run-pass/class-methods-cross-crate.rs +++ b/src/test/run-pass/class-methods-cross-crate.rs @@ -13,10 +13,10 @@ extern crate cci_class_3; use cci_class_3::kitties::cat; pub fn main() { - let mut nyan : cat = cat(52_usize, 99); - let kitty = cat(1000_usize, 2); + let mut nyan : cat = cat(52, 99); + let kitty = cat(1000, 2); assert_eq!(nyan.how_hungry, 99); assert_eq!(kitty.how_hungry, 2); nyan.speak(); - assert_eq!(nyan.meow_count(), 53_usize); + assert_eq!(nyan.meow_count(), 53); } diff --git a/src/test/run-pass/class-methods.rs b/src/test/run-pass/class-methods.rs index 18fb03ec935..8fa76342286 100644 --- a/src/test/run-pass/class-methods.rs +++ b/src/test/run-pass/class-methods.rs @@ -15,7 +15,7 @@ struct cat { } impl cat { - pub fn speak(&mut self) { self.meows += 1_usize; } + pub fn speak(&mut self) { self.meows += 1; } pub fn meow_count(&mut self) -> uint { self.meows } } @@ -27,10 +27,10 @@ fn cat(in_x: uint, in_y: int) -> cat { } pub fn main() { - let mut nyan: cat = cat(52_usize, 99); - let kitty = cat(1000_usize, 2); + let mut nyan: cat = cat(52, 99); + let kitty = cat(1000, 2); assert_eq!(nyan.how_hungry, 99); assert_eq!(kitty.how_hungry, 2); nyan.speak(); - assert_eq!(nyan.meow_count(), 53_usize); + assert_eq!(nyan.meow_count(), 53); } diff --git a/src/test/run-pass/class-poly-methods.rs b/src/test/run-pass/class-poly-methods.rs index b529b0a0772..557f9986238 100644 --- a/src/test/run-pass/class-poly-methods.rs +++ b/src/test/run-pass/class-poly-methods.rs @@ -32,12 +32,12 @@ fn cat<U>(in_x : uint, in_y : int, in_info: Vec<U> ) -> cat<U> { } pub fn main() { - let mut nyan : cat<int> = cat::<int>(52_usize, 99, vec!(9)); - let mut kitty = cat(1000_usize, 2, vec!("tabby".to_string())); + let mut nyan : cat<int> = cat::<int>(52, 99, vec!(9)); + let mut kitty = cat(1000, 2, vec!("tabby".to_string())); assert_eq!(nyan.how_hungry, 99); assert_eq!(kitty.how_hungry, 2); nyan.speak(vec!(1,2,3)); - assert_eq!(nyan.meow_count(), 55_usize); + assert_eq!(nyan.meow_count(), 55); kitty.speak(vec!("meow".to_string(), "mew".to_string(), "purr".to_string(), "chirp".to_string())); - assert_eq!(kitty.meow_count(), 1004_usize); + assert_eq!(kitty.meow_count(), 1004); } diff --git a/src/test/run-pass/class-separate-impl.rs b/src/test/run-pass/class-separate-impl.rs index daff321efcf..2bdc053675f 100644 --- a/src/test/run-pass/class-separate-impl.rs +++ b/src/test/run-pass/class-separate-impl.rs @@ -39,8 +39,8 @@ impl cat { impl cat { fn meow(&mut self) { println!("Meow"); - self.meows += 1_usize; - if self.meows % 5_usize == 0_usize { + self.meows += 1; + if self.meows % 5 == 0 { self.how_hungry += 1; } } @@ -67,6 +67,6 @@ fn print_out(thing: Box<ToString>, expected: String) { } pub fn main() { - let nyan: Box<ToString> = box cat(0_usize, 2, "nyan".to_string()) as Box<ToString>; + let nyan: Box<ToString> = box cat(0, 2, "nyan".to_string()) as Box<ToString>; print_out(nyan, "nyan".to_string()); } diff --git a/src/test/run-pass/class-typarams.rs b/src/test/run-pass/class-typarams.rs index b56a749d33b..c50a8cc83a5 100644 --- a/src/test/run-pass/class-typarams.rs +++ b/src/test/run-pass/class-typarams.rs @@ -17,7 +17,7 @@ struct cat<U> { } impl<U> cat<U> { - pub fn speak(&mut self) { self.meows += 1_usize; } + pub fn speak(&mut self) { self.meows += 1; } pub fn meow_count(&mut self) -> uint { self.meows } } @@ -31,6 +31,6 @@ fn cat<U>(in_x : uint, in_y : int) -> cat<U> { pub fn main() { - let _nyan : cat<int> = cat::<int>(52_usize, 99); - // let mut kitty = cat(1000_usize, 2); + let _nyan : cat<int> = cat::<int>(52, 99); + // let mut kitty = cat(1000, 2); } diff --git a/src/test/run-pass/classes-simple-cross-crate.rs b/src/test/run-pass/classes-simple-cross-crate.rs index 8037d77807d..09660454648 100644 --- a/src/test/run-pass/classes-simple-cross-crate.rs +++ b/src/test/run-pass/classes-simple-cross-crate.rs @@ -13,8 +13,8 @@ extern crate cci_class; use cci_class::kitties::cat; pub fn main() { - let nyan : cat = cat(52_usize, 99); - let kitty = cat(1000_usize, 2); + let nyan : cat = cat(52, 99); + let kitty = cat(1000, 2); assert_eq!(nyan.how_hungry, 99); assert_eq!(kitty.how_hungry, 2); } diff --git a/src/test/run-pass/classes-simple-method.rs b/src/test/run-pass/classes-simple-method.rs index b15d6544fed..502fa73ed93 100644 --- a/src/test/run-pass/classes-simple-method.rs +++ b/src/test/run-pass/classes-simple-method.rs @@ -26,8 +26,8 @@ fn cat(in_x : uint, in_y : int) -> cat { } pub fn main() { - let mut nyan : cat = cat(52_usize, 99); - let kitty = cat(1000_usize, 2); + let mut nyan : cat = cat(52, 99); + let kitty = cat(1000, 2); assert_eq!(nyan.how_hungry, 99); assert_eq!(kitty.how_hungry, 2); nyan.speak(); diff --git a/src/test/run-pass/classes-simple.rs b/src/test/run-pass/classes-simple.rs index 9bf8df3ce4b..3cf529f2958 100644 --- a/src/test/run-pass/classes-simple.rs +++ b/src/test/run-pass/classes-simple.rs @@ -22,8 +22,8 @@ fn cat(in_x : uint, in_y : int) -> cat { } pub fn main() { - let nyan : cat = cat(52_usize, 99); - let kitty = cat(1000_usize, 2); + let nyan : cat = cat(52, 99); + let kitty = cat(1000, 2); assert_eq!(nyan.how_hungry, 99); assert_eq!(kitty.how_hungry, 2); } diff --git a/src/test/run-pass/coerce-reborrow-imm-vec-rcvr.rs b/src/test/run-pass/coerce-reborrow-imm-vec-rcvr.rs index ade18a71259..32230c82a72 100644 --- a/src/test/run-pass/coerce-reborrow-imm-vec-rcvr.rs +++ b/src/test/run-pass/coerce-reborrow-imm-vec-rcvr.rs @@ -18,7 +18,7 @@ fn bip(v: &[uint]) -> Vec<uint> { } pub fn main() { - let mut the_vec = vec!(1_usize, 2, 3, 100); + let mut the_vec = vec!(1, 2, 3, 100); assert_eq!(the_vec.clone(), bar(&mut the_vec)); assert_eq!(the_vec.clone(), bip(&the_vec)); } diff --git a/src/test/run-pass/concat.rs b/src/test/run-pass/concat.rs index b0c3a5922b6..2de881993f1 100644 --- a/src/test/run-pass/concat.rs +++ b/src/test/run-pass/concat.rs @@ -15,12 +15,12 @@ pub fn main() { assert_eq!(concat!("qux", "quux",).to_string(), "quxquux".to_string()); assert_eq!( - concat!(1, 2, 3_usize, 4f32, 4.0, 'a', true), + concat!(1, 2, 3, 4f32, 4.0, 'a', true), "12344.0atrue" ); assert!(match "12344.0atrue" { - concat!(1, 2, 3_usize, 4f32, 4.0, 'a', true) => true, + concat!(1, 2, 3, 4f32, 4.0, 'a', true) => true, _ => false }) } diff --git a/src/test/run-pass/conditional-debug-macro-off.rs b/src/test/run-pass/conditional-debug-macro-off.rs index b5a5f57d07a..90142350772 100644 --- a/src/test/run-pass/conditional-debug-macro-off.rs +++ b/src/test/run-pass/conditional-debug-macro-off.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// compile-flags: --cfg ndebug +// compile-flags: -C debug-assertions=no // exec-env:RUST_LOG=conditional-debug-macro-off=4 #[macro_use] diff --git a/src/test/run-pass/const-block.rs b/src/test/run-pass/const-block.rs index cdb96e5dcbf..bdde0cf02c9 100644 --- a/src/test/run-pass/const-block.rs +++ b/src/test/run-pass/const-block.rs @@ -58,6 +58,6 @@ pub fn main() { assert_eq!(BLOCK_FN(300), 300); assert_eq!(BLOCK_ENUM_CONSTRUCTOR(200), Some(200)); // FIXME #13972 - // assert_eq!(BLOCK_UNSAFE_SAFE_PTR as *const isize as usize, 0xdeadbeef_us); - // assert_eq!(BLOCK_UNSAFE_SAFE_PTR_2 as *const isize as usize, 0xdeadbeef_us); + // assert_eq!(BLOCK_UNSAFE_SAFE_PTR as *const isize as usize, 0xdeadbeef); + // assert_eq!(BLOCK_UNSAFE_SAFE_PTR_2 as *const isize as usize, 0xdeadbeef); } diff --git a/src/test/run-pass/const-bound.rs b/src/test/run-pass/const-bound.rs index 3a64f53dbb0..9b0e7e4e75e 100644 --- a/src/test/run-pass/const-bound.rs +++ b/src/test/run-pass/const-bound.rs @@ -20,7 +20,7 @@ pub fn main() { foo("hi".to_string()); foo(~[1, 2, 3]); foo(F{field: 42}); - foo((1, 2_usize)); + foo((1, 2)); foo(@1);*/ foo(Box::new(1)); } diff --git a/src/test/run-pass/deprecated-derive.rs b/src/test/run-pass/deprecated-derive.rs new file mode 100644 index 00000000000..494d62c7737 --- /dev/null +++ b/src/test/run-pass/deprecated-derive.rs @@ -0,0 +1,15 @@ +// 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. + +#[derive(Show)] +//~^ WARNING derive(Show) is deprecated +struct Test1; + +fn main() { } diff --git a/src/test/run-pass/double-ref.rs b/src/test/run-pass/double-ref.rs index 8018f681f38..0cb48670f23 100644 --- a/src/test/run-pass/double-ref.rs +++ b/src/test/run-pass/double-ref.rs @@ -9,23 +9,23 @@ // except according to those terms. fn check_expr() { - let _: & uint = &1_usize; - let _: & & uint = &&1_usize; - let _: & & & uint = &&&1_usize; - let _: & & & uint = & &&1_usize; - let _: & & & & uint = &&&&1_usize; - let _: & & & & uint = & &&&1_usize; - let _: & & & & & uint = &&&&&1_usize; + let _: & uint = &1; + let _: & & uint = &&1; + let _: & & & uint = &&&1; + let _: & & & uint = & &&1; + let _: & & & & uint = &&&&1; + let _: & & & & uint = & &&&1; + let _: & & & & & uint = &&&&&1; } fn check_ty() { - let _: &uint = & 1_usize; - let _: &&uint = & & 1_usize; - let _: &&&uint = & & & 1_usize; - let _: & &&uint = & & & 1_usize; - let _: &&&&uint = & & & & 1_usize; - let _: & &&&uint = & & & & 1_usize; - let _: &&&&&uint = & & & & & 1_usize; + let _: &uint = & 1; + let _: &&uint = & & 1; + let _: &&&uint = & & & 1; + let _: & &&uint = & & & 1; + let _: &&&&uint = & & & & 1; + let _: & &&&uint = & & & & 1; + let _: &&&&&uint = & & & & & 1; } fn check_pat() { diff --git a/src/test/run-pass/drop-trait-enum.rs b/src/test/run-pass/drop-trait-enum.rs index f94da9fc747..353bd7a9ce0 100644 --- a/src/test/run-pass/drop-trait-enum.rs +++ b/src/test/run-pass/drop-trait-enum.rs @@ -62,7 +62,7 @@ pub fn main() { let (sender, receiver) = channel(); { - let v = Foo::NestedVariant(box 42_usize, SendOnDrop { sender: sender.clone() }, sender); + let v = Foo::NestedVariant(box 42, SendOnDrop { sender: sender.clone() }, sender); } assert_eq!(receiver.recv().unwrap(), Message::DestructorRan); assert_eq!(receiver.recv().unwrap(), Message::Dropped); @@ -79,10 +79,10 @@ pub fn main() { let (sender, receiver) = channel(); let t = { thread::spawn(move|| { - let mut v = Foo::NestedVariant(box 42usize, SendOnDrop { + let mut v = Foo::NestedVariant(box 42, SendOnDrop { sender: sender.clone() }, sender.clone()); - v = Foo::NestedVariant(box 42_usize, + v = Foo::NestedVariant(box 42, SendOnDrop { sender: sender.clone() }, sender.clone()); v = Foo::SimpleVariant(sender.clone()); diff --git a/src/test/run-pass/extern-pass-char.rs b/src/test/run-pass/extern-pass-char.rs index 49c3bf62dbc..2e86b3774c8 100644 --- a/src/test/run-pass/extern-pass-char.rs +++ b/src/test/run-pass/extern-pass-char.rs @@ -17,6 +17,6 @@ extern { pub fn main() { unsafe { - assert_eq!(22_u8, rust_dbg_extern_identity_u8(22_u8)); + assert_eq!(22, rust_dbg_extern_identity_u8(22)); } } diff --git a/src/test/run-pass/extern-pass-u32.rs b/src/test/run-pass/extern-pass-u32.rs index 07c04af8e1b..2c018084407 100644 --- a/src/test/run-pass/extern-pass-u32.rs +++ b/src/test/run-pass/extern-pass-u32.rs @@ -17,6 +17,6 @@ extern { pub fn main() { unsafe { - assert_eq!(22_u32, rust_dbg_extern_identity_u32(22_u32)); + assert_eq!(22, rust_dbg_extern_identity_u32(22)); } } diff --git a/src/test/run-pass/extern-pass-u64.rs b/src/test/run-pass/extern-pass-u64.rs index e19c73ebe20..e72e87d3d93 100644 --- a/src/test/run-pass/extern-pass-u64.rs +++ b/src/test/run-pass/extern-pass-u64.rs @@ -17,6 +17,6 @@ extern { pub fn main() { unsafe { - assert_eq!(22_u64, rust_dbg_extern_identity_u64(22_u64)); + assert_eq!(22, rust_dbg_extern_identity_u64(22)); } } diff --git a/src/test/run-pass/extern-stress.rs b/src/test/run-pass/extern-stress.rs deleted file mode 100644 index b9e08e47b37..00000000000 --- a/src/test/run-pass/extern-stress.rs +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// This creates a bunch of descheduling tasks that run concurrently -// while holding onto C stacks - -extern crate libc; -use std::thread::Thread; - -mod rustrt { - extern crate libc; - - #[link(name = "rust_test_helpers")] - extern { - pub fn rust_dbg_call(cb: extern "C" fn(libc::uintptr_t) -> libc::uintptr_t, - data: libc::uintptr_t) - -> libc::uintptr_t; - } -} - -extern fn cb(data: libc::uintptr_t) -> libc::uintptr_t { - if data == 1 { - data - } else { - Thread::yield_now(); - count(data - 1) + count(data - 1) - } -} - -fn count(n: libc::uintptr_t) -> libc::uintptr_t { - unsafe { - rustrt::rust_dbg_call(cb, n) - } -} - -pub fn main() { - (0_usize..100).map(|_| { - Thread::scoped(move|| { - assert_eq!(count(5), 16); - }) - }).collect::<Vec<_>>(); -} diff --git a/src/test/run-pass/extern-yield.rs b/src/test/run-pass/extern-yield.rs deleted file mode 100644 index 80428d787f2..00000000000 --- a/src/test/run-pass/extern-yield.rs +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -extern crate libc; -use std::thread::Thread; - -mod rustrt { - extern crate libc; - - #[link(name = "rust_test_helpers")] - extern { - pub fn rust_dbg_call(cb: extern "C" fn (libc::uintptr_t) -> libc::uintptr_t, - data: libc::uintptr_t) - -> libc::uintptr_t; - } -} - -extern fn cb(data: libc::uintptr_t) -> libc::uintptr_t { - if data == 1 { - data - } else { - count(data - 1) + count(data - 1) - } -} - -fn count(n: libc::uintptr_t) -> libc::uintptr_t { - unsafe { - Thread::yield_now(); - rustrt::rust_dbg_call(cb, n) - } -} - -pub fn main() { - (0..10_usize).map(|i| { - Thread::scoped(move|| { - let result = count(5); - println!("result = {}", result); - assert_eq!(result, 16); - }) - }).collect::<Vec<_>>(); -} diff --git a/src/test/run-pass/foreign-fn-linkname.rs b/src/test/run-pass/foreign-fn-linkname.rs index 24b711328a1..172ece0c4bf 100644 --- a/src/test/run-pass/foreign-fn-linkname.rs +++ b/src/test/run-pass/foreign-fn-linkname.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-fast doesn't like extern crate extern crate libc; use std::ffi::CString; @@ -32,5 +31,5 @@ fn strlen(str: String) -> uint { pub fn main() { let len = strlen("Rust".to_string()); - assert_eq!(len, 4_usize); + assert_eq!(len, 4); } diff --git a/src/test/run-pass/foreign-mod-unused-const.rs b/src/test/run-pass/foreign-mod-unused-const.rs index e1ed0b8ea3b..03023f03233 100644 --- a/src/test/run-pass/foreign-mod-unused-const.rs +++ b/src/test/run-pass/foreign-mod-unused-const.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-fast doesn't like extern crate extern crate libc; diff --git a/src/test/run-pass/foreign2.rs b/src/test/run-pass/foreign2.rs index ce2f8955664..5ebc4effb37 100644 --- a/src/test/run-pass/foreign2.rs +++ b/src/test/run-pass/foreign2.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-fast doesn't like extern crate extern crate libc; diff --git a/src/test/run-pass/i32-sub.rs b/src/test/run-pass/i32-sub.rs index e5451431ade..cebfd89d8aa 100644 --- a/src/test/run-pass/i32-sub.rs +++ b/src/test/run-pass/i32-sub.rs @@ -11,4 +11,4 @@ -pub fn main() { let mut x: i32 = -400_i32; x = 0_i32 - x; assert!((x == 400_i32)); } +pub fn main() { let mut x: i32 = -400; x = 0 - x; assert!((x == 400)); } diff --git a/src/test/run-pass/i8-incr.rs b/src/test/run-pass/i8-incr.rs index fbb4e446dd5..c91e738b822 100644 --- a/src/test/run-pass/i8-incr.rs +++ b/src/test/run-pass/i8-incr.rs @@ -12,9 +12,9 @@ pub fn main() { - let mut x: i8 = -12i8; - let y: i8 = -12i8; - x = x + 1i8; - x = x - 1i8; + let mut x: i8 = -12; + let y: i8 = -12; + x = x + 1; + x = x - 1; assert_eq!(x, y); } diff --git a/src/test/run-pass/if-check.rs b/src/test/run-pass/if-check.rs index d2a1a3c71a5..766cced4c26 100644 --- a/src/test/run-pass/if-check.rs +++ b/src/test/run-pass/if-check.rs @@ -9,9 +9,9 @@ // except according to those terms. fn even(x: uint) -> bool { - if x < 2_usize { + if x < 2 { return false; - } else if x == 2_usize { return true; } else { return even(x - 2_usize); } + } else if x == 2 { return true; } else { return even(x - 2); } } fn foo(x: uint) { @@ -22,4 +22,4 @@ fn foo(x: uint) { } } -pub fn main() { foo(2_usize); } +pub fn main() { foo(2); } diff --git a/src/test/run-pass/intrinsic-alignment.rs b/src/test/run-pass/intrinsic-alignment.rs index 4b0e9168e19..d111462ed5a 100644 --- a/src/test/run-pass/intrinsic-alignment.rs +++ b/src/test/run-pass/intrinsic-alignment.rs @@ -27,8 +27,8 @@ mod m { #[cfg(target_arch = "x86")] pub fn main() { unsafe { - assert_eq!(::rusti::pref_align_of::<u64>(), 8_usize); - assert_eq!(::rusti::min_align_of::<u64>(), 4_usize); + assert_eq!(::rusti::pref_align_of::<u64>(), 8); + assert_eq!(::rusti::min_align_of::<u64>(), 4); } } @@ -36,8 +36,8 @@ mod m { #[cfg(any(target_arch = "x86_64", target_arch = "arm", target_arch = "aarch64"))] pub fn main() { unsafe { - assert_eq!(::rusti::pref_align_of::<u64>(), 8_usize); - assert_eq!(::rusti::min_align_of::<u64>(), 8_usize); + assert_eq!(::rusti::pref_align_of::<u64>(), 8); + assert_eq!(::rusti::min_align_of::<u64>(), 8); } } } @@ -48,8 +48,8 @@ mod m { #[cfg(target_arch = "x86_64")] pub fn main() { unsafe { - assert_eq!(::rusti::pref_align_of::<u64>(), 8u); - assert_eq!(::rusti::min_align_of::<u64>(), 8u); + assert_eq!(::rusti::pref_align_of::<u64>(), 8); + assert_eq!(::rusti::min_align_of::<u64>(), 8); } } } @@ -60,8 +60,8 @@ mod m { #[cfg(target_arch = "x86")] pub fn main() { unsafe { - assert_eq!(::rusti::pref_align_of::<u64>(), 8_usize); - assert_eq!(::rusti::min_align_of::<u64>(), 8_usize); + assert_eq!(::rusti::pref_align_of::<u64>(), 8); + assert_eq!(::rusti::min_align_of::<u64>(), 8); } } @@ -69,8 +69,8 @@ mod m { #[cfg(target_arch = "x86_64")] pub fn main() { unsafe { - assert_eq!(::rusti::pref_align_of::<u64>(), 8_usize); - assert_eq!(::rusti::min_align_of::<u64>(), 8_usize); + assert_eq!(::rusti::pref_align_of::<u64>(), 8); + assert_eq!(::rusti::min_align_of::<u64>(), 8); } } } @@ -81,8 +81,8 @@ mod m { #[cfg(any(target_arch = "arm", target_arch = "aarch64"))] pub fn main() { unsafe { - assert_eq!(::rusti::pref_align_of::<u64>(), 8_usize); - assert_eq!(::rusti::min_align_of::<u64>(), 8_usize); + assert_eq!(::rusti::pref_align_of::<u64>(), 8); + assert_eq!(::rusti::min_align_of::<u64>(), 8); } } } diff --git a/src/test/run-pass/intrinsics-integer.rs b/src/test/run-pass/intrinsics-integer.rs index 2b0f7cc7d7d..e5724c1e0dc 100644 --- a/src/test/run-pass/intrinsics-integer.rs +++ b/src/test/run-pass/intrinsics-integer.rs @@ -37,83 +37,83 @@ pub fn main() { unsafe { use rusti::*; - assert_eq!(ctpop8(0u8), 0u8); - assert_eq!(ctpop16(0u16), 0u16); - assert_eq!(ctpop32(0u32), 0u32); - assert_eq!(ctpop64(0u64), 0u64); - - assert_eq!(ctpop8(1u8), 1u8); - assert_eq!(ctpop16(1u16), 1u16); - assert_eq!(ctpop32(1u32), 1u32); - assert_eq!(ctpop64(1u64), 1u64); - - assert_eq!(ctpop8(10u8), 2u8); - assert_eq!(ctpop16(10u16), 2u16); - assert_eq!(ctpop32(10u32), 2u32); - assert_eq!(ctpop64(10u64), 2u64); - - assert_eq!(ctpop8(100u8), 3u8); - assert_eq!(ctpop16(100u16), 3u16); - assert_eq!(ctpop32(100u32), 3u32); - assert_eq!(ctpop64(100u64), 3u64); - - assert_eq!(ctpop8(-1u8), 8u8); - assert_eq!(ctpop16(-1u16), 16u16); - assert_eq!(ctpop32(-1u32), 32u32); - assert_eq!(ctpop64(-1u64), 64u64); - - assert_eq!(ctlz8(0u8), 8u8); - assert_eq!(ctlz16(0u16), 16u16); - assert_eq!(ctlz32(0u32), 32u32); - assert_eq!(ctlz64(0u64), 64u64); - - assert_eq!(ctlz8(1u8), 7u8); - assert_eq!(ctlz16(1u16), 15u16); - assert_eq!(ctlz32(1u32), 31u32); - assert_eq!(ctlz64(1u64), 63u64); - - assert_eq!(ctlz8(10u8), 4u8); - assert_eq!(ctlz16(10u16), 12u16); - assert_eq!(ctlz32(10u32), 28u32); - assert_eq!(ctlz64(10u64), 60u64); - - assert_eq!(ctlz8(100u8), 1u8); - assert_eq!(ctlz16(100u16), 9u16); - assert_eq!(ctlz32(100u32), 25u32); - assert_eq!(ctlz64(100u64), 57u64); - - assert_eq!(cttz8(-1u8), 0u8); - assert_eq!(cttz16(-1u16), 0u16); - assert_eq!(cttz32(-1u32), 0u32); - assert_eq!(cttz64(-1u64), 0u64); - - assert_eq!(cttz8(0u8), 8u8); - assert_eq!(cttz16(0u16), 16u16); - assert_eq!(cttz32(0u32), 32u32); - assert_eq!(cttz64(0u64), 64u64); - - assert_eq!(cttz8(1u8), 0u8); - assert_eq!(cttz16(1u16), 0u16); - assert_eq!(cttz32(1u32), 0u32); - assert_eq!(cttz64(1u64), 0u64); - - assert_eq!(cttz8(10u8), 1u8); - assert_eq!(cttz16(10u16), 1u16); - assert_eq!(cttz32(10u32), 1u32); - assert_eq!(cttz64(10u64), 1u64); - - assert_eq!(cttz8(100u8), 2u8); - assert_eq!(cttz16(100u16), 2u16); - assert_eq!(cttz32(100u32), 2u32); - assert_eq!(cttz64(100u64), 2u64); - - assert_eq!(cttz8(-1u8), 0u8); - assert_eq!(cttz16(-1u16), 0u16); - assert_eq!(cttz32(-1u32), 0u32); - assert_eq!(cttz64(-1u64), 0u64); - - assert_eq!(bswap16(0x0A0Bu16), 0x0B0Au16); - assert_eq!(bswap32(0x0ABBCC0Du32), 0x0DCCBB0Au32); - assert_eq!(bswap64(0x0122334455667708u64), 0x0877665544332201u64); + assert_eq!(ctpop8(0), 0); + assert_eq!(ctpop16(0), 0); + assert_eq!(ctpop32(0), 0); + assert_eq!(ctpop64(0), 0); + + assert_eq!(ctpop8(1), 1); + assert_eq!(ctpop16(1), 1); + assert_eq!(ctpop32(1), 1); + assert_eq!(ctpop64(1), 1); + + assert_eq!(ctpop8(10), 2); + assert_eq!(ctpop16(10), 2); + assert_eq!(ctpop32(10), 2); + assert_eq!(ctpop64(10), 2); + + assert_eq!(ctpop8(100), 3); + assert_eq!(ctpop16(100), 3); + assert_eq!(ctpop32(100), 3); + assert_eq!(ctpop64(100), 3); + + assert_eq!(ctpop8(-1), 8); + assert_eq!(ctpop16(-1), 16); + assert_eq!(ctpop32(-1), 32); + assert_eq!(ctpop64(-1), 64); + + assert_eq!(ctlz8(0), 8); + assert_eq!(ctlz16(0), 16); + assert_eq!(ctlz32(0), 32); + assert_eq!(ctlz64(0), 64); + + assert_eq!(ctlz8(1), 7); + assert_eq!(ctlz16(1), 15); + assert_eq!(ctlz32(1), 31); + assert_eq!(ctlz64(1), 63); + + assert_eq!(ctlz8(10), 4); + assert_eq!(ctlz16(10), 12); + assert_eq!(ctlz32(10), 28); + assert_eq!(ctlz64(10), 60); + + assert_eq!(ctlz8(100), 1); + assert_eq!(ctlz16(100), 9); + assert_eq!(ctlz32(100), 25); + assert_eq!(ctlz64(100), 57); + + assert_eq!(cttz8(-1), 0); + assert_eq!(cttz16(-1), 0); + assert_eq!(cttz32(-1), 0); + assert_eq!(cttz64(-1), 0); + + assert_eq!(cttz8(0), 8); + assert_eq!(cttz16(0), 16); + assert_eq!(cttz32(0), 32); + assert_eq!(cttz64(0), 64); + + assert_eq!(cttz8(1), 0); + assert_eq!(cttz16(1), 0); + assert_eq!(cttz32(1), 0); + assert_eq!(cttz64(1), 0); + + assert_eq!(cttz8(10), 1); + assert_eq!(cttz16(10), 1); + assert_eq!(cttz32(10), 1); + assert_eq!(cttz64(10), 1); + + assert_eq!(cttz8(100), 2); + assert_eq!(cttz16(100), 2); + assert_eq!(cttz32(100), 2); + assert_eq!(cttz64(100), 2); + + assert_eq!(cttz8(-1), 0); + assert_eq!(cttz16(-1), 0); + assert_eq!(cttz32(-1), 0); + assert_eq!(cttz64(-1), 0); + + assert_eq!(bswap16(0x0A0B), 0x0B0A); + assert_eq!(bswap32(0x0ABBCC0D), 0x0DCCBB0A); + assert_eq!(bswap64(0x0122334455667708), 0x0877665544332201); } } diff --git a/src/test/run-pass/intrinsics-math.rs b/src/test/run-pass/intrinsics-math.rs index ed88b3c65e0..ab65f35dd34 100644 --- a/src/test/run-pass/intrinsics-math.rs +++ b/src/test/run-pass/intrinsics-math.rs @@ -65,8 +65,8 @@ pub fn main() { assert_approx_eq!(sqrtf32(64f32), 8f32); assert_approx_eq!(sqrtf64(64f64), 8f64); - assert_approx_eq!(powif32(25f32, -2i32), 0.0016f32); - assert_approx_eq!(powif64(23.2f64, 2i32), 538.24f64); + assert_approx_eq!(powif32(25f32, -2), 0.0016f32); + assert_approx_eq!(powif64(23.2f64, 2), 538.24f64); assert_approx_eq!(sinf32(0f32), 0f32); assert_approx_eq!(sinf64(f64::consts::PI / 2f64), 1f64); diff --git a/src/test/run-pass/issue-1112.rs b/src/test/run-pass/issue-1112.rs index 22c88c874f0..2ade0df7f6b 100644 --- a/src/test/run-pass/issue-1112.rs +++ b/src/test/run-pass/issue-1112.rs @@ -24,21 +24,21 @@ struct X<T> { pub fn main() { let x: X<int> = X { a: 12345678, - b: 9u8, + b: 9, c: true, - d: 10u8, - e: 11u16, - f: 12u8, - g: 13u8 + d: 10, + e: 11, + f: 12, + g: 13 }; bar(x); } fn bar<T>(x: X<T>) { - assert_eq!(x.b, 9u8); + assert_eq!(x.b, 9); assert_eq!(x.c, true); - assert_eq!(x.d, 10u8); - assert_eq!(x.e, 11u16); - assert_eq!(x.f, 12u8); - assert_eq!(x.g, 13u8); + assert_eq!(x.d, 10); + assert_eq!(x.e, 11); + assert_eq!(x.f, 12); + assert_eq!(x.g, 13); } diff --git a/src/test/run-pass/issue-11736.rs b/src/test/run-pass/issue-11736.rs index b901e95ff55..b09d516dd35 100644 --- a/src/test/run-pass/issue-11736.rs +++ b/src/test/run-pass/issue-11736.rs @@ -15,7 +15,7 @@ use std::num::Float; fn main() { // Generate sieve of Eratosthenes for n up to 1e6 - let n = 1000000_usize; + let n = 1000000; let mut sieve = BitVec::from_elem(n+1, true); let limit: uint = (n as f32).sqrt() as uint; for i in 2..limit+1 { diff --git a/src/test/run-pass/issue-11958.rs b/src/test/run-pass/issue-11958.rs index 00613f35f17..bb34dae77b3 100644 --- a/src/test/run-pass/issue-11958.rs +++ b/src/test/run-pass/issue-11958.rs @@ -19,6 +19,6 @@ use std::thunk::Thunk; pub fn main() { - let mut x = 1i32; + let mut x = 1; let _thunk = Thunk::new(move|| { x = 2; }); } diff --git a/src/test/run-pass/issue-12909.rs b/src/test/run-pass/issue-12909.rs index b7dc98b92e0..11a2e52cf97 100644 --- a/src/test/run-pass/issue-12909.rs +++ b/src/test/run-pass/issue-12909.rs @@ -15,7 +15,7 @@ fn copy<T: Copy>(&x: &T) -> T { } fn main() { - let arr = [(1, 1_usize), (2, 2), (3, 3)]; + let arr = [(1, 1), (2, 2), (3, 3)]; let v1: Vec<&_> = arr.iter().collect(); let v2: Vec<_> = arr.iter().map(copy).collect(); diff --git a/src/test/run-pass/issue-15571.rs b/src/test/run-pass/issue-15571.rs index 5b093d16cbf..3dc76f4a089 100644 --- a/src/test/run-pass/issue-15571.rs +++ b/src/test/run-pass/issue-15571.rs @@ -47,7 +47,7 @@ fn match_on_binding() { } fn match_on_upvar() { - let mut foo: Option<Box<_>> = Some(box 8i32); + let mut foo: Option<Box<_>> = Some(box 8); let f = move|| { match foo { None => {}, diff --git a/src/test/run-pass/issue-15673.rs b/src/test/run-pass/issue-15673.rs index a6b8a04eeb6..227d8f7b8c8 100644 --- a/src/test/run-pass/issue-15673.rs +++ b/src/test/run-pass/issue-15673.rs @@ -11,5 +11,5 @@ use std::iter::AdditiveIterator; fn main() { let x: [u64; 3] = [1, 2, 3]; - assert_eq!(6, (0_usize..3).map(|i| x[i]).sum()); + assert_eq!(6, (0..3).map(|i| x[i]).sum()); } diff --git a/src/test/run-pass/issue-15734.rs b/src/test/run-pass/issue-15734.rs index e66ac8ff53c..18e4190ee45 100644 --- a/src/test/run-pass/issue-15734.rs +++ b/src/test/run-pass/issue-15734.rs @@ -53,12 +53,12 @@ impl<T, M: Index<(uint, uint), Output=T>> Index<uint> for Row<M> { } fn main() { - let m = Mat::new(vec!(1_usize, 2, 3, 4, 5, 6), 3); + let m = Mat::new(vec!(1, 2, 3, 4, 5, 6), 3); let r = m.row(1); assert!(r.index(&2) == &6); assert!(r[2] == 6); - assert!(r[2_usize] == 6_usize); + assert!(r[2] == 6); assert!(6 == r[2]); let e = r[2]; diff --git a/src/test/run-pass/issue-17662.rs b/src/test/run-pass/issue-17662.rs index 7bd41cc5b52..dbfa91553e6 100644 --- a/src/test/run-pass/issue-17662.rs +++ b/src/test/run-pass/issue-17662.rs @@ -17,7 +17,7 @@ use std::marker; struct Bar<'a> { m: marker::PhantomData<&'a ()> } impl<'a> i::Foo<'a, uint> for Bar<'a> { - fn foo(&self) -> uint { 5_usize } + fn foo(&self) -> uint { 5 } } pub fn main() { diff --git a/src/test/run-pass/issue-18539.rs b/src/test/run-pass/issue-18539.rs index ce56f3e8d72..b92cfa1f29b 100644 --- a/src/test/run-pass/issue-18539.rs +++ b/src/test/run-pass/issue-18539.rs @@ -19,5 +19,5 @@ fn uint_to_foo(_: uint) -> Foo { #[allow(unused_must_use)] fn main() { - (0_usize..10).map(uint_to_foo); + (0..10).map(uint_to_foo); } diff --git a/src/test/run-pass/issue-20055-box-trait.rs b/src/test/run-pass/issue-20055-box-trait.rs index 572a0d82528..7e89cfe24e1 100644 --- a/src/test/run-pass/issue-20055-box-trait.rs +++ b/src/test/run-pass/issue-20055-box-trait.rs @@ -41,10 +41,10 @@ pub fn foo(box_1: fn () -> Box<[i8; 1]>, } pub fn main() { - fn box_1() -> Box<[i8; 1]> { Box::new( [1i8; 1] ) } - fn box_2() -> Box<[i8; 2]> { Box::new( [1i8; 2] ) } - fn box_3() -> Box<[i8; 3]> { Box::new( [1i8; 3] ) } - fn box_4() -> Box<[i8; 4]> { Box::new( [1i8; 4] ) } + fn box_1() -> Box<[i8; 1]> { Box::new( [1; 1] ) } + fn box_2() -> Box<[i8; 2]> { Box::new( [1; 2] ) } + fn box_3() -> Box<[i8; 3]> { Box::new( [1; 3] ) } + fn box_4() -> Box<[i8; 4]> { Box::new( [1; 4] ) } foo(box_1, box_2, box_3, box_4); } diff --git a/src/test/run-pass/issue-20055-box-unsized-array.rs b/src/test/run-pass/issue-20055-box-unsized-array.rs index f751be6f13b..5af5186e94f 100644 --- a/src/test/run-pass/issue-20055-box-unsized-array.rs +++ b/src/test/run-pass/issue-20055-box-unsized-array.rs @@ -29,10 +29,10 @@ pub fn foo(box_1: fn () -> Box<[i8; 1]>, } pub fn main() { - fn box_1() -> Box<[i8; 1]> { Box::new( [1i8] ) } - fn box_2() -> Box<[i8; 20]> { Box::new( [1i8; 20] ) } - fn box_3() -> Box<[i8; 300]> { Box::new( [1i8; 300] ) } - fn box_4() -> Box<[i8; 4000]> { Box::new( [1i8; 4000] ) } + fn box_1() -> Box<[i8; 1]> { Box::new( [1] ) } + fn box_2() -> Box<[i8; 20]> { Box::new( [1; 20] ) } + fn box_3() -> Box<[i8; 300]> { Box::new( [1; 300] ) } + fn box_4() -> Box<[i8; 4000]> { Box::new( [1; 4000] ) } foo(box_1, box_2, box_3, box_4); } diff --git a/src/test/run-pass/issue-20676.rs b/src/test/run-pass/issue-20676.rs index 01a2322ae93..640774f9d24 100644 --- a/src/test/run-pass/issue-20676.rs +++ b/src/test/run-pass/issue-20676.rs @@ -15,6 +15,6 @@ use std::fmt; fn main() { - let a: &fmt::Debug = &1_i32; + let a: &fmt::Debug = &1; format!("{:?}", a); } diff --git a/src/test/run-pass/issue-21475.rs b/src/test/run-pass/issue-21475.rs index 145145af519..29701bd668a 100644 --- a/src/test/run-pass/issue-21475.rs +++ b/src/test/run-pass/issue-21475.rs @@ -11,10 +11,10 @@ use m::{START, END}; fn main() { - match 42u32 { + match 42 { m::START...m::END => {}, - 0u32...m::END => {}, - m::START...59u32 => {}, + 0...m::END => {}, + m::START...59 => {}, _ => {}, } } diff --git a/src/test/run-pass/issue-2185.rs b/src/test/run-pass/issue-2185.rs index 20ff8d29b70..3da0a67ea8e 100644 --- a/src/test/run-pass/issue-2185.rs +++ b/src/test/run-pass/issue-2185.rs @@ -72,17 +72,17 @@ fn range(lo: uint, hi: uint, it: |uint|) { let mut i = lo; while i < hi { it(i); - i += 1_usize; + i += 1; } } pub fn main() { - let range: 'static ||uint|| = |a| range(0_usize, 1000_usize, a); + let range: 'static ||uint|| = |a| range(0, 1000, a); let filt: 'static ||v: uint|| = |a| filter( range, - |&&n: uint| n % 3_usize != 0_usize && n % 5_usize != 0_usize, + |&&n: uint| n % 3 != 0 && n % 5 != 0, a); - let sum = foldl(filt, 0_usize, |accum, &&n: uint| accum + n ); + let sum = foldl(filt, 0, |accum, &&n: uint| accum + n ); println!("{}", sum); } diff --git a/src/test/run-pass/issue-22036.rs b/src/test/run-pass/issue-22036.rs index c06a29c09f7..7bc6393ef89 100644 --- a/src/test/run-pass/issue-22036.rs +++ b/src/test/run-pass/issue-22036.rs @@ -28,6 +28,6 @@ impl<I> DigitCollection for I where I: Iterator<Item=u8> { } fn main() { - let xs = vec![1u8, 2, 3, 4, 5]; + let xs = vec![1, 2, 3, 4, 5]; assert_eq!(xs.into_iter().digit_sum(), 15); } diff --git a/src/test/run-pass/issue-2550.rs b/src/test/run-pass/issue-2550.rs index 395b2c4b459..c55de959a94 100644 --- a/src/test/run-pass/issue-2550.rs +++ b/src/test/run-pass/issue-2550.rs @@ -22,5 +22,5 @@ fn f<T>(_x: T) { } pub fn main() { - f(C(1_usize)); + f(C(1)); } diff --git a/src/test/run-pass/issue-2989.rs b/src/test/run-pass/issue-2989.rs index 8767d397b64..8b6eb12f102 100644 --- a/src/test/run-pass/issue-2989.rs +++ b/src/test/run-pass/issue-2989.rs @@ -21,11 +21,11 @@ impl methods for () { // the position of this function is significant! - if it comes before methods // then it works, if it comes after it then it doesn't! fn to_bools(bitv: Storage) -> Vec<bool> { - (0_usize..8).map(|i| { + (0..8).map(|i| { let w = i / 64; let b = i % 64; - let x = 1u64 & (bitv.storage[w] >> b); - x == 1u64 + let x = 1 & (bitv.storage[w] >> b); + x == 1 }).collect() } @@ -35,7 +35,7 @@ pub fn main() { let bools = vec!(false, false, true, false, false, true, true, false); let bools2 = to_bools(Storage{storage: vec!(0b01100100)}); - for i in 0_usize..8 { + for i in 0..8 { println!("{} => {} vs {}", i, bools[i], bools2[i]); } diff --git a/src/test/run-pass/issue-3609.rs b/src/test/run-pass/issue-3609.rs index 28e44536892..b51edcf8bec 100644 --- a/src/test/run-pass/issue-3609.rs +++ b/src/test/run-pass/issue-3609.rs @@ -28,7 +28,7 @@ fn foo(name: String, samples_chan: Sender<Msg>) { // FIXME (#22405): Replace `Box::new` with `box` here when/if possible. let callback: SamplesFn = Box::new(move |buffer| { - for i in 0_usize..buffer.len() { + for i in 0..buffer.len() { println!("{}: {}", i, buffer[i]) } }); diff --git a/src/test/run-pass/issue-4735.rs b/src/test/run-pass/issue-4735.rs index bf422bd0405..196e9748b10 100644 --- a/src/test/run-pass/issue-4735.rs +++ b/src/test/run-pass/issue-4735.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-fast doesn't like extern crate #![allow(unknown_features)] #![feature(box_syntax)] diff --git a/src/test/run-pass/issue-4759-1.rs b/src/test/run-pass/issue-4759-1.rs index ce2f488b90c..a565460c42e 100644 --- a/src/test/run-pass/issue-4759-1.rs +++ b/src/test/run-pass/issue-4759-1.rs @@ -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(); } diff --git a/src/test/run-pass/issue-6130.rs b/src/test/run-pass/issue-6130.rs index 93429ff10dc..1a1f538a548 100644 --- a/src/test/run-pass/issue-6130.rs +++ b/src/test/run-pass/issue-6130.rs @@ -12,9 +12,9 @@ pub fn main() { let i: uint = 0; - assert!(i <= 0xFFFF_FFFF_usize); + assert!(i <= 0xFFFF_FFFF); let i: int = 0; - assert!(i >= -0x8000_0000__isize); - assert!(i <= 0x7FFF_FFFF__isize); + assert!(i >= -0x8000_0000); + assert!(i <= 0x7FFF_FFFF); } diff --git a/src/test/run-pass/issue-6892.rs b/src/test/run-pass/issue-6892.rs index 557ec82233d..6faca339651 100644 --- a/src/test/run-pass/issue-6892.rs +++ b/src/test/run-pass/issue-6892.rs @@ -49,7 +49,7 @@ fn main() { assert_eq!(unsafe { NUM_DROPS }, 3); { let _x = FooBar::_Foo(Foo); } assert_eq!(unsafe { NUM_DROPS }, 5); - { let _x = FooBar::_Bar(42_usize); } + { let _x = FooBar::_Bar(42); } assert_eq!(unsafe { NUM_DROPS }, 6); { let _ = Foo; } @@ -60,6 +60,6 @@ fn main() { assert_eq!(unsafe { NUM_DROPS }, 9); { let _ = FooBar::_Foo(Foo); } assert_eq!(unsafe { NUM_DROPS }, 11); - { let _ = FooBar::_Bar(42_usize); } + { let _ = FooBar::_Bar(42); } assert_eq!(unsafe { NUM_DROPS }, 12); } diff --git a/src/test/run-pass/issue-7012.rs b/src/test/run-pass/issue-7012.rs index 96db28f4a10..3a9864f3a76 100644 --- a/src/test/run-pass/issue-7012.rs +++ b/src/test/run-pass/issue-7012.rs @@ -18,11 +18,11 @@ would be printed, however the below prints false. struct signature<'a> { pattern : &'a [u32] } static test1: signature<'static> = signature { - pattern: &[0x243f6a88u32,0x85a308d3u32,0x13198a2eu32,0x03707344u32,0xa4093822u32,0x299f31d0u32] + pattern: &[0x243f6a88,0x85a308d3,0x13198a2e,0x03707344,0xa4093822,0x299f31d0] }; pub fn main() { - let test: &[u32] = &[0x243f6a88u32,0x85a308d3u32,0x13198a2eu32, - 0x03707344u32,0xa4093822u32,0x299f31d0u32]; + let test: &[u32] = &[0x243f6a88,0x85a308d3,0x13198a2e, + 0x03707344,0xa4093822,0x299f31d0]; println!("{}",test==test1.pattern); } diff --git a/src/test/run-pass/issue-8783.rs b/src/test/run-pass/issue-8783.rs index 815e00e1291..303dd191006 100644 --- a/src/test/run-pass/issue-8783.rs +++ b/src/test/run-pass/issue-8783.rs @@ -13,7 +13,7 @@ use std::default::Default; struct X { pub x: uint } impl Default for X { fn default() -> X { - X { x: 42_usize } + X { x: 42 } } } diff --git a/src/test/run-pass/issue2170exe.rs b/src/test/run-pass/issue2170exe.rs index b4a41ef44f8..58424089c5e 100644 --- a/src/test/run-pass/issue2170exe.rs +++ b/src/test/run-pass/issue2170exe.rs @@ -12,5 +12,5 @@ extern crate issue2170lib; pub fn main() { - // let _ = issue2170lib::rsrc(2i32); + // let _ = issue2170lib::rsrc(2); } diff --git a/src/test/run-pass/iter-cloned-type-inference.rs b/src/test/run-pass/iter-cloned-type-inference.rs new file mode 100644 index 00000000000..6ce226bbeca --- /dev/null +++ b/src/test/run-pass/iter-cloned-type-inference.rs @@ -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 to see that the element type of .cloned() can be inferred +// properly. Previously this would fail to deduce the type of `sum`. + +#![feature(core)] + +use std::iter::AdditiveIterator; + +fn square_sum(v: &[i64]) -> i64 { + let sum = v.iter().cloned().sum(); + sum * sum +} + +fn main() { + assert_eq!(36, square_sum(&[1,2,3])); +} diff --git a/src/test/run-pass/ivec-tag.rs b/src/test/run-pass/ivec-tag.rs index dd38a5f8b3b..121338823d2 100644 --- a/src/test/run-pass/ivec-tag.rs +++ b/src/test/run-pass/ivec-tag.rs @@ -13,8 +13,8 @@ use std::sync::mpsc::{channel, Sender}; fn producer(tx: &Sender<Vec<u8>>) { tx.send( - vec!(1u8, 2u8, 3u8, 4u8, 5u8, 6u8, 7u8, 8u8, 9u8, 10u8, 11u8, 12u8, - 13u8)).unwrap(); + vec!(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13)).unwrap(); } pub fn main() { diff --git a/src/test/run-pass/last-use-in-cap-clause.rs b/src/test/run-pass/last-use-in-cap-clause.rs index 74ddb990c31..45964efad97 100644 --- a/src/test/run-pass/last-use-in-cap-clause.rs +++ b/src/test/run-pass/last-use-in-cap-clause.rs @@ -19,8 +19,8 @@ struct A { a: Box<isize> } fn foo() -> Box<FnMut() -> isize + 'static> { let k: Box<_> = box 22; let _u = A {a: k.clone()}; - // FIXME(#16640) suffix in `22_isize` suffix shouldn't be necessary - let result = || 22_isize; + // FIXME(#16640) suffix in `22` suffix shouldn't be necessary + let result = || 22; // FIXME (#22405): Replace `Box::new` with `box` here when/if possible. Box::new(result) } diff --git a/src/test/run-pass/logging-enabled-debug.rs b/src/test/run-pass/logging-enabled-debug.rs index 262d9b21eb4..dfc92728270 100644 --- a/src/test/run-pass/logging-enabled-debug.rs +++ b/src/test/run-pass/logging-enabled-debug.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// compile-flags:--cfg ndebug +// compile-flags:-C debug-assertions=no // exec-env:RUST_LOG=logging-enabled-debug=debug #[macro_use] diff --git a/src/test/run-pass/logging-separate-lines.rs b/src/test/run-pass/logging-separate-lines.rs index 8526dfe72da..82a155b1173 100644 --- a/src/test/run-pass/logging-separate-lines.rs +++ b/src/test/run-pass/logging-separate-lines.rs @@ -10,6 +10,7 @@ // ignore-windows // exec-env:RUST_LOG=debug +// compile-flags:-C debug-assertions=y #[macro_use] extern crate log; diff --git a/src/test/run-pass/macro-interpolation.rs b/src/test/run-pass/macro-interpolation.rs index 069aeb9220e..1cbd4f6bc70 100644 --- a/src/test/run-pass/macro-interpolation.rs +++ b/src/test/run-pass/macro-interpolation.rs @@ -24,6 +24,6 @@ macro_rules! overly_complicated { pub fn main() { assert!(overly_complicated!(f, x, Option<uint>, { return Some(x); }, - Some(8_usize), Some(y), y) == 8_usize) + Some(8), Some(y), y) == 8) } diff --git a/src/test/run-pass/macro-pat.rs b/src/test/run-pass/macro-pat.rs index 6f2626a5af5..7a3e55322c8 100644 --- a/src/test/run-pass/macro-pat.rs +++ b/src/test/run-pass/macro-pat.rs @@ -47,9 +47,9 @@ fn f(c: Option<char>) -> uint { } pub fn main() { - assert_eq!(1_usize, f(Some('x'))); - assert_eq!(2_usize, f(Some('y'))); - assert_eq!(3_usize, f(None)); + assert_eq!(1, f(Some('x'))); + assert_eq!(2, f(Some('y'))); + assert_eq!(3, f(None)); assert_eq!(1, match Some('x') { Some(char_x!()) => 1, diff --git a/src/test/run-pass/match-with-ret-arm.rs b/src/test/run-pass/match-with-ret-arm.rs index d2e27fc822e..79b197f08e2 100644 --- a/src/test/run-pass/match-with-ret-arm.rs +++ b/src/test/run-pass/match-with-ret-arm.rs @@ -16,6 +16,6 @@ pub fn main() { None => return (), Some(num) => num as u32 }; - assert_eq!(f, 1234u32); + assert_eq!(f, 1234); println!("{}", f) } diff --git a/src/test/run-pass/method-mut-self-modifies-mut-slice-lvalue.rs b/src/test/run-pass/method-mut-self-modifies-mut-slice-lvalue.rs index 0ad600dd85d..3ffac98418a 100644 --- a/src/test/run-pass/method-mut-self-modifies-mut-slice-lvalue.rs +++ b/src/test/run-pass/method-mut-self-modifies-mut-slice-lvalue.rs @@ -38,7 +38,7 @@ impl<'a> MyWriter for &'a mut [u8] { } fn main() { - let mut buf = [0_u8; 6]; + let mut buf = [0; 6]; { let mut writer: &mut [_] = &mut buf; diff --git a/src/test/run-pass/method-self-arg-aux1.rs b/src/test/run-pass/method-self-arg-aux1.rs index e9a1e19d4bf..81212ee348f 100644 --- a/src/test/run-pass/method-self-arg-aux1.rs +++ b/src/test/run-pass/method-self-arg-aux1.rs @@ -26,5 +26,5 @@ fn main() { x.foo(&x); - assert!(method_self_arg1::get_count() == 2u64*3*3*3*5*5*5*7*7*7); + assert!(method_self_arg1::get_count() == 2*3*3*3*5*5*5*7*7*7); } diff --git a/src/test/run-pass/method-self-arg-aux2.rs b/src/test/run-pass/method-self-arg-aux2.rs index 7fa810ce154..ca81860dd08 100644 --- a/src/test/run-pass/method-self-arg-aux2.rs +++ b/src/test/run-pass/method-self-arg-aux2.rs @@ -30,5 +30,5 @@ fn main() { x.run_trait(); - assert!(method_self_arg2::get_count() == 2u64*2*3*3*5*5*7*7*11*11*13*13*17); + assert!(method_self_arg2::get_count() == 2*2*3*3*5*5*7*7*11*11*13*13*17); } diff --git a/src/test/run-pass/method-self-arg-trait.rs b/src/test/run-pass/method-self-arg-trait.rs index c79141d9795..17fdd7b45c2 100644 --- a/src/test/run-pass/method-self-arg-trait.rs +++ b/src/test/run-pass/method-self-arg-trait.rs @@ -75,5 +75,5 @@ fn main() { x.baz(); - unsafe { assert!(COUNT == 2u64*2*3*3*5*5*7*7*11*11*13*13*17); } + unsafe { assert!(COUNT == 2*2*3*3*5*5*7*7*11*11*13*13*17); } } diff --git a/src/test/run-pass/method-self-arg.rs b/src/test/run-pass/method-self-arg.rs index de24297c7b5..62b3d52860b 100644 --- a/src/test/run-pass/method-self-arg.rs +++ b/src/test/run-pass/method-self-arg.rs @@ -54,5 +54,5 @@ fn main() { x.foo(&x); - unsafe { assert!(COUNT == 2_usize*3*3*3*5*5*5*7*7*7); } + unsafe { assert!(COUNT == 2*3*3*3*5*5*5*7*7*7); } } diff --git a/src/test/run-pass/newtype-struct-with-dtor.rs b/src/test/run-pass/newtype-struct-with-dtor.rs index 8631755f37f..15c4e8b0453 100644 --- a/src/test/run-pass/newtype-struct-with-dtor.rs +++ b/src/test/run-pass/newtype-struct-with-dtor.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-fast doesn't like extern crate extern crate libc; use libc::c_int; diff --git a/src/test/run-pass/nul-characters.rs b/src/test/run-pass/nul-characters.rs index 22786c0abc8..4a14969209f 100644 --- a/src/test/run-pass/nul-characters.rs +++ b/src/test/run-pass/nul-characters.rs @@ -10,10 +10,10 @@ pub fn main() { - let all_nuls1 = "\0\x00\u0000\U00000000"; - let all_nuls2 = "\U00000000\u0000\x00\0"; - let all_nuls3 = "\u0000\U00000000\x00\0"; - let all_nuls4 = "\x00\u0000\0\U00000000"; + let all_nuls1 = "\0\x00\u{0}\u{0}"; + let all_nuls2 = "\u{0}\u{0}\x00\0"; + let all_nuls3 = "\u{0}\u{0}\x00\0"; + let all_nuls4 = "\x00\u{0}\0\u{0}"; // sizes for two should suffice assert_eq!(all_nuls1.len(), 4); @@ -35,8 +35,8 @@ pub fn main() // testing equality between explicit character literals assert_eq!('\0', '\x00'); - assert_eq!('\u0000', '\x00'); - assert_eq!('\u0000', '\U00000000'); + assert_eq!('\u{0}', '\x00'); + assert_eq!('\u{0}', '\u{0}'); // NUL characters should make a difference assert!("Hello World" != "Hello \0World"); diff --git a/src/test/run-pass/nullable-pointer-iotareduction.rs b/src/test/run-pass/nullable-pointer-iotareduction.rs index bb62b1599a4..03027e40d6c 100644 --- a/src/test/run-pass/nullable-pointer-iotareduction.rs +++ b/src/test/run-pass/nullable-pointer-iotareduction.rs @@ -55,7 +55,7 @@ macro_rules! check_fancy { check_fancy!($e, $T, |ptr| assert!(*ptr == $e)); }}; ($e:expr, $T:ty, |$v:ident| $chk:expr) => {{ - assert!(E::Nothing::<$T>((), ((), ()), [23i8; 0]).is_none()); + assert!(E::Nothing::<$T>((), ((), ()), [23; 0]).is_none()); let e = $e; let t_ = E::Thing::<$T>(23, e); match t_.get_ref() { diff --git a/src/test/run-pass/object-method-numbering.rs b/src/test/run-pass/object-method-numbering.rs index 8da753acb96..9c7a925b5bb 100644 --- a/src/test/run-pass/object-method-numbering.rs +++ b/src/test/run-pass/object-method-numbering.rs @@ -29,7 +29,7 @@ impl SomeTrait for i32 { } fn main() { - let x = 22_i32; + let x = 22; let x1: &SomeTrait<SomeType=i32> = &x; let y = get_int(x1); assert_eq!(x, y); diff --git a/src/test/run-pass/objects-coerce-freeze-borrored.rs b/src/test/run-pass/objects-coerce-freeze-borrored.rs index 998af27c338..d2523bc4f24 100644 --- a/src/test/run-pass/objects-coerce-freeze-borrored.rs +++ b/src/test/run-pass/objects-coerce-freeze-borrored.rs @@ -40,9 +40,9 @@ fn do_it_imm(obj: &Foo, v: uint) { } pub fn main() { - let mut x = 22_usize; + let mut x = 22; let obj = &mut x as &mut Foo; do_it_mut(obj); - do_it_imm(obj, 23_usize); + do_it_imm(obj, 23); do_it_mut(obj); } diff --git a/src/test/run-pass/objects-owned-object-borrowed-method-headerless.rs b/src/test/run-pass/objects-owned-object-borrowed-method-headerless.rs index 30a8c270bd7..9cee266c4a7 100644 --- a/src/test/run-pass/objects-owned-object-borrowed-method-headerless.rs +++ b/src/test/run-pass/objects-owned-object-borrowed-method-headerless.rs @@ -37,7 +37,7 @@ pub fn main() { box BarStruct{ x: 2 } as Box<FooTrait> ); - for i in 0_usize..foos.len() { + for i in 0..foos.len() { assert_eq!(i, foos[i].foo()); } } diff --git a/src/test/run-pass/or-pattern.rs b/src/test/run-pass/or-pattern.rs index 654d2429a0b..ef399044abc 100644 --- a/src/test/run-pass/or-pattern.rs +++ b/src/test/run-pass/or-pattern.rs @@ -16,6 +16,6 @@ fn or_alt(q: blah) -> int { pub fn main() { assert_eq!(or_alt(blah::c), 0); - assert_eq!(or_alt(blah::a(10, 100, 0_usize)), 110); + assert_eq!(or_alt(blah::a(10, 100, 0)), 110); assert_eq!(or_alt(blah::b(20, 200)), 220); } diff --git a/src/test/run-pass/overloaded-calls-param-vtables.rs b/src/test/run-pass/overloaded-calls-param-vtables.rs index 2ef9e08134c..0ac9c97532b 100644 --- a/src/test/run-pass/overloaded-calls-param-vtables.rs +++ b/src/test/run-pass/overloaded-calls-param-vtables.rs @@ -28,5 +28,5 @@ impl<'a, A: Add<i32, Output=i32>> Fn<(A,)> for G<A> { fn main() { // ICE trigger - (G(PhantomData))(1_i32); + (G(PhantomData))(1); } diff --git a/src/test/run-pass/packed-struct-vec.rs b/src/test/run-pass/packed-struct-vec.rs index cfe49c38c52..92f57f04b10 100644 --- a/src/test/run-pass/packed-struct-vec.rs +++ b/src/test/run-pass/packed-struct-vec.rs @@ -24,7 +24,7 @@ pub fn main() { assert_eq!(mem::size_of::<[Foo; 10]>(), 90); - for i in 0_usize..10 { + for i in 0..10 { assert_eq!(foos[i], Foo { bar: 1, baz: 2}); } diff --git a/src/test/run-pass/path.rs b/src/test/run-pass/path.rs index 02d8602d59e..08d00d4dc03 100644 --- a/src/test/run-pass/path.rs +++ b/src/test/run-pass/path.rs @@ -14,4 +14,4 @@ mod foo { pub fn bar(_offset: uint) { } } -pub fn main() { foo::bar(0_usize); } +pub fn main() { foo::bar(0); } diff --git a/src/test/run-pass/private-class-field.rs b/src/test/run-pass/private-class-field.rs index c7380b362fb..b4d04ba18f9 100644 --- a/src/test/run-pass/private-class-field.rs +++ b/src/test/run-pass/private-class-field.rs @@ -26,6 +26,6 @@ fn cat(in_x : uint, in_y : int) -> cat { } pub fn main() { - let mut nyan : cat = cat(52_usize, 99); - assert_eq!(nyan.meow_count(), 52_usize); + let mut nyan : cat = cat(52, 99); + assert_eq!(nyan.meow_count(), 52); } diff --git a/src/test/run-pass/pure-sum.rs b/src/test/run-pass/pure-sum.rs index 1fd83041f62..f12cf82f939 100644 --- a/src/test/run-pass/pure-sum.rs +++ b/src/test/run-pass/pure-sum.rs @@ -14,31 +14,31 @@ #![feature(box_syntax)] fn sums_to(v: Vec<int> , sum: int) -> bool { - let mut i = 0_usize; + let mut i = 0; let mut sum0 = 0; while i < v.len() { sum0 += v[i]; - i += 1_usize; + i += 1; } return sum0 == sum; } fn sums_to_using_uniq(v: Vec<int> , sum: int) -> bool { - let mut i = 0_usize; + let mut i = 0; let mut sum0: Box<_> = box 0; while i < v.len() { *sum0 += v[i]; - i += 1_usize; + i += 1; } return *sum0 == sum; } fn sums_to_using_rec(v: Vec<int> , sum: int) -> bool { - let mut i = 0_usize; + let mut i = 0; let mut sum0 = F {f: 0}; while i < v.len() { sum0.f += v[i]; - i += 1_usize; + i += 1; } return sum0.f == sum; } @@ -46,11 +46,11 @@ fn sums_to_using_rec(v: Vec<int> , sum: int) -> bool { struct F<T> { f: T } fn sums_to_using_uniq_rec(v: Vec<int> , sum: int) -> bool { - let mut i = 0_usize; + let mut i = 0; let mut sum0 = F::<Box<_>> {f: box 0}; while i < v.len() { *sum0.f += v[i]; - i += 1_usize; + i += 1; } return *sum0.f == sum; } diff --git a/src/test/run-pass/ranges-precedence.rs b/src/test/run-pass/ranges-precedence.rs index db414abb7ff..41ed9a74d13 100644 --- a/src/test/run-pass/ranges-precedence.rs +++ b/src/test/run-pass/ranges-precedence.rs @@ -38,7 +38,7 @@ fn main() { let x = ..1+3; assert!(x == (..4)); - let a = &[0i32, 1, 2, 3, 4, 5, 6]; + let a = &[0, 1, 2, 3, 4, 5, 6]; let x = &a[1+1..2+2]; assert!(x == &a[2..4]); let x = &a[..1+2]; diff --git a/src/test/run-pass/raw-str.rs b/src/test/run-pass/raw-str.rs index 35e863d05a1..298ac8f77eb 100644 --- a/src/test/run-pass/raw-str.rs +++ b/src/test/run-pass/raw-str.rs Binary files differdiff --git a/src/test/run-pass/realloc-16687.rs b/src/test/run-pass/realloc-16687.rs index de5b14104c5..e8bcff38131 100644 --- a/src/test/run-pass/realloc-16687.rs +++ b/src/test/run-pass/realloc-16687.rs @@ -35,9 +35,9 @@ unsafe fn test_triangle() -> bool { // from pairs of rows (where each pair of rows is equally sized), // and the elements of the triangle match their row-pair index. unsafe fn sanity_check(ascend: &[*mut u8]) { - for i in 0_usize..COUNT / 2 { + for i in 0..COUNT / 2 { let (p0, p1, size) = (ascend[2*i], ascend[2*i+1], idx_to_size(i)); - for j in 0_usize..size { + for j in 0..size { assert_eq!(*p0.offset(j as int), i as u8); assert_eq!(*p1.offset(j as int), i as u8); } @@ -88,14 +88,14 @@ unsafe fn test_triangle() -> bool { // that at least two rows will be allocated near each other, so // that we trigger the bug (a buffer overrun) in an observable // way.) - for i in 0_usize..COUNT / 2 { + for i in 0..COUNT / 2 { let size = idx_to_size(i); ascend[2*i] = allocate(size, ALIGN); ascend[2*i+1] = allocate(size, ALIGN); } // Initialize each pair of rows to distinct value. - for i in 0_usize..COUNT / 2 { + for i in 0..COUNT / 2 { let (p0, p1, size) = (ascend[2*i], ascend[2*i+1], idx_to_size(i)); for j in 0..size { *p0.offset(j as int) = i as u8; @@ -109,7 +109,7 @@ unsafe fn test_triangle() -> bool { test_3(ascend); // triangle -> square test_4(ascend); // square -> triangle - for i in 0_usize..COUNT / 2 { + for i in 0..COUNT / 2 { let size = idx_to_size(i); deallocate(ascend[2*i], size, ALIGN); deallocate(ascend[2*i+1], size, ALIGN); @@ -123,7 +123,7 @@ unsafe fn test_triangle() -> bool { // rows as we go. unsafe fn test_1(ascend: &mut [*mut u8]) { let new_size = idx_to_size(COUNT-1); - for i in 0_usize..COUNT / 2 { + for i in 0..COUNT / 2 { let (p0, p1, old_size) = (ascend[2*i], ascend[2*i+1], idx_to_size(i)); assert!(old_size < new_size); @@ -138,7 +138,7 @@ unsafe fn test_triangle() -> bool { // Test 2: turn the square back into a triangle, top to bottom. unsafe fn test_2(ascend: &mut [*mut u8]) { let old_size = idx_to_size(COUNT-1); - for i in 0_usize..COUNT / 2 { + for i in 0..COUNT / 2 { let (p0, p1, new_size) = (ascend[2*i], ascend[2*i+1], idx_to_size(i)); assert!(new_size < old_size); @@ -153,7 +153,7 @@ unsafe fn test_triangle() -> bool { // Test 3: turn triangle into a square, bottom to top. unsafe fn test_3(ascend: &mut [*mut u8]) { let new_size = idx_to_size(COUNT-1); - for i in (0_usize..COUNT / 2).rev() { + for i in (0..COUNT / 2).rev() { let (p0, p1, old_size) = (ascend[2*i], ascend[2*i+1], idx_to_size(i)); assert!(old_size < new_size); @@ -168,7 +168,7 @@ unsafe fn test_triangle() -> bool { // Test 4: turn the square back into a triangle, bottom to top. unsafe fn test_4(ascend: &mut [*mut u8]) { let old_size = idx_to_size(COUNT-1); - for i in (0_usize..COUNT / 2).rev() { + for i in (0..COUNT / 2).rev() { let (p0, p1, new_size) = (ascend[2*i], ascend[2*i+1], idx_to_size(i)); assert!(new_size < old_size); diff --git a/src/test/run-pass/rec-align-u32.rs b/src/test/run-pass/rec-align-u32.rs index 51b800bc9f0..94fe3f1d9ea 100644 --- a/src/test/run-pass/rec-align-u32.rs +++ b/src/test/run-pass/rec-align-u32.rs @@ -38,19 +38,19 @@ struct Outer { #[cfg(any(target_arch = "x86", target_arch = "arm", target_arch = "aarch64"))] mod m { - pub fn align() -> uint { 4_usize } - pub fn size() -> uint { 8_usize } + pub fn align() -> uint { 4 } + pub fn size() -> uint { 8 } } #[cfg(target_arch = "x86_64")] mod m { - pub fn align() -> uint { 4_usize } - pub fn size() -> uint { 8_usize } + pub fn align() -> uint { 4 } + pub fn size() -> uint { 8 } } pub fn main() { unsafe { - let x = Outer {c8: 22u8, t: Inner {c64: 44u32}}; + let x = Outer {c8: 22, t: Inner {c64: 44}}; // Send it through the shape code let y = format!("{:?}", x); diff --git a/src/test/run-pass/rec-align-u64.rs b/src/test/run-pass/rec-align-u64.rs index 835b4c40f5c..8b7434ed063 100644 --- a/src/test/run-pass/rec-align-u64.rs +++ b/src/test/run-pass/rec-align-u64.rs @@ -44,14 +44,14 @@ struct Outer { mod m { #[cfg(target_arch = "x86")] pub mod m { - pub fn align() -> uint { 4_usize } - pub fn size() -> uint { 12_usize } + pub fn align() -> uint { 4 } + pub fn size() -> uint { 12 } } #[cfg(any(target_arch = "x86_64", target_arch = "arm", target_arch = "aarch64"))] pub mod m { - pub fn align() -> uint { 8_usize } - pub fn size() -> uint { 16_usize } + pub fn align() -> uint { 8 } + pub fn size() -> uint { 16 } } } @@ -59,8 +59,8 @@ mod m { mod m { #[cfg(target_arch = "x86_64")] pub mod m { - pub fn align() -> uint { 8u } - pub fn size() -> uint { 16u } + pub fn align() -> uint { 8 } + pub fn size() -> uint { 16 } } } @@ -68,14 +68,14 @@ mod m { mod m { #[cfg(target_arch = "x86")] pub mod m { - pub fn align() -> uint { 8_usize } - pub fn size() -> uint { 16_usize } + pub fn align() -> uint { 8 } + pub fn size() -> uint { 16 } } #[cfg(target_arch = "x86_64")] pub mod m { - pub fn align() -> uint { 8_usize } - pub fn size() -> uint { 16_usize } + pub fn align() -> uint { 8 } + pub fn size() -> uint { 16 } } } @@ -83,14 +83,14 @@ mod m { mod m { #[cfg(any(target_arch = "arm", target_arch = "aarch64"))] pub mod m { - pub fn align() -> uint { 8_usize } - pub fn size() -> uint { 16_usize } + pub fn align() -> uint { 8 } + pub fn size() -> uint { 16 } } } pub fn main() { unsafe { - let x = Outer {c8: 22u8, t: Inner {c64: 44u64}}; + let x = Outer {c8: 22, t: Inner {c64: 44}}; let y = format!("{:?}", x); diff --git a/src/test/run-pass/record-pat.rs b/src/test/run-pass/record-pat.rs index 282a24a407c..b152470fbb6 100644 --- a/src/test/run-pass/record-pat.rs +++ b/src/test/run-pass/record-pat.rs @@ -20,6 +20,6 @@ fn m(input: t3) -> int { } pub fn main() { - assert_eq!(m(t3::c(T2 {x: t1::a(10), y: 5}, 4_usize)), 10); - assert_eq!(m(t3::c(T2 {x: t1::b(10_usize), y: 5}, 4_usize)), 19); + assert_eq!(m(t3::c(T2 {x: t1::a(10), y: 5}, 4)), 10); + assert_eq!(m(t3::c(T2 {x: t1::b(10), y: 5}, 4)), 19); } diff --git a/src/test/run-pass/regions-borrow-at.rs b/src/test/run-pass/regions-borrow-at.rs index 1e91ab7e921..56dd386ead1 100644 --- a/src/test/run-pass/regions-borrow-at.rs +++ b/src/test/run-pass/regions-borrow-at.rs @@ -16,8 +16,8 @@ fn foo(x: &uint) -> uint { } pub fn main() { - let p: Box<_> = box 22_usize; + let p: Box<_> = box 22; let r = foo(&*p); println!("r={}", r); - assert_eq!(r, 22_usize); + assert_eq!(r, 22); } diff --git a/src/test/run-pass/regions-borrow-uniq.rs b/src/test/run-pass/regions-borrow-uniq.rs index 7c9b1ae226f..0673179eef0 100644 --- a/src/test/run-pass/regions-borrow-uniq.rs +++ b/src/test/run-pass/regions-borrow-uniq.rs @@ -16,7 +16,7 @@ fn foo(x: &uint) -> uint { } pub fn main() { - let p: Box<_> = box 3_usize; + let p: Box<_> = box 3; let r = foo(&*p); - assert_eq!(r, 3_usize); + assert_eq!(r, 3); } diff --git a/src/test/run-pass/regions-copy-closure.rs b/src/test/run-pass/regions-copy-closure.rs index 3704fc1d8d1..b39343b1f57 100644 --- a/src/test/run-pass/regions-copy-closure.rs +++ b/src/test/run-pass/regions-copy-closure.rs @@ -20,7 +20,7 @@ fn box_it<'a>(x: Box<FnMut() + 'a>) -> closure_box<'a> { } pub fn main() { - let mut i = 3i32; + let mut i = 3; assert_eq!(i, 3); { let cl = || i += 1; diff --git a/src/test/run-pass/regions-escape-into-other-fn.rs b/src/test/run-pass/regions-escape-into-other-fn.rs index 0ca17e218d2..3708d187d71 100644 --- a/src/test/run-pass/regions-escape-into-other-fn.rs +++ b/src/test/run-pass/regions-escape-into-other-fn.rs @@ -15,6 +15,6 @@ fn foo(x: &uint) -> &uint { x } fn bar(x: &uint) -> uint { *x } pub fn main() { - let p: Box<_> = box 3_usize; + let p: Box<_> = box 3; assert_eq!(bar(foo(&*p)), 3); } diff --git a/src/test/run-pass/regions-params.rs b/src/test/run-pass/regions-params.rs index c71953e20f8..181d962cfae 100644 --- a/src/test/run-pass/regions-params.rs +++ b/src/test/run-pass/regions-params.rs @@ -21,6 +21,6 @@ fn parameterized(x: &uint) -> uint { } pub fn main() { - let x = 3_usize; - assert_eq!(parameterized(&x), 3_usize); + let x = 3; + assert_eq!(parameterized(&x), 3); } diff --git a/src/test/run-pass/regions-refcell.rs b/src/test/run-pass/regions-refcell.rs index a224017780e..30d8fc34d00 100644 --- a/src/test/run-pass/regions-refcell.rs +++ b/src/test/run-pass/regions-refcell.rs @@ -18,7 +18,7 @@ use std::cell::RefCell; // This version does not yet work (associated type issues)... #[cfg(cannot_use_this_yet)] fn foo<'a>(map: RefCell<HashMap<&'static str, &'a [u8]>>) { - let one = [1_usize]; + let one = [1]; assert_eq!(map.borrow().get("one"), Some(&one[..])); } @@ -26,7 +26,7 @@ fn foo<'a>(map: RefCell<HashMap<&'static str, &'a [u8]>>) { // ... and this version does not work (the lifetime of `one` is // supposed to match the lifetime `'a`) ... fn foo<'a>(map: RefCell<HashMap<&'static str, &'a [u8]>>) { - let one = [1_usize]; + let one = [1]; assert_eq!(map.borrow().get("one"), Some(&one.as_slice())); } @@ -41,9 +41,9 @@ fn foo<'a>(map: RefCell<HashMap<&'static str, &'a [u8]>>) { } fn main() { - let zer = [0u8]; - let one = [1u8]; - let two = [2u8]; + let zer = [0]; + let one = [1]; + let two = [2]; let mut map = HashMap::new(); map.insert("zero", &zer[..]); map.insert("one", &one[..]); diff --git a/src/test/run-pass/regions-trait-object-1.rs b/src/test/run-pass/regions-trait-object-1.rs index eb3bec77326..807227d47db 100644 --- a/src/test/run-pass/regions-trait-object-1.rs +++ b/src/test/run-pass/regions-trait-object-1.rs @@ -37,7 +37,7 @@ fn extension<'e>(x: &'e E<'e>) -> Box<M+'e> { } fn main() { - let w = E { f: &10u8 }; + let w = E { f: &10 }; let o = extension(&w); - assert_eq!(o.n(), 10u8); + assert_eq!(o.n(), 10); } diff --git a/src/test/run-pass/rename-directory.rs b/src/test/run-pass/rename-directory.rs index abe6ffe7d4c..9209db22433 100644 --- a/src/test/run-pass/rename-directory.rs +++ b/src/test/run-pass/rename-directory.rs @@ -34,7 +34,7 @@ fn rename_directory() { let fromp = CString::new(test_file.as_vec()).unwrap(); let modebuf = CString::new(b"w+b").unwrap(); let ostream = libc::fopen(fromp.as_ptr(), modebuf.as_ptr()); - assert!((ostream as uint != 0_usize)); + assert!((ostream as uint != 0)); let s = "hello".to_string(); let buf = CString::new(b"hello").unwrap(); let write_len = libc::fwrite(buf.as_ptr() as *mut _, diff --git a/src/test/run-pass/ret-bang.rs b/src/test/run-pass/ret-bang.rs index 74227192cab..14b398b3d9a 100644 --- a/src/test/run-pass/ret-bang.rs +++ b/src/test/run-pass/ret-bang.rs @@ -14,11 +14,11 @@ fn my_err(s: String) -> ! { println!("{}", s); panic!(); } fn okay(i: uint) -> int { - if i == 3_usize { + if i == 3 { my_err("I don't like three".to_string()); } else { return 42; } } -pub fn main() { okay(4_usize); } +pub fn main() { okay(4); } diff --git a/src/test/run-pass/running-with-no-runtime.rs b/src/test/run-pass/running-with-no-runtime.rs index ec033b74dd1..abb16c39d11 100644 --- a/src/test/run-pass/running-with-no-runtime.rs +++ b/src/test/run-pass/running-with-no-runtime.rs @@ -43,15 +43,15 @@ fn start(argc: int, argv: *const *const u8) -> int { }; let me = &*args[0]; - let x: &[u8] = &[1u8]; + let x: &[u8] = &[1]; pass(Command::new(me).arg(x).output().unwrap()); - let x: &[u8] = &[2u8]; + let x: &[u8] = &[2]; pass(Command::new(me).arg(x).output().unwrap()); - let x: &[u8] = &[3u8]; + let x: &[u8] = &[3]; pass(Command::new(me).arg(x).output().unwrap()); - let x: &[u8] = &[4u8]; + let x: &[u8] = &[4]; pass(Command::new(me).arg(x).output().unwrap()); - let x: &[u8] = &[5u8]; + let x: &[u8] = &[5]; pass(Command::new(me).arg(x).output().unwrap()); 0 diff --git a/src/test/run-pass/send-is-not-static-par-for.rs b/src/test/run-pass/send-is-not-static-par-for.rs index c6b64d97fbd..c6b64d97fbd 100755..100644 --- a/src/test/run-pass/send-is-not-static-par-for.rs +++ b/src/test/run-pass/send-is-not-static-par-for.rs diff --git a/src/test/run-pass/sendfn-is-a-block.rs b/src/test/run-pass/sendfn-is-a-block.rs index 18519573c26..51c20bcd098 100644 --- a/src/test/run-pass/sendfn-is-a-block.rs +++ b/src/test/run-pass/sendfn-is-a-block.rs @@ -10,10 +10,10 @@ fn test<F>(f: F) -> uint where F: FnOnce(uint) -> uint { - return f(22_usize); + return f(22); } pub fn main() { - let y = test(|x| 4_usize * x); - assert_eq!(y, 88_usize); + let y = test(|x| 4 * x); + assert_eq!(y, 88); } diff --git a/src/test/run-pass/shift-various-types.rs b/src/test/run-pass/shift-various-types.rs index 2f56e09b2df..26dc6c5316b 100644 --- a/src/test/run-pass/shift-various-types.rs +++ b/src/test/run-pass/shift-various-types.rs @@ -25,17 +25,17 @@ struct Panolpy { } fn foo(p: &Panolpy) { - assert_eq!(22_i32 >> p.i8, 11_i32); - assert_eq!(22_i32 >> p.i16, 11_i32); - assert_eq!(22_i32 >> p.i32, 11_i32); - assert_eq!(22_i32 >> p.i64, 11_i32); - assert_eq!(22_i32 >> p.isize, 11_i32); + assert_eq!(22 >> p.i8, 11); + assert_eq!(22 >> p.i16, 11); + assert_eq!(22 >> p.i32, 11); + assert_eq!(22 >> p.i64, 11); + assert_eq!(22 >> p.isize, 11); - assert_eq!(22_i32 >> p.u8, 11_i32); - assert_eq!(22_i32 >> p.u16, 11_i32); - assert_eq!(22_i32 >> p.u32, 11_i32); - assert_eq!(22_i32 >> p.u64, 11_i32); - assert_eq!(22_i32 >> p.usize, 11_i32); + assert_eq!(22 >> p.u8, 11); + assert_eq!(22 >> p.u16, 11); + assert_eq!(22 >> p.u32, 11); + assert_eq!(22 >> p.u64, 11); + assert_eq!(22 >> p.usize, 11); } fn main() { diff --git a/src/test/compile-fail/unsized4.rs b/src/test/run-pass/single-derive-attr-with-gate.rs index f8b8ad2bf2e..cc5d8fc7891 100644 --- a/src/test/compile-fail/unsized4.rs +++ b/src/test/run-pass/single-derive-attr-with-gate.rs @@ -1,4 +1,4 @@ -// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// 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. // @@ -8,12 +8,11 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// Test that bounds are sized-compatible. +#![feature(custom_derive)] -trait T : Sized {} -fn f<Y: ?Sized + T>() { -//~^ERROR incompatible bounds on `Y`, bound `T` does not allow unsized type -} +#[derive_Clone] +struct Test; pub fn main() { + Test.clone(); } diff --git a/src/test/run-pass/small-enums-with-fields.rs b/src/test/run-pass/small-enums-with-fields.rs index 475af8f2b8e..86eed715f32 100644 --- a/src/test/run-pass/small-enums-with-fields.rs +++ b/src/test/run-pass/small-enums-with-fields.rs @@ -29,14 +29,14 @@ macro_rules! check { pub fn main() { check!(Option<u8>, 2, None, "None", - Some(129u8), "Some(129)"); + Some(129), "Some(129)"); check!(Option<i16>, 4, None, "None", - Some(-20000i16), "Some(-20000)"); + Some(-20000), "Some(-20000)"); check!(Either<u8, i8>, 2, - Either::Left(132u8), "Left(132)", - Either::Right(-32i8), "Right(-32)"); + Either::Left(132), "Left(132)", + Either::Right(-32), "Right(-32)"); check!(Either<u8, i16>, 4, - Either::Left(132u8), "Left(132)", - Either::Right(-20000i16), "Right(-20000)"); + Either::Left(132), "Left(132)", + Either::Right(-20000), "Right(-20000)"); } diff --git a/src/test/run-pass/static-methods-in-traits.rs b/src/test/run-pass/static-methods-in-traits.rs index 5f6dc4f2a53..47f46041c22 100644 --- a/src/test/run-pass/static-methods-in-traits.rs +++ b/src/test/run-pass/static-methods-in-traits.rs @@ -21,7 +21,7 @@ mod a { impl Foo for uint { fn foo() -> uint { - 5_usize + 5 } } } diff --git a/src/test/run-pass/string-self-append.rs b/src/test/run-pass/string-self-append.rs index 359c14ea7b0..cef7a93aeed 100644 --- a/src/test/run-pass/string-self-append.rs +++ b/src/test/run-pass/string-self-append.rs @@ -12,12 +12,12 @@ pub fn main() { // Make sure we properly handle repeated self-appends. let mut a: String = "A".to_string(); let mut i = 20; - let mut expected_len = 1_usize; + let mut expected_len = 1; while i > 0 { println!("{}", a.len()); assert_eq!(a.len(), expected_len); a = format!("{}{}", a, a); i -= 1; - expected_len *= 2_usize; + expected_len *= 2; } } diff --git a/src/test/run-pass/struct-order-of-eval-1.rs b/src/test/run-pass/struct-order-of-eval-1.rs index 6cebd17496a..a64477242c0 100644 --- a/src/test/run-pass/struct-order-of-eval-1.rs +++ b/src/test/run-pass/struct-order-of-eval-1.rs @@ -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!"); } diff --git a/src/test/run-pass/struct-order-of-eval-2.rs b/src/test/run-pass/struct-order-of-eval-2.rs index 786f080bb9e..359ecdab630 100644 --- a/src/test/run-pass/struct-order-of-eval-2.rs +++ b/src/test/run-pass/struct-order-of-eval-2.rs @@ -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 index 00000000000..856ed7c105e --- /dev/null +++ b/src/test/run-pass/struct-order-of-eval-3.rs @@ -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 index 00000000000..25923beffdd --- /dev/null +++ b/src/test/run-pass/struct-order-of-eval-4.rs @@ -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); +} diff --git a/src/test/run-pass/struct-return.rs b/src/test/run-pass/struct-return.rs index c8768731e2b..d67c6322c61 100644 --- a/src/test/run-pass/struct-return.rs +++ b/src/test/run-pass/struct-return.rs @@ -28,19 +28,19 @@ mod rustrt { fn test1() { unsafe { - let q = Quad { a: 0xaaaa_aaaa_aaaa_aaaa_u64, - b: 0xbbbb_bbbb_bbbb_bbbb_u64, - c: 0xcccc_cccc_cccc_cccc_u64, - d: 0xdddd_dddd_dddd_dddd_u64 }; + let q = Quad { a: 0xaaaa_aaaa_aaaa_aaaa, + b: 0xbbbb_bbbb_bbbb_bbbb, + c: 0xcccc_cccc_cccc_cccc, + d: 0xdddd_dddd_dddd_dddd }; let qq = rustrt::rust_dbg_abi_1(q); println!("a: {:x}", qq.a as uint); println!("b: {:x}", qq.b as uint); println!("c: {:x}", qq.c as uint); println!("d: {:x}", qq.d as uint); - assert_eq!(qq.a, q.c + 1u64); - assert_eq!(qq.b, q.d - 1u64); - assert_eq!(qq.c, q.a + 1u64); - assert_eq!(qq.d, q.b - 1u64); + assert_eq!(qq.a, q.c + 1); + assert_eq!(qq.b, q.d - 1); + assert_eq!(qq.c, q.a + 1); + assert_eq!(qq.d, q.b - 1); } } @@ -48,14 +48,14 @@ fn test1() { fn test2() { unsafe { let f = Floats { a: 1.234567890e-15_f64, - b: 0b_1010_1010_u8, + b: 0b_1010_1010, c: 1.0987654321e-15_f64 }; let ff = rustrt::rust_dbg_abi_2(f); println!("a: {}", ff.a as f64); println!("b: {}", ff.b as uint); println!("c: {}", ff.c as f64); assert_eq!(ff.a, f.c + 1.0f64); - assert_eq!(ff.b, 0xff_u8); + assert_eq!(ff.b, 0xff); assert_eq!(ff.c, f.a - 1.0f64); } } diff --git a/src/test/run-pass/syntax-extension-source-utils.rs b/src/test/run-pass/syntax-extension-source-utils.rs index ddd8cd8be3d..684ca7fa2b6 100644 --- a/src/test/run-pass/syntax-extension-source-utils.rs +++ b/src/test/run-pass/syntax-extension-source-utils.rs @@ -23,7 +23,7 @@ macro_rules! indirect_line { () => ( line!() ) } pub fn main() { assert_eq!(line!(), 25); - assert!((column!() == 4u32)); + assert!((column!() == 4)); assert_eq!(indirect_line!(), 27); assert!((file!().ends_with("syntax-extension-source-utils.rs"))); assert_eq!(stringify!((2*3) + 5).to_string(), "( 2 * 3 ) + 5".to_string()); diff --git a/src/test/run-pass/tag-align-dyn-u64.rs b/src/test/run-pass/tag-align-dyn-u64.rs index b7fe4983b01..8d8d4caad24 100644 --- a/src/test/run-pass/tag-align-dyn-u64.rs +++ b/src/test/run-pass/tag-align-dyn-u64.rs @@ -8,9 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-linux #7340 fails on 32-bit Linux -// ignore-macos #7340 fails on 32-bit macos - use std::mem; enum Tag<A> { @@ -23,15 +20,16 @@ struct Rec { } fn mk_rec() -> Rec { - return Rec { c8:0u8, t:Tag::Tag2(0u64) }; + return Rec { c8:0, t:Tag::Tag2(0) }; } -fn is_8_byte_aligned(u: &Tag<u64>) -> bool { +fn is_u64_aligned(u: &Tag<u64>) -> bool { let p: uint = unsafe { mem::transmute(u) }; - return (p & 7_usize) == 0_usize; + let u64_align = std::mem::min_align_of::<u64>(); + return (p & (u64_align - 1)) == 0; } pub fn main() { let x = mk_rec(); - assert!(is_8_byte_aligned(&x.t)); + assert!(is_u64_aligned(&x.t)); } diff --git a/src/test/run-pass/tag-align-dyn-variants.rs b/src/test/run-pass/tag-align-dyn-variants.rs index cb298e720ed..917f2c5b374 100644 --- a/src/test/run-pass/tag-align-dyn-variants.rs +++ b/src/test/run-pass/tag-align-dyn-variants.rs @@ -8,9 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-linux #7340 fails on 32-bit Linux -// ignore-macos #7340 fails on 32-bit macos - use std::mem; enum Tag<A,B> { @@ -26,12 +23,12 @@ struct Rec<A,B> { } fn mk_rec<A,B>(a: A, b: B) -> Rec<A,B> { - Rec { chA:0u8, tA:Tag::VarA(a), chB:1u8, tB:Tag::VarB(b) } + Rec { chA:0, tA:Tag::VarA(a), chB:1, tB:Tag::VarB(b) } } fn is_aligned<A>(amnt: uint, u: &A) -> bool { let p: uint = unsafe { mem::transmute(u) }; - return (p & (amnt-1_usize)) == 0_usize; + return (p & (amnt-1)) == 0; } fn variant_data_is_aligned<A,B>(amnt: uint, u: &Tag<A,B>) -> bool { @@ -42,33 +39,34 @@ fn variant_data_is_aligned<A,B>(amnt: uint, u: &Tag<A,B>) -> bool { } pub fn main() { + let u64_align = std::mem::min_align_of::<u64>(); let x = mk_rec(22u64, 23u64); - assert!(is_aligned(8_usize, &x.tA)); - assert!(variant_data_is_aligned(8_usize, &x.tA)); - assert!(is_aligned(8_usize, &x.tB)); - assert!(variant_data_is_aligned(8_usize, &x.tB)); + assert!(is_aligned(u64_align, &x.tA)); + assert!(variant_data_is_aligned(u64_align, &x.tA)); + assert!(is_aligned(u64_align, &x.tB)); + assert!(variant_data_is_aligned(u64_align, &x.tB)); let x = mk_rec(22u64, 23u32); - assert!(is_aligned(8_usize, &x.tA)); - assert!(variant_data_is_aligned(8_usize, &x.tA)); - assert!(is_aligned(8_usize, &x.tB)); - assert!(variant_data_is_aligned(4_usize, &x.tB)); + assert!(is_aligned(u64_align, &x.tA)); + assert!(variant_data_is_aligned(u64_align, &x.tA)); + assert!(is_aligned(u64_align, &x.tB)); + assert!(variant_data_is_aligned(4, &x.tB)); let x = mk_rec(22u32, 23u64); - assert!(is_aligned(8_usize, &x.tA)); - assert!(variant_data_is_aligned(4_usize, &x.tA)); - assert!(is_aligned(8_usize, &x.tB)); - assert!(variant_data_is_aligned(8_usize, &x.tB)); + assert!(is_aligned(u64_align, &x.tA)); + assert!(variant_data_is_aligned(4, &x.tA)); + assert!(is_aligned(u64_align, &x.tB)); + assert!(variant_data_is_aligned(u64_align, &x.tB)); let x = mk_rec(22u32, 23u32); - assert!(is_aligned(4_usize, &x.tA)); - assert!(variant_data_is_aligned(4_usize, &x.tA)); - assert!(is_aligned(4_usize, &x.tB)); - assert!(variant_data_is_aligned(4_usize, &x.tB)); + assert!(is_aligned(4, &x.tA)); + assert!(variant_data_is_aligned(4, &x.tA)); + assert!(is_aligned(4, &x.tB)); + assert!(variant_data_is_aligned(4, &x.tB)); let x = mk_rec(22f64, 23f64); - assert!(is_aligned(8_usize, &x.tA)); - assert!(variant_data_is_aligned(8_usize, &x.tA)); - assert!(is_aligned(8_usize, &x.tB)); - assert!(variant_data_is_aligned(8_usize, &x.tB)); + assert!(is_aligned(u64_align, &x.tA)); + assert!(variant_data_is_aligned(u64_align, &x.tA)); + assert!(is_aligned(u64_align, &x.tB)); + assert!(variant_data_is_aligned(u64_align, &x.tB)); } diff --git a/src/test/run-pass/tag-align-shape.rs b/src/test/run-pass/tag-align-shape.rs index cc0a75181db..5db886c815b 100644 --- a/src/test/run-pass/tag-align-shape.rs +++ b/src/test/run-pass/tag-align-shape.rs @@ -20,7 +20,7 @@ struct t_rec { } pub fn main() { - let x = t_rec {c8: 22u8, t: a_tag::a_tag_var(44u64)}; + let x = t_rec {c8: 22, t: a_tag::a_tag_var(44)}; let y = format!("{:?}", x); println!("y = {:?}", y); assert_eq!(y, "t_rec { c8: 22, t: a_tag_var(44) }".to_string()); diff --git a/src/test/run-pass/tag-align-u64.rs b/src/test/run-pass/tag-align-u64.rs index 713f55cc10c..df99d77142c 100644 --- a/src/test/run-pass/tag-align-u64.rs +++ b/src/test/run-pass/tag-align-u64.rs @@ -8,9 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-linux #7340 fails on 32-bit Linux -// ignore-macos #7340 fails on 32-bit macos - use std::mem; enum Tag { @@ -23,15 +20,16 @@ struct Rec { } fn mk_rec() -> Rec { - return Rec { c8:0u8, t:Tag::TagInner(0u64) }; + return Rec { c8:0, t:Tag::TagInner(0) }; } -fn is_8_byte_aligned(u: &Tag) -> bool { +fn is_u64_aligned(u: &Tag) -> bool { let p: uint = unsafe { mem::transmute(u) }; - return (p & 7_usize) == 0_usize; + let u64_align = std::mem::min_align_of::<u64>(); + return (p & (u64_align - 1)) == 0; } pub fn main() { let x = mk_rec(); - assert!(is_8_byte_aligned(&x.t)); + assert!(is_u64_aligned(&x.t)); } diff --git a/src/test/run-pass/task-comm-16.rs b/src/test/run-pass/task-comm-16.rs index 1d297c04c82..ca009677ee9 100644 --- a/src/test/run-pass/task-comm-16.rs +++ b/src/test/run-pass/task-comm-16.rs @@ -16,12 +16,12 @@ fn test_rec() { struct R {val0: int, val1: u8, val2: char} let (tx, rx) = channel(); - let r0: R = R {val0: 0, val1: 1u8, val2: '2'}; + let r0: R = R {val0: 0, val1: 1, val2: '2'}; tx.send(r0).unwrap(); let mut r1: R; r1 = rx.recv().unwrap(); assert_eq!(r1.val0, 0); - assert_eq!(r1.val1, 1u8); + assert_eq!(r1.val1, 1); assert_eq!(r1.val2, '2'); } @@ -84,14 +84,14 @@ fn test_tag() { let (tx, rx) = channel(); tx.send(t::tag1).unwrap(); tx.send(t::tag2(10)).unwrap(); - tx.send(t::tag3(10, 11u8, 'A')).unwrap(); + tx.send(t::tag3(10, 11, 'A')).unwrap(); let mut t1: t; t1 = rx.recv().unwrap(); assert_eq!(t1, t::tag1); t1 = rx.recv().unwrap(); assert_eq!(t1, t::tag2(10)); t1 = rx.recv().unwrap(); - assert_eq!(t1, t::tag3(10, 11u8, 'A')); + assert_eq!(t1, t::tag3(10, 11, 'A')); } fn test_chan() { diff --git a/src/test/run-pass/tcp-stress.rs b/src/test/run-pass/tcp-stress.rs index 82584c83de0..23ea998c026 100644 --- a/src/test/run-pass/tcp-stress.rs +++ b/src/test/run-pass/tcp-stress.rs @@ -52,7 +52,7 @@ fn main() { let addr = rx.recv().unwrap(); let (tx, rx) = channel(); - for _ in 0_usize..1000 { + for _ in 0..1000 { let tx = tx.clone(); Builder::new().stack_size(64 * 1024).spawn(move|| { match TcpStream::connect(addr) { @@ -71,7 +71,7 @@ fn main() { // Wait for all clients to exit, but don't wait for the server to exit. The // server just runs infinitely. drop(tx); - for _ in 0_usize..1000 { + for _ in 0..1000 { rx.recv().unwrap(); } unsafe { libc::exit(0) } diff --git a/src/test/run-pass/test-should-fail-good-message.rs b/src/test/run-pass/test-should-fail-good-message.rs index dcb2fe6dfc0..b8e05b4d35a 100644 --- a/src/test/run-pass/test-should-fail-good-message.rs +++ b/src/test/run-pass/test-should-fail-good-message.rs @@ -12,13 +12,13 @@ // 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") } diff --git a/src/test/run-pass/trait-default-method-bound-subst4.rs b/src/test/run-pass/trait-default-method-bound-subst4.rs index 383849ca512..acaa74373f0 100644 --- a/src/test/run-pass/trait-default-method-bound-subst4.rs +++ b/src/test/run-pass/trait-default-method-bound-subst4.rs @@ -21,6 +21,6 @@ fn f<T, V: A<T>>(i: V, j: uint) -> uint { } pub fn main () { - assert_eq!(f::<f64, int>(0, 2_usize), 2_usize); - assert_eq!(f::<uint, int>(0, 2_usize), 2_usize); + assert_eq!(f::<f64, int>(0, 2), 2); + assert_eq!(f::<uint, int>(0, 2), 2); } diff --git a/src/test/run-pass/trait-object-generics.rs b/src/test/run-pass/trait-object-generics.rs index 6f89490716f..18097b59b08 100644 --- a/src/test/run-pass/trait-object-generics.rs +++ b/src/test/run-pass/trait-object-generics.rs @@ -49,5 +49,5 @@ impl<V> Trait<u8,V> for () { pub fn main() { let a = box() () as Box<Trait<u8, u8>>; - assert_eq!(a.method(Type::Constant((1u8, 2u8))), 0); + assert_eq!(a.method(Type::Constant((1, 2))), 0); } diff --git a/src/test/run-pass/trait-object-with-lifetime-bound.rs b/src/test/run-pass/trait-object-with-lifetime-bound.rs index 4e481910aa9..99910f15738 100644 --- a/src/test/run-pass/trait-object-with-lifetime-bound.rs +++ b/src/test/run-pass/trait-object-with-lifetime-bound.rs @@ -36,7 +36,7 @@ fn extension<'e>(x: &'e E<'e>) -> Box<M+'e> { } fn main() { - let w = E { f: &10u8 }; + let w = E { f: &10 }; let o = extension(&w); - assert_eq!(o.n(), 10u8); + assert_eq!(o.n(), 10); } diff --git a/src/test/run-pass/traits-assoc-type-in-supertrait.rs b/src/test/run-pass/traits-assoc-type-in-supertrait.rs new file mode 100644 index 00000000000..6a4a6710131 --- /dev/null +++ b/src/test/run-pass/traits-assoc-type-in-supertrait.rs @@ -0,0 +1,31 @@ +// 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 case where an associated type is referenced from within the +// supertrait definition. Issue #20220. + +use std::vec::IntoIter; + +pub trait Foo: Iterator<Item=<Self as Foo>::Key> { + type Key; +} + +impl Foo for IntoIter<i32> { + type Key = i32; +} + +fn sum_foo<F:Foo<Key=i32>>(f: F) -> i32 { + f.fold(0, |a,b| a + b) +} + +fn main() { + let x = sum_foo(vec![11, 10, 1].into_iter()); + assert_eq!(x, 22); +} diff --git a/src/test/run-pass/traits-issue-23003.rs b/src/test/run-pass/traits-issue-23003.rs new file mode 100644 index 00000000000..37b13d319aa --- /dev/null +++ b/src/test/run-pass/traits-issue-23003.rs @@ -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. + +// Test stack overflow triggered by evaluating the implications. To be +// WF, the type `Receipt<Complete>` would require that `<Complete as +// Async>::Cancel` be WF. This normalizes to `Receipt<Complete>` +// again, leading to an infinite cycle. Issue #23003. + +#![allow(dead_code)] +#![allow(unused_variables)] + +use std::marker::PhantomData; + +trait Async { + type Cancel; +} + +struct Receipt<A:Async> { + marker: PhantomData<A>, +} + +struct Complete { + core: Option<()>, +} + +impl Async for Complete { + type Cancel = Receipt<Complete>; +} + +fn foo(r: Receipt<Complete>) { } + +fn main() { } diff --git a/src/test/run-pass/traits-repeated-supertrait.rs b/src/test/run-pass/traits-repeated-supertrait.rs new file mode 100644 index 00000000000..fdaa8d6f4d6 --- /dev/null +++ b/src/test/run-pass/traits-repeated-supertrait.rs @@ -0,0 +1,56 @@ +// 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 a case of a trait which extends the same supertrait twice, but +// with difference type parameters. Test that we can invoke the +// various methods in various ways successfully. +// See also `compile-fail/trait-repeated-supertrait-ambig.rs`. + +trait CompareTo<T> { + fn same_as(&self, t: T) -> bool; +} + +trait CompareToInts : CompareTo<i64> + CompareTo<u64> { +} + +impl CompareTo<i64> for i64 { + fn same_as(&self, t: i64) -> bool { *self == t } +} + +impl CompareTo<u64> for i64 { + fn same_as(&self, t: u64) -> bool { *self == (t as i64) } +} + +impl CompareToInts for i64 { } + +fn with_obj(c: &CompareToInts) -> bool { + c.same_as(22_i64) && c.same_as(22_u64) +} + +fn with_trait<C:CompareToInts>(c: &C) -> bool { + c.same_as(22_i64) && c.same_as(22_u64) +} + +fn with_ufcs1<C:CompareToInts>(c: &C) -> bool { + CompareToInts::same_as(c, 22_i64) && CompareToInts::same_as(c, 22_u64) +} + +fn with_ufcs2<C:CompareToInts>(c: &C) -> bool { + CompareTo::same_as(c, 22_i64) && CompareTo::same_as(c, 22_u64) +} + +fn main() { + assert_eq!(22_i64.same_as(22_i64), true); + assert_eq!(22_i64.same_as(22_u64), true); + assert_eq!(with_trait(&22), true); + assert_eq!(with_obj(&22), true); + assert_eq!(with_ufcs1(&22), true); + assert_eq!(with_ufcs2(&22), true); +} diff --git a/src/test/run-pass/type-params-in-for-each.rs b/src/test/run-pass/type-params-in-for-each.rs index cf8a09998da..5d80cec2a05 100644 --- a/src/test/run-pass/type-params-in-for-each.rs +++ b/src/test/run-pass/type-params-in-for-each.rs @@ -16,11 +16,11 @@ struct S<T> { fn range_<F>(lo: uint, hi: uint, mut it: F) where F: FnMut(uint) { let mut lo_ = lo; - while lo_ < hi { it(lo_); lo_ += 1_usize; } + while lo_ < hi { it(lo_); lo_ += 1; } } fn create_index<T>(_index: Vec<S<T>> , _hash_fn: extern fn(T) -> uint) { - range_(0_usize, 256_usize, |_i| { + range_(0, 256, |_i| { let _bucket: Vec<T> = Vec::new(); }) } diff --git a/src/test/run-pass/typeck_type_placeholder_1.rs b/src/test/run-pass/typeck_type_placeholder_1.rs index 48dc9443821..c850c01753b 100644 --- a/src/test/run-pass/typeck_type_placeholder_1.rs +++ b/src/test/run-pass/typeck_type_placeholder_1.rs @@ -21,17 +21,17 @@ static CONSTEXPR: TestStruct = TestStruct{x: &413 as *const _}; pub fn main() { - let x: Vec<_> = (0_usize..5).collect(); + let x: Vec<_> = (0..5).collect(); let expected: &[uint] = &[0,1,2,3,4]; assert_eq!(x, expected); - let x = (0_usize..5).collect::<Vec<_>>(); + let x = (0..5).collect::<Vec<_>>(); assert_eq!(x, expected); let y: _ = "hello"; assert_eq!(y.len(), 5); - let ptr = &5_usize; + let ptr = &5; let ptr2 = ptr as *const _; assert_eq!(ptr as *const uint as uint, ptr2 as uint); diff --git a/src/test/run-pass/u32-decr.rs b/src/test/run-pass/u32-decr.rs index 6ad320580df..027bd7ca680 100644 --- a/src/test/run-pass/u32-decr.rs +++ b/src/test/run-pass/u32-decr.rs @@ -12,7 +12,7 @@ pub fn main() { - let mut word: u32 = 200000u32; - word = word - 1u32; - assert_eq!(word, 199999u32); + let mut word: u32 = 200000; + word = word - 1; + assert_eq!(word, 199999); } diff --git a/src/test/run-pass/u8-incr-decr.rs b/src/test/run-pass/u8-incr-decr.rs index 0a178b250af..ff25d95d1fd 100644 --- a/src/test/run-pass/u8-incr-decr.rs +++ b/src/test/run-pass/u8-incr-decr.rs @@ -15,13 +15,13 @@ // These constants were chosen because they aren't used anywhere // in the rest of the generated code so they're easily grep-able. pub fn main() { - let mut x: u8 = 19u8; // 0x13 + let mut x: u8 = 19; // 0x13 - let mut y: u8 = 35u8; // 0x23 + let mut y: u8 = 35; // 0x23 - x = x + 7u8; // 0x7 + x = x + 7; // 0x7 - y = y - 9u8; // 0x9 + y = y - 9; // 0x9 assert_eq!(x, y); } diff --git a/src/test/run-pass/u8-incr.rs b/src/test/run-pass/u8-incr.rs index 90ed3a5eec3..7f69d078134 100644 --- a/src/test/run-pass/u8-incr.rs +++ b/src/test/run-pass/u8-incr.rs @@ -12,12 +12,12 @@ pub fn main() { - let mut x: u8 = 12u8; - let y: u8 = 12u8; - x = x + 1u8; - x = x - 1u8; + let mut x: u8 = 12; + let y: u8 = 12; + x = x + 1; + x = x - 1; assert_eq!(x, y); - // x = 14u8; - // x = x + 1u8; + // x = 14; + // x = x + 1; } diff --git a/src/test/run-pass/ufcs-trait-object.rs b/src/test/run-pass/ufcs-trait-object.rs index 2ae63040d17..34cf44bba2e 100644 --- a/src/test/run-pass/ufcs-trait-object.rs +++ b/src/test/run-pass/ufcs-trait-object.rs @@ -20,6 +20,6 @@ impl Foo for i32 { } fn main() { - let a: &Foo = &22_i32; + let a: &Foo = &22; assert_eq!(Foo::test(a), 22); } diff --git a/src/test/run-pass/unboxed-closures-unique-type-id.rs b/src/test/run-pass/unboxed-closures-unique-type-id.rs index 5c36832d9f6..ce05f077357 100644 --- a/src/test/run-pass/unboxed-closures-unique-type-id.rs +++ b/src/test/run-pass/unboxed-closures-unique-type-id.rs @@ -12,8 +12,8 @@ // // error: internal compiler error: get_unique_type_id_of_type() - // unexpected type: closure, -// ty_closure(syntax::ast::DefId{krate: 0u32, node: 66u32}, -// ReScope(63u32)) +// ty_closure(syntax::ast::DefId{krate: 0, node: 66}, +// ReScope(63)) // // This is a regression test for issue #17021. // @@ -28,8 +28,8 @@ pub fn replace_map<'a, T, F>(src: &mut T, prod: F) where F: FnOnce(T) -> T { } pub fn main() { - let mut a = 7_usize; + let mut a = 7; let b = &mut a; replace_map(b, |x: uint| x * 2); - assert_eq!(*b, 14_usize); + assert_eq!(*b, 14); } diff --git a/src/test/run-pass/unique-pat-2.rs b/src/test/run-pass/unique-pat-2.rs index 5db96bc3564..8141e3bce3c 100644 --- a/src/test/run-pass/unique-pat-2.rs +++ b/src/test/run-pass/unique-pat-2.rs @@ -17,7 +17,7 @@ struct Foo {a: int, b: uint} enum bar { u(Box<Foo>), w(int), } pub fn main() { - assert!(match bar::u(box Foo{a: 10, b: 40_usize}) { + assert!(match bar::u(box Foo{a: 10, b: 40}) { bar::u(box Foo{a: a, b: b}) => { a + (b as int) } _ => { 66 } } == 50); diff --git a/src/test/run-pass/unique-send-2.rs b/src/test/run-pass/unique-send-2.rs index 43824812ec5..654ac9a095c 100644 --- a/src/test/run-pass/unique-send-2.rs +++ b/src/test/run-pass/unique-send-2.rs @@ -20,9 +20,9 @@ fn child(tx: &Sender<Box<uint>>, i: uint) { pub fn main() { let (tx, rx) = channel(); - let n = 100_usize; - let mut expected = 0_usize; - let _t = (0_usize..n).map(|i| { + let n = 100; + let mut expected = 0; + let _t = (0..n).map(|i| { expected += i; let tx = tx.clone(); thread::spawn(move|| { @@ -30,8 +30,8 @@ pub fn main() { }) }).collect::<Vec<_>>(); - let mut actual = 0_usize; - for _ in 0_usize..n { + let mut actual = 0; + for _ in 0..n { let j = rx.recv().unwrap(); actual += *j; } diff --git a/src/test/run-pass/unsized.rs b/src/test/run-pass/unsized.rs index ae175d27b0a..1a479d05d50 100644 --- a/src/test/run-pass/unsized.rs +++ b/src/test/run-pass/unsized.rs @@ -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. diff --git a/src/test/run-pass/unsized2.rs b/src/test/run-pass/unsized2.rs index 10b2f2fb709..e0d37ff40de 100644 --- a/src/test/run-pass/unsized2.rs +++ b/src/test/run-pass/unsized2.rs @@ -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)] diff --git a/src/test/run-pass/unsized3.rs b/src/test/run-pass/unsized3.rs index c9a9d6ad147..5bd76d093d4 100644 --- a/src/test/run-pass/unsized3.rs +++ b/src/test/run-pass/unsized3.rs @@ -66,12 +66,10 @@ pub fn main() { f: [T; 3] } - let data: Box<_> = box Foo_{f: [1i32, 2, 3] }; + let data: Box<Foo_<i32>> = box Foo_{f: [1, 2, 3] }; let x: &Foo<i32> = mem::transmute(raw::Slice { len: 3, data: &*data }); assert!(x.f.len() == 3); assert!(x.f[0] == 1); - assert!(x.f[1] == 2); - assert!(x.f[2] == 3); struct Baz_ { f1: uint, diff --git a/src/test/run-pass/utf8.rs b/src/test/run-pass/utf8.rs index 96bba01068f..4be54bd7080 100644 --- a/src/test/run-pass/utf8.rs +++ b/src/test/run-pass/utf8.rs @@ -24,7 +24,7 @@ pub fn main() { assert_eq!(y_diaeresis as int, 0xff); assert_eq!(pi as int, 0x3a0); - assert_eq!(pi as int, '\u03a0' as int); + assert_eq!(pi as int, '\u{3a0}' as int); assert_eq!('\x0a' as int, '\n' as int); let bhutan: String = "འབྲུག་ཡུལ།".to_string(); @@ -33,11 +33,11 @@ pub fn main() { let austria: String = "Österreich".to_string(); let bhutan_e: String = - "\u0f60\u0f56\u0fb2\u0f74\u0f42\u0f0b\u0f61\u0f74\u0f63\u0f0d".to_string(); - let japan_e: String = "\u65e5\u672c".to_string(); + "\u{f60}\u{f56}\u{fb2}\u{f74}\u{f42}\u{f0b}\u{f61}\u{f74}\u{f63}\u{f0d}".to_string(); + let japan_e: String = "\u{65e5}\u{672c}".to_string(); let uzbekistan_e: String = - "\u040e\u0437\u0431\u0435\u043a\u0438\u0441\u0442\u043e\u043d".to_string(); - let austria_e: String = "\u00d6sterreich".to_string(); + "\u{40e}\u{437}\u{431}\u{435}\u{43a}\u{438}\u{441}\u{442}\u{43e}\u{43d}".to_string(); + let austria_e: String = "\u{d6}sterreich".to_string(); let oo: char = 'Ö'; assert_eq!(oo as int, 0xd6); diff --git a/src/test/run-pass/utf8_chars.rs b/src/test/run-pass/utf8_chars.rs index 84f605eef57..c54b3b69c68 100644 --- a/src/test/run-pass/utf8_chars.rs +++ b/src/test/run-pass/utf8_chars.rs @@ -14,30 +14,30 @@ use std::str; pub fn main() { // Chars of 1, 2, 3, and 4 bytes - let chs: Vec<char> = vec!('e', 'é', '€', '\U00010000'); + let chs: Vec<char> = vec!('e', 'é', '€', '\u{10000}'); let s: String = chs.iter().cloned().collect(); let schs: Vec<char> = s.chars().collect(); - assert!(s.len() == 10_usize); - assert!(s.chars().count() == 4_usize); - assert!(schs.len() == 4_usize); + assert!(s.len() == 10); + assert!(s.chars().count() == 4); + assert!(schs.len() == 4); assert!(schs.iter().cloned().collect::<String>() == s); - assert!(s.char_at(0_usize) == 'e'); - assert!(s.char_at(1_usize) == 'é'); + assert!(s.char_at(0) == 'e'); + assert!(s.char_at(1) == 'é'); assert!((str::from_utf8(s.as_bytes()).is_ok())); // invalid prefix - assert!((!str::from_utf8(&[0x80_u8]).is_ok())); + assert!((!str::from_utf8(&[0x80]).is_ok())); // invalid 2 byte prefix - assert!((!str::from_utf8(&[0xc0_u8]).is_ok())); - assert!((!str::from_utf8(&[0xc0_u8, 0x10_u8]).is_ok())); + assert!((!str::from_utf8(&[0xc0]).is_ok())); + assert!((!str::from_utf8(&[0xc0, 0x10]).is_ok())); // invalid 3 byte prefix - assert!((!str::from_utf8(&[0xe0_u8]).is_ok())); - assert!((!str::from_utf8(&[0xe0_u8, 0x10_u8]).is_ok())); - assert!((!str::from_utf8(&[0xe0_u8, 0xff_u8, 0x10_u8]).is_ok())); + assert!((!str::from_utf8(&[0xe0]).is_ok())); + assert!((!str::from_utf8(&[0xe0, 0x10]).is_ok())); + assert!((!str::from_utf8(&[0xe0, 0xff, 0x10]).is_ok())); // invalid 4 byte prefix - assert!((!str::from_utf8(&[0xf0_u8]).is_ok())); - assert!((!str::from_utf8(&[0xf0_u8, 0x10_u8]).is_ok())); - assert!((!str::from_utf8(&[0xf0_u8, 0xff_u8, 0x10_u8]).is_ok())); - assert!((!str::from_utf8(&[0xf0_u8, 0xff_u8, 0xff_u8, 0x10_u8]).is_ok())); + assert!((!str::from_utf8(&[0xf0]).is_ok())); + assert!((!str::from_utf8(&[0xf0, 0x10]).is_ok())); + assert!((!str::from_utf8(&[0xf0, 0xff, 0x10]).is_ok())); + assert!((!str::from_utf8(&[0xf0, 0xff, 0xff, 0x10]).is_ok())); } diff --git a/src/test/run-pass/variadic-ffi.rs b/src/test/run-pass/variadic-ffi.rs index 5a476ed9ee2..b3fff6977a5 100644 --- a/src/test/run-pass/variadic-ffi.rs +++ b/src/test/run-pass/variadic-ffi.rs @@ -13,7 +13,6 @@ extern crate libc; use std::ffi::{self, CString}; use libc::{c_char, c_int}; -// ignore-fast doesn't like extern crate extern { fn sprintf(s: *mut c_char, format: *const c_char, ...) -> c_int; diff --git a/src/test/run-pass/vec-fixed-length.rs b/src/test/run-pass/vec-fixed-length.rs index 015baea5fb5..a0b3564d84e 100644 --- a/src/test/run-pass/vec-fixed-length.rs +++ b/src/test/run-pass/vec-fixed-length.rs @@ -17,11 +17,11 @@ pub fn main() { assert_eq!(x[2], 3); assert_eq!(x[3], 4); - assert_eq!(size_of::<[u8; 4]>(), 4_usize); + assert_eq!(size_of::<[u8; 4]>(), 4); // FIXME #10183 // FIXME #18069 //if cfg!(target_pointer_width = "64") { - // assert_eq!(size_of::<[u8; (1 << 32)]>(), (1_usize << 32)); + // assert_eq!(size_of::<[u8; (1 << 32)]>(), (1 << 32)); //} } diff --git a/src/test/run-pass/weird-exprs.rs b/src/test/run-pass/weird-exprs.rs index baea1b8826a..20e42575b27 100644 --- a/src/test/run-pass/weird-exprs.rs +++ b/src/test/run-pass/weird-exprs.rs @@ -65,7 +65,7 @@ fn canttouchthis() -> uint { fn p() -> bool { true } let _a = (assert!((true)) == (assert!(p()))); let _c = (assert!((p())) == ()); - let _b: bool = (println!("{}", 0) == (return 0_usize)); + let _b: bool = (println!("{}", 0) == (return 0)); } fn angrydome() { diff --git a/src/test/run-pass/where-for-self.rs b/src/test/run-pass/where-for-self.rs index 1fd223b0dd3..67757d7efa8 100644 --- a/src/test/run-pass/where-for-self.rs +++ b/src/test/run-pass/where-for-self.rs @@ -55,7 +55,7 @@ fn foo2<T>(x: &T) } fn main() { - let x = 42u32; + let x = 42; foo1(&x); foo2(&x); unsafe { diff --git a/src/test/run-pass/x86stdcall.rs b/src/test/run-pass/x86stdcall.rs index dea58c8e86f..b884adb7a6e 100644 --- a/src/test/run-pass/x86stdcall.rs +++ b/src/test/run-pass/x86stdcall.rs @@ -22,7 +22,7 @@ mod kernel32 { #[cfg(windows)] pub fn main() { unsafe { - let expected = 1234_usize; + let expected = 1234; kernel32::SetLastError(expected); let actual = kernel32::GetLastError(); println!("actual = {}", actual); diff --git a/src/test/run-pass/x86stdcall2.rs b/src/test/run-pass/x86stdcall2.rs index 86c1ae0f51f..b5b9d95d87f 100644 --- a/src/test/run-pass/x86stdcall2.rs +++ b/src/test/run-pass/x86stdcall2.rs @@ -30,10 +30,10 @@ mod kernel32 { #[cfg(windows)] pub fn main() { let heap = unsafe { kernel32::GetProcessHeap() }; - let mem = unsafe { kernel32::HeapAlloc(heap, 0u32, 100u32) }; - assert!(mem != 0_usize); - let res = unsafe { kernel32::HeapFree(heap, 0u32, mem) }; - assert!(res != 0u8); + let mem = unsafe { kernel32::HeapAlloc(heap, 0, 100) }; + assert!(mem != 0); + let res = unsafe { kernel32::HeapFree(heap, 0, mem) }; + assert!(res != 0); } #[cfg(not(windows))] |
