## 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
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.
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.
*)
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"
.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.
.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"
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,
"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"
$ 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.
tmp/install-debugger-scripts$(1)_H_$(2)-gdb.done: \
$$(DEBUGGER_RUSTLIB_ETC_SCRIPTS_GDB_ABS) \
$$(DEBUGGER_BIN_SCRIPTS_GDB_ABS)
+ $(Q)touch $$@.start_time
$(Q)mkdir -p $$(HBIN$(1)_H_$(2))
$(Q)mkdir -p $$(HLIB$(1)_H_$(2))/rustlib/etc
$(Q)install $$(DEBUGGER_BIN_SCRIPTS_GDB_ABS) $$(HBIN$(1)_H_$(2))
$(Q)install $$(DEBUGGER_RUSTLIB_ETC_SCRIPTS_GDB_ABS) $$(HLIB$(1)_H_$(2))/rustlib/etc
- $(Q)touch $$@
+ $(Q)touch -r $$@.start_time $$@ && rm $$@.start_time
tmp/install-debugger-scripts$(1)_H_$(2)-lldb.done: \
$$(DEBUGGER_RUSTLIB_ETC_SCRIPTS_LLDB_ABS) \
$$(DEBUGGER_BIN_SCRIPTS_LLDB_ABS)
+ $(Q)touch $$@.start_time
$(Q)mkdir -p $$(HBIN$(1)_H_$(2))
$(Q)mkdir -p $$(HLIB$(1)_H_$(2))/rustlib/etc
$(Q)install $$(DEBUGGER_BIN_SCRIPTS_LLDB_ABS) $$(HBIN$(1)_H_$(2))
$(Q)install $$(DEBUGGER_RUSTLIB_ETC_SCRIPTS_LLDB_ABS) $$(HLIB$(1)_H_$(2))/rustlib/etc
- $(Q)touch $$@
+ $(Q)touch -r $$@.start_time $$@ && rm $$@.start_time
tmp/install-debugger-scripts$(1)_H_$(2)-all.done: \
$$(DEBUGGER_RUSTLIB_ETC_SCRIPTS_ALL_ABS) \
$$(DEBUGGER_BIN_SCRIPTS_ALL_ABS)
+ $(Q)touch $$@.start_time
$(Q)mkdir -p $$(HBIN$(1)_H_$(2))
$(Q)mkdir -p $$(HLIB$(1)_H_$(2))/rustlib/etc
$(Q)install $$(DEBUGGER_BIN_SCRIPTS_ALL_ABS) $$(HBIN$(1)_H_$(2))
$(Q)install $$(DEBUGGER_RUSTLIB_ETC_SCRIPTS_ALL_ABS) $$(HLIB$(1)_H_$(2))/rustlib/etc
- $(Q)touch $$@
+ $(Q)touch -r $$@.start_time $$@ && rm $$@.start_time
tmp/install-debugger-scripts$(1)_H_$(2)-none.done:
$(Q)touch $$@
tmp/install-debugger-scripts$(1)_T_$(2)_H_$(3)-gdb.done: \
$$(DEBUGGER_RUSTLIB_ETC_SCRIPTS_GDB_ABS) \
$$(DEBUGGER_BIN_SCRIPTS_GDB_ABS)
+ $(Q)touch $$@.start_time
$(Q)mkdir -p $$(TBIN$(1)_T_$(2)_H_$(3))
$(Q)mkdir -p $$(TLIB$(1)_T_$(2)_H_$(3))/rustlib/etc
$(Q)install $(DEBUGGER_BIN_SCRIPTS_GDB_ABS) $$(TBIN$(1)_T_$(2)_H_$(3))
$(Q)install $(DEBUGGER_RUSTLIB_ETC_SCRIPTS_GDB_ABS) $$(TLIB$(1)_T_$(2)_H_$(3))/rustlib/etc
- $(Q)touch $$@
+ $(Q)touch -r $$@.start_time $$@ && rm $$@.start_time
tmp/install-debugger-scripts$(1)_T_$(2)_H_$(3)-lldb.done: \
$$(DEBUGGER_RUSTLIB_ETC_SCRIPTS_LLDB_ABS) \
$$(DEBUGGER_BIN_SCRIPTS_LLDB_ABS)
+ $(Q)touch $$@.start_time
$(Q)mkdir -p $$(TBIN$(1)_T_$(2)_H_$(3))
$(Q)mkdir -p $$(TLIB$(1)_T_$(2)_H_$(3))/rustlib/etc
$(Q)install $(DEBUGGER_BIN_SCRIPTS_LLDB_ABS) $$(TBIN$(1)_T_$(2)_H_$(3))
$(Q)install $(DEBUGGER_RUSTLIB_ETC_SCRIPTS_LLDB_ABS) $$(TLIB$(1)_T_$(2)_H_$(3))/rustlib/etc
- $(Q)touch $$@
+ $(Q)touch -r $$@.start_time $$@ && rm $$@.start_time
tmp/install-debugger-scripts$(1)_T_$(2)_H_$(3)-all.done: \
$$(DEBUGGER_RUSTLIB_ETC_SCRIPTS_ALL_ABS) \
$$(DEBUGGER_BIN_SCRIPTS_ALL_ABS)
+ $(Q)touch $$@.start_time
$(Q)mkdir -p $$(TBIN$(1)_T_$(2)_H_$(3))
$(Q)mkdir -p $$(TLIB$(1)_T_$(2)_H_$(3))/rustlib/etc
$(Q)install $(DEBUGGER_BIN_SCRIPTS_ALL_ABS) $$(TBIN$(1)_T_$(2)_H_$(3))
$(Q)install $(DEBUGGER_RUSTLIB_ETC_SCRIPTS_ALL_ABS) $$(TLIB$(1)_T_$(2)_H_$(3))/rustlib/etc
- $(Q)touch $$@
+ $(Q)touch -r $$@.start_time $$@ && rm $$@.start_time
tmp/install-debugger-scripts$(1)_T_$(2)_H_$(3)-none.done:
$(Q)touch $$@
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
# the stamp in the source dir.
$$(LLVM_STAMP_$(1)): $(S)src/rustllvm/llvm-auto-clean-trigger
@$$(call E, make: cleaning llvm)
+ $(Q)touch $$@.start_time
$(Q)$(MAKE) clean-llvm$(1)
@$$(call E, make: done cleaning llvm)
- touch $$@
+ touch -r $$@.start_time $$@ && rm $$@.start_time
ifeq ($$(CFG_ENABLE_LLVM_STATIC_STDCPP),1)
LLVM_STDCPP_LOCATION_$(1) = $$(shell $$(CC_$(1)) $$(CFG_GCCISH_CFLAGS_$(1)) \
# 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
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)
$$(TSREQ$(1)_T_$(2)_H_$(3)) \
| $$(TLIB$(1)_T_$(2)_H_$(3))/
@$$(call E, rustc: $$(@D)/lib$(4))
+ @touch $$@.start_time
$$(call REMOVE_ALL_OLD_GLOB_MATCHES, \
$$(dir $$@)$$(call CFG_LIB_GLOB_$(2),$(4)))
$$(call REMOVE_ALL_OLD_GLOB_MATCHES, \
--out-dir $$(@D) \
-C extra-filename=-$$(CFG_FILENAME_EXTRA) \
$$<
- @touch $$@
+ @touch -r $$@.start_time $$@ && rm $$@.start_time
$$(call LIST_ALL_OLD_GLOB_MATCHES, \
$$(dir $$@)$$(call CFG_LIB_GLOB_$(2),$(4)))
$$(call LIST_ALL_OLD_GLOB_MATCHES, \
$$(call TEST_OK_FILE,$(1),$(2),$(3),$(4)): \
$(3)/stage$(1)/test/$(4)test-$(2)$$(X_$(2))
@$$(call E, run: $$<)
+ $$(Q)touch $$@.start_time
$$(Q)$$(call CFG_RUN_TEST_$(2),$$<,$(1),$(2),$(3)) $$(TESTARGS) \
--logfile $$(call TEST_LOG_FILE,$(1),$(2),$(3),$(4)) \
$$(call CRATE_TEST_EXTRA_ARGS,$(1),$(2),$(3),$(4)) \
- && touch $$@
+ && touch -r $$@.start_time $$@ && rm $$@.start_time
endef
define DEF_TEST_CRATE_RULES_android
$$(call TEST_OK_FILE,$(1),$(2),$(3),$(4)): \
$(3)/stage$(1)/test/$(4)test-$(2)$$(X_$(2))
@$$(call E, run: $$< via adb)
+ $$(Q)touch $$@.start_time
$$(Q)$(CFG_ADB) push $$< $(CFG_ADB_TEST_DIR)
$$(Q)$(CFG_ADB) shell '(cd $(CFG_ADB_TEST_DIR); LD_LIBRARY_PATH=./$(2) \
./$$(notdir $$<) \
@if grep -q "result: ok" tmp/check-stage$(1)-T-$(2)-H-$(3)-$(4).tmp; \
then \
rm tmp/check-stage$(1)-T-$(2)-H-$(3)-$(4).tmp; \
- touch $$@; \
+ touch -r $$@.start_time $$@ && rm $$@.start_time; \
else \
rm tmp/check-stage$(1)-T-$(2)-H-$(3)-$(4).tmp; \
exit 101; \
# 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
$$(TEST_SREQ$(1)_T_$(2)_H_$(3)) \
$$(CTEST_DEPS_$(4)_$(1)-T-$(2)-H-$(3))
@$$(call E, run $(4) [$(2)]: $$<)
+ $$(Q)touch $$@.start_time
$$(Q)$$(call CFG_RUN_CTEST_$(2),$(1),$$<,$(3)) \
$$(CTEST_ARGS$(1)-T-$(2)-H-$(3)-$(4)) \
--logfile $$(call TEST_LOG_FILE,$(1),$(2),$(3),$(4)) \
- && touch $$@
+ && touch -r $$@.start_time $$@ && rm $$@.start_time
else
$$(PRETTY_DEPS_$(4)) \
$$(PRETTY_DEPS$(1)_H_$(3)_$(4))
@$$(call E, run pretty-rpass [$(2)]: $$<)
+ $$(Q)touch $$@.start_time
$$(Q)$$(call CFG_RUN_CTEST_$(2),$(1),$$<,$(3)) \
$$(PRETTY_ARGS$(1)-T-$(2)-H-$(3)-$(4)) \
--logfile $$(call TEST_LOG_FILE,$(1),$(2),$(3),$(4)) \
- && touch $$@
+ && touch -r $$@.start_time $$@ && rm $$@.start_time
endef
ifeq ($(2),$$(CFG_BUILD))
$$(call TEST_OK_FILE,$(1),$(2),$(3),doc-$(4)): $$(DOCTESTDEP_$(1)_$(2)_$(3)_$(4))
@$$(call E, run doc-$(4) [$(2)])
+ $$(Q)touch $$@.start_time
$$(Q)$$(RUSTDOC_$(1)_T_$(2)_H_$(3)) --cfg dox --test $$< \
- --test-args "$$(TESTARGS)" && touch $$@
+ --test-args "$$(TESTARGS)" && \
+ touch -r $$@.start_time $$@ && rm $$@.start_time
else
$$(call TEST_OK_FILE,$(1),$(2),$(3),doc-$(4)):
touch $$@
ifeq ($(2),$$(CFG_BUILD))
$$(call TEST_OK_FILE,$(1),$(2),$(3),doc-crate-$(4)): $$(CRATEDOCTESTDEP_$(1)_$(2)_$(3)_$(4))
@$$(call E, run doc-crate-$(4) [$(2)])
+ $$(Q)touch $$@.start_time
$$(Q)CFG_LLVM_LINKAGE_FILE=$$(LLVM_LINKAGE_PATH_$(3)) \
$$(RUSTDOC_$(1)_T_$(2)_H_$(3)) --test --cfg dox \
- $$(CRATEFILE_$(4)) --test-args "$$(TESTARGS)" && touch $$@
+ $$(CRATEFILE_$(4)) --test-args "$$(TESTARGS)" && \
+ touch -r $$@.start_time $$@ && rm $$@.start_time
else
$$(call TEST_OK_FILE,$(1),$(2),$(3),doc-crate-$(4)):
touch $$@
$$(CSREQ$(1)_T_$(2)_H_$(3))
@rm -rf $(3)/test/run-make/$$*
@mkdir -p $(3)/test/run-make/$$*
+ $$(Q)touch $$@.start_time
$$(Q)$$(CFG_PYTHON) $(S)src/etc/maketest.py $$(dir $$<) \
$$(MAKE) \
$$(HBIN$(1)_H_$(3))/rustc$$(X_$(3)) \
"$$(LD_LIBRARY_PATH_ENV_TARGETDIR$(1)_T_$(2)_H_$(3))" \
$(1) \
$$(S)
- @touch $$@
+ @touch -r $$@.start_time $$@ && rm $$@.start_time
else
# FIXME #11094 - The above rule doesn't work right for multiple targets
check-stage$(1)-T-$(2)-H-$(3)-rmake-exec:
use std::fmt;
use std::str::FromStr;
+use std::path::PathBuf;
#[derive(Clone, Copy, PartialEq, Debug)]
pub enum Mode {
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>,
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,
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
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,
#![feature(unboxed_closures)]
#![feature(std_misc)]
#![feature(test)]
-#![feature(unicode)]
#![feature(core)]
+#![feature(path)]
+#![feature(io)]
+#![feature(net)]
+#![feature(path_ext)]
#![deny(warnings)]
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;
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),
}
}
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"),
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"),
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, || {
_ => 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;
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(),
}
// 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(""))
}
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)
})
}
// 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,
/// //~| 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
let letters = line[kind_start..].chars();
let kind = letters.skip_while(|c| c.is_whitespace())
.take_while(|c| !c.is_whitespace())
- .map(|c| c.to_lowercase())
+ .flat_map(|c| c.to_lowercase())
.collect::<String>();
let letters = line[kind_start..].chars();
let msg = letters.skip_while(|c| c.is_whitespace())
// 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;
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
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 => ()
}
}
- 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)) &&
!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
})
}
-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
}
// 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>) {
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,
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() {
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
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() {
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" => {
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");
};
// The value our Makefile configures valgrind to return on failure
- static 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);
}
fn check_correct_failure_status(proc_res: &ProcRes) {
// The value the rust runtime returns on failure
- static 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);
}
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;
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() }
};
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))
}
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,
};
}
"--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,
};
}
// 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,
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())),
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
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")
};
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));
};
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.");
}
}
.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
// 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"\\"))
);
}
}
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,
"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");
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,
};
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");
}
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.");
}
.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");
}
// 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);
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 \
dump_output(config, test_executable, &out, &err);
return ProcRes {
- status: status,
+ status: Status::Normal(status),
stdout: out,
stderr: err,
cmdline: format!("{:?}", cmd)
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);
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) => {
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
}
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, &[])
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,
make_run_args(config, props, testfile),
env,
&config.run_lib_path,
- Some(aux_dir.as_str().unwrap()),
+ Some(aux_dir.to_str().unwrap()),
None)
}
}
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);
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,
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(
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,
}
enum TargetLocation {
- ThisFile(Path),
- ThisDirectory(Path),
+ ThisFile(PathBuf),
+ ThisDirectory(PathBuf),
}
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 {
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 {
}
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
}
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());
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) {
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)
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,
}
}
&stderr_out);
ProcRes {
- status: process::ProcessExit::ExitStatus(exitcode),
+ status: Status::Parsed(exitcode),
stdout: stdout_out,
stderr: stderr_out,
cmdline: cmdline
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(),
// 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)
}
}
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());
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)
}
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)
}
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)
}
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()
}
// 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
-static OS_TABLE: &'static [(&'static str, &'static str)] = &[
+const OS_TABLE: &'static [(&'static str, &'static str)] = &[
("mingw32", "windows"),
("win32", "windows"),
("windows", "windows"),
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);
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.
### Array expressions
```antlr
-array_expr : '[' "mut" ? vec_elems? ']' ;
+array_expr : '[' "mut" ? array_elems? ']' ;
array_elems : [expr [',' expr]*] | [expr ',' ".." expr] ;
```
% 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).
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();
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();
}
```
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".
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() {
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();
}
```
numbers[0] is 2
```
-Each time, we can get a slithtly different output because the threads
-are not quaranteed to run in any set order. If you get the same order
-every time it is because each of these threads are very small and
-complete too fast for their indeterminate behavior to surface.
+Each time, we can get a slightly different output because the threads are not
+guaranteed to run in any set order. If you get the same order every time it is
+because each of these threads are very small and complete too fast for their
+indeterminate behavior to surface.
The important part here is that the Rust compiler was able to use ownership to
give us assurance _at compile time_ that we weren't doing something incorrect
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();
}
```
##### 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
* `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.
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.
* `staged_api` - Allows usage of stability markers and `#![staged_api]` in a crate
+* `static_assert` - The `#[static_assert]` functionality is experimental and
+ unstable. The attribute can be attached to a `static` of
+ type `bool` and the compiler will error if the `bool` is
+ `false` at compile time. This version of this functionality
+ is unintuitive and suboptimal.
+
* `start` - Allows use of the `#[start]` attribute, which changes the entry point
into a Rust program. This capabiilty, especially the signature for the
annotated function, is subject to change.
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
### Array expressions
```{.ebnf .gram}
-array_expr : '[' "mut" ? vec_elems? ']' ;
+array_expr : '[' "mut" ? array_elems? ']' ;
array_elems : [expr [',' expr]*] | [expr ';' expr] ;
```
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:
```
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(());
}
```
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));
}
```
* [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)
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:
## 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");
```
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;
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:
`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.
% 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:
```
/// ```
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.
+
tell `random()` what to generate. In a similar fashion, both of these work:
```{rust,ignore}
-let input_num = "5".parse::<u32>(); // input_num: Option<u32>
-let input_num: Result<u32, _> = "5".parse(); // input_num: Result<u32, <u32 as FromStr>::Err>
+let input_num_option = "5".parse::<u32>().ok(); // input_num: Option<u32>
+let input_num_result: Result<u32, _> = "5".parse(); // input_num: Result<u32, <u32 as FromStr>::Err>
```
-Here we're converting the `Result` returned by `parse` to an `Option` by using
+Above, we're converting the `Result` returned by `parse` to an `Option` by using
the `ok` method as well. Anyway, with us now converting our input to a number,
our code looks like this:
```bash
$ cargo build
Compiling guessing_game v0.0.1 (file:///home/you/projects/guessing_game)
-src/main.rs:22:15: 22:24 error: mismatched types: expected `u32` but found `core::option::Option<u32>` (expected u32 but found enum core::option::Option)
-src/main.rs:22 match cmp(input_num, secret_number) {
+src/main.rs:21:15: 21:24 error: mismatched types: expected `u32`, found `core::result::Result<u32, core::num::ParseIntError>` (expected u32, found enum `core::result::Result`) [E0308]
+src/main.rs:21 match cmp(input_num, secret_number) {
^~~~~~~~~
error: aborting due to previous error
```
-Oh yeah! Our `input_num` has the type `Option<u32>`, rather than `u32`. We
-need to unwrap the Option. If you remember from before, `match` is a great way
+Oh yeah! Our `input_num` has the type `Result<u32, <some error>>`, rather than `u32`. We
+need to unwrap the Result. If you remember from before, `match` is a great way
to do that. Try this code:
```{rust,no_run}
let input_num: Result<u32, _> = input.parse();
let num = match input_num {
- Ok(num) => num,
+ Ok(n) => n,
Err(_) => {
println!("Please input a number!");
return;
}
```
-We use a `match` to either give us the `u32` inside of the `Option`, or else
+We use a `match` to either give us the `u32` inside of the `Result`, or else
print an error message and return. Let's give this a shot:
```bash
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
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);
+```
```ignore
#![crate_type="dylib"]
-#![feature(plugin_registrar)]
+#![feature(plugin_registrar, rustc_private)]
extern crate syntax;
extern crate rustc;
}
};
- 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");
}
}
- MacEager::expr(cx.expr_usize(sp, total))
+ MacEager::expr(cx.expr_u32(sp, total))
}
#[plugin_registrar]
### 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.
one_hundred: 100,
});
- let y = box foo(x);
+ let y: Box<BigStruct> = box foo(x);
}
```
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!"
+```
import subprocess
import re
import os
-from licenseck import *
+from licenseck import check_license
import snapshot
err = 0
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):
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
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',
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")
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)
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)
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
fn bsearch_range_table(c: char, r: &'static [(char,char)]) -> bool {
use core::cmp::Ordering::{Equal, Less, Greater};
use core::slice::SliceExt;
- r.binary_search(|&(lo,hi)| {
+ r.binary_search_by(|&(lo,hi)| {
if lo <= c && c <= hi { Equal }
else if hi < c { Less }
else { Greater }
- }).found().is_some()
+ }).is_ok()
}\n
""")
pub_string = ""
if is_pub:
pub_string = "pub "
- f.write(" %sstatic %s: %s = &[\n" % (pub_string, name, t_type))
+ f.write(" %sconst %s: %s = &[\n" % (pub_string, name, t_type))
data = ""
first = True
for dat in t_data:
def emit_regex_module(f, cats, w_data):
f.write("pub mod regex {\n")
regex_class = "&'static [(char, char)]"
- class_table = "&'static [(&'static str, &'static %s)]" % regex_class
+ class_table = "&'static [(&'static str, %s)]" % regex_class
emit_table(f, "UNICODE_CLASSES", cats, class_table,
- pfun=lambda x: "(\"%s\",&super::%s::%s_table)" % (x[0], x[1], x[0]))
+ pfun=lambda x: "(\"%s\",super::%s::%s_table)" % (x[0], x[1], x[0]))
- f.write(" pub static PERLD: &'static %s = &super::general_category::Nd_table;\n\n"
+ f.write(" pub const PERLD: %s = super::general_category::Nd_table;\n\n"
% regex_class)
- f.write(" pub static PERLS: &'static %s = &super::property::White_Space_table;\n\n"
+ f.write(" pub const PERLS: %s = super::property::White_Space_table;\n\n"
% regex_class)
emit_table(f, "PERLW", w_data, regex_class)
use core::slice::SliceExt;
use core::option::Option;
use core::option::Option::{Some, None};
- use core::slice;
+ use core::result::Result::{Ok, Err};
pub fn to_lower(c: char) -> char {
match bsearch_case_table(c, LuLl_table) {
}
fn bsearch_case_table(c: char, table: &'static [(char, char)]) -> Option<usize> {
- match table.binary_search(|&(key, _)| {
+ match table.binary_search_by(|&(key, _)| {
if c == key { Equal }
else if key < c { Less }
else { Greater }
}) {
- slice::BinarySearchResult::Found(i) => Some(i),
- slice::BinarySearchResult::NotFound(_) => None,
+ Ok(i) => Some(i),
+ Err(_) => None,
}
}
def emit_grapheme_module(f, grapheme_table, grapheme_cats):
f.write("""pub mod grapheme {
- use core::kinds::Copy;
use core::slice::SliceExt;
pub use self::GraphemeCat::*;
- use core::slice;
+ use core::result::Result::{Ok, Err};
#[allow(non_camel_case_types)]
#[derive(Clone, Copy)]
fn bsearch_range_value_table(c: char, r: &'static [(char, char, GraphemeCat)]) -> GraphemeCat {
use core::cmp::Ordering::{Equal, Less, Greater};
- match r.binary_search(|&(lo, hi, _)| {
+ match r.binary_search_by(|&(lo, hi, _)| {
if lo <= c && c <= hi { Equal }
else if hi < c { Less }
else { Greater }
}) {
- slice::BinarySearchResult::Found(idx) => {
+ Ok(idx) => {
let (_, _, cat) = r[idx];
cat
}
- slice::BinarySearchResult::NotFound(_) => GC_Any
+ Err(_) => GC_Any
}
}
f.write(" use core::option::Option;\n")
f.write(" use core::option::Option::{Some, None};\n")
f.write(" use core::slice::SliceExt;\n")
- f.write(" use core::slice;\n")
+ f.write(" use core::result::Result::{Ok, Err};\n")
f.write("""
fn bsearch_range_value_table(c: char, is_cjk: bool, r: &'static [(char, char, u8, u8)]) -> u8 {
use core::cmp::Ordering::{Equal, Less, Greater};
- match r.binary_search(|&(lo, hi, _, _)| {
+ match r.binary_search_by(|&(lo, hi, _, _)| {
if lo <= c && c <= hi { Equal }
else if hi < c { Less }
else { Greater }
}) {
- slice::BinarySearchResult::Found(idx) => {
+ Ok(idx) => {
let (_, _, r_ncjk, r_cjk) = r[idx];
if is_cjk { r_cjk } else { r_ncjk }
}
- slice::BinarySearchResult::NotFound(_) => 1
+ Err(_) => 1
}
}
""")
fn bsearch_range_value_table(c: char, r: &'static [(char, char, u8)]) -> u8 {
use core::cmp::Ordering::{Equal, Less, Greater};
use core::slice::SliceExt;
- use core::slice;
- match r.binary_search(|&(lo, hi, _)| {
+ use core::result::Result::{Ok, Err};
+ match r.binary_search_by(|&(lo, hi, _)| {
if lo <= c && c <= hi { Equal }
else if hi < c { Less }
else { Greater }
}) {
- slice::BinarySearchResult::Found(idx) => {
+ Ok(idx) => {
let (_, _, result) = r[idx];
result
}
- slice::BinarySearchResult::NotFound(_) => 0
+ Err(_) => 0
}
}\n
""")
unicode_version = re.search(pattern, readme.read()).groups()
rf.write("""
/// The version of [Unicode](http://www.unicode.org/)
-/// that the `UnicodeChar` and `UnicodeStrPrelude` traits are based on.
+/// that the unicode parts of `CharExt` and `UnicodeStrPrelude` traits are based on.
pub const UNICODE_VERSION: (u64, u64, u64) = (%s, %s, %s);
""" % unicode_version)
(canon_decomp, compat_decomp, gencats, combines,
%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
{
$$ = 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
;
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); }
}
| 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
;
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
-Subproject commit b001609960ca33047e5cbc5a231c1e24b6041d4b
+Subproject commit e24a1a025a1f214e40eedafe3b9c7b1d69937922
//! }
//! ```
+use boxed::Box;
+
use core::prelude::*;
use core::atomic;
pub fn new(data: T) -> Arc<T> {
// Start the weak pointer count as 1 which is the weak pointer that's
// held by all the strong pointers (kinda), see std/rc.rs for more info
- let x = box ArcInner {
+ let x: Box<_> = box ArcInner {
strong: atomic::AtomicUsize::new(1),
weak: atomic::AtomicUsize::new(1),
data: data,
//! }
//! ```
//!
-//! 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")]
/// let x = Box::new(5);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
+ #[inline(always)]
pub fn new(x: T) -> Box<T> {
box x
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> Default for Box<[T]> {
#[stable(feature = "rust1", since = "1.0.0")]
- fn default() -> Box<[T]> { box [] }
+ fn default() -> Box<[T]> { Box::<[T; 0]>::new([]) }
}
#[stable(feature = "rust1", since = "1.0.0")]
#[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;
extern crate test;
use self::test::Bencher;
use core::ptr::PtrExt;
+ use boxed::Box;
use heap;
#[test]
#[bench]
fn alloc_owned_small(b: &mut Bencher) {
b.iter(|| {
- box 10
+ let _: Box<_> = box 10;
})
}
}
//! 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)]
// Primitive types using the heaps above
+// Need to conditionally define the mod from `boxed.rs` to avoid
+// duplicating the lang-items when building in test cfg; but also need
+// to allow code to have `use boxed::HEAP;`
+// and `use boxed::Box;` declarations.
#[cfg(not(test))]
pub mod boxed;
#[cfg(test)]
+mod boxed { pub use std::boxed::{Box, HEAP}; }
+#[cfg(test)]
mod boxed_test;
pub mod arc;
pub mod rc;
#[cfg(test)]
mod tests {
use super::{Rc, Weak, weak_count, strong_count};
+ use std::boxed::Box;
use std::cell::RefCell;
use std::option::Option;
use std::option::Option::{Some, None};
#[test]
fn test_destructor() {
- let x = Rc::new(box 5);
+ let x: Rc<Box<_>> = Rc::new(box 5);
assert_eq!(**x, 5);
}
//! 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]
}
#[test]
-#[should_fail]
+#[should_panic]
fn test_arena_destructors_fail() {
let arena = Arena::new();
// Put some stuff in the arena.
#[bench]
pub fn bench_copy_nonarena(b: &mut Bencher) {
b.iter(|| {
- box Point {
+ let _: Box<_> = box Point {
x: 1,
y: 2,
z: 3,
- }
+ };
})
}
#[bench]
pub fn bench_noncopy_nonarena(b: &mut Bencher) {
b.iter(|| {
- box Noncopy {
+ let _: Box<_> = box Noncopy {
string: "hello world".to_string(),
array: vec!( 1, 2, 3, 4, 5 ),
- }
+ };
})
}
#[test]
fn test_push_unique() {
- let mut heap = BinaryHeap::from_vec(vec![box 2, box 4, box 9]);
+ let mut heap = BinaryHeap::<Box<_>>::from_vec(vec![box 2, box 4, box 9]);
assert_eq!(heap.len(), 3);
assert!(*heap.peek().unwrap() == box 9);
heap.push(box 11);
// 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)))
}
}
//
// Note that we can technically avoid this branch with the expression
// `(nbits + u32::BITS - 1) / 32::BITS`, but if nbits is almost usize::MAX this will overflow.
- if bits % u32::BITS == 0 {
- bits / u32::BITS
+ if bits % u32::BITS as usize == 0 {
+ bits / u32::BITS as usize
} else {
- bits / u32::BITS + 1
+ bits / u32::BITS as usize + 1
}
}
/// 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 - bits % u32::BITS) % u32::BITS
+ !0 >> (u32::BITS as usize - bits % u32::BITS as usize) % u32::BITS as usize
}
impl BitVec {
/// An operation might screw up the unused bits in the last block of the
/// `BitVec`. As per (3), it's assumed to be all 0s. This method fixes it up.
fn fix_last_block(&mut self) {
- let extra_bits = self.len() % u32::BITS;
+ let extra_bits = self.len() % u32::BITS as usize;
if extra_bits > 0 {
let mask = (1 << extra_bits) - 1;
let storage_len = self.storage.len();
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();
/// false, false, true, false]));
/// ```
pub fn from_bytes(bytes: &[u8]) -> BitVec {
- let len = bytes.len().checked_mul(u8::BITS).expect("capacity overflow");
+ let len = bytes.len().checked_mul(u8::BITS as usize).expect("capacity overflow");
let mut bit_vec = BitVec::with_capacity(len);
let complete_words = bytes.len() / 4;
let extra_bytes = bytes.len() % 4;
}
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);
}
if i >= self.nbits {
return None;
}
- let w = i / u32::BITS;
- let b = i % u32::BITS;
+ let w = i / u32::BITS as usize;
+ let b = i % u32::BITS as usize;
self.storage.get(w).map(|&block|
(block & (1 << b)) != 0
)
reason = "panic semantics are likely to change in the future")]
pub fn set(&mut self, i: usize, x: bool) {
assert!(i < self.nbits);
- let w = i / u32::BITS;
- let b = i % u32::BITS;
+ let w = i / u32::BITS as usize;
+ let b = i % u32::BITS as usize;
let flag = 1 << b;
let val = if x { self.storage[w] | flag }
else { self.storage[w] & !flag };
/// ```
#[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();
}
/// 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))
}
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn capacity(&self) -> usize {
- self.storage.capacity().checked_mul(u32::BITS).unwrap_or(usize::MAX)
+ self.storage.capacity().checked_mul(u32::BITS as usize).unwrap_or(usize::MAX)
}
/// Grows the `BitVec` in-place, adding `n` copies of `value` to the `BitVec`.
let full_value = if value { !0 } else { 0 };
// Correct the old tail word, setting or clearing formerly unused bits
- let old_last_word = blocks_for_bits(self.nbits) - 1;
- if self.nbits % u32::BITS > 0 {
+ let num_cur_blocks = blocks_for_bits(self.nbits);
+ if self.nbits % u32::BITS as usize > 0 {
let mask = mask_for_bits(self.nbits);
if value {
- self.storage[old_last_word] |= !mask;
+ self.storage[num_cur_blocks - 1] |= !mask;
} else {
// Extra bits are already zero by invariant.
}
// Fill in words after the old tail word
let stop_idx = cmp::min(self.storage.len(), new_nblocks);
- for idx in old_last_word + 1..stop_idx {
+ for idx in num_cur_blocks..stop_idx {
self.storage[idx] = full_value;
}
// (3)
self.set(i, false);
self.nbits = i;
- if self.nbits % u32::BITS == 0 {
+ if self.nbits % u32::BITS as usize == 0 {
// (2)
self.storage.pop();
}
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn push(&mut self, elem: bool) {
- if self.nbits % u32::BITS == 0 {
+ if self.nbits % u32::BITS as usize == 0 {
self.storage.push(0);
}
let insert_pos = self.nbits;
#[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; }
}
}
// Truncate
let trunc_len = cmp::max(old_len - n, 1);
bit_vec.storage.truncate(trunc_len);
- bit_vec.nbits = trunc_len * u32::BITS;
+ bit_vec.nbits = trunc_len * u32::BITS as usize;
}
/// Iterator over each u32 stored in the `BitSet`.
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn len(&self) -> usize {
- self.bit_vec.blocks().fold(0, |acc, n| acc + n.count_ones())
+ self.bit_vec.blocks().fold(0, |acc, n| acc + n.count_ones() as usize)
}
/// Returns whether there are no bits set in this set
fn next(&mut self) -> Option<usize> {
while self.next_idx < self.set.bit_vec.len() ||
self.next_idx < self.other.bit_vec.len() {
- let bit_idx = self.next_idx % u32::BITS;
+ let bit_idx = self.next_idx % u32::BITS as usize;
if bit_idx == 0 {
let s_bit_vec = &self.set.bit_vec;
let o_bit_vec = &self.other.bit_vec;
// Merging the two words is a bit of an awkward dance since
// one BitVec might be longer than the other
- let word_idx = self.next_idx / u32::BITS;
+ let word_idx = self.next_idx / u32::BITS as usize;
let w1 = if word_idx < s_bit_vec.storage.len() {
s_bit_vec.storage[word_idx]
} else { 0 };
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)
}
#[test]
fn test_bit_vec_push_pop() {
- let mut s = BitVec::from_elem(5 * u32::BITS - 2, false);
- assert_eq!(s.len(), 5 * u32::BITS - 2);
- assert_eq!(s[5 * u32::BITS - 3], false);
+ let mut s = BitVec::from_elem(5 * u32::BITS as usize - 2, false);
+ assert_eq!(s.len(), 5 * u32::BITS as usize - 2);
+ assert_eq!(s[5 * u32::BITS as usize - 3], false);
s.push(true);
s.push(true);
- assert_eq!(s[5 * u32::BITS - 2], true);
- assert_eq!(s[5 * u32::BITS - 1], true);
+ assert_eq!(s[5 * u32::BITS as usize - 2], true);
+ assert_eq!(s[5 * u32::BITS as usize - 1], true);
// Here the internal vector will need to be extended
s.push(false);
- assert_eq!(s[5 * u32::BITS], false);
+ assert_eq!(s[5 * u32::BITS as usize], false);
s.push(false);
- assert_eq!(s[5 * u32::BITS + 1], false);
- assert_eq!(s.len(), 5 * u32::BITS + 2);
+ assert_eq!(s[5 * u32::BITS as usize + 1], false);
+ assert_eq!(s.len(), 5 * u32::BITS as usize + 2);
// Pop it all off
assert_eq!(s.pop(), Some(false));
assert_eq!(s.pop(), Some(false));
assert_eq!(s.pop(), Some(true));
assert_eq!(s.pop(), Some(true));
- assert_eq!(s.len(), 5 * u32::BITS - 2);
+ assert_eq!(s.len(), 5 * u32::BITS as usize - 2);
}
#[test]
fn test_bit_vec_truncate() {
- let mut s = BitVec::from_elem(5 * u32::BITS, true);
+ let mut s = BitVec::from_elem(5 * u32::BITS as usize, true);
- assert_eq!(s, BitVec::from_elem(5 * u32::BITS, true));
- assert_eq!(s.len(), 5 * u32::BITS);
- s.truncate(4 * u32::BITS);
- assert_eq!(s, BitVec::from_elem(4 * u32::BITS, true));
- assert_eq!(s.len(), 4 * u32::BITS);
+ assert_eq!(s, BitVec::from_elem(5 * u32::BITS as usize, true));
+ assert_eq!(s.len(), 5 * u32::BITS as usize);
+ s.truncate(4 * u32::BITS as usize);
+ assert_eq!(s, BitVec::from_elem(4 * u32::BITS as usize, true));
+ assert_eq!(s.len(), 4 * u32::BITS as usize);
// Truncating to a size > s.len() should be a noop
- s.truncate(5 * u32::BITS);
- assert_eq!(s, BitVec::from_elem(4 * u32::BITS, true));
- assert_eq!(s.len(), 4 * u32::BITS);
- s.truncate(3 * u32::BITS - 10);
- assert_eq!(s, BitVec::from_elem(3 * u32::BITS - 10, true));
- assert_eq!(s.len(), 3 * u32::BITS - 10);
+ s.truncate(5 * u32::BITS as usize);
+ assert_eq!(s, BitVec::from_elem(4 * u32::BITS as usize, true));
+ assert_eq!(s.len(), 4 * u32::BITS as usize);
+ s.truncate(3 * u32::BITS as usize - 10);
+ assert_eq!(s, BitVec::from_elem(3 * u32::BITS as usize - 10, true));
+ assert_eq!(s.len(), 3 * u32::BITS as usize - 10);
s.truncate(0);
assert_eq!(s, BitVec::from_elem(0, true));
assert_eq!(s.len(), 0);
#[test]
fn test_bit_vec_reserve() {
- let mut s = BitVec::from_elem(5 * u32::BITS, true);
+ let mut s = BitVec::from_elem(5 * u32::BITS as usize, true);
// Check capacity
- assert!(s.capacity() >= 5 * u32::BITS);
- s.reserve(2 * u32::BITS);
- assert!(s.capacity() >= 7 * u32::BITS);
- s.reserve(7 * u32::BITS);
- assert!(s.capacity() >= 12 * u32::BITS);
- s.reserve_exact(7 * u32::BITS);
- assert!(s.capacity() >= 12 * u32::BITS);
- s.reserve(7 * u32::BITS + 1);
- assert!(s.capacity() >= 12 * u32::BITS + 1);
+ assert!(s.capacity() >= 5 * u32::BITS as usize);
+ s.reserve(2 * u32::BITS as usize);
+ assert!(s.capacity() >= 7 * u32::BITS as usize);
+ s.reserve(7 * u32::BITS as usize);
+ assert!(s.capacity() >= 12 * u32::BITS as usize);
+ s.reserve_exact(7 * u32::BITS as usize);
+ assert!(s.capacity() >= 12 * u32::BITS as usize);
+ s.reserve(7 * u32::BITS as usize + 1);
+ assert!(s.capacity() >= 12 * u32::BITS as usize + 1);
// Check that length hasn't changed
- assert_eq!(s.len(), 5 * u32::BITS);
+ assert_eq!(s.len(), 5 * u32::BITS as usize);
s.push(true);
s.push(false);
s.push(true);
- assert_eq!(s[5 * u32::BITS - 1], true);
- assert_eq!(s[5 * u32::BITS - 0], true);
- assert_eq!(s[5 * u32::BITS + 1], false);
- assert_eq!(s[5 * u32::BITS + 2], true);
+ assert_eq!(s[5 * u32::BITS as usize - 1], true);
+ assert_eq!(s[5 * u32::BITS as usize - 0], true);
+ assert_eq!(s[5 * u32::BITS as usize + 1], false);
+ assert_eq!(s[5 * u32::BITS as usize + 2], true);
}
#[test]
use super::BitVec;
- static BENCH_BITS : usize = 1 << 14;
+ const BENCH_BITS : usize = 1 << 14;
fn rng() -> rand::IsaacRng {
let seed: &[_] = &[1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
let mut bit_vec = 0 as usize;
b.iter(|| {
for _ in 0..100 {
- bit_vec |= 1 << ((r.next_u32() as usize) % u32::BITS);
+ bit_vec |= 1 << ((r.next_u32() as usize) % u32::BITS as usize);
}
black_box(&bit_vec);
});
#[bench]
fn bench_bit_set_small(b: &mut Bencher) {
let mut r = rng();
- let mut bit_vec = BitVec::from_elem(u32::BITS, false);
+ let mut bit_vec = BitVec::from_elem(u32::BITS as usize, false);
b.iter(|| {
for _ in 0..100 {
- bit_vec.set((r.next_u32() as usize) % u32::BITS, true);
+ bit_vec.set((r.next_u32() as usize) % u32::BITS as usize, true);
}
black_box(&bit_vec);
});
#[bench]
fn bench_bit_vec_small_iter(b: &mut Bencher) {
- let bit_vec = BitVec::from_elem(u32::BITS, false);
+ let bit_vec = BitVec::from_elem(u32::BITS as usize, false);
b.iter(|| {
let mut sum = 0;
for _ in 0..10 {
use super::{BitVec, BitSet};
- static BENCH_BITS : usize = 1 << 14;
+ const BENCH_BITS : usize = 1 << 14;
fn rng() -> rand::IsaacRng {
let seed: &[_] = &[1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
let mut bit_vec = BitSet::new();
b.iter(|| {
for _ in 0..100 {
- bit_vec.insert((r.next_u32() as usize) % u32::BITS);
+ bit_vec.insert((r.next_u32() as usize) % u32::BITS as usize);
}
black_box(&bit_vec);
});
use core::hash::{Hash, Hasher};
use core::iter::{Map, FromIterator, IntoIterator};
use core::ops::{Index, IndexMut};
-use core::{iter, fmt, mem};
+use core::{iter, fmt, mem, usize};
use Bound::{self, Included, Excluded, Unbounded};
use borrow::Borrow;
$Range {
inner: AbsIter {
traversals: traversals,
- size: 0, // unused
+ size: usize::MAX, // unused
}
}
}
ptr::copy(
self.edges_mut().as_mut_ptr().offset(index as isize),
self.edges().as_ptr().offset(index as isize + 1),
- self.len() - index + 1
+ // index can be == len+1, so do the +1 first to avoid underflow.
+ (self.len() + 1) - index
);
edge
fn bit<E:CLike>(e: &E) -> usize {
use core::usize;
let value = e.to_usize();
- assert!(value < usize::BITS,
+ assert!(value < usize::BITS as usize,
"EnumSet only supports up to {} variants.", usize::BITS - 1);
1 << value
}
#[unstable(feature = "collections",
reason = "matches collection reform specification, waiting for dust to settle")]
pub fn len(&self) -> usize {
- self.bits.count_ones()
+ self.bits.count_ones() as usize
}
/// Returns true if the `EnumSet` is empty.
}
fn size_hint(&self) -> (usize, Option<usize>) {
- let exact = self.bits.count_ones();
+ let exact = self.bits.count_ones() as usize;
(exact, Some(exact))
}
}
}
#[test]
- #[should_fail]
+ #[should_panic]
fn test_overflow() {
#[allow(dead_code)]
#[derive(Copy)]
//! // 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)
//! }
//! }
//!
//! 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\"");
//! ```
//! * `o` - precedes the argument with a "0o"
//! * '0' - This is used to indicate for integer formats that the padding should
//! both be done with a `0` character as well as be sign-aware. A format
-//! like `{:08d}` would yield `00000001` for the integer `1`, while the
+//! like `{:08}` would yield `00000001` for the integer `1`, while the
//! same format would yield `-0000001` for the integer `-1`. Notice that
//! the negative version has one fewer zero than the positive version.
//!
//!
//! 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]
#[test]
fn test_basic() {
- let mut m = LinkedList::new();
+ let mut m = LinkedList::<Box<_>>::new();
assert_eq!(m.pop_front(), None);
assert_eq!(m.pop_back(), None);
assert_eq!(m.pop_front(), None);
use core::marker::Sized;
use core::mem::size_of;
use core::mem;
+use core::num::wrapping::WrappingOps;
use core::ops::FnMut;
use core::option::Option::{self, Some, None};
use core::ptr::PtrExt;
impl Iterator for ElementSwaps {
type Item = (usize, usize);
- #[inline]
+ // #[inline]
fn next(&mut self) -> Option<(usize, usize)> {
+ fn new_pos_wrapping(i: usize, s: Direction) -> usize {
+ i.wrapping_add(match s { Pos => 1, Neg => -1 })
+ }
+
fn new_pos(i: usize, s: Direction) -> usize {
- i + match s { Pos => 1, Neg => -1 }
+ match s { Pos => i + 1, Neg => i - 1 }
}
// Find the index of the largest mobile element:
// swap should be with a smaller `size` element.
let max = self.sdir.iter().cloned().enumerate()
.filter(|&(i, sd)|
- new_pos(i, sd.dir) < self.sdir.len() &&
+ new_pos_wrapping(i, sd.dir) < self.sdir.len() &&
self.sdir[new_pos(i, sd.dir)].size < sd.size)
.max_by(|&(_, sd)| sd.size);
match max {
fn merge_sort<T, F>(v: &mut [T], mut compare: F) where F: FnMut(&T, &T) -> Ordering {
// warning: this wildly uses unsafe.
- static BASE_INSERTION: usize = 32;
- static LARGE_INSERTION: usize = 16;
+ const BASE_INSERTION: usize = 32;
+ const LARGE_INSERTION: usize = 16;
// FIXME #12092: smaller insertion runs seems to make sorting
// vectors of large elements a little faster on some platforms,
#[cfg(test)]
mod tests {
+ use alloc::boxed::Box;
use core::cmp::Ordering::{Greater, Less, Equal};
use core::prelude::{Some, None, Clone};
use core::prelude::{Iterator, IteratorExt};
}
#[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();
}
#[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();
}
#[test]
- #[should_fail]
+ #[should_panic]
fn test_swap_remove_fail() {
let mut v = vec![1];
let _ = v.swap_remove(0);
#[test]
fn test_swap_remove_noncopyable() {
// Tests that we don't accidentally run destructors twice.
- let mut v = Vec::new();
+ let mut v: Vec<Box<_>> = Vec::new();
v.push(box 0u8);
v.push(box 0u8);
v.push(box 0u8);
#[test]
fn test_truncate() {
- let mut v = vec![box 6,box 5,box 4];
+ let mut v: Vec<Box<_>> = vec![box 6,box 5,box 4];
v.truncate(1);
let v = v;
assert_eq!(v.len(), 1);
#[test]
fn test_clear() {
- let mut v = vec![box 6,box 5,box 4];
+ let mut v: Vec<Box<_>> = vec![box 6,box 5,box 4];
v.clear();
assert_eq!(v.len(), 0);
// If the unsafe block didn't drop things properly, we blow up here.
#[test]
fn test_dedup_unique() {
- let mut v0 = vec![box 1, box 1, box 2, box 3];
+ let mut v0: Vec<Box<_>> = vec![box 1, box 1, box 2, box 3];
v0.dedup();
- let mut v1 = vec![box 1, box 2, box 2, box 3];
+ let mut v1: Vec<Box<_>> = vec![box 1, box 2, box 2, box 3];
v1.dedup();
- let mut v2 = vec![box 1, box 2, box 3, box 3];
+ let mut v2: Vec<Box<_>> = vec![box 1, box 2, box 3, box 3];
v2.dedup();
/*
* If the boxed pointers were leaked or otherwise misused, valgrind
#[test]
fn test_dedup_shared() {
- let mut v0 = vec![box 1, box 1, box 2, box 3];
+ let mut v0: Vec<Box<_>> = vec![box 1, box 1, box 2, box 3];
v0.dedup();
- let mut v1 = vec![box 1, box 2, box 2, box 3];
+ let mut v1: Vec<Box<_>> = vec![box 1, box 2, box 2, box 3];
v1.dedup();
- let mut v2 = vec![box 1, box 2, box 3, box 3];
+ let mut v2: Vec<Box<_>> = vec![box 1, box 2, box 3, box 3];
v2.dedup();
/*
* If the pointers were leaked or otherwise misused, valgrind and/or
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]);
}
#[test]
- #[should_fail]
+ #[should_panic]
fn test_insert_oob() {
let mut a = vec![1, 2, 3];
a.insert(4, 5);
}
#[test]
- #[should_fail]
+ #[should_panic]
fn test_remove_fail() {
let mut a = vec![1];
let _ = a.remove(0);
}
#[test]
- #[should_fail]
+ #[should_panic]
fn test_permute_fail() {
- let v = [(box 0, Rc::new(0)), (box 0, Rc::new(0)),
- (box 0, Rc::new(0)), (box 0, Rc::new(0))];
+ let v: [(Box<_>, Rc<_>); 4] =
+ [(box 0, Rc::new(0)), (box 0, Rc::new(0)),
+ (box 0, Rc::new(0)), (box 0, Rc::new(0))];
let mut i = 0;
for _ in v.permutations() {
if i == 2 {
}
#[test]
- #[should_fail]
+ #[should_panic]
fn test_windowsator_0() {
let v = &[1,2,3,4];
let _it = v.windows(0);
}
#[test]
- #[should_fail]
+ #[should_panic]
fn test_chunksator_0() {
let v = &[1,2,3,4];
let _it = v.chunks(0);
#[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);
}
#[test]
- #[should_fail]
+ #[should_panic]
fn test_overflow_does_not_cause_segfault() {
let mut v = vec![];
v.reserve_exact(-1);
}
#[test]
- #[should_fail]
+ #[should_panic]
fn test_overflow_does_not_cause_segfault_managed() {
let mut v = vec![Rc::new(1)];
v.reserve_exact(-1);
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);
#[test]
fn test_to_vec() {
- let xs = box [1, 2, 3];
+ let xs: Box<_> = box [1, 2, 3];
let ys = xs.to_vec();
assert_eq!(ys, [1, 2, 3]);
}
//
// 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
//!
//! let s = "Hello, world.";
//! ```
//!
-//! This `&str` is a `&'static str`, which is the type of string literals. They're `'static`
-//! because literals are available for the entire lifetime of the program.
+//! This `&str` is a `&'static str`, which is the type of string literals.
+//! They're `'static` because literals are available for the entire lifetime of
+//! the program.
//!
//! You can get a non-`'static` `&str` by taking a slice of a `String`:
//!
//!
//! # Representation
//!
-//! Rust's string type, `str`, is a sequence of Unicode scalar values encoded as a stream of UTF-8
-//! bytes. All [strings](../../reference.html#literals) are guaranteed to be validly encoded UTF-8
-//! sequences. Additionally, strings are not null-terminated and can thus contain null bytes.
+//! Rust's string type, `str`, is a sequence of Unicode scalar values encoded as
+//! a stream of UTF-8 bytes. All [strings](../../reference.html#literals) are
+//! guaranteed to be validly encoded UTF-8 sequences. Additionally, strings are
+//! not null-terminated and can thus contain null bytes.
//!
-//! The actual representation of `str`s have direct mappings to slices: `&str` is the same as
-//! `&[u8]`.
+//! The actual representation of `str`s have direct mappings to slices: `&str`
+//! is the same as `&[u8]`.
#![doc(primitive = "str")]
#![stable(feature = "rust1", since = "1.0.0")]
use self::RecompositionState::*;
use self::DecompositionType::*;
-use core::char::CharExt;
use core::clone::Clone;
use core::iter::AdditiveIterator;
-use core::iter::{Iterator, IteratorExt};
+use core::iter::{Iterator, IteratorExt, Extend};
use core::ops::Index;
use core::ops::RangeFull;
use core::option::Option::{self, Some, None};
use core::result::Result;
use core::slice::AsSlice;
use core::str as core_str;
+use unicode::char::CharExt;
use unicode::str::{UnicodeStr, Utf16Encoder};
use vec_deque::VecDeque;
// 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")]
/// ```
#[unstable(feature = "collections")]
#[deprecated(since = "1.0.0", reason = "use `split()` with a `&str`")]
+ #[allow(deprecated) /* for SplitStr */]
fn split_str<'a, P: Pattern<'a>>(&'a self, pat: P) -> SplitStr<'a, P> {
core_str::StrExt::split_str(&self[..], pat)
}
/// Returns a slice of the string from the character range [`begin`..`end`).
///
- /// That is, start at the `begin`-th code point of the string and continue to the `end`-th code
- /// point. This does not detect or handle edge cases such as leaving a combining character as
- /// the first code point of the string.
+ /// That is, start at the `begin`-th code point of the string and continue
+ /// to the `end`-th code point. This does not detect or handle edge cases
+ /// such as leaving a combining character as the first code point of the
+ /// string.
///
- /// Due to the design of UTF-8, this operation is `O(end)`. See `slice`, `slice_to` and
- /// `slice_from` for `O(1)` variants that use byte indices rather than code point indices.
+ /// Due to the design of UTF-8, this operation is `O(end)`. See `slice`,
+ /// `slice_to` and `slice_from` for `O(1)` variants that use byte indices
+ /// rather than code point indices.
///
/// # Panics
///
- /// Panics if `begin` > `end` or the either `begin` or `end` are beyond the last character of
- /// the string.
+ /// Panics if `begin` > `end` or the either `begin` or `end` are beyond the
+ /// last character of the string.
///
/// # Examples
///
///
/// # Unsafety
///
- /// Caller must check both UTF-8 character boundaries and the boundaries of the entire slice as
- /// well.
+ /// Caller must check both UTF-8 character boundaries and the boundaries of
+ /// the entire slice as well.
///
/// # Examples
///
///
/// 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;
fn trim_right(&self) -> &str {
UnicodeStr::trim_right(&self[..])
}
+
+ /// Returns the lowercase equivalent of this string.
+ ///
+ /// # Examples
+ ///
+ /// let s = "HELLO";
+ /// assert_eq!(s.to_lowercase(), "hello");
+ #[unstable(feature = "collections")]
+ fn to_lowercase(&self) -> String {
+ let mut s = String::with_capacity(self.len());
+ s.extend(self[..].chars().flat_map(|c| c.to_lowercase()));
+ return s;
+ }
+
+ /// Returns the uppercase equivalent of this string.
+ ///
+ /// # Examples
+ ///
+ /// let s = "hello";
+ /// assert_eq!(s.to_uppercase(), "HELLO");
+ #[unstable(feature = "collections")]
+ fn to_uppercase(&self) -> String {
+ let mut s = String::with_capacity(self.len());
+ s.extend(self[..].chars().flat_map(|c| c.to_uppercase()));
+ return s;
+ }
}
#[stable(feature = "rust1", since = "1.0.0")]
}
#[test]
- #[should_fail]
+ #[should_panic]
fn test_slice_fail() {
"中华Việt Nam".slice(0, 2);
}
}
#[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.)
}
#[test]
- #[should_fail]
+ #[should_panic]
fn test_subslice_offset_2() {
let a = "alchemiter";
let b = "cruxtruder";
#[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() {
#[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() {
/// ```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> {
}
}
- static TAG_CONT_U8: u8 = 128u8;
- static REPLACEMENT: &'static [u8] = b"\xEF\xBF\xBD"; // U+FFFD in UTF-8
+ 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 {
unsafe { *xs.get_unchecked(i) }
}
})}
- 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;
}
}
}
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;
}
i += 1;
- if safe_get(v, i, total) & 192u8 != TAG_CONT_U8 {
+ if safe_get(v, i, total) & 192 != TAG_CONT_U8 {
error!();
continue;
}
/// ```
/// 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")]
/// 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")]
/// ```
/// 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")]
/// 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")]
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])];
}
#[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);
assert_eq!(s, "ไทย中华Vit Nam; foobar");
}
- #[test] #[should_fail]
+ #[test] #[should_panic]
fn remove_bad() {
"ศ".to_string().remove(1);
}
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() {
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");
#[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);
});
__impl_slice_eq1! { Vec<A>, Vec<B> }
__impl_slice_eq2! { Vec<A>, &'b [B] }
__impl_slice_eq2! { Vec<A>, &'b mut [B] }
-__impl_slice_eq2! { CowVec<'a, A>, &'b [B], Clone }
-__impl_slice_eq2! { CowVec<'a, A>, &'b mut [B], Clone }
-__impl_slice_eq2! { CowVec<'a, A>, Vec<B>, Clone }
+__impl_slice_eq2! { Cow<'a, [A]>, &'b [B], Clone }
+__impl_slice_eq2! { Cow<'a, [A]>, &'b mut [B], Clone }
+__impl_slice_eq2! { Cow<'a, [A]>, Vec<B>, Clone }
macro_rules! array_impls {
($($N: expr)+) => {
__impl_slice_eq2! { Vec<A>, [B; $N] }
__impl_slice_eq2! { Vec<A>, &'b [B; $N] }
// __impl_slice_eq2! { Vec<A>, &'b mut [B; $N] }
- // __impl_slice_eq2! { CowVec<'a, A>, [B; $N], Clone }
- // __impl_slice_eq2! { CowVec<'a, A>, &'b [B; $N], Clone }
- // __impl_slice_eq2! { CowVec<'a, A>, &'b mut [B; $N], Clone }
+ // __impl_slice_eq2! { Cow<'a, [A]>, [B; $N], Clone }
+ // __impl_slice_eq2! { Cow<'a, [A]>, &'b [B; $N], Clone }
+ // __impl_slice_eq2! { Cow<'a, [A]>, &'b mut [B; $N], Clone }
)+
}
}
#[test]
fn test_clone_from() {
let mut v = vec!();
- let three = vec!(box 1, box 2, box 3);
- let two = vec!(box 4, box 5);
+ let three: Vec<Box<_>> = vec!(box 1, box 2, box 3);
+ let two: Vec<Box<_>> = vec!(box 4, box 5);
// zero, long
v.clone_from(&three);
assert_eq!(v, three);
}
#[test]
- #[should_fail]
+ #[should_panic]
fn test_vec_truncate_fail() {
struct BadElem(i32);
impl Drop for BadElem {
}
#[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);
}
#[test]
- #[should_fail]
+ #[should_panic]
fn test_map_in_place_incompatible_types_fail() {
let v = vec![0, 1, 2];
v.map_in_place(|_| ());
use core::iter::{self, repeat, FromIterator, IntoIterator, RandomAccessIterator};
use core::mem;
use core::num::{Int, UnsignedInt};
+use core::num::wrapping::WrappingOps;
use core::ops::{Index, IndexMut};
use core::ptr::{self, Unique};
use core::raw::Slice as RawSlice;
#[unstable(feature = "collections")]
pub use VecDeque as RingBuf;
-static INITIAL_CAPACITY: usize = 7; // 2^3 - 1
-static MINIMUM_CAPACITY: usize = 1; // 2 - 1
+const INITIAL_CAPACITY: usize = 7; // 2^3 - 1
+const MINIMUM_CAPACITY: usize = 1; // 2 - 1
/// `VecDeque` is a growable ring buffer, which can be used as a
/// double-ended queue efficiently.
#[inline]
fn wrap_index(&self, idx: usize) -> usize { wrap_index(idx, self.cap) }
+ /// Returns the index in the underlying buffer for a given logical element
+ /// index + addend.
+ #[inline]
+ fn wrap_add(&self, idx: usize, addend: usize) -> usize {
+ wrap_index(idx.wrapping_add(addend), self.cap)
+ }
+
+ /// Returns the index in the underlying buffer for a given logical element
+ /// index - subtrahend.
+ #[inline]
+ fn wrap_sub(&self, idx: usize, subtrahend: usize) -> usize {
+ wrap_index(idx.wrapping_sub(subtrahend), self.cap)
+ }
+
/// Copies a contiguous block of memory len long from src to dst
#[inline]
unsafe fn copy(&self, dst: usize, src: usize, len: usize) {
#[stable(feature = "rust1", since = "1.0.0")]
pub fn get(&self, i: usize) -> Option<&T> {
if i < self.len() {
- let idx = self.wrap_index(self.tail + i);
+ let idx = self.wrap_add(self.tail, i);
unsafe { Some(&*self.ptr.offset(idx as isize)) }
} else {
None
#[stable(feature = "rust1", since = "1.0.0")]
pub fn get_mut(&mut self, i: usize) -> Option<&mut T> {
if i < self.len() {
- let idx = self.wrap_index(self.tail + i);
+ let idx = self.wrap_add(self.tail, i);
unsafe { Some(&mut *self.ptr.offset(idx as isize)) }
} else {
None
pub fn swap(&mut self, i: usize, j: usize) {
assert!(i < self.len());
assert!(j < self.len());
- let ri = self.wrap_index(self.tail + i);
- let rj = self.wrap_index(self.tail + j);
+ let ri = self.wrap_add(self.tail, i);
+ let rj = self.wrap_add(self.tail, j);
unsafe {
ptr::swap(self.ptr.offset(ri as isize), self.ptr.offset(rj as isize))
}
// [. . . o o o o o o o . . . . . . ]
// H T
// [o o . o o o o o ]
- let len = self.wrap_index(self.head - target_cap);
+ let len = self.wrap_sub(self.head, target_cap);
unsafe {
self.copy_nonoverlapping(0, target_cap, len);
}
// [o o o o o . . . . . . . . . o o ]
// H T
// [o o o o o . o o ]
- debug_assert!(self.wrap_index(self.head - 1) < target_cap);
+ debug_assert!(self.wrap_sub(self.head, 1) < target_cap);
let len = self.cap - self.tail;
let new_tail = target_cap - len;
unsafe {
None
} else {
let tail = self.tail;
- self.tail = self.wrap_index(self.tail + 1);
+ self.tail = self.wrap_add(self.tail, 1);
unsafe { Some(self.buffer_read(tail)) }
}
}
debug_assert!(!self.is_full());
}
- self.tail = self.wrap_index(self.tail - 1);
+ self.tail = self.wrap_sub(self.tail, 1);
let tail = self.tail;
unsafe { self.buffer_write(tail, t); }
}
}
let head = self.head;
- self.head = self.wrap_index(self.head + 1);
+ self.head = self.wrap_add(self.head, 1);
unsafe { self.buffer_write(head, t) }
}
if self.is_empty() {
None
} else {
- self.head = self.wrap_index(self.head - 1);
+ self.head = self.wrap_sub(self.head, 1);
let head = self.head;
unsafe { Some(self.buffer_read(head)) }
}
// A - The element that should be after the insertion point
// M - Indicates element was moved
- let idx = self.wrap_index(self.tail + i);
+ let idx = self.wrap_add(self.tail, i);
let distance_to_tail = i;
let distance_to_head = self.len() - i;
// [A o o o o o o o . . . . . I]
//
- self.tail = self.wrap_index(self.tail - 1);
+ self.tail = self.wrap_sub(self.tail, 1);
},
(true, true, _) => unsafe {
// contiguous, insert closer to tail:
// [o I A o o o o o . . . . . . . o]
// M M
- let new_tail = self.wrap_index(self.tail - 1);
+ let new_tail = self.wrap_sub(self.tail, 1);
self.copy(new_tail, self.tail, 1);
// Already moved the tail, so we only copy `i - 1` elements.
// M M M
self.copy(idx + 1, idx, self.head - idx);
- self.head = self.wrap_index(self.head + 1);
+ self.head = self.wrap_add(self.head, 1);
},
(false, true, true) => unsafe {
// discontiguous, insert closer to tail, tail section:
}
// tail might've been changed so we need to recalculate
- let new_idx = self.wrap_index(self.tail + i);
+ let new_idx = self.wrap_add(self.tail, i);
unsafe {
self.buffer_write(new_idx, t);
}
// R - Indicates element that is being removed
// M - Indicates element was moved
- let idx = self.wrap_index(self.tail + i);
+ let idx = self.wrap_add(self.tail, i);
let elem = unsafe {
Some(self.buffer_read(idx))
// M M
self.copy(self.tail + 1, self.tail, i);
- self.tail = self.wrap_index(self.tail + 1);
+ self.tail = self.wrap_add(self.tail, 1);
},
(false, false, false) => unsafe {
// discontiguous, remove closer to head, head section:
self.copy(0, 1, self.head - 1);
}
- self.head = self.wrap_index(self.head - 1);
+ self.head = self.wrap_sub(self.head, 1);
},
(false, true, false) => unsafe {
// discontiguous, remove closer to tail, head section:
// move elements from tail to end forward, excluding the last one
self.copy(self.tail + 1, self.tail, self.cap - self.tail - 1);
- self.tail = self.wrap_index(self.tail + 1);
+ self.tail = self.wrap_add(self.tail, 1);
}
}
}
// Cleanup where the ends of the buffers are
- self.head = self.wrap_index(self.head - other_len);
+ self.head = self.wrap_sub(self.head, other_len);
other.head = other.wrap_index(other_len);
other
#[inline]
fn count(tail: usize, head: usize, size: usize) -> usize {
// size is always a power of 2
- (head - tail) & (size - 1)
+ (head.wrapping_sub(tail)) & (size - 1)
}
/// `VecDeque` iterator.
return None;
}
let tail = self.tail;
- self.tail = wrap_index(self.tail + 1, self.ring.len());
+ self.tail = wrap_index(self.tail.wrapping_add(1), self.ring.len());
unsafe { Some(self.ring.get_unchecked(tail)) }
}
if self.tail == self.head {
return None;
}
- self.head = wrap_index(self.head - 1, self.ring.len());
+ self.head = wrap_index(self.head.wrapping_sub(1), self.ring.len());
unsafe { Some(self.ring.get_unchecked(self.head)) }
}
}
if j >= self.indexable() {
None
} else {
- let idx = wrap_index(self.tail + j, self.ring.len());
+ let idx = wrap_index(self.tail.wrapping_add(j), self.ring.len());
unsafe { Some(self.ring.get_unchecked(idx)) }
}
}
return None;
}
let tail = self.tail;
- self.tail = wrap_index(self.tail + 1, self.ring.len());
+ self.tail = wrap_index(self.tail.wrapping_add(1), self.ring.len());
unsafe {
let elem = self.ring.get_unchecked_mut(tail);
if self.tail == self.head {
return None;
}
- self.head = wrap_index(self.head - 1, self.ring.len());
+ self.head = wrap_index(self.head.wrapping_sub(1), self.ring.len());
unsafe {
let elem = self.ring.get_unchecked_mut(self.head);
}
#[test]
- #[should_fail]
+ #[should_panic]
fn test_index_out_of_bounds() {
let mut deq = VecDeque::new();
for i in 1..4 {
#[test]
fn test_move_iter() {
- let mut m = VecMap::new();
+ let mut m: VecMap<Box<_>> = VecMap::new();
m.insert(1, box 2);
let mut called = false;
for (k, v) in m {
}
#[test]
- #[should_fail]
+ #[should_panic]
fn test_index_nonexistent() {
let mut map = VecMap::new();
v: UnsafeCell<int>,
}
+#[allow(deprecated)]
unsafe impl Sync for AtomicInt {}
#[unstable(feature = "core")]
v: UnsafeCell<uint>,
}
+#[allow(deprecated)]
unsafe impl Sync for AtomicUint {}
#[unstable(feature = "core")]
///
/// 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
///
/// ```
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
/// assert_eq!(c, Some('4'));
/// ```
#[inline]
-#[unstable(feature = "core", reason = "pending integer conventions")]
+#[stable(feature = "rust1", since = "1.0.0")]
pub fn from_digit(num: u32, radix: u32) -> Option<char> {
if radix > 36 {
panic!("from_digit: radix is too high (maximum 36)");
}
}
-/// Basic `char` manipulations.
-#[stable(feature = "rust1", since = "1.0.0")]
+// NB: the stabilization and documentation for this trait is in
+// unicode/char.rs, not here
+#[allow(missing_docs)] // docs in libunicode/u_char.rs
pub trait CharExt {
- /// Checks if a `char` parses as a numeric digit in the given radix.
- ///
- /// Compared to `is_numeric()`, this function only recognizes the characters
- /// `0-9`, `a-z` and `A-Z`.
- ///
- /// # Return value
- ///
- /// Returns `true` if `c` is a valid digit under `radix`, and `false`
- /// otherwise.
- ///
- /// # Panics
- ///
- /// Panics if given a radix > 36.
- ///
- /// # Examples
- ///
- /// ```
- /// let c = '1';
- ///
- /// assert!(c.is_digit(10));
- ///
- /// assert!('f'.is_digit(16));
- /// ```
- #[unstable(feature = "core",
- reason = "pending integer conventions")]
fn is_digit(self, radix: u32) -> bool;
-
- /// Converts a character to the corresponding digit.
- ///
- /// # Return value
- ///
- /// If `c` is between '0' and '9', the corresponding value between 0 and
- /// 9. If `c` is 'a' or 'A', 10. If `c` is 'b' or 'B', 11, etc. Returns
- /// none if the character does not refer to a digit in the given radix.
- ///
- /// # Panics
- ///
- /// Panics if given a radix outside the range [0..36].
- ///
- /// # Examples
- ///
- /// ```
- /// let c = '1';
- ///
- /// assert_eq!(c.to_digit(10), Some(1));
- ///
- /// assert_eq!('f'.to_digit(16), Some(15));
- /// ```
- #[unstable(feature = "core",
- reason = "pending integer conventions")]
fn to_digit(self, radix: u32) -> Option<u32>;
-
- /// Returns an iterator that yields the hexadecimal Unicode escape of a character, as `char`s.
- ///
- /// All characters are escaped with Rust syntax of the form `\\u{NNNN}` where `NNNN` is the
- /// shortest hexadecimal representation of the code point.
- ///
- /// # Examples
- ///
- /// ```
- /// for i in '❤'.escape_unicode() {
- /// println!("{}", i);
- /// }
- /// ```
- ///
- /// This prints:
- ///
- /// ```text
- /// \
- /// u
- /// {
- /// 2
- /// 7
- /// 6
- /// 4
- /// }
- /// ```
- ///
- /// Collecting into a `String`:
- ///
- /// ```
- /// let heart: String = '❤'.escape_unicode().collect();
- ///
- /// assert_eq!(heart, r"\u{2764}");
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
fn escape_unicode(self) -> EscapeUnicode;
-
- /// Returns an iterator that yields the 'default' ASCII and
- /// C++11-like literal escape of a character, as `char`s.
- ///
- /// The default is chosen with a bias toward producing literals that are
- /// legal in a variety of languages, including C++11 and similar C-family
- /// languages. The exact rules are:
- ///
- /// * Tab, CR and LF are escaped as '\t', '\r' and '\n' respectively.
- /// * Single-quote, double-quote and backslash chars are backslash-
- /// escaped.
- /// * Any other chars in the range [0x20,0x7e] are not escaped.
- /// * Any other chars are given hex Unicode escapes; see `escape_unicode`.
- ///
- /// # Examples
- ///
- /// ```
- /// for i in '"'.escape_default() {
- /// println!("{}", i);
- /// }
- /// ```
- ///
- /// This prints:
- ///
- /// ```text
- /// \
- /// "
- /// ```
- ///
- /// Collecting into a `String`:
- ///
- /// ```
- /// let quote: String = '"'.escape_default().collect();
- ///
- /// assert_eq!(quote, "\\\"");
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
fn escape_default(self) -> EscapeDefault;
-
- /// Returns the number of bytes this character would need if encoded in UTF-8.
- ///
- /// # Examples
- ///
- /// ```
- /// let n = 'ß'.len_utf8();
- ///
- /// assert_eq!(n, 2);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
fn len_utf8(self) -> usize;
-
- /// Returns the number of bytes this character would need if encoded in UTF-16.
- ///
- /// # Examples
- ///
- /// ```
- /// let n = 'ß'.len_utf16();
- ///
- /// assert_eq!(n, 1);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
fn len_utf16(self) -> usize;
-
- /// Encodes this character as UTF-8 into the provided byte buffer, and then returns the number
- /// of bytes written.
- ///
- /// If the buffer is not large enough, nothing will be written into it and a `None` will be
- /// returned.
- ///
- /// # Examples
- ///
- /// In both of these examples, 'ß' takes two bytes to encode.
- ///
- /// ```
- /// let mut b = [0; 2];
- ///
- /// let result = 'ß'.encode_utf8(&mut b);
- ///
- /// assert_eq!(result, Some(2));
- /// ```
- ///
- /// A buffer that's too small:
- ///
- /// ```
- /// let mut b = [0; 1];
- ///
- /// let result = 'ß'.encode_utf8(&mut b);
- ///
- /// assert_eq!(result, None);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
fn encode_utf8(self, dst: &mut [u8]) -> Option<usize>;
-
- /// Encodes this character as UTF-16 into the provided `u16` buffer, and then returns the
- /// number of `u16`s written.
- ///
- /// If the buffer is not large enough, nothing will be written into it and a `None` will be
- /// returned.
- ///
- /// # Examples
- ///
- /// In both of these examples, 'ß' takes one byte to encode.
- ///
- /// ```
- /// let mut b = [0; 1];
- ///
- /// let result = 'ß'.encode_utf16(&mut b);
- ///
- /// assert_eq!(result, Some(1));
- /// ```
- ///
- /// A buffer that's too small:
- ///
- /// ```
- /// let mut b = [0; 0];
- ///
- /// let result = 'ß'.encode_utf8(&mut b);
- ///
- /// assert_eq!(result, None);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
fn encode_utf16(self, dst: &mut [u16]) -> Option<usize>;
}
-#[stable(feature = "rust1", since = "1.0.0")]
impl CharExt for char {
- #[unstable(feature = "core",
- reason = "pending integer conventions")]
fn is_digit(self, radix: u32) -> bool {
self.to_digit(radix).is_some()
}
- #[unstable(feature = "core",
- reason = "pending integer conventions")]
fn to_digit(self, radix: u32) -> Option<u32> {
if radix > 36 {
panic!("to_digit: radix is too high (maximum 36)");
else { None }
}
- #[stable(feature = "rust1", since = "1.0.0")]
fn escape_unicode(self) -> EscapeUnicode {
EscapeUnicode { c: self, state: EscapeUnicodeState::Backslash }
}
- #[stable(feature = "rust1", since = "1.0.0")]
fn escape_default(self) -> EscapeDefault {
let init_state = match self {
'\t' => EscapeDefaultState::Backslash('t'),
}
#[inline]
- #[stable(feature = "rust1", since = "1.0.0")]
fn len_utf8(self) -> usize {
let code = self as u32;
if code < MAX_ONE_B {
}
#[inline]
- #[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]
- #[unstable(feature = "core",
- reason = "pending decision about Iterator/Writer/Reader")]
fn encode_utf8(self, dst: &mut [u8]) -> Option<usize> {
encode_utf8_raw(self as u32, dst)
}
#[inline]
- #[unstable(feature = "core",
- reason = "pending decision about Iterator/Writer/Reader")]
fn encode_utf16(self, dst: &mut [u16]) -> Option<usize> {
encode_utf16_raw(self as u32, dst)
}
/// If the buffer is not large enough, nothing will be written into it
/// and a `None` will be returned.
#[inline]
-#[unstable(feature = "core")]
pub fn encode_utf8_raw(code: u32, dst: &mut [u8]) -> Option<usize> {
// Marked #[inline] to allow llvm optimizing it away
if code < MAX_ONE_B && dst.len() >= 1 {
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
/// If the buffer is not large enough, nothing will be written into it
/// and a `None` will be returned.
#[inline]
-#[unstable(feature = "core")]
pub fn encode_utf16_raw(mut ch: u32, dst: &mut [u16]) -> Option<usize> {
// Marked #[inline] to allow llvm optimizing it away
- if (ch & 0xFFFF_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
}
#[derive(Clone)]
-#[unstable(feature = "core")]
enum EscapeUnicodeState {
Backslash,
Type,
}
#[derive(Clone)]
-#[unstable(feature = "core")]
enum EscapeDefaultState {
Backslash(char),
Char(char),
SignNeg
}
-static DIGIT_E_RADIX: u32 = ('e' as u32) - ('a' as u32) + 11;
+const DIGIT_E_RADIX: u32 = ('e' as u32) - ('a' as u32) + 11;
/// Converts a number to its string representation as a byte vector.
/// This is meant to be a common base implementation for all numeric string
// 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()),
deccum = deccum / radix_gen;
deccum = deccum.trunc();
- let c = char::from_digit(current_digit.to_int().unwrap() as u32, radix);
+ let c = char::from_digit(current_digit.to_isize().unwrap() as u32, radix);
buf[end] = c.unwrap() as u8;
end += 1;
// See note in first loop.
let current_digit = deccum.trunc().abs();
- let c = char::from_digit(current_digit.to_int().unwrap() as u32,
+ let c = char::from_digit(current_digit.to_isize().unwrap() as u32,
radix);
buf[end] = c.unwrap() as u8;
end += 1;
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]) };
#[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)
// 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 {
/// A hexadecimal (base 16) radix, formatted with upper-case characters
#[derive(Clone, PartialEq)]
-pub struct UpperHex;
+struct UpperHex;
macro_rules! radix {
($T:ident, $base:expr, $prefix:expr, $($x:pat => $conv:expr),+) => {
}
macro_rules! radix_fmt {
- ($T:ty as $U:ty, $fmt:ident, $S:expr) => {
+ ($T:ty as $U:ty, $fmt:ident) => {
#[stable(feature = "rust1", since = "1.0.0")]
impl fmt::Debug for RadixFmt<$T, Radix> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
}
}
-macro_rules! show {
- ($T:ident with $S:expr) => {
+macro_rules! debug {
+ ($T:ident) => {
#[stable(feature = "rust1", since = "1.0.0")]
impl fmt::Debug for $T {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
}
macro_rules! integer {
($Int:ident, $Uint:ident) => {
- integer! { $Int, $Uint, stringify!($Int), stringify!($Uint) }
- };
- ($Int:ident, $Uint:ident, $SI:expr, $SU:expr) => {
int_base! { Display for $Int as $Int -> Decimal }
int_base! { Binary for $Int as $Uint -> Binary }
int_base! { Octal for $Int as $Uint -> Octal }
int_base! { LowerHex for $Int as $Uint -> LowerHex }
int_base! { UpperHex for $Int as $Uint -> UpperHex }
- radix_fmt! { $Int as $Int, fmt_int, $SI }
- show! { $Int with $SI }
+ radix_fmt! { $Int as $Int, fmt_int }
+ debug! { $Int }
int_base! { Display for $Uint as $Uint -> Decimal }
int_base! { Binary for $Uint as $Uint -> Binary }
int_base! { Octal for $Uint as $Uint -> Octal }
int_base! { LowerHex for $Uint as $Uint -> LowerHex }
int_base! { UpperHex for $Uint as $Uint -> UpperHex }
- radix_fmt! { $Uint as $Uint, fmt_int, $SU }
- show! { $Uint with $SU }
+ radix_fmt! { $Uint as $Uint, fmt_int }
+ debug! { $Uint }
}
}
-integer! { isize, usize, "i", "u" }
+integer! { isize, usize }
integer! { i8, u8 }
integer! { i16, u16 }
integer! { i32, u32 }
}
fn hash_slice<H: Hasher>(data: &[$ty], state: &mut H) {
- let newlen = data.len() * ::$ty::BYTES;
+ let newlen = data.len() * ::$ty::BYTES as usize;
let ptr = data.as_ptr() as *const u8;
state.write(unsafe { slice::from_raw_parts(ptr, newlen) })
}
use prelude::*;
use default::Default;
-
+use num::wrapping::WrappingOps;
use super::Hasher;
/// An implementation of SipHash 2-4.
($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;
macro_rules! rotl {
($x:expr, $b:expr) =>
- (($x << $b) | ($x >> (64 - $b)))
+ (($x << $b) | ($x >> (64.wrapping_sub($b))))
}
macro_rules! compress {
($v0:expr, $v1:expr, $v2:expr, $v3:expr) =>
({
- $v0 += $v1; $v1 = rotl!($v1, 13); $v1 ^= $v0;
+ $v0 = $v0.wrapping_add($v1); $v1 = rotl!($v1, 13); $v1 ^= $v0;
$v0 = rotl!($v0, 32);
- $v2 += $v3; $v3 = rotl!($v3, 16); $v3 ^= $v2;
- $v0 += $v3; $v3 = rotl!($v3, 21); $v3 ^= $v0;
- $v2 += $v1; $v1 = rotl!($v1, 17); $v1 ^= $v2;
+ $v2 = $v2.wrapping_add($v3); $v3 = rotl!($v3, 16); $v3 ^= $v2;
+ $v0 = $v0.wrapping_add($v3); $v3 = rotl!($v3, 21); $v3 ^= $v0;
+ $v2 = $v2.wrapping_add($v1); $v1 = rotl!($v1, 17); $v1 ^= $v2;
$v2 = rotl!($v2, 32);
})
}
/// 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;
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);
+
+ /// 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.
+ pub fn overflowing_sub<T>(a: T, b: T) -> T;
+ /// Returns (a * b) mod 2^N, where N is the width of N in bits.
+ pub fn overflowing_mul<T>(a: T, b: T) -> T;
}
///
/// ```
/// 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")]
P: FnMut(Self::Item) -> bool,
Self: ExactSizeIterator + DoubleEndedIterator
{
- let mut i = self.len() - 1;
+ let mut i = self.len();
+
while let Some(v) = self.next_back() {
if predicate(v) {
- return Some(i);
+ return Some(i - 1);
}
i -= 1;
}
#[inline]
fn idx(&mut self, index: usize) -> Option<<I as Iterator>::Item> {
let amt = self.indexable();
- self.iter.idx(amt - index - 1)
+ if amt > index {
+ self.iter.idx(amt - index - 1)
+ } else {
+ None
+ }
}
}
/// ```
/// 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);
/// ```
}
#[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()
}
}
#[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 {
}
#[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()
}
}
}
#[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 {
}
#[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()
}
#[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 {
}
#[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)
}
#[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() {
}
#[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 {
}
#[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 {
}
#[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) {
f: F,
}
-impl<I: Iterator, F, B> Map<I, F> where F: FnMut(I::Item) -> B {
- #[inline]
- fn do_map(&mut self, elt: Option<I::Item>) -> Option<B> {
- match elt {
- Some(a) => Some((self.f)(a)),
- _ => None
- }
- }
-}
-
#[stable(feature = "rust1", since = "1.0.0")]
impl<B, I: Iterator, F> Iterator for Map<I, F> where F: FnMut(I::Item) -> B {
type Item = B;
#[inline]
fn next(&mut self) -> Option<B> {
- let next = self.iter.next();
- self.do_map(next)
+ self.iter.next().map(|a| (self.f)(a))
}
#[inline]
{
#[inline]
fn next_back(&mut self) -> Option<B> {
- let next = self.iter.next_back();
- self.do_map(next)
+ self.iter.next_back().map(|a| (self.f)(a))
}
}
#[inline]
fn idx(&mut self, index: usize) -> Option<B> {
- let elt = self.iter.idx(index);
- self.do_map(elt)
+ self.iter.idx(index).map(|a| (self.f)(a))
}
}
f: F,
/// The current internal state to be passed to the closure next.
+ #[unstable(feature = "core")]
pub state: St,
}
#[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;
pub struct Unfold<St, F> {
f: F,
/// Internal state that will be passed to the closure on the next iteration
+ #[unstable(feature = "core")]
pub state: St,
}
Some(a) => {
let sz = self.stop.to_i64().map(|b| b.checked_sub(a));
match sz {
- Some(Some(bound)) => bound.to_uint(),
+ Some(Some(bound)) => bound.to_usize(),
_ => None,
}
},
Some(a) => {
let sz = self.stop.to_u64().map(|b| b.checked_sub(a));
match sz {
- Some(Some(bound)) => bound.to_uint(),
+ Some(Some(bound)) => bound.to_usize(),
_ => None
}
},
if self.start >= self.end {
(0, Some(0))
} else {
- let length = (self.end - self.start).to_uint();
+ let length = (self.end - self.start).to_usize();
(length.unwrap_or(0), length)
}
}
//! 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
// 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]
#![feature(unboxed_closures)]
#![feature(rustc_attrs)]
#![feature(optin_builtin_traits)]
+#![feature(concat_idents)]
#[macro_use]
mod macros;
/// 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
///
#[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
///
/// 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
///
/// ```
#[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
///
/// ```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; }
/// }
/// 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"]
/// 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
use option::Option;
#[unstable(feature = "core", reason = "pending integer conventions")]
-pub const RADIX: uint = 2;
+pub const RADIX: u32 = 2;
#[unstable(feature = "core", reason = "pending integer conventions")]
-pub const MANTISSA_DIGITS: uint = 24;
+pub const MANTISSA_DIGITS: u32 = 24;
#[unstable(feature = "core", reason = "pending integer conventions")]
-pub const DIGITS: uint = 6;
+pub const DIGITS: u32 = 6;
#[stable(feature = "rust1", since = "1.0.0")]
pub const EPSILON: f32 = 1.19209290e-07_f32;
pub const MAX: f32 = 3.40282347e+38_f32;
#[unstable(feature = "core", reason = "pending integer conventions")]
-pub const MIN_EXP: int = -125;
+pub const MIN_EXP: i32 = -125;
#[unstable(feature = "core", reason = "pending integer conventions")]
-pub const MAX_EXP: int = 128;
+pub const MAX_EXP: i32 = 128;
#[unstable(feature = "core", reason = "pending integer conventions")]
-pub const MIN_10_EXP: int = -37;
+pub const MIN_10_EXP: i32 = -37;
#[unstable(feature = "core", reason = "pending integer conventions")]
-pub const MAX_10_EXP: int = 38;
+pub const MAX_10_EXP: i32 = 38;
#[stable(feature = "rust1", since = "1.0.0")]
pub const NAN: f32 = 0.0_f32/0.0_f32;
#[inline]
#[unstable(feature = "core")]
#[deprecated(since = "1.0.0")]
- fn mantissa_digits(_: Option<f32>) -> uint { MANTISSA_DIGITS }
+ fn mantissa_digits(_: Option<f32>) -> uint { MANTISSA_DIGITS as uint }
#[inline]
#[unstable(feature = "core")]
#[deprecated(since = "1.0.0")]
- fn digits(_: Option<f32>) -> uint { DIGITS }
+ fn digits(_: Option<f32>) -> uint { DIGITS as uint }
#[inline]
#[unstable(feature = "core")]
#[inline]
#[unstable(feature = "core")]
#[deprecated(since = "1.0.0")]
- fn min_exp(_: Option<f32>) -> int { MIN_EXP }
+ fn min_exp(_: Option<f32>) -> int { MIN_EXP as int }
#[inline]
#[unstable(feature = "core")]
#[deprecated(since = "1.0.0")]
- fn max_exp(_: Option<f32>) -> int { MAX_EXP }
+ fn max_exp(_: Option<f32>) -> int { MAX_EXP as int }
#[inline]
#[unstable(feature = "core")]
#[deprecated(since = "1.0.0")]
- fn min_10_exp(_: Option<f32>) -> int { MIN_10_EXP }
+ fn min_10_exp(_: Option<f32>) -> int { MIN_10_EXP as int }
#[inline]
#[unstable(feature = "core")]
#[deprecated(since = "1.0.0")]
- fn max_10_exp(_: Option<f32>) -> int { MAX_10_EXP }
+ fn max_10_exp(_: Option<f32>) -> int { MAX_10_EXP as int }
#[inline]
#[unstable(feature = "core")]
// members of `Bounded` and `Float`.
#[unstable(feature = "core", reason = "pending integer conventions")]
-pub const RADIX: uint = 2;
+pub const RADIX: u32 = 2;
-pub const MANTISSA_DIGITS: uint = 53;
+pub const MANTISSA_DIGITS: u32 = 53;
#[unstable(feature = "core", reason = "pending integer conventions")]
-pub const DIGITS: uint = 15;
+pub const DIGITS: u32 = 15;
#[stable(feature = "rust1", since = "1.0.0")]
pub const EPSILON: f64 = 2.2204460492503131e-16_f64;
pub const MAX: f64 = 1.7976931348623157e+308_f64;
#[unstable(feature = "core", reason = "pending integer conventions")]
-pub const MIN_EXP: int = -1021;
+pub const MIN_EXP: i32 = -1021;
#[unstable(feature = "core", reason = "pending integer conventions")]
-pub const MAX_EXP: int = 1024;
+pub const MAX_EXP: i32 = 1024;
#[unstable(feature = "core", reason = "pending integer conventions")]
-pub const MIN_10_EXP: int = -307;
+pub const MIN_10_EXP: i32 = -307;
#[unstable(feature = "core", reason = "pending integer conventions")]
-pub const MAX_10_EXP: int = 308;
+pub const MAX_10_EXP: i32 = 308;
#[stable(feature = "rust1", since = "1.0.0")]
pub const NAN: f64 = 0.0_f64/0.0_f64;
#[inline]
#[unstable(feature = "core")]
#[deprecated(since = "1.0.0")]
- fn mantissa_digits(_: Option<f64>) -> uint { MANTISSA_DIGITS }
+ fn mantissa_digits(_: Option<f64>) -> uint { MANTISSA_DIGITS as uint }
#[inline]
#[unstable(feature = "core")]
#[deprecated(since = "1.0.0")]
- fn digits(_: Option<f64>) -> uint { DIGITS }
+ fn digits(_: Option<f64>) -> uint { DIGITS as uint }
#[inline]
#[unstable(feature = "core")]
#[inline]
#[unstable(feature = "core")]
#[deprecated(since = "1.0.0")]
- fn min_exp(_: Option<f64>) -> int { MIN_EXP }
+ fn min_exp(_: Option<f64>) -> int { MIN_EXP as int }
#[inline]
#[unstable(feature = "core")]
#[deprecated(since = "1.0.0")]
- fn max_exp(_: Option<f64>) -> int { MAX_EXP }
+ fn max_exp(_: Option<f64>) -> int { MAX_EXP as int }
#[inline]
#[unstable(feature = "core")]
#[deprecated(since = "1.0.0")]
- fn min_10_exp(_: Option<f64>) -> int { MIN_10_EXP }
+ fn min_10_exp(_: Option<f64>) -> int { MIN_10_EXP as int }
#[inline]
#[unstable(feature = "core")]
#[deprecated(since = "1.0.0")]
- fn max_10_exp(_: Option<f64>) -> int { MAX_10_EXP }
+ fn max_10_exp(_: Option<f64>) -> int { MAX_10_EXP as int }
#[inline]
#[unstable(feature = "core")]
// FIXME(#11621): Should be deprecated once CTFE is implemented in favour of
// calling the `mem::size_of` function.
#[unstable(feature = "core")]
-pub const BITS : uint = $bits;
+pub const BITS : u32 = $bits;
// FIXME(#11621): Should be deprecated once CTFE is implemented in favour of
// calling the `mem::size_of` function.
#[unstable(feature = "core")]
-pub const BYTES : uint = ($bits / 8);
+pub const BYTES : u32 = ($bits / 8);
// FIXME(#11621): Should be deprecated once CTFE is implemented in favour of
// calling the `Bounded::min_value` function.
#![stable(feature = "rust1", since = "1.0.0")]
#![allow(missing_docs)]
+use self::wrapping::{OverflowingOps, WrappingOps};
+
use char::CharExt;
use clone::Clone;
use cmp::{PartialEq, Eq, PartialOrd, Ord};
use result::Result::{self, Ok, Err};
use str::{FromStr, StrExt};
+#[unstable(feature = "core", reason = "may be removed or relocated")]
+pub mod wrapping;
+
/// A built-in signed or unsigned integer.
#[stable(feature = "rust1", since = "1.0.0")]
pub trait Int
+ BitXor<Output=Self>
+ Shl<uint, Output=Self>
+ Shr<uint, Output=Self>
+ + WrappingOps
+ + OverflowingOps
{
/// Returns the `0` value of this integer type.
// FIXME (#5527): Should be an associated constant
/// ```
#[unstable(feature = "core",
reason = "pending integer conventions")]
- fn count_ones(self) -> uint;
+ fn count_ones(self) -> u32;
/// Returns the number of zeros in the binary representation of `self`.
///
#[unstable(feature = "core",
reason = "pending integer conventions")]
#[inline]
- fn count_zeros(self) -> uint {
+ fn count_zeros(self) -> u32 {
(!self).count_ones()
}
/// ```
#[unstable(feature = "core",
reason = "pending integer conventions")]
- fn leading_zeros(self) -> uint;
+ fn leading_zeros(self) -> u32;
/// Returns the number of trailing zeros in the binary representation
/// of `self`.
/// ```
#[unstable(feature = "core",
reason = "pending integer conventions")]
- fn trailing_zeros(self) -> uint;
+ fn trailing_zeros(self) -> u32;
/// Shifts the bits to the left by a specified amount amount, `n`, wrapping
/// the truncated bits to the end of the resulting integer.
/// ```
#[unstable(feature = "core",
reason = "pending integer conventions")]
- fn rotate_left(self, n: uint) -> Self;
+ fn rotate_left(self, n: u32) -> Self;
/// Shifts the bits to the right by a specified amount amount, `n`, wrapping
/// the truncated bits to the beginning of the resulting integer.
/// ```
#[unstable(feature = "core",
reason = "pending integer conventions")]
- fn rotate_right(self, n: uint) -> Self;
+ fn rotate_right(self, n: u32) -> Self;
/// Reverses the byte order of the integer.
///
let mut base = self;
let mut acc: Self = Int::one();
+ let mut prev_base = self;
+ let mut base_oflo = false;
while exp > 0 {
if (exp & 1) == 1 {
- acc = acc * base;
+ if base_oflo {
+ // ensure overflow occurs in the same manner it
+ // would have otherwise (i.e. signal any exception
+ // it would have otherwise).
+ acc = acc * (prev_base * prev_base);
+ } else {
+ acc = acc * base;
+ }
}
- base = base * base;
+ prev_base = base;
+ let (new_base, new_base_oflo) = base.overflowing_mul(base);
+ base = new_base;
+ base_oflo = new_base_oflo;
exp /= 2;
}
acc
fn max_value() -> $T { -1 }
#[inline]
- fn count_ones(self) -> uint { unsafe { $ctpop(self as $ActualT) as uint } }
+ fn count_ones(self) -> u32 { unsafe { $ctpop(self as $ActualT) as u32 } }
#[inline]
- fn leading_zeros(self) -> uint { unsafe { $ctlz(self as $ActualT) as uint } }
+ fn leading_zeros(self) -> u32 { unsafe { $ctlz(self as $ActualT) as u32 } }
#[inline]
- fn trailing_zeros(self) -> uint { unsafe { $cttz(self as $ActualT) as uint } }
+ fn trailing_zeros(self) -> u32 { unsafe { $cttz(self as $ActualT) as u32 } }
#[inline]
- fn rotate_left(self, n: uint) -> $T {
+ fn rotate_left(self, n: u32) -> $T {
// Protect against undefined behaviour for over-long bit shifts
let n = n % $BITS;
(self << n) | (self >> (($BITS - n) % $BITS))
}
#[inline]
- fn rotate_right(self, n: uint) -> $T {
+ fn rotate_right(self, n: u32) -> $T {
// Protect against undefined behaviour for over-long bit shifts
let n = n % $BITS;
(self >> n) | (self << (($BITS - n) % $BITS))
fn max_value() -> $T { let min: $T = Int::min_value(); !min }
#[inline]
- fn count_ones(self) -> uint { (self as $UnsignedT).count_ones() }
+ fn count_ones(self) -> u32 { (self as $UnsignedT).count_ones() }
#[inline]
- fn leading_zeros(self) -> uint { (self as $UnsignedT).leading_zeros() }
+ fn leading_zeros(self) -> u32 { (self as $UnsignedT).leading_zeros() }
#[inline]
- fn trailing_zeros(self) -> uint { (self as $UnsignedT).trailing_zeros() }
+ fn trailing_zeros(self) -> u32 { (self as $UnsignedT).trailing_zeros() }
#[inline]
- fn rotate_left(self, n: uint) -> $T { (self as $UnsignedT).rotate_left(n) as $T }
+ fn rotate_left(self, n: u32) -> $T { (self as $UnsignedT).rotate_left(n) as $T }
#[inline]
- fn rotate_right(self, n: uint) -> $T { (self as $UnsignedT).rotate_right(n) as $T }
+ fn rotate_right(self, n: u32) -> $T { (self as $UnsignedT).rotate_right(n) as $T }
#[inline]
fn swap_bytes(self) -> $T { (self as $UnsignedT).swap_bytes() as $T }
/// A built-in unsigned integer.
#[stable(feature = "rust1", since = "1.0.0")]
-pub trait UnsignedInt: Int {
+pub trait UnsignedInt: Int + WrappingOps {
/// Returns `true` iff `self == 2^k` for some `k`.
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
fn is_power_of_two(self) -> bool {
- (self - Int::one()) & self == Int::zero() && !(self == Int::zero())
+ (self.wrapping_sub(Int::one())) & self == Int::zero() && !(self == Int::zero())
}
/// Returns the smallest power of two greater than or equal to `self`.
fn next_power_of_two(self) -> Self {
let bits = size_of::<Self>() * 8;
let one: Self = Int::one();
- one << ((bits - (self - one).leading_zeros()) % bits)
+ one << ((bits - self.wrapping_sub(one).leading_zeros() as usize) % bits)
}
/// Returns the smallest power of two greater than or equal to `n`. If the
pub trait ToPrimitive {
/// Converts the value of `self` to an `int`.
#[inline]
+ #[unstable(feature = "core")]
+ #[deprecated(since = "1.0.0", reason = "use to_isize")]
fn to_int(&self) -> Option<int> {
- self.to_i64().and_then(|x| x.to_int())
+ self.to_i64().and_then(|x| x.to_isize())
+ }
+
+ /// Converts the value of `self` to an `isize`.
+ #[inline]
+ fn to_isize(&self) -> Option<isize> {
+ self.to_i64().and_then(|x| x.to_isize())
}
/// Converts the value of `self` to an `i8`.
/// Converts the value of `self` to an `uint`.
#[inline]
+ #[unstable(feature = "core")]
+ #[deprecated(since = "1.0.0", reason = "use to_usize")]
fn to_uint(&self) -> Option<uint> {
- self.to_u64().and_then(|x| x.to_uint())
+ self.to_u64().and_then(|x| x.to_usize())
+ }
+
+ /// Converts the value of `self` to a `usize`.
+ #[inline]
+ fn to_usize(&self) -> Option<usize> {
+ self.to_u64().and_then(|x| x.to_usize())
}
/// Converts the value of `self` to an `u8`.
#[inline]
fn to_int(&self) -> Option<int> { impl_to_primitive_int_to_int!($T, int, *self) }
#[inline]
+ fn to_isize(&self) -> Option<isize> { impl_to_primitive_int_to_int!($T, isize, *self) }
+ #[inline]
fn to_i8(&self) -> Option<i8> { impl_to_primitive_int_to_int!($T, i8, *self) }
#[inline]
fn to_i16(&self) -> Option<i16> { impl_to_primitive_int_to_int!($T, i16, *self) }
#[inline]
fn to_uint(&self) -> Option<uint> { impl_to_primitive_int_to_uint!($T, uint, *self) }
#[inline]
+ fn to_usize(&self) -> Option<usize> { impl_to_primitive_int_to_uint!($T, usize, *self) }
+ #[inline]
fn to_u8(&self) -> Option<u8> { impl_to_primitive_int_to_uint!($T, u8, *self) }
#[inline]
fn to_u16(&self) -> Option<u16> { impl_to_primitive_int_to_uint!($T, u16, *self) }
)
}
-impl_to_primitive_int! { int }
+impl_to_primitive_int! { isize }
impl_to_primitive_int! { i8 }
impl_to_primitive_int! { i16 }
impl_to_primitive_int! { i32 }
#[inline]
fn to_int(&self) -> Option<int> { impl_to_primitive_uint_to_int!(int, *self) }
#[inline]
+ fn to_isize(&self) -> Option<int> { impl_to_primitive_uint_to_int!(isize, *self) }
+ #[inline]
fn to_i8(&self) -> Option<i8> { impl_to_primitive_uint_to_int!(i8, *self) }
#[inline]
fn to_i16(&self) -> Option<i16> { impl_to_primitive_uint_to_int!(i16, *self) }
#[inline]
fn to_uint(&self) -> Option<uint> { impl_to_primitive_uint_to_uint!($T, uint, *self) }
#[inline]
+ fn to_usize(&self) -> Option<uint> { impl_to_primitive_uint_to_uint!($T, usize, *self) }
+ #[inline]
fn to_u8(&self) -> Option<u8> { impl_to_primitive_uint_to_uint!($T, u8, *self) }
#[inline]
fn to_u16(&self) -> Option<u16> { impl_to_primitive_uint_to_uint!($T, u16, *self) }
)
}
-impl_to_primitive_uint! { uint }
+impl_to_primitive_uint! { usize }
impl_to_primitive_uint! { u8 }
impl_to_primitive_uint! { u16 }
impl_to_primitive_uint! { u32 }
#[inline]
fn to_int(&self) -> Option<int> { Some(*self as int) }
#[inline]
+ fn to_isize(&self) -> Option<int> { Some(*self as isize) }
+ #[inline]
fn to_i8(&self) -> Option<i8> { Some(*self as i8) }
#[inline]
fn to_i16(&self) -> Option<i16> { Some(*self as i16) }
#[inline]
fn to_uint(&self) -> Option<uint> { Some(*self as uint) }
#[inline]
+ fn to_usize(&self) -> Option<uint> { Some(*self as usize) }
+ #[inline]
fn to_u8(&self) -> Option<u8> { Some(*self as u8) }
#[inline]
fn to_u16(&self) -> Option<u16> { Some(*self as u16) }
/// Convert an `int` to return an optional value of this type. If the
/// value cannot be represented by this value, the `None` is returned.
#[inline]
+ #[unstable(feature = "core")]
+ #[deprecated(since = "1.0.0", reason = "use from_isize")]
fn from_int(n: int) -> Option<Self> {
FromPrimitive::from_i64(n as i64)
}
+ /// Convert an `isize` to return an optional value of this type. If the
+ /// value cannot be represented by this value, the `None` is returned.
+ #[inline]
+ fn from_isize(n: isize) -> Option<Self> {
+ FromPrimitive::from_i64(n as i64)
+ }
+
/// Convert an `i8` to return an optional value of this type. If the
/// type cannot be represented by this value, the `None` is returned.
#[inline]
/// Convert an `uint` to return an optional value of this type. If the
/// type cannot be represented by this value, the `None` is returned.
#[inline]
+ #[unstable(feature = "core")]
+ #[deprecated(since = "1.0.0", reason = "use from_usize")]
fn from_uint(n: uint) -> Option<Self> {
FromPrimitive::from_u64(n as u64)
}
+ /// Convert a `usize` to return an optional value of this type. If the
+ /// type cannot be represented by this value, the `None` is returned.
+ #[inline]
+ fn from_usize(n: usize) -> Option<Self> {
+ FromPrimitive::from_u64(n as u64)
+ }
+
/// Convert an `u8` to return an optional value of this type. If the
/// type cannot be represented by this value, the `None` is returned.
#[inline]
/// A utility function that just calls `FromPrimitive::from_int`.
#[unstable(feature = "core", reason = "likely to be removed")]
+#[deprecated(since = "1.0.0", reason = "use from_isize")]
pub fn from_int<A: FromPrimitive>(n: int) -> Option<A> {
- FromPrimitive::from_int(n)
+ FromPrimitive::from_isize(n)
+}
+
+/// A utility function that just calls `FromPrimitive::from_isize`.
+#[unstable(feature = "core", reason = "likely to be removed")]
+pub fn from_isize<A: FromPrimitive>(n: isize) -> Option<A> {
+ FromPrimitive::from_isize(n)
}
/// A utility function that just calls `FromPrimitive::from_i8`.
/// A utility function that just calls `FromPrimitive::from_uint`.
#[unstable(feature = "core", reason = "likely to be removed")]
+#[deprecated(since = "1.0.0", reason = "use from_uint")]
pub fn from_uint<A: FromPrimitive>(n: uint) -> Option<A> {
- FromPrimitive::from_uint(n)
+ FromPrimitive::from_usize(n)
+}
+
+/// A utility function that just calls `FromPrimitive::from_usize`.
+#[unstable(feature = "core", reason = "likely to be removed")]
+pub fn from_usize<A: FromPrimitive>(n: usize) -> Option<A> {
+ FromPrimitive::from_usize(n)
}
/// A utility function that just calls `FromPrimitive::from_u8`.
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() }
($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
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> {
}
}
}
-from_str_radix_int_impl! { int }
+from_str_radix_int_impl! { isize }
from_str_radix_int_impl! { i8 }
from_str_radix_int_impl! { i16 }
from_str_radix_int_impl! { i32 }
from_str_radix_int_impl! { i64 }
-from_str_radix_int_impl! { uint }
+from_str_radix_int_impl! { usize }
from_str_radix_int_impl! { u8 }
from_str_radix_int_impl! { u16 }
from_str_radix_int_impl! { u32 }
macro_rules! uint_module { ($T:ty, $T_SIGNED:ty, $bits:expr) => (
#[unstable(feature = "core")]
-pub const BITS : uint = $bits;
+pub const BITS : u32 = $bits;
#[unstable(feature = "core")]
-pub const BYTES : uint = ($bits / 8);
+pub const BYTES : u32 = ($bits / 8);
#[stable(feature = "rust1", since = "1.0.0")]
pub const MIN: $T = 0 as $T;
#[stable(feature = "rust1", since = "1.0.0")]
-pub const MAX: $T = 0 as $T - 1 as $T;
+pub const MAX: $T = !0 as $T;
) }
--- /dev/null
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <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(missing_docs)]
+
+use ops::*;
+
+use intrinsics::{overflowing_add, overflowing_sub, overflowing_mul};
+
+use intrinsics::{i8_add_with_overflow, u8_add_with_overflow};
+use intrinsics::{i16_add_with_overflow, u16_add_with_overflow};
+use intrinsics::{i32_add_with_overflow, u32_add_with_overflow};
+use intrinsics::{i64_add_with_overflow, u64_add_with_overflow};
+use intrinsics::{i8_sub_with_overflow, u8_sub_with_overflow};
+use intrinsics::{i16_sub_with_overflow, u16_sub_with_overflow};
+use intrinsics::{i32_sub_with_overflow, u32_sub_with_overflow};
+use intrinsics::{i64_sub_with_overflow, u64_sub_with_overflow};
+use intrinsics::{i8_mul_with_overflow, u8_mul_with_overflow};
+use intrinsics::{i16_mul_with_overflow, u16_mul_with_overflow};
+use intrinsics::{i32_mul_with_overflow, u32_mul_with_overflow};
+use intrinsics::{i64_mul_with_overflow, u64_mul_with_overflow};
+
+pub trait WrappingOps {
+ fn wrapping_add(self, rhs: Self) -> Self;
+ fn wrapping_sub(self, rhs: Self) -> Self;
+ fn wrapping_mul(self, rhs: Self) -> Self;
+}
+
+#[unstable(feature = "core", reason = "may be removed, renamed, or relocated")]
+pub trait OverflowingOps {
+ fn overflowing_add(self, rhs: Self) -> (Self, bool);
+ fn overflowing_sub(self, rhs: Self) -> (Self, bool);
+ fn overflowing_mul(self, rhs: Self) -> (Self, bool);
+}
+
+macro_rules! wrapping_impl {
+ ($($t:ty)*) => ($(
+ impl WrappingOps for $t {
+ #[inline(always)]
+ fn wrapping_add(self, rhs: $t) -> $t {
+ unsafe {
+ overflowing_add(self, rhs)
+ }
+ }
+ #[inline(always)]
+ fn wrapping_sub(self, rhs: $t) -> $t {
+ unsafe {
+ overflowing_sub(self, rhs)
+ }
+ }
+ #[inline(always)]
+ fn wrapping_mul(self, rhs: $t) -> $t {
+ unsafe {
+ overflowing_mul(self, rhs)
+ }
+ }
+ }
+ )*)
+}
+
+wrapping_impl! { uint u8 u16 u32 u64 int i8 i16 i32 i64 }
+
+#[unstable(feature = "core", reason = "may be removed, renamed, or relocated")]
+#[derive(PartialEq,Eq,PartialOrd,Ord,Clone,Copy)]
+pub struct Wrapping<T>(pub T);
+
+impl<T:WrappingOps> Add for Wrapping<T> {
+ type Output = Wrapping<T>;
+
+ #[inline(always)]
+ fn add(self, other: Wrapping<T>) -> Wrapping<T> {
+ Wrapping(self.0.wrapping_add(other.0))
+ }
+}
+
+impl<T:WrappingOps> Sub for Wrapping<T> {
+ type Output = Wrapping<T>;
+
+ #[inline(always)]
+ fn sub(self, other: Wrapping<T>) -> Wrapping<T> {
+ Wrapping(self.0.wrapping_sub(other.0))
+ }
+}
+
+impl<T:WrappingOps> Mul for Wrapping<T> {
+ type Output = Wrapping<T>;
+
+ #[inline(always)]
+ fn mul(self, other: Wrapping<T>) -> Wrapping<T> {
+ Wrapping(self.0.wrapping_mul(other.0))
+ }
+}
+
+impl<T:WrappingOps+Not<Output=T>> Not for Wrapping<T> {
+ type Output = Wrapping<T>;
+
+ fn not(self) -> Wrapping<T> {
+ Wrapping(!self.0)
+ }
+}
+
+impl<T:WrappingOps+BitXor<Output=T>> BitXor for Wrapping<T> {
+ type Output = Wrapping<T>;
+
+ #[inline(always)]
+ fn bitxor(self, other: Wrapping<T>) -> Wrapping<T> {
+ Wrapping(self.0 ^ other.0)
+ }
+}
+
+impl<T:WrappingOps+BitOr<Output=T>> BitOr for Wrapping<T> {
+ type Output = Wrapping<T>;
+
+ #[inline(always)]
+ fn bitor(self, other: Wrapping<T>) -> Wrapping<T> {
+ Wrapping(self.0 | other.0)
+ }
+}
+
+impl<T:WrappingOps+BitAnd<Output=T>> BitAnd for Wrapping<T> {
+ type Output = Wrapping<T>;
+
+ #[inline(always)]
+ fn bitand(self, other: Wrapping<T>) -> Wrapping<T> {
+ Wrapping(self.0 & other.0)
+ }
+}
+
+impl<T:WrappingOps+Shl<uint,Output=T>> Shl<uint> for Wrapping<T> {
+ type Output = Wrapping<T>;
+
+ #[inline(always)]
+ fn shl(self, other: uint) -> Wrapping<T> {
+ Wrapping(self.0 << other)
+ }
+}
+
+impl<T:WrappingOps+Shr<uint,Output=T>> Shr<uint> for Wrapping<T> {
+ type Output = Wrapping<T>;
+
+ #[inline(always)]
+ fn shr(self, other: uint) -> Wrapping<T> {
+ Wrapping(self.0 >> other)
+ }
+}
+
+macro_rules! overflowing_impl {
+ ($($t:ident)*) => ($(
+ impl OverflowingOps for $t {
+ #[inline(always)]
+ fn overflowing_add(self, rhs: $t) -> ($t, bool) {
+ unsafe {
+ concat_idents!($t, _add_with_overflow)(self, rhs)
+ }
+ }
+ #[inline(always)]
+ fn overflowing_sub(self, rhs: $t) -> ($t, bool) {
+ unsafe {
+ concat_idents!($t, _sub_with_overflow)(self, rhs)
+ }
+ }
+ #[inline(always)]
+ fn overflowing_mul(self, rhs: $t) -> ($t, bool) {
+ unsafe {
+ concat_idents!($t, _mul_with_overflow)(self, rhs)
+ }
+ }
+ }
+ )*)
+}
+
+overflowing_impl! { u8 u16 u32 u64 i8 i16 i32 i64 }
+
+#[cfg(target_pointer_width = "64")]
+impl OverflowingOps for usize {
+ #[inline(always)]
+ fn overflowing_add(self, rhs: usize) -> (usize, bool) {
+ unsafe {
+ let res = u64_add_with_overflow(self as u64, rhs as u64);
+ (res.0 as usize, res.1)
+ }
+ }
+ #[inline(always)]
+ fn overflowing_sub(self, rhs: usize) -> (usize, bool) {
+ unsafe {
+ let res = u64_sub_with_overflow(self as u64, rhs as u64);
+ (res.0 as usize, res.1)
+ }
+ }
+ #[inline(always)]
+ fn overflowing_mul(self, rhs: usize) -> (usize, bool) {
+ unsafe {
+ let res = u64_mul_with_overflow(self as u64, rhs as u64);
+ (res.0 as usize, res.1)
+ }
+ }
+}
+
+#[cfg(target_pointer_width = "32")]
+impl OverflowingOps for usize {
+ #[inline(always)]
+ fn overflowing_add(self, rhs: usize) -> (usize, bool) {
+ unsafe {
+ let res = u32_add_with_overflow(self as u32, rhs as u32);
+ (res.0 as usize, res.1)
+ }
+ }
+ #[inline(always)]
+ fn overflowing_sub(self, rhs: usize) -> (usize, bool) {
+ unsafe {
+ let res = u32_sub_with_overflow(self as u32, rhs as u32);
+ (res.0 as usize, res.1)
+ }
+ }
+ #[inline(always)]
+ fn overflowing_mul(self, rhs: usize) -> (usize, bool) {
+ unsafe {
+ let res = u32_mul_with_overflow(self as u32, rhs as u32);
+ (res.0 as usize, res.1)
+ }
+ }
+}
+
+#[cfg(target_pointer_width = "64")]
+impl OverflowingOps for isize {
+ #[inline(always)]
+ fn overflowing_add(self, rhs: isize) -> (isize, bool) {
+ unsafe {
+ let res = i64_add_with_overflow(self as i64, rhs as i64);
+ (res.0 as isize, res.1)
+ }
+ }
+ #[inline(always)]
+ fn overflowing_sub(self, rhs: isize) -> (isize, bool) {
+ unsafe {
+ let res = i64_sub_with_overflow(self as i64, rhs as i64);
+ (res.0 as isize, res.1)
+ }
+ }
+ #[inline(always)]
+ fn overflowing_mul(self, rhs: isize) -> (isize, bool) {
+ unsafe {
+ let res = i64_mul_with_overflow(self as i64, rhs as i64);
+ (res.0 as isize, res.1)
+ }
+ }
+}
+
+#[cfg(target_pointer_width = "32")]
+impl OverflowingOps for isize {
+ #[inline(always)]
+ fn overflowing_add(self, rhs: isize) -> (isize, bool) {
+ unsafe {
+ let res = i32_add_with_overflow(self as i32, rhs as i32);
+ (res.0 as isize, res.1)
+ }
+ }
+ #[inline(always)]
+ fn overflowing_sub(self, rhs: isize) -> (isize, bool) {
+ unsafe {
+ let res = i32_sub_with_overflow(self as i32, rhs as i32);
+ (res.0 as isize, res.1)
+ }
+ }
+ #[inline(always)]
+ fn overflowing_mul(self, rhs: isize) -> (isize, bool) {
+ unsafe {
+ let res = i32_mul_with_overflow(self as i32, rhs as i32);
+ (res.0 as isize, res.1)
+ }
+ }
+}
#[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
/// # 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);
/// ```
#[deprecated(reason = "unboxed new closures do not have a universal representation; \
`&Fn` (etc) trait objects should use `TraitObject` instead",
since= "1.0.0")]
+#[allow(deprecated) /* for deriving Copy impl */]
pub struct Closure {
pub code: *mut (),
pub env: *mut (),
//! fn write_info(info: &Info) -> Result<(), IoError> {
//! let mut file = File::open_mode(&Path::new("my_best_friends.txt"), Open, Write);
//! // Early return on error
-//! if let Err(e) = file.write_line(format!("name: {}", info.name).as_slice()) {
+//! if let Err(e) = file.write_line(&format!("name: {}", info.name)) {
//! return Err(e)
//! }
-//! if let Err(e) = file.write_line(format!("age: {}", info.age).as_slice()) {
+//! if let Err(e) = file.write_line(&format!("age: {}", info.age)) {
//! return Err(e)
//! }
-//! return file.write_line(format!("rating: {}", info.rating).as_slice());
+//! return file.write_line(&format!("rating: {}", info.rating));
//! }
//! ```
//!
//! fn write_info(info: &Info) -> Result<(), IoError> {
//! let mut file = File::open_mode(&Path::new("my_best_friends.txt"), Open, Write);
//! // Early return on error
-//! try!(file.write_line(format!("name: {}", info.name).as_slice()));
-//! try!(file.write_line(format!("age: {}", info.age).as_slice()));
-//! try!(file.write_line(format!("rating: {}", info.rating).as_slice()));
+//! try!(file.write_line(&format!("name: {}", info.name)));
+//! try!(file.write_line(&format!("age: {}", info.age)));
+//! try!(file.write_line(&format!("rating: {}", info.rating)));
//! return Ok(());
//! }
//! ```
ChunksMut { v: self, chunk_size: chunk_size }
}
+ #[inline]
fn swap(&mut self, a: usize, b: usize) {
unsafe {
// Can't take two mutable loans from one vector, so instead just cast
forward_iterator! { RSplitNMut: T, &'a mut [T] }
/// An iterator over overlapping subslices of length `size`.
-#[derive(Clone)]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Windows<'a, T:'a> {
v: &'a [T],
size: usize
}
+// FIXME(#19839) Remove in favor of `#[derive(Clone)]`
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, T> Clone for Windows<'a, T> {
+ fn clone(&self) -> Windows<'a, T> {
+ Windows {
+ v: self.v,
+ size: self.size,
+ }
+ }
+}
+
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T> Iterator for Windows<'a, T> {
type Item = &'a [T];
///
/// When the slice len is not evenly divided by the chunk size, the last slice
/// of the iteration will be the remainder.
-#[derive(Clone)]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Chunks<'a, T:'a> {
v: &'a [T],
size: usize
}
+// FIXME(#19839) Remove in favor of `#[derive(Clone)]`
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, T> Clone for Chunks<'a, T> {
+ fn clone(&self) -> Chunks<'a, T> {
+ Chunks {
+ v: self.v,
+ size: self.size,
+ }
+ }
+}
+
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T> Iterator for Chunks<'a, T> {
type Item = &'a [T];
/// Parse a `bool` from a string.
///
- /// Yields an `Option<bool>`, because `s` may or may not actually be
- /// parseable.
+ /// Yields a `Result<bool, ParseBoolError>`, because `s` may or may not
+ /// actually be parseable.
///
/// # Examples
///
/// ```rust
+ /// use std::str::FromStr;
+ ///
+ /// assert_eq!(FromStr::from_str("true"), Ok(true));
+ /// assert_eq!(FromStr::from_str("false"), Ok(false));
+ /// assert!(<bool as FromStr>::from_str("not even a boolean").is_err());
+ /// ```
+ ///
+ /// Note, in many cases, the StrExt::parse() which is based on
+ /// this FromStr::from_str() is more proper.
+ ///
+ /// ```rust
/// assert_eq!("true".parse(), Ok(true));
/// assert_eq!("false".parse(), Ok(false));
/// assert!("not even a boolean".parse::<bool>().is_err());
iter: slice::Iter<'a, u8>
}
-// Return the initial codepoint accumulator for the first byte.
-// The first byte is special, only want bottom 5 bits for width 2, 4 bits
-// for width 3, and 3 bits for width 4
-macro_rules! utf8_first_byte {
- ($byte:expr, $width:expr) => (($byte & (0x7F >> $width)) as u32)
-}
+/// Return the initial codepoint accumulator for the first byte.
+/// The first byte is special, only want bottom 5 bits for width 2, 4 bits
+/// for width 3, and 3 bits for width 4.
+#[inline]
+fn utf8_first_byte(byte: u8, width: u32) -> u32 { (byte & (0x7F >> width)) as u32 }
-// return the value of $ch updated with continuation byte $byte
-macro_rules! utf8_acc_cont_byte {
- ($ch:expr, $byte:expr) => (($ch << 6) | ($byte & CONT_MASK) as u32)
-}
+/// Return the value of `ch` updated with continuation byte `byte`.
+#[inline]
+fn utf8_acc_cont_byte(ch: u32, byte: u8) -> u32 { (ch << 6) | (byte & CONT_MASK) as u32 }
-macro_rules! utf8_is_cont_byte {
- ($byte:expr) => (($byte & !CONT_MASK) == TAG_CONT_U8)
-}
+/// Checks whether the byte is a UTF-8 continuation byte (i.e. starts with the
+/// bits `10`).
+#[inline]
+fn utf8_is_cont_byte(byte: u8) -> bool { (byte & !CONT_MASK) == TAG_CONT_U8 }
#[inline]
fn unwrap_or_0(opt: Option<&u8>) -> u8 {
// Multibyte case follows
// Decode from a byte combination out of: [[[x y] z] w]
// NOTE: Performance is sensitive to the exact formulation here
- let init = utf8_first_byte!(x, 2);
+ let init = utf8_first_byte(x, 2);
let y = unwrap_or_0(bytes.next());
- let mut ch = utf8_acc_cont_byte!(init, y);
+ let mut ch = utf8_acc_cont_byte(init, y);
if x >= 0xE0 {
// [[x y z] w] case
// 5th bit in 0xE0 .. 0xEF is always clear, so `init` is still valid
let z = unwrap_or_0(bytes.next());
- let y_z = utf8_acc_cont_byte!((y & CONT_MASK) as u32, z);
+ let y_z = utf8_acc_cont_byte((y & CONT_MASK) as u32, z);
ch = init << 12 | y_z;
if x >= 0xF0 {
// [x y z w] case
// use only the lower 3 bits of `init`
let w = unwrap_or_0(bytes.next());
- ch = (init & 7) << 18 | utf8_acc_cont_byte!(y_z, w);
+ ch = (init & 7) << 18 | utf8_acc_cont_byte(y_z, w);
}
}
// Decode from a byte combination out of: [x [y [z w]]]
let mut ch;
let z = unwrap_or_0(bytes.next_back());
- ch = utf8_first_byte!(z, 2);
- if utf8_is_cont_byte!(z) {
+ ch = utf8_first_byte(z, 2);
+ if utf8_is_cont_byte(z) {
let y = unwrap_or_0(bytes.next_back());
- ch = utf8_first_byte!(y, 3);
- if utf8_is_cont_byte!(y) {
+ ch = utf8_first_byte(y, 3);
+ if utf8_is_cont_byte(y) {
let x = unwrap_or_0(bytes.next_back());
- ch = utf8_first_byte!(x, 4);
- ch = utf8_acc_cont_byte!(ch, y);
+ ch = utf8_first_byte(x, 4);
+ ch = utf8_acc_cont_byte(ch, y);
}
- ch = utf8_acc_cont_byte!(ch, z);
+ ch = utf8_acc_cont_byte(ch, z);
}
- ch = utf8_acc_cont_byte!(ch, w);
+ ch = utf8_acc_cont_byte(ch, w);
Some(ch)
}
#[inline]
#[allow(dead_code)]
fn maximal_suffix(arr: &[u8], reversed: bool) -> (usize, usize) {
+ use num::wrapping::WrappingOps;
let mut left = -1; // Corresponds to i in the paper
let mut right = 0; // Corresponds to j in the paper
let mut offset = 1; // Corresponds to k in the paper
let a;
let b;
if reversed {
- a = arr[left + offset];
+ a = arr[left.wrapping_add(offset)];
b = arr[right + offset];
} else {
a = arr[right + offset];
- b = arr[left + offset];
+ b = arr[left.wrapping_add(offset)];
}
if a < b {
// Suffix is smaller, period is entire prefix so far.
right += offset;
offset = 1;
- period = right - left;
+ period = right.wrapping_sub(left);
} else if a == b {
// Advance through repetition of the current period.
if offset == period {
period = 1;
}
}
- (left + 1, period)
+ (left.wrapping_add(1), period)
}
}
#[unstable(feature = "core")]
#[deprecated(since = "1.0.0", reason = "use `Split` with a `&str`")]
pub struct SplitStr<'a, P: Pattern<'a>>(Split<'a, P>);
+#[allow(deprecated)]
impl<'a, P: Pattern<'a>> Iterator for SplitStr<'a, P> {
type Item = &'a str;
// ASCII characters are always valid, so only large
// bytes need more examination.
if first >= 128 {
- let w = UTF8_CHAR_WIDTH[first as usize] as usize;
+ let w = UTF8_CHAR_WIDTH[first as usize];
let second = next!();
// 2-byte encoding is for codepoints \u{0080} to \u{07ff}
// first C2 80 last DF BF
}
/// 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
fn split_terminator<'a, P: Pattern<'a>>(&'a self, pat: P) -> SplitTerminator<'a, P>;
fn rsplitn<'a, P: Pattern<'a>>(&'a self, count: usize, pat: P) -> RSplitN<'a, P>;
fn match_indices<'a, P: Pattern<'a>>(&'a self, pat: P) -> MatchIndices<'a, P>;
+ #[allow(deprecated) /* for SplitStr */]
fn split_str<'a, P: Pattern<'a>>(&'a self, pat: P) -> SplitStr<'a, P>;
fn lines<'a>(&'a self) -> Lines<'a>;
fn lines_any<'a>(&'a self) -> LinesAny<'a>;
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,
}
}
i -= 1;
}
- let mut val = s.as_bytes()[i] as u32;
- let w = UTF8_CHAR_WIDTH[val as usize] as usize;
- assert!((w != 0));
+ let first= s.as_bytes()[i];
+ let w = UTF8_CHAR_WIDTH[first as usize];
+ assert!(w != 0);
- val = utf8_first_byte!(val, w);
- val = utf8_acc_cont_byte!(val, s.as_bytes()[i + 1]);
- if w > 2 { val = utf8_acc_cont_byte!(val, s.as_bytes()[i + 2]); }
- if w > 3 { val = utf8_acc_cont_byte!(val, s.as_bytes()[i + 3]); }
+ let mut val = utf8_first_byte(first, w as u32);
+ val = utf8_acc_cont_byte(val, s.as_bytes()[i + 1]);
+ if w > 2 { val = utf8_acc_cont_byte(val, s.as_bytes()[i + 2]); }
+ if w > 3 { val = utf8_acc_cont_byte(val, s.as_bytes()[i + 3]); }
return CharRange {ch: unsafe { mem::transmute(val) }, next: i};
}
#[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);
}
// Multibyte case is a fn to allow char_range_at to inline cleanly
fn multibyte_char_range_at(bytes: &[u8], i: usize) -> (u32, usize) {
- let mut val = bytes[i] as u32;
- let w = UTF8_CHAR_WIDTH[val as usize] as usize;
- assert!((w != 0));
+ let first = bytes[i];
+ let w = UTF8_CHAR_WIDTH[first as usize];
+ assert!(w != 0);
- val = utf8_first_byte!(val, w);
- val = utf8_acc_cont_byte!(val, bytes[i + 1]);
- if w > 2 { val = utf8_acc_cont_byte!(val, bytes[i + 2]); }
- if w > 3 { val = utf8_acc_cont_byte!(val, bytes[i + 3]); }
+ let mut val = utf8_first_byte(first, w as u32);
+ val = utf8_acc_cont_byte(val, bytes[i + 1]);
+ if w > 2 { val = utf8_acc_cont_byte(val, bytes[i + 2]); }
+ if w > 3 { val = utf8_acc_cont_byte(val, bytes[i + 3]); }
- return (val, i + w);
+ return (val, i + w as usize);
}
multibyte_char_range_at(bytes, i)
#[test]
fn any_downcast_mut() {
let mut a = 5_usize;
- let mut b = box 7_usize;
+ let mut b: Box<_> = box 7_usize;
let a_r = &mut a as &mut Any;
let tmp: &mut uint = &mut *b;
}
#[test]
-#[should_fail]
+#[should_panic]
fn discard_doesnt_unborrow() {
let x = RefCell::new(0);
let _b = x.borrow();
#[test]
fn test_to_lowercase() {
- assert_eq!('A'.to_lowercase(), 'a');
- assert_eq!('Ö'.to_lowercase(), 'ö');
- assert_eq!('ß'.to_lowercase(), 'ß');
- assert_eq!('Ü'.to_lowercase(), 'ü');
- assert_eq!('💩'.to_lowercase(), '💩');
- assert_eq!('Σ'.to_lowercase(), 'σ');
- assert_eq!('Τ'.to_lowercase(), 'τ');
- assert_eq!('Ι'.to_lowercase(), 'ι');
- assert_eq!('Γ'.to_lowercase(), 'γ');
- assert_eq!('Μ'.to_lowercase(), 'μ');
- assert_eq!('Α'.to_lowercase(), 'α');
- assert_eq!('Σ'.to_lowercase(), 'σ');
+ fn lower(c: char) -> char {
+ let mut it = c.to_lowercase();
+ let c = it.next().unwrap();
+ assert!(it.next().is_none());
+ c
+ }
+ assert_eq!(lower('A'), 'a');
+ assert_eq!(lower('Ö'), 'ö');
+ assert_eq!(lower('ß'), 'ß');
+ assert_eq!(lower('Ü'), 'ü');
+ assert_eq!(lower('💩'), '💩');
+ assert_eq!(lower('Σ'), 'σ');
+ assert_eq!(lower('Τ'), 'τ');
+ assert_eq!(lower('Ι'), 'ι');
+ assert_eq!(lower('Γ'), 'γ');
+ assert_eq!(lower('Μ'), 'μ');
+ assert_eq!(lower('Α'), 'α');
+ assert_eq!(lower('Σ'), 'σ');
}
#[test]
fn test_to_uppercase() {
- assert_eq!('a'.to_uppercase(), 'A');
- assert_eq!('ö'.to_uppercase(), 'Ö');
- assert_eq!('ß'.to_uppercase(), 'ß'); // not ẞ: Latin capital letter sharp s
- assert_eq!('ü'.to_uppercase(), 'Ü');
- assert_eq!('💩'.to_uppercase(), '💩');
-
- assert_eq!('σ'.to_uppercase(), 'Σ');
- assert_eq!('τ'.to_uppercase(), 'Τ');
- assert_eq!('ι'.to_uppercase(), 'Ι');
- assert_eq!('γ'.to_uppercase(), 'Γ');
- assert_eq!('μ'.to_uppercase(), 'Μ');
- assert_eq!('α'.to_uppercase(), 'Α');
- assert_eq!('ς'.to_uppercase(), 'Σ');
+ fn upper(c: char) -> char {
+ let mut it = c.to_uppercase();
+ let c = it.next().unwrap();
+ assert!(it.next().is_none());
+ c
+ }
+ assert_eq!(upper('a'), 'A');
+ assert_eq!(upper('ö'), 'Ö');
+ assert_eq!(upper('ß'), 'ß'); // not ẞ: Latin capital letter sharp s
+ assert_eq!(upper('ü'), 'Ü');
+ assert_eq!(upper('💩'), '💩');
+
+ assert_eq!(upper('σ'), 'Σ');
+ assert_eq!(upper('τ'), 'Τ');
+ assert_eq!(upper('ι'), 'Ι');
+ assert_eq!(upper('γ'), 'Γ');
+ assert_eq!(upper('μ'), 'Μ');
+ assert_eq!(upper('α'), 'Α');
+ assert_eq!(upper('ς'), 'Σ');
}
#[test]
#[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);
}
#[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);
}
}
#[test]
-#[should_fail]
+#[should_panic]
fn test_fail() {
let mut i = 0;
try_finally(
}
#[test]
-#[should_fail]
+#[should_panic]
fn test_radix_base_too_large() {
let _ = radix(55, 37);
}
// 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);
- let cs: Box<[u8]> = box [1u8, 2u8, 3u8];
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ 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]>
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; }
}
[ 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);
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));
#[test]
fn test_all() {
- let v: Box<[int]> = box [1, 2, 3, 4, 5];
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let v: Box<[int]> = Box::new([1, 2, 3, 4, 5]);
assert!(v.iter().all(|&x| x < 10));
assert!(!v.iter().all(|&x| x % 2 == 0));
assert!(!v.iter().all(|&x| x > 100));
#[test]
fn test_any() {
- let v: Box<[int]> = box [1, 2, 3, 4, 5];
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let v: Box<[int]> = Box::new([1, 2, 3, 4, 5]);
assert!(v.iter().any(|&x| x < 10));
assert!(v.iter().any(|&x| x % 2 == 0));
assert!(!v.iter().any(|&x| x > 100));
}
#[test]
-#[should_fail]
+#[should_panic]
fn test_rposition_panic() {
- let v = [(box 0, box 0), (box 0, box 0),
- (box 0, box 0), (box 0, box 0)];
+ let v: [(Box<_>, Box<_>); 4] =
+ [(box 0, box 0), (box 0, box 0),
+ (box 0, box 0), (box 0, box 0)];
let mut i = 0;
v.iter().rposition(|_elt| {
if i == 2 {
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]
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]);
}
// 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)]
}
unsafe {
- assert_eq!([76u8], transmute::<_, Vec<u8>>("L".to_string()));
+ assert_eq!([76], transmute::<_, Vec<u8>>("L".to_string()));
}
}
assert!(-(0b11 as $T) - (1 as $T) == (0b11 as $T).not());
}
- static A: $T = 0b0101100;
- static B: $T = 0b0100001;
- static C: $T = 0b1111001;
+ const A: $T = 0b0101100;
+ const B: $T = 0b0100001;
+ const C: $T = 0b1111001;
- static _0: $T = 0;
- static _1: $T = !0;
+ const _0: $T = 0;
+ const _1: $T = !0;
#[test]
fn test_count_ones() {
#[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);
- i8_val += 1 as i8;
+ i8_val = i8_val.wrapping_add(1);
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);
- i16_val += 1 as i16;
+ i16_val = i16_val.wrapping_add(1);
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);
- i32_val += 1 as i32;
+ i32_val = i32_val.wrapping_add(1);
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);
- i64_val += 1 as i64;
+ i64_val = i64_val.wrapping_add(1);
assert_eq!("-9223372036854775808".parse::<i64>().ok(), Some(i64_val));
assert_eq!("-9223372036854775809".parse::<i64>().ok(), None);
}
assert!(MAX - (0b1011 as $T) == (0b1011 as $T).not());
}
- static A: $T = 0b0101100;
- static B: $T = 0b0100001;
- static C: $T = 0b1111001;
+ const A: $T = 0b0101100;
+ const B: $T = 0b0100001;
+ const C: $T = 0b1111001;
- static _0: $T = 0;
- static _1: $T = !0;
+ const _0: $T = 0;
+ const _1: $T = !0;
#[test]
fn test_count_ones() {
#[test]
fn test_get_ptr() {
unsafe {
- let x = box 0;
+ let x: Box<_> = box 0;
let addr_x: *const int = mem::transmute(&*x);
let opt = Some(x);
let y = opt.unwrap();
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();
}
#[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();
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;
}
#[test]
-#[should_fail]
+#[should_panic]
pub fn test_unwrap_or_else_panic() {
fn handler(msg: &'static str) -> int {
if msg == "I got this." {
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() {
//! [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]
-> *mut c_void;
}
-static LZ_NORM : c_int = 0x80; // LZ with 128 probes, "normal"
-static TINFL_FLAG_PARSE_ZLIB_HEADER : c_int = 0x1; // parse zlib header and adler32 checksum
-static TDEFL_WRITE_ZLIB_HEADER : c_int = 0x01000; // write zlib header and adler32 checksum
+const LZ_NORM: c_int = 0x80; // LZ with 128 probes, "normal"
+const TINFL_FLAG_PARSE_ZLIB_HEADER: c_int = 0x1; // parse zlib header and adler32 checksum
+const TDEFL_WRITE_ZLIB_HEADER: c_int = 0x01000; // write zlib header and adler32 checksum
fn deflate_bytes_internal(bytes: &[u8], flags: c_int) -> Option<Bytes> {
unsafe {
//! 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]
//!
//! fn print_usage(program: &str, opts: &[OptGroup]) {
//! let brief = format!("Usage: {} [options]", program);
-//! print!("{}", usage(brief.as_slice(), opts));
+//! print!("{}", usage(brief, opts));
//! }
//!
//! fn main() {
//! Err(f) => { panic!(f.to_string()) }
//! };
//! if matches.opt_present("h") {
-//! print_usage(program.as_slice(), opts);
+//! print_usage(program, opts);
//! return;
//! }
//! let output = matches.opt_str("o");
//! let input = if !matches.free.is_empty() {
//! matches.free[0].clone()
//! } else {
-//! print_usage(program.as_slice(), opts);
+//! print_usage(program, opts);
//! return;
//! };
-//! do_work(input.as_slice(), output);
+//! do_work(input, output);
//! }
//! ```
+
+// 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")]
#![feature(collections)]
#![feature(int_uint)]
#![feature(staged_api)]
+#![feature(core)]
#![feature(str_words)]
#![cfg_attr(test, feature(rustc_private))]
//! Each node label is derived directly from the int representing the node,
//! while the edge labels are all empty strings.
//!
-//! This example also illustrates how to use `CowVec` to return
+//! This example also illustrates how to use `Cow<[T]>` to return
//! an owned vector or a borrowed slice as appropriate: we construct the
//! node vector from scratch, but borrow the edge list (rather than
//! constructing a copy of all the edges from scratch).
//!
//! * [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)]
/// that is bound by the self lifetime `'a`.
///
/// The `nodes` and `edges` method each return instantiations of
-/// `CowVec` to leave implementers the freedom to create
+/// `Cow<[T]>` to leave implementers the freedom to create
/// entirely new vectors or to pass back slices into internally owned
/// vectors.
pub trait GraphWalk<'a, N, E> {
// 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/",
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;
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;
}
#[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};
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};
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;
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 {
}
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 {
}
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 {
}
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 {
}
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;
}
//! 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")]
/// ```
#[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.
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!())
})
use core::prelude::*;
use core::num::Int;
+use core::num::wrapping::WrappingOps;
use {Rng, SeedableRng, Rand};
const KEY_WORDS : uint = 8; // 8 words for the 256-bit key
macro_rules! quarter_round{
($a: expr, $b: expr, $c: expr, $d: expr) => {{
- $a += $b; $d ^= $a; $d = $d.rotate_left(16);
- $c += $d; $b ^= $c; $b = $b.rotate_left(12);
- $a += $b; $d ^= $a; $d = $d.rotate_left( 8);
- $c += $d; $b ^= $c; $b = $b.rotate_left( 7);
+ $a = $a.wrapping_add($b); $d = $d ^ $a; $d = $d.rotate_left(16);
+ $c = $c.wrapping_add($d); $b = $b ^ $c; $b = $b.rotate_left(12);
+ $a = $a.wrapping_add($b); $d = $d ^ $a; $d = $d.rotate_left( 8);
+ $c = $c.wrapping_add($d); $b = $b ^ $c; $b = $b.rotate_left( 7);
}}
}
}
for i in 0..STATE_WORDS {
- output[i] += input[i];
+ output[i] = output[i].wrapping_add(input[i]);
}
}
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()) {
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<_>>();
#[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 {
}
}
#[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);
}
}
}
#[test]
- #[should_fail]
+ #[should_panic]
fn test_chi_squared_invalid_dof() {
ChiSquared::new(-1.0);
}
mut pdf: P,
mut zero_case: Z)
-> f64 where P: FnMut(f64) -> f64, Z: FnMut(&mut R, f64) -> f64 {
- static SCALE: f64 = (1u64 << 53) as f64;
+ const SCALE: f64 = (1u64 << 53) as f64;
loop {
// reimplement the f64 generation as an optimisation suggested
// by the Doornik paper: we have a lot of precision-space
[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 },
}
}
#[test]
- #[should_fail]
+ #[should_panic]
fn test_normal_invalid_sd() {
Normal::new(10.0, -1.0);
}
}
}
#[test]
- #[should_fail]
+ #[should_panic]
fn test_log_normal_invalid_sd() {
LogNormal::new(10.0, -1.0);
}
use core::prelude::{PartialOrd};
use core::num::Int;
+use core::num::wrapping::WrappingOps;
use Rng;
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.
///
// bijection.
fn construct_range(low: $ty, high: $ty) -> Range<$ty> {
- let range = high as $unsigned - low as $unsigned;
+ let range = (high as $unsigned).wrapping_sub(low as $unsigned);
let unsigned_max: $unsigned = Int::max_value();
// this is the largest number that fits into $unsigned
// be uniformly distributed)
if v < r.accept_zone as $unsigned {
// and return it, with some adjustments
- return r.low + (v % r.range as $unsigned) as $ty;
+ return r.low.wrapping_add((v % r.range as $unsigned) as $ty);
}
}
}
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);
//! 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 as w;
use {Rng, SeedableRng, Rand};
-const RAND_SIZE_LEN: u32 = 8;
-const RAND_SIZE: u32 = 1 << (RAND_SIZE_LEN as uint);
-const RAND_SIZE_UINT: uint = 1 << (RAND_SIZE_LEN as uint);
+type w32 = w<u32>;
+type w64 = w<u64>;
+
+const RAND_SIZE_LEN: usize = 8;
+const RAND_SIZE: u32 = 1 << RAND_SIZE_LEN;
+const RAND_SIZE_USIZE: usize = 1 << RAND_SIZE_LEN;
/// A random number generator that uses the ISAAC algorithm[1].
///
#[derive(Copy)]
pub struct IsaacRng {
cnt: u32,
- rsl: [u32; RAND_SIZE_UINT],
- mem: [u32; RAND_SIZE_UINT],
- a: u32,
- b: u32,
- c: u32
+ rsl: [w32; RAND_SIZE_USIZE],
+ mem: [w32; RAND_SIZE_USIZE],
+ a: w32,
+ b: w32,
+ c: w32,
}
static EMPTY: IsaacRng = IsaacRng {
cnt: 0,
- rsl: [0; RAND_SIZE_UINT],
- mem: [0; RAND_SIZE_UINT],
- a: 0, b: 0, c: 0
+ rsl: [w(0); RAND_SIZE_USIZE],
+ mem: [w(0); RAND_SIZE_USIZE],
+ a: w(0), b: w(0), c: w(0),
};
impl IsaacRng {
/// of `rsl` as a seed, otherwise construct one algorithmically (not
/// randomly).
fn init(&mut self, use_rsl: bool) {
- let mut a = 0x9e3779b9;
+ let mut a = w(0x9e3779b9);
let mut b = a;
let mut c = a;
let mut d = a;
macro_rules! mix {
() => {{
- a^=b<<11; d+=a; b+=c;
- b^=c>>2; e+=b; c+=d;
- c^=d<<8; f+=c; d+=e;
- d^=e>>16; g+=d; e+=f;
- e^=f<<10; h+=e; f+=g;
- f^=g>>4; a+=f; g+=h;
- g^=h<<8; b+=g; h+=a;
- h^=a>>9; c+=h; a+=b;
+ a=a^(b<<11); d=d+a; b=b+c;
+ b=b^(c>>2); e=e+b; c=c+d;
+ c=c^(d<<8); f=f+c; d=d+e;
+ d=d^(e>>16); g=g+d; e=e+f;
+ e=e^(f<<10); h=h+e; f=f+g;
+ f=f^(g>>4); a=a+f; g=g+h;
+ g=g^(h<<8); b=b+g; h=h+a;
+ h=h^(a>>9); c=c+h; a=a+b;
}}
}
if use_rsl {
macro_rules! memloop {
($arr:expr) => {{
- for i in range_step(0, RAND_SIZE as uint, 8) {
- a+=$arr[i ]; b+=$arr[i+1];
- c+=$arr[i+2]; d+=$arr[i+3];
- e+=$arr[i+4]; f+=$arr[i+5];
- g+=$arr[i+6]; h+=$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; self.mem[i+1]=b;
self.mem[i+2]=c; self.mem[i+3]=d;
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; self.mem[i+1]=b;
self.mem[i+2]=c; self.mem[i+3]=d;
#[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;
- static MIDPOINT: uint = (RAND_SIZE / 2) as uint;
+ const MIDPOINT: usize = RAND_SIZE_USIZE / 2;
macro_rules! ind {
- ($x:expr) => ( 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 = (a ^ mix) + self.mem[base + m2_offset];
let y = ind!(x) + a + b;
self.mem[base + mr_offset] = y;
- b = ind!(y >> RAND_SIZE_LEN as uint) + x;
+ b = ind!(y >> RAND_SIZE_LEN) + x;
self.rsl[base + mr_offset] = b;
}}
}
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 = (a ^ mix) + self.mem[base + m2_offset];
let y = ind!(x) + a + b;
self.mem[base + mr_offset] = y;
- b = ind!(y >> RAND_SIZE_LEN as uint) + x;
+ b = ind!(y >> RAND_SIZE_LEN) + x;
self.rsl[base + mr_offset] = b;
}}
}
// (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
}
}
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);
}
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.
/// 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 {
fn init(&mut self, use_rsl: bool) {
macro_rules! init {
($var:ident) => (
- let mut $var = 0x9e3779b97f4a7c13;
+ let mut $var = w(0x9e3779b97f4a7c13);
)
}
init!(a); init!(b); init!(c); init!(d);
macro_rules! mix {
() => {{
- a-=e; f^=h>>9; h+=a;
- b-=f; g^=a<<9; a+=b;
- c-=g; h^=b>>23; b+=c;
- d-=h; a^=c<<15; c+=d;
- e-=a; b^=d>>14; d+=e;
- f-=b; c^=e<<20; e+=f;
- g-=c; d^=f>>17; f+=g;
- h-=d; e^=g<<14; 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;
}}
}
macro_rules! memloop {
($arr:expr) => {{
for i in (0..RAND_SIZE_64 / 8).map(|i| i * 8) {
- a+=$arr[i ]; b+=$arr[i+1];
- c+=$arr[i+2]; d+=$arr[i+3];
- e+=$arr[i+4]; f+=$arr[i+5];
- g+=$arr[i+6]; h+=$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; self.mem[i+1]=b;
self.mem[i+2]=c; self.mem[i+3]=d;
/// Refills the output buffer (`self.rsl`)
fn isaac64(&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_64 / 2;
- const MP_VEC: [(uint, uint); 2] = [(0,MIDPOINT), (MIDPOINT, 0)];
+ 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 {
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 {
// 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
}
}
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);
}
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;
#[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)));
}
#[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);
#[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);
//! 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",
use distributions::range::SampleRange;
#[cfg(test)]
-static RAND_BENCH_N: u64 = 100;
+const RAND_BENCH_N: u64 = 100;
pub mod distributions;
pub mod isaac;
/// ```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());
/// ```
type Item = char;
fn next(&mut self) -> Option<char> {
- static GEN_ASCII_STR_CHARSET: &'static [u8] =
+ const GEN_ASCII_STR_CHARSET: &'static [u8] =
b"ABCDEFGHIJKLMNOPQRSTUVWXYZ\
abcdefghijklmnopqrstuvwxyz\
0123456789";
#[inline]
fn rand<R: Rng>(rng: &mut R) -> char {
// a char is 21 bits
- static CHAR_MASK: u32 = 0x001f_ffff;
+ const CHAR_MASK: u32 = 0x001f_ffff;
loop {
// Rejection sampling. About 0.2% of numbers with at most
// 21-bits are invalid codepoints (surrogates), so this
#[cfg(test)]
mod tests {
- use std::prelude::v1::*;
use std::rand::{Rng, thread_rng, Open01, Closed01};
struct ConstantRng(u64);
/// How many bytes of entropy the underling RNG is allowed to generate
/// before it is reseeded.
-static DEFAULT_GENERATION_THRESHOLD: uint = 32 * 1024;
+const DEFAULT_GENERATION_THRESHOLD: uint = 32 * 1024;
/// A wrapper around any RNG which reseeds the underlying RNG after it
/// has generated a certain number of random bytes.
assert_eq!(string1, string2);
}
- static FILL_BYTES_V_LEN: uint = 13579;
+ 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
use std::slice;
use std::iter::repeat;
-static BUF_CAPACITY: uint = 128;
+const BUF_CAPACITY: uint = 128;
fn combine(seek: SeekStyle, cur: uint, end: uint, offset: i64) -> IoResult<u64> {
// compute offset as signed and clamp to prevent overflow
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);
}
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]
b.iter(|| {
let mut wr = SeekableMemWriter::new();
for _ in 0..times {
- wr.write(&src).unwrap();
+ wr.write_all(&src).unwrap();
}
let v = wr.unwrap();
-// 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.
//
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-//! Really Bad Markup Language (rbml) is a temporary measure until we migrate
-//! the rust object metadata to a better serialization format. It is not
-//! intended to be used by users.
+//! Really Bad Markup Language (rbml) is an internal serialization format of rustc.
+//! This is not intended to be used by users.
//!
-//! It is loosely based on the Extensible Binary Markup Language (ebml):
-//! http://www.matroska.org/technical/specs/rfc/index.html
+//! Originally based on the Extensible Binary Markup Language
+//! (ebml; http://www.matroska.org/technical/specs/rfc/index.html),
+//! it is now a separate format tuned for the rust object metadata.
+//!
+//! # Encoding
+//!
+//! RBML document consists of the tag, length and data.
+//! The encoded data can contain multiple RBML documents concatenated.
+//!
+//! **Tags** are a hint for the following data.
+//! Tags are a number from 0x000 to 0xfff, where 0xf0 through 0xff is reserved.
+//! Tags less than 0xf0 are encoded in one literal byte.
+//! Tags greater than 0xff are encoded in two big-endian bytes,
+//! where the tag number is ORed with 0xf000. (E.g. tag 0x123 = `f1 23`)
+//!
+//! **Lengths** encode the length of the following data.
+//! It is a variable-length unsigned int, and one of the following forms:
+//!
+//! - `80` through `fe` for lengths up to 0x7e;
+//! - `40 ff` through `7f ff` for lengths up to 0x3fff;
+//! - `20 40 00` through `3f ff ff` for lengths up to 0x1fffff;
+//! - `10 20 00 00` through `1f ff ff ff` for lengths up to 0xfffffff.
+//!
+//! The "overlong" form is allowed so that the length can be encoded
+//! without the prior knowledge of the encoded data.
+//! For example, the length 0 can be represented either by `80`, `40 00`,
+//! `20 00 00` or `10 00 00 00`.
+//! The encoder tries to minimize the length if possible.
+//! Also, some predefined tags listed below are so commonly used that
+//! their lengths are omitted ("implicit length").
+//!
+//! **Data** can be either binary bytes or zero or more nested RBML documents.
+//! Nested documents cannot overflow, and should be entirely contained
+//! within a parent document.
+//!
+//! # Predefined Tags
+//!
+//! Most RBML tags are defined by the application.
+//! (For the rust object metadata, see also `rustc::metadata::common`.)
+//! RBML itself does define a set of predefined tags however,
+//! intended for the auto-serialization implementation.
+//!
+//! Predefined tags with an implicit length:
+//!
+//! - `U8` (`00`): 1-byte unsigned integer.
+//! - `U16` (`01`): 2-byte big endian unsigned integer.
+//! - `U32` (`02`): 4-byte big endian unsigned integer.
+//! - `U64` (`03`): 8-byte big endian unsigned integer.
+//! Any of `U*` tags can be used to encode primitive unsigned integer types,
+//! as long as it is no greater than the actual size.
+//! For example, `u8` can only be represented via the `U8` tag.
+//!
+//! - `I8` (`04`): 1-byte signed integer.
+//! - `I16` (`05`): 2-byte big endian signed integer.
+//! - `I32` (`06`): 4-byte big endian signed integer.
+//! - `I64` (`07`): 8-byte big endian signed integer.
+//! Similar to `U*` tags. Always uses two's complement encoding.
+//!
+//! - `Bool` (`08`): 1-byte boolean value, `00` for false and `01` for true.
+//!
+//! - `Char` (`09`): 4-byte big endian Unicode scalar value.
+//! Surrogate pairs or out-of-bound values are invalid.
+//!
+//! - `F32` (`0a`): 4-byte big endian unsigned integer representing
+//! IEEE 754 binary32 floating-point format.
+//! - `F64` (`0b`): 8-byte big endian unsigned integer representing
+//! IEEE 754 binary64 floating-point format.
+//!
+//! - `Sub8` (`0c`): 1-byte unsigned integer for supplementary information.
+//! - `Sub32` (`0d`): 4-byte unsigned integer for supplementary information.
+//! Those two tags normally occur as the first subdocument of certain tags,
+//! namely `Enum`, `Vec` and `Map`, to provide a variant or size information.
+//! They can be used interchangably.
+//!
+//! Predefined tags with an explicit length:
+//!
+//! - `Str` (`10`): A UTF-8-encoded string.
+//!
+//! - `Enum` (`11`): An enum.
+//! The first subdocument should be `Sub*` tags with a variant ID.
+//! Subsequent subdocuments, if any, encode variant arguments.
+//!
+//! - `Vec` (`12`): A vector (sequence).
+//! - `VecElt` (`13`): A vector element.
+//! The first subdocument should be `Sub*` tags with the number of elements.
+//! Subsequent subdocuments should be `VecElt` tag per each element.
+//!
+//! - `Map` (`14`): A map (associated array).
+//! - `MapKey` (`15`): A key part of the map entry.
+//! - `MapVal` (`16`): A value part of the map entry.
+//! The first subdocument should be `Sub*` tags with the number of entries.
+//! Subsequent subdocuments should be an alternating sequence of
+//! `MapKey` and `MapVal` tags per each entry.
+//!
+//! - `Opaque` (`17`): An opaque, custom-format tag.
+//! Used to wrap ordinary custom tags or data in the auto-serialized context.
+//! Rustc typically uses this to encode type informations.
+//!
+//! 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]
reader::get_doc(*self, tag)
}
+ pub fn is_empty(&self) -> bool {
+ self.start == self.end
+ }
+
pub fn as_str_slice<'a>(&'a self) -> &'a str {
str::from_utf8(&self.data[self.start..self.end]).unwrap()
}
#[derive(Copy, Debug)]
pub enum EbmlEncoderTag {
- EsUint, // 0
- EsU64, // 1
- EsU32, // 2
- EsU16, // 3
- EsU8, // 4
- EsInt, // 5
- EsI64, // 6
- EsI32, // 7
- EsI16, // 8
- EsI8, // 9
- EsBool, // 10
- EsChar, // 11
- EsStr, // 12
- EsF64, // 13
- EsF32, // 14
- EsFloat, // 15
- EsEnum, // 16
- EsEnumVid, // 17
- EsEnumBody, // 18
- EsVec, // 19
- EsVecLen, // 20
- EsVecElt, // 21
- EsMap, // 22
- EsMapLen, // 23
- EsMapKey, // 24
- EsMapVal, // 25
-
- EsOpaque,
-
- EsLabel, // Used only when debugging
+ // tags 00..1f are reserved for auto-serialization.
+ // first NUM_IMPLICIT_TAGS tags are implicitly sized and lengths are not encoded.
+
+ EsU8 = 0x00, // + 1 byte
+ EsU16 = 0x01, // + 2 bytes
+ EsU32 = 0x02, // + 4 bytes
+ EsU64 = 0x03, // + 8 bytes
+ EsI8 = 0x04, // + 1 byte
+ EsI16 = 0x05, // + 2 bytes
+ EsI32 = 0x06, // + 4 bytes
+ EsI64 = 0x07, // + 8 bytes
+ EsBool = 0x08, // + 1 byte
+ EsChar = 0x09, // + 4 bytes
+ EsF32 = 0x0a, // + 4 bytes
+ EsF64 = 0x0b, // + 8 bytes
+ EsSub8 = 0x0c, // + 1 byte
+ EsSub32 = 0x0d, // + 4 bytes
+ // 0x0e and 0x0f are reserved
+
+ EsStr = 0x10,
+ EsEnum = 0x11, // encodes the variant id as the first EsSub*
+ EsVec = 0x12, // encodes the # of elements as the first EsSub*
+ EsVecElt = 0x13,
+ EsMap = 0x14, // encodes the # of pairs as the first EsSub*
+ EsMapKey = 0x15,
+ EsMapVal = 0x16,
+ EsOpaque = 0x17,
}
+const NUM_TAGS: uint = 0x1000;
+const NUM_IMPLICIT_TAGS: uint = 0x0e;
+
+static TAG_IMPLICIT_LEN: [i8; NUM_IMPLICIT_TAGS] = [
+ 1, 2, 4, 8, // EsU*
+ 1, 2, 4, 8, // ESI*
+ 1, // EsBool
+ 4, // EsChar
+ 4, 8, // EsF*
+ 1, 4, // EsSub*
+];
+
#[derive(Debug)]
pub enum Error {
IntTooBig(uint),
+ InvalidTag(uint),
Expected(String),
IoError(std::old_io::IoError),
ApplicationError(String)
use serialize;
- use super::{ ApplicationError, EsVec, EsMap, EsEnum, EsVecLen, EsVecElt,
- EsMapLen, EsMapKey, EsEnumVid, EsU64, EsU32, EsU16, EsU8, EsInt, EsI64,
+ use super::{ ApplicationError, EsVec, EsMap, EsEnum, EsSub8, EsSub32,
+ EsVecElt, EsMapKey, EsU64, EsU32, EsU16, EsU8, EsI64,
EsI32, EsI16, EsI8, EsBool, EsF64, EsF32, EsChar, EsStr, EsMapVal,
- EsEnumBody, EsUint, EsOpaque, EsLabel, EbmlEncoderTag, Doc, TaggedDoc,
- Error, IntTooBig, Expected };
+ EsOpaque, EbmlEncoderTag, Doc, TaggedDoc,
+ Error, IntTooBig, InvalidTag, Expected, NUM_IMPLICIT_TAGS, TAG_IMPLICIT_LEN };
pub type DecodeResult<T> = Result<T, Error>;
// rbml reading
pub next: uint
}
+ pub fn tag_at(data: &[u8], start: uint) -> DecodeResult<Res> {
+ let v = data[start] as uint;
+ if v < 0xf0 {
+ Ok(Res { val: v, next: start + 1 })
+ } else if v > 0xf0 {
+ Ok(Res { val: ((v & 0xf) << 8) | data[start + 1] as uint, next: start + 2 })
+ } else {
+ // every tag starting with byte 0xf0 is an overlong form, which is prohibited.
+ Err(InvalidTag(v))
+ }
+ }
+
#[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),
}
}
+ pub fn tag_len_at(data: &[u8], tag: Res) -> DecodeResult<Res> {
+ if tag.val < NUM_IMPLICIT_TAGS && TAG_IMPLICIT_LEN[tag.val] >= 0 {
+ Ok(Res { val: TAG_IMPLICIT_LEN[tag.val] as uint, next: tag.next })
+ } else {
+ vuint_at(data, tag.next)
+ }
+ }
+
pub fn doc_at<'a>(data: &'a [u8], start: uint) -> DecodeResult<TaggedDoc<'a>> {
- let elt_tag = try!(vuint_at(data, start));
- let elt_size = try!(vuint_at(data, elt_tag.next));
+ let elt_tag = try!(tag_at(data, start));
+ let elt_size = try!(tag_len_at(data, elt_tag));
let end = elt_size.next + elt_size.val;
Ok(TaggedDoc {
tag: elt_tag.val,
pub fn maybe_get_doc<'a>(d: Doc<'a>, tg: uint) -> Option<Doc<'a>> {
let mut pos = d.start;
while pos < d.end {
- let elt_tag = try_or!(vuint_at(d.data, pos), None);
- let elt_size = try_or!(vuint_at(d.data, elt_tag.next), None);
+ let elt_tag = try_or!(tag_at(d.data, pos), None);
+ let elt_size = try_or!(tag_len_at(d.data, elt_tag), None);
pos = elt_size.next + elt_size.val;
if elt_tag.val == tg {
return Some(Doc { data: d.data, start: elt_size.next,
{
let mut pos = d.start;
while pos < d.end {
- let elt_tag = try_or!(vuint_at(d.data, pos), false);
- let elt_size = try_or!(vuint_at(d.data, elt_tag.next), false);
+ let elt_tag = try_or!(tag_at(d.data, pos), false);
+ let elt_size = try_or!(tag_len_at(d.data, elt_tag), false);
pos = elt_size.next + elt_size.val;
let doc = Doc { data: d.data, start: elt_size.next, end: pos };
if !it(elt_tag.val, doc) {
{
let mut pos = d.start;
while pos < d.end {
- let elt_tag = try_or!(vuint_at(d.data, pos), false);
- let elt_size = try_or!(vuint_at(d.data, elt_tag.next), false);
+ let elt_tag = try_or!(tag_at(d.data, pos), false);
+ let elt_size = try_or!(tag_len_at(d.data, elt_tag), false);
pos = elt_size.next + elt_size.val;
if elt_tag.val == tg {
let doc = Doc { data: d.data, start: elt_size.next,
}
}
- fn _check_label(&mut self, lbl: &str) -> DecodeResult<()> {
- if self.pos < self.parent.end {
- let TaggedDoc { tag: r_tag, doc: r_doc } =
- try!(doc_at(self.parent.data, self.pos));
-
- if r_tag == (EsLabel as uint) {
- self.pos = r_doc.end;
- let str = r_doc.as_str_slice();
- if lbl != str {
- return Err(Expected(format!("Expected label {:?} but \
- found {:?}", lbl, str)));
- }
- }
- }
- Ok(())
- }
-
fn next_doc(&mut self, exp_tag: EbmlEncoderTag) -> DecodeResult<Doc<'doc>> {
debug!(". next_doc(exp_tag={:?})", exp_tag);
if self.pos >= self.parent.end {
Ok(r)
}
- fn _next_uint(&mut self, exp_tag: EbmlEncoderTag) -> DecodeResult<uint> {
- let r = doc_as_u32(try!(self.next_doc(exp_tag)));
- debug!("_next_uint exp_tag={:?} result={:?}", exp_tag, r);
- Ok(r as uint)
+ fn _next_sub(&mut self) -> DecodeResult<uint> {
+ // empty vector/map optimization
+ if self.parent.is_empty() {
+ return Ok(0);
+ }
+
+ let TaggedDoc { tag: r_tag, doc: r_doc } =
+ try!(doc_at(self.parent.data, self.pos));
+ let r = if r_tag == (EsSub8 as uint) {
+ doc_as_u8(r_doc) as uint
+ } else if r_tag == (EsSub32 as uint) {
+ doc_as_u32(r_doc) as uint
+ } else {
+ return Err(Expected(format!("expected EBML doc with tag {:?} or {:?} but \
+ found tag {:?}", EsSub8, EsSub32, r_tag)));
+ };
+ if r_doc.end > self.parent.end {
+ return Err(Expected(format!("invalid EBML, child extends to \
+ {:#x}, parent to {:#x}",
+ r_doc.end, self.parent.end)));
+ }
+ self.pos = r_doc.end;
+ debug!("_next_sub result={:?}", r);
+ Ok(r)
+ }
+
+ // variable-length unsigned integer with different tags.
+ // `first_tag` should be a tag for u8 or i8.
+ // `last_tag` should be the largest allowed integer tag with the matching signedness.
+ // all tags between them should be valid, in the order of u8, u16, u32 and u64.
+ fn _next_int(&mut self,
+ first_tag: EbmlEncoderTag,
+ last_tag: EbmlEncoderTag) -> DecodeResult<u64> {
+ if self.pos >= self.parent.end {
+ return Err(Expected(format!("no more documents in \
+ current node!")));
+ }
+
+ let TaggedDoc { tag: r_tag, doc: r_doc } =
+ try!(doc_at(self.parent.data, self.pos));
+ let r = if first_tag as uint <= r_tag && r_tag <= last_tag as uint {
+ match r_tag - first_tag as uint {
+ 0 => doc_as_u8(r_doc) as u64,
+ 1 => doc_as_u16(r_doc) as u64,
+ 2 => doc_as_u32(r_doc) as u64,
+ 3 => doc_as_u64(r_doc) as u64,
+ _ => unreachable!(),
+ }
+ } else {
+ return Err(Expected(format!("expected EBML doc with tag {:?} through {:?} but \
+ found tag {:?}", first_tag, last_tag, r_tag)));
+ };
+ if r_doc.end > self.parent.end {
+ return Err(Expected(format!("invalid EBML, child extends to \
+ {:#x}, parent to {:#x}",
+ r_doc.end, self.parent.end)));
+ }
+ self.pos = r_doc.end;
+ debug!("_next_int({:?}, {:?}) result={:?}", first_tag, last_tag, r);
+ Ok(r)
}
pub fn read_opaque<R, F>(&mut self, op: F) -> DecodeResult<R> where
type Error = Error;
fn read_nil(&mut self) -> DecodeResult<()> { Ok(()) }
- fn read_u64(&mut self) -> DecodeResult<u64> { Ok(doc_as_u64(try!(self.next_doc(EsU64)))) }
- fn read_u32(&mut self) -> DecodeResult<u32> { Ok(doc_as_u32(try!(self.next_doc(EsU32)))) }
- fn read_u16(&mut self) -> DecodeResult<u16> { Ok(doc_as_u16(try!(self.next_doc(EsU16)))) }
- fn read_u8 (&mut self) -> DecodeResult<u8 > { Ok(doc_as_u8 (try!(self.next_doc(EsU8 )))) }
+ fn read_u64(&mut self) -> DecodeResult<u64> { self._next_int(EsU8, EsU64) }
+ fn read_u32(&mut self) -> DecodeResult<u32> { Ok(try!(self._next_int(EsU8, EsU32)) as u32) }
+ fn read_u16(&mut self) -> DecodeResult<u16> { Ok(try!(self._next_int(EsU8, EsU16)) as u16) }
+ fn read_u8(&mut self) -> DecodeResult<u8> { Ok(doc_as_u8(try!(self.next_doc(EsU8)))) }
fn read_uint(&mut self) -> DecodeResult<uint> {
- let v = doc_as_u64(try!(self.next_doc(EsUint)));
+ let v = try!(self._next_int(EsU8, EsU64));
if v > (::std::usize::MAX as u64) {
Err(IntTooBig(v as uint))
} else {
}
}
- fn read_i64(&mut self) -> DecodeResult<i64> {
- Ok(doc_as_u64(try!(self.next_doc(EsI64))) as i64)
- }
- fn read_i32(&mut self) -> DecodeResult<i32> {
- Ok(doc_as_u32(try!(self.next_doc(EsI32))) as i32)
- }
- fn read_i16(&mut self) -> DecodeResult<i16> {
- Ok(doc_as_u16(try!(self.next_doc(EsI16))) as i16)
- }
- fn read_i8 (&mut self) -> DecodeResult<i8> {
- Ok(doc_as_u8(try!(self.next_doc(EsI8 ))) as i8)
- }
+ fn read_i64(&mut self) -> DecodeResult<i64> { Ok(try!(self._next_int(EsI8, EsI64)) as i64) }
+ fn read_i32(&mut self) -> DecodeResult<i32> { Ok(try!(self._next_int(EsI8, EsI32)) as i32) }
+ fn read_i16(&mut self) -> DecodeResult<i16> { Ok(try!(self._next_int(EsI8, EsI16)) as i16) }
+ fn read_i8(&mut self) -> DecodeResult<i8> { Ok(doc_as_u8(try!(self.next_doc(EsI8))) as i8) }
fn read_int(&mut self) -> DecodeResult<int> {
- let v = doc_as_u64(try!(self.next_doc(EsInt))) as i64;
+ let v = try!(self._next_int(EsI8, EsI64)) as i64;
if v > (isize::MAX as i64) || v < (isize::MIN as i64) {
debug!("FIXME \\#6122: Removing this makes this function miscompile");
Err(IntTooBig(v as uint))
F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
{
debug!("read_enum({})", name);
- try!(self._check_label(name));
let doc = try!(self.next_doc(EsEnum));
where F: FnMut(&mut Decoder<'doc>, uint) -> DecodeResult<T>,
{
debug!("read_enum_variant()");
- let idx = try!(self._next_uint(EsEnumVid));
+ let idx = try!(self._next_sub());
debug!(" idx={}", idx);
- let doc = try!(self.next_doc(EsEnumBody));
-
- let (old_parent, old_pos) = (self.parent, self.pos);
- self.parent = doc;
- self.pos = self.parent.start;
-
- let result = try!(f(self, idx));
-
- self.parent = old_parent;
- self.pos = old_pos;
- Ok(result)
+ f(self, idx)
}
fn read_enum_variant_arg<T, F>(&mut self, idx: uint, f: F) -> DecodeResult<T> where
where F: FnMut(&mut Decoder<'doc>, uint) -> DecodeResult<T>,
{
debug!("read_enum_struct_variant()");
- let idx = try!(self._next_uint(EsEnumVid));
+ let idx = try!(self._next_sub());
debug!(" idx={}", idx);
- let doc = try!(self.next_doc(EsEnumBody));
-
- let (old_parent, old_pos) = (self.parent, self.pos);
- self.parent = doc;
- self.pos = self.parent.start;
-
- let result = try!(f(self, idx));
-
- self.parent = old_parent;
- self.pos = old_pos;
- Ok(result)
+ f(self, idx)
}
fn read_enum_struct_variant_field<T, F>(&mut self,
F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
{
debug!("read_struct_field(name={}, idx={})", name, idx);
- try!(self._check_label(name));
f(self)
}
{
debug!("read_seq()");
self.push_doc(EsVec, move |d| {
- let len = try!(d._next_uint(EsVecLen));
+ let len = try!(d._next_sub());
debug!(" len={}", len);
f(d, len)
})
{
debug!("read_map()");
self.push_doc(EsMap, move |d| {
- let len = try!(d._next_uint(EsMapLen));
+ let len = try!(d._next_sub());
debug!(" len={}", len);
f(d, len)
})
use std::num::Int;
use std::old_io::{Writer, Seek};
use std::old_io;
+ use std::slice::bytes;
+ use std::num::ToPrimitive;
- use super::{ EsVec, EsMap, EsEnum, EsVecLen, EsVecElt, EsMapLen, EsMapKey,
- EsEnumVid, EsU64, EsU32, EsU16, EsU8, EsInt, EsI64, EsI32, EsI16, EsI8,
- EsBool, EsF64, EsF32, EsChar, EsStr, EsMapVal, EsEnumBody, EsUint,
- EsOpaque, EsLabel, EbmlEncoderTag };
+ use super::{ EsVec, EsMap, EsEnum, EsSub8, EsSub32, EsVecElt, EsMapKey,
+ EsU64, EsU32, EsU16, EsU8, EsI64, EsI32, EsI16, EsI8,
+ EsBool, EsF64, EsF32, EsChar, EsStr, EsMapVal,
+ EsOpaque, NUM_IMPLICIT_TAGS, NUM_TAGS };
+ use super::io::SeekableMemWriter;
use serialize;
pub type EncodeResult = old_io::IoResult<()>;
// rbml writing
- pub struct Encoder<'a, W:'a> {
- pub writer: &'a mut W,
+ pub struct Encoder<'a> {
+ pub writer: &'a mut SeekableMemWriter,
size_positions: Vec<uint>,
+ relax_limit: u64, // do not move encoded bytes before this position
+ }
+
+ fn write_tag<W: Writer>(w: &mut W, n: uint) -> EncodeResult {
+ if n < 0xf0 {
+ w.write_all(&[n as u8])
+ } else if 0x100 <= n && n < NUM_TAGS {
+ w.write_all(&[0xf0 | (n >> 8) as u8, n as u8])
+ } else {
+ Err(old_io::IoError {
+ kind: old_io::OtherIoError,
+ desc: "invalid tag",
+ detail: Some(format!("{}", n))
+ })
+ }
}
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,
})
}
- impl<'a, W: Writer + Seek> Encoder<'a, W> {
- pub fn new(w: &'a mut W) -> Encoder<'a, W> {
+ impl<'a> Encoder<'a> {
+ pub fn new(w: &'a mut SeekableMemWriter) -> Encoder<'a> {
Encoder {
writer: w,
size_positions: vec!(),
+ relax_limit: 0,
}
}
/// FIXME(pcwalton): Workaround for badness in trans. DO NOT USE ME.
- pub unsafe fn unsafe_clone(&self) -> Encoder<'a, W> {
+ pub unsafe fn unsafe_clone(&self) -> Encoder<'a> {
Encoder {
writer: mem::transmute_copy(&self.writer),
size_positions: self.size_positions.clone(),
+ relax_limit: self.relax_limit,
}
}
pub fn start_tag(&mut self, tag_id: uint) -> EncodeResult {
debug!("Start tag {:?}", tag_id);
+ assert!(tag_id >= NUM_IMPLICIT_TAGS);
// Write the enum ID:
- try!(write_vuint(self.writer, tag_id));
+ try!(write_tag(self.writer, tag_id));
// 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)
}
let cur_pos = try!(self.writer.tell());
try!(self.writer.seek(last_size_pos as i64, old_io::SeekSet));
let size = cur_pos as uint - last_size_pos - 4;
- try!(write_sized_vuint(self.writer, size, 4));
- let r = try!(self.writer.seek(cur_pos as i64, old_io::SeekSet));
+
+ // relax the size encoding for small tags (bigger tags are costly to move).
+ // we should never try to move the stable positions, however.
+ const RELAX_MAX_SIZE: uint = 0x100;
+ if size <= RELAX_MAX_SIZE && last_size_pos >= self.relax_limit as uint {
+ // we can't alter the buffer in place, so have a temporary buffer
+ let mut buf = [0u8; RELAX_MAX_SIZE];
+ {
+ let data = &self.writer.get_ref()[last_size_pos+4..cur_pos as uint];
+ bytes::copy_memory(&mut buf, data);
+ }
+
+ // overwrite the size and data and continue
+ try!(write_vuint(self.writer, size));
+ try!(self.writer.write_all(&buf[..size]));
+ } else {
+ // overwrite the size with an overlong encoding and skip past the data
+ try!(write_sized_vuint(self.writer, size, 4));
+ try!(self.writer.seek(cur_pos as i64, old_io::SeekSet));
+ }
debug!("End tag (size = {:?})", size);
- Ok(r)
+ Ok(())
}
pub fn wr_tag<F>(&mut self, tag_id: uint, blk: F) -> EncodeResult where
}
pub fn wr_tagged_bytes(&mut self, tag_id: uint, b: &[u8]) -> EncodeResult {
- try!(write_vuint(self.writer, tag_id));
+ assert!(tag_id >= NUM_IMPLICIT_TAGS);
+ try!(write_tag(self.writer, tag_id));
try!(write_vuint(self.writer, b.len()));
self.writer.write_all(b)
}
self.wr_tagged_bytes(tag_id, v.as_bytes())
}
+ // for auto-serialization
+ fn wr_tagged_raw_bytes(&mut self, tag_id: uint, b: &[u8]) -> EncodeResult {
+ try!(write_tag(self.writer, tag_id));
+ self.writer.write_all(b)
+ }
+
+ fn wr_tagged_raw_u64(&mut self, tag_id: uint, v: u64) -> EncodeResult {
+ let bytes: [u8; 8] = unsafe { mem::transmute(v.to_be()) };
+ self.wr_tagged_raw_bytes(tag_id, &bytes)
+ }
+
+ fn wr_tagged_raw_u32(&mut self, tag_id: uint, v: u32) -> EncodeResult{
+ let bytes: [u8; 4] = unsafe { mem::transmute(v.to_be()) };
+ self.wr_tagged_raw_bytes(tag_id, &bytes)
+ }
+
+ fn wr_tagged_raw_u16(&mut self, tag_id: uint, v: u16) -> EncodeResult {
+ let bytes: [u8; 2] = unsafe { mem::transmute(v.to_be()) };
+ self.wr_tagged_raw_bytes(tag_id, &bytes)
+ }
+
+ fn wr_tagged_raw_u8(&mut self, tag_id: uint, v: u8) -> EncodeResult {
+ self.wr_tagged_raw_bytes(tag_id, &[v])
+ }
+
+ fn wr_tagged_raw_i64(&mut self, tag_id: uint, v: i64) -> EncodeResult {
+ self.wr_tagged_raw_u64(tag_id, v as u64)
+ }
+
+ fn wr_tagged_raw_i32(&mut self, tag_id: uint, v: i32) -> EncodeResult {
+ self.wr_tagged_raw_u32(tag_id, v as u32)
+ }
+
+ fn wr_tagged_raw_i16(&mut self, tag_id: uint, v: i16) -> EncodeResult {
+ self.wr_tagged_raw_u16(tag_id, v as u16)
+ }
+
+ fn wr_tagged_raw_i8(&mut self, tag_id: uint, v: i8) -> EncodeResult {
+ self.wr_tagged_raw_bytes(tag_id, &[v as u8])
+ }
+
pub fn wr_bytes(&mut self, b: &[u8]) -> EncodeResult {
debug!("Write {:?} bytes", b.len());
self.writer.write_all(b)
debug!("Write str: {:?}", s);
self.writer.write_all(s.as_bytes())
}
- }
-
- // FIXME (#2743): optionally perform "relaxations" on end_tag to more
- // efficiently encode sizes; this is a fixed point iteration
-
- // Set to true to generate more debugging in EBML code.
- // Totally lame approach.
- #[cfg(not(ndebug))]
- static DEBUG: bool = true;
- #[cfg(ndebug)]
- static DEBUG: bool = false;
- impl<'a, W: Writer + Seek> Encoder<'a, W> {
- // used internally to emit things like the vector length and so on
- fn _emit_tagged_uint(&mut self, t: EbmlEncoderTag, v: uint) -> EncodeResult {
- assert!(v <= 0xFFFF_FFFF);
- self.wr_tagged_u32(t as uint, v as u32)
+ /// Returns the current position while marking it stable, i.e.
+ /// generated bytes so far woundn't be affected by relaxation.
+ pub fn mark_stable_position(&mut self) -> u64 {
+ let pos = self.writer.tell().unwrap();
+ if self.relax_limit < pos {
+ self.relax_limit = pos;
+ }
+ pos
}
+ }
- fn _emit_label(&mut self, label: &str) -> EncodeResult {
- // There are various strings that we have access to, such as
- // the name of a record field, which do not actually appear in
- // the encoded EBML (normally). This is just for
- // efficiency. When debugging, though, we can emit such
- // labels and then they will be checked by decoder to
- // try and check panics more quickly.
- if DEBUG { self.wr_tagged_str(EsLabel as uint, label) }
- else { Ok(()) }
+ impl<'a> Encoder<'a> {
+ // used internally to emit things like the vector length and so on
+ fn _emit_tagged_sub(&mut self, v: uint) -> EncodeResult {
+ if let Some(v) = v.to_u8() {
+ self.wr_tagged_raw_u8(EsSub8 as uint, v)
+ } else if let Some(v) = v.to_u32() {
+ self.wr_tagged_raw_u32(EsSub32 as uint, v)
+ } else {
+ Err(old_io::IoError {
+ kind: old_io::OtherIoError,
+ desc: "length or variant id too big",
+ detail: Some(format!("{}", v))
+ })
+ }
}
pub fn emit_opaque<F>(&mut self, f: F) -> EncodeResult where
- F: FnOnce(&mut Encoder<W>) -> EncodeResult,
+ F: FnOnce(&mut Encoder) -> EncodeResult,
{
try!(self.start_tag(EsOpaque as uint));
try!(f(self));
}
}
- impl<'a, W: Writer + Seek> serialize::Encoder for Encoder<'a, W> {
+ impl<'a> serialize::Encoder for Encoder<'a> {
type Error = old_io::IoError;
fn emit_nil(&mut self) -> EncodeResult {
}
fn emit_uint(&mut self, v: uint) -> EncodeResult {
- self.wr_tagged_u64(EsUint as uint, v as u64)
+ self.emit_u64(v as u64)
}
fn emit_u64(&mut self, v: u64) -> EncodeResult {
- self.wr_tagged_u64(EsU64 as uint, v)
+ match v.to_u32() {
+ Some(v) => self.emit_u32(v),
+ None => self.wr_tagged_raw_u64(EsU64 as uint, v)
+ }
}
fn emit_u32(&mut self, v: u32) -> EncodeResult {
- self.wr_tagged_u32(EsU32 as uint, v)
+ match v.to_u16() {
+ Some(v) => self.emit_u16(v),
+ None => self.wr_tagged_raw_u32(EsU32 as uint, v)
+ }
}
fn emit_u16(&mut self, v: u16) -> EncodeResult {
- self.wr_tagged_u16(EsU16 as uint, v)
+ match v.to_u8() {
+ Some(v) => self.emit_u8(v),
+ None => self.wr_tagged_raw_u16(EsU16 as uint, v)
+ }
}
fn emit_u8(&mut self, v: u8) -> EncodeResult {
- self.wr_tagged_u8(EsU8 as uint, v)
+ self.wr_tagged_raw_u8(EsU8 as uint, v)
}
fn emit_int(&mut self, v: int) -> EncodeResult {
- self.wr_tagged_i64(EsInt as uint, v as i64)
+ self.emit_i64(v as i64)
}
fn emit_i64(&mut self, v: i64) -> EncodeResult {
- self.wr_tagged_i64(EsI64 as uint, v)
+ match v.to_i32() {
+ Some(v) => self.emit_i32(v),
+ None => self.wr_tagged_raw_i64(EsI64 as uint, v)
+ }
}
fn emit_i32(&mut self, v: i32) -> EncodeResult {
- self.wr_tagged_i32(EsI32 as uint, v)
+ match v.to_i16() {
+ Some(v) => self.emit_i16(v),
+ None => self.wr_tagged_raw_i32(EsI32 as uint, v)
+ }
}
fn emit_i16(&mut self, v: i16) -> EncodeResult {
- self.wr_tagged_i16(EsI16 as uint, v)
+ match v.to_i8() {
+ Some(v) => self.emit_i8(v),
+ None => self.wr_tagged_raw_i16(EsI16 as uint, v)
+ }
}
fn emit_i8(&mut self, v: i8) -> EncodeResult {
- self.wr_tagged_i8(EsI8 as uint, v)
+ self.wr_tagged_raw_i8(EsI8 as uint, v)
}
fn emit_bool(&mut self, v: bool) -> EncodeResult {
- self.wr_tagged_u8(EsBool as uint, v as u8)
+ self.wr_tagged_raw_u8(EsBool as uint, v as u8)
}
fn emit_f64(&mut self, v: f64) -> EncodeResult {
let bits = unsafe { mem::transmute(v) };
- self.wr_tagged_u64(EsF64 as uint, bits)
+ self.wr_tagged_raw_u64(EsF64 as uint, bits)
}
fn emit_f32(&mut self, v: f32) -> EncodeResult {
let bits = unsafe { mem::transmute(v) };
- self.wr_tagged_u32(EsF32 as uint, bits)
+ self.wr_tagged_raw_u32(EsF32 as uint, bits)
}
fn emit_char(&mut self, v: char) -> EncodeResult {
- self.wr_tagged_u32(EsChar as uint, v as u32)
+ self.wr_tagged_raw_u32(EsChar as uint, v as u32)
}
fn emit_str(&mut self, v: &str) -> EncodeResult {
self.wr_tagged_str(EsStr as uint, v)
}
- fn emit_enum<F>(&mut self, name: &str, f: F) -> EncodeResult where
- F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
+ fn emit_enum<F>(&mut self, _name: &str, f: F) -> EncodeResult where
+ F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
{
- try!(self._emit_label(name));
try!(self.start_tag(EsEnum as uint));
try!(f(self));
self.end_tag()
v_id: uint,
_: uint,
f: F) -> EncodeResult where
- F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
+ F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
{
- try!(self._emit_tagged_uint(EsEnumVid, v_id));
- try!(self.start_tag(EsEnumBody as uint));
- try!(f(self));
- self.end_tag()
+ try!(self._emit_tagged_sub(v_id));
+ f(self)
}
fn emit_enum_variant_arg<F>(&mut self, _: uint, f: F) -> EncodeResult where
- F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
+ F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
{
f(self)
}
v_id: uint,
cnt: uint,
f: F) -> EncodeResult where
- F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
+ F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
{
self.emit_enum_variant(v_name, v_id, cnt, f)
}
_: &str,
idx: uint,
f: F) -> EncodeResult where
- F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
+ F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
{
self.emit_enum_variant_arg(idx, f)
}
fn emit_struct<F>(&mut self, _: &str, _len: uint, f: F) -> EncodeResult where
- F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
+ F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
{
f(self)
}
- fn emit_struct_field<F>(&mut self, name: &str, _: uint, f: F) -> EncodeResult where
- F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
+ fn emit_struct_field<F>(&mut self, _name: &str, _: uint, f: F) -> EncodeResult where
+ F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
{
- try!(self._emit_label(name));
f(self)
}
fn emit_tuple<F>(&mut self, len: uint, f: F) -> EncodeResult where
- F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
+ F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
{
self.emit_seq(len, f)
}
fn emit_tuple_arg<F>(&mut self, idx: uint, f: F) -> EncodeResult where
- F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
+ F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
{
self.emit_seq_elt(idx, f)
}
fn emit_tuple_struct<F>(&mut self, _: &str, len: uint, f: F) -> EncodeResult where
- F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
+ F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
{
self.emit_seq(len, f)
}
fn emit_tuple_struct_arg<F>(&mut self, idx: uint, f: F) -> EncodeResult where
- F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
+ F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
{
self.emit_seq_elt(idx, f)
}
fn emit_option<F>(&mut self, f: F) -> EncodeResult where
- F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
+ F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
{
self.emit_enum("Option", f)
}
self.emit_enum_variant("None", 0, 0, |_| Ok(()))
}
fn emit_option_some<F>(&mut self, f: F) -> EncodeResult where
- F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
+ F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
{
self.emit_enum_variant("Some", 1, 1, f)
}
fn emit_seq<F>(&mut self, len: uint, f: F) -> EncodeResult where
- F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
+ F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
{
+ if len == 0 {
+ // empty vector optimization
+ return self.wr_tagged_bytes(EsVec as uint, &[]);
+ }
try!(self.start_tag(EsVec as uint));
- try!(self._emit_tagged_uint(EsVecLen, len));
+ try!(self._emit_tagged_sub(len));
try!(f(self));
self.end_tag()
}
fn emit_seq_elt<F>(&mut self, _idx: uint, f: F) -> EncodeResult where
- F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
+ F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
{
try!(self.start_tag(EsVecElt as uint));
}
fn emit_map<F>(&mut self, len: uint, f: F) -> EncodeResult where
- F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
+ F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
{
+ if len == 0 {
+ // empty map optimization
+ return self.wr_tagged_bytes(EsMap as uint, &[]);
+ }
try!(self.start_tag(EsMap as uint));
- try!(self._emit_tagged_uint(EsMapLen, len));
+ try!(self._emit_tagged_sub(len));
try!(f(self));
self.end_tag()
}
fn emit_map_elt_key<F>(&mut self, _idx: uint, f: F) -> EncodeResult where
- F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
+ F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
{
try!(self.start_tag(EsMapKey as uint));
}
fn emit_map_elt_val<F>(&mut self, _idx: uint, f: F) -> EncodeResult where
- F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
+ F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
{
try!(self.start_tag(EsMapVal as uint));
try!(f(self));
#[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<_>>();
#[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<_>>();
#[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;
#[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;
//!
//! 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]
#![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;
})
}
- // FIXME(#10894) should continue recursing
fn visit_ty(&mut self, t: &ast::Ty) {
run_lints!(self, check_ty, t);
+ visit::walk_ty(self, t);
}
fn visit_ident(&mut self, sp: Span, id: ast::Ident) {
-// 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.
//
use back::svh::Svh;
-// EBML enum definitions and utils shared by the encoder and decoder
+// RBML enum definitions and utils shared by the encoder and decoder
+//
+// 0x00..0x1f: reserved for RBML generic type tags
+// 0x20..0xef: free for use, preferred for frequent tags
+// 0xf0..0xff: internally used by RBML to encode 0x100..0xfff in two bytes
+// 0x100..0xfff: free for use, preferred for infrequent tags
-pub const tag_items: uint = 0x00;
+pub const tag_items: uint = 0x100; // top-level only
-pub const tag_paths_data_name: uint = 0x01;
+pub const tag_paths_data_name: uint = 0x20;
-pub const tag_def_id: uint = 0x02;
+pub const tag_def_id: uint = 0x21;
-pub const tag_items_data: uint = 0x03;
+pub const tag_items_data: uint = 0x22;
-pub const tag_items_data_item: uint = 0x04;
+pub const tag_items_data_item: uint = 0x23;
-pub const tag_items_data_item_family: uint = 0x05;
+pub const tag_items_data_item_family: uint = 0x24;
-pub const tag_items_data_item_type: uint = 0x07;
+pub const tag_items_data_item_type: uint = 0x25;
-pub const tag_items_data_item_symbol: uint = 0x08;
+pub const tag_items_data_item_symbol: uint = 0x26;
-pub const tag_items_data_item_variant: uint = 0x09;
+pub const tag_items_data_item_variant: uint = 0x27;
-pub const tag_items_data_parent_item: uint = 0x0a;
+pub const tag_items_data_parent_item: uint = 0x28;
-pub const tag_items_data_item_is_tuple_struct_ctor: uint = 0x0b;
+pub const tag_items_data_item_is_tuple_struct_ctor: uint = 0x29;
-pub const tag_index: uint = 0x0c;
+pub const tag_index: uint = 0x2a;
-pub const tag_index_buckets: uint = 0x0d;
+pub const tag_index_buckets: uint = 0x2b;
-pub const tag_index_buckets_bucket: uint = 0x0e;
+pub const tag_index_buckets_bucket: uint = 0x2c;
-pub const tag_index_buckets_bucket_elt: uint = 0x0f;
+pub const tag_index_buckets_bucket_elt: uint = 0x2d;
-pub const tag_index_table: uint = 0x10;
+pub const tag_index_table: uint = 0x2e;
-pub const tag_meta_item_name_value: uint = 0x11;
+pub const tag_meta_item_name_value: uint = 0x2f;
-pub const tag_meta_item_name: uint = 0x12;
+pub const tag_meta_item_name: uint = 0x30;
-pub const tag_meta_item_value: uint = 0x13;
+pub const tag_meta_item_value: uint = 0x31;
-pub const tag_attributes: uint = 0x14;
+pub const tag_attributes: uint = 0x101; // top-level only
-pub const tag_attribute: uint = 0x15;
+pub const tag_attribute: uint = 0x32;
-pub const tag_meta_item_word: uint = 0x16;
+pub const tag_meta_item_word: uint = 0x33;
-pub const tag_meta_item_list: uint = 0x17;
+pub const tag_meta_item_list: uint = 0x34;
// The list of crates that this crate depends on
-pub const tag_crate_deps: uint = 0x18;
+pub const tag_crate_deps: uint = 0x102; // top-level only
// A single crate dependency
-pub const tag_crate_dep: uint = 0x19;
+pub const tag_crate_dep: uint = 0x35;
-pub const tag_crate_hash: uint = 0x1a;
-pub const tag_crate_crate_name: uint = 0x1b;
+pub const tag_crate_hash: uint = 0x103; // top-level only
+pub const tag_crate_crate_name: uint = 0x104; // top-level only
-pub const tag_crate_dep_crate_name: uint = 0x1d;
-pub const tag_crate_dep_hash: uint = 0x1e;
+pub const tag_crate_dep_crate_name: uint = 0x36;
+pub const tag_crate_dep_hash: uint = 0x37;
-pub const tag_mod_impl: uint = 0x1f;
+pub const tag_mod_impl: uint = 0x38;
-pub const tag_item_trait_item: uint = 0x20;
+pub const tag_item_trait_item: uint = 0x39;
-pub const tag_item_trait_ref: uint = 0x21;
-pub const tag_item_super_trait_ref: uint = 0x22;
+pub const tag_item_trait_ref: uint = 0x3a;
// discriminator value for variants
-pub const tag_disr_val: uint = 0x23;
+pub const tag_disr_val: uint = 0x3c;
// used to encode ast_map::PathElem
-pub const tag_path: uint = 0x24;
-pub const tag_path_len: uint = 0x25;
-pub const tag_path_elem_mod: uint = 0x26;
-pub const tag_path_elem_name: uint = 0x27;
-pub const tag_item_field: uint = 0x28;
-pub const tag_item_field_origin: uint = 0x29;
-
-pub const tag_item_variances: uint = 0x2a;
+pub const tag_path: uint = 0x3d;
+pub const tag_path_len: uint = 0x3e;
+pub const tag_path_elem_mod: uint = 0x3f;
+pub const tag_path_elem_name: uint = 0x40;
+pub const tag_item_field: uint = 0x41;
+pub const tag_item_field_origin: uint = 0x42;
+
+pub const tag_item_variances: uint = 0x43;
/*
trait items contain tag_item_trait_item elements,
impl items contain tag_item_impl_item elements, and classes
both, tag_item_trait_item and tag_item_impl_item have to be two
different tags.
*/
-pub const tag_item_impl_item: uint = 0x30;
-pub const tag_item_trait_method_explicit_self: uint = 0x31;
+pub const tag_item_impl_item: uint = 0x44;
+pub const tag_item_trait_method_explicit_self: uint = 0x45;
// Reexports are found within module tags. Each reexport contains def_ids
// and names.
-pub const tag_items_data_item_reexport: uint = 0x38;
-pub const tag_items_data_item_reexport_def_id: uint = 0x39;
-pub const tag_items_data_item_reexport_name: uint = 0x3a;
+pub const tag_items_data_item_reexport: uint = 0x46;
+pub const tag_items_data_item_reexport_def_id: uint = 0x47;
+pub const tag_items_data_item_reexport_name: uint = 0x48;
// used to encode crate_ctxt side tables
#[derive(Copy, PartialEq, FromPrimitive)]
#[repr(uint)]
-pub enum astencode_tag { // Reserves 0x40 -- 0x5f
- tag_ast = 0x40,
-
- tag_tree = 0x41,
-
- tag_id_range = 0x42,
-
- tag_table = 0x43,
- tag_table_id = 0x44,
- tag_table_val = 0x45,
- tag_table_def = 0x46,
- tag_table_node_type = 0x47,
- tag_table_item_subst = 0x48,
- tag_table_freevars = 0x49,
- tag_table_tcache = 0x4a,
- tag_table_param_defs = 0x4b,
- tag_table_mutbl = 0x4c,
- tag_table_last_use = 0x4d,
- tag_table_spill = 0x4e,
- tag_table_method_map = 0x4f,
- tag_table_vtable_map = 0x50,
- tag_table_adjustments = 0x51,
- tag_table_moves_map = 0x52,
- tag_table_capture_map = 0x53,
- tag_table_closure_tys = 0x54,
- tag_table_closure_kinds = 0x55,
- tag_table_upvar_capture_map = 0x56,
- tag_table_capture_modes = 0x57,
- tag_table_object_cast_map = 0x58,
- tag_table_const_qualif = 0x59,
+pub enum astencode_tag { // Reserves 0x50 -- 0x6f
+ tag_ast = 0x50,
+
+ tag_tree = 0x51,
+
+ tag_id_range = 0x52,
+
+ tag_table = 0x53,
+ // GAP 0x54, 0x55
+ tag_table_def = 0x56,
+ tag_table_node_type = 0x57,
+ tag_table_item_subst = 0x58,
+ tag_table_freevars = 0x59,
+ tag_table_tcache = 0x5a,
+ tag_table_param_defs = 0x5b,
+ tag_table_mutbl = 0x5c,
+ tag_table_last_use = 0x5d,
+ tag_table_spill = 0x5e,
+ tag_table_method_map = 0x5f,
+ tag_table_vtable_map = 0x60,
+ tag_table_adjustments = 0x61,
+ tag_table_moves_map = 0x62,
+ tag_table_capture_map = 0x63,
+ tag_table_closure_tys = 0x64,
+ tag_table_closure_kinds = 0x65,
+ tag_table_upvar_capture_map = 0x66,
+ tag_table_capture_modes = 0x67,
+ tag_table_object_cast_map = 0x68,
+ tag_table_const_qualif = 0x69,
}
-pub const tag_item_trait_item_sort: uint = 0x60;
+pub const tag_item_trait_item_sort: uint = 0x70;
-pub const tag_item_trait_parent_sort: uint = 0x61;
+pub const tag_item_trait_parent_sort: uint = 0x71;
-pub const tag_item_impl_type_basename: uint = 0x62;
+pub const tag_item_impl_type_basename: uint = 0x72;
-pub const tag_crate_triple: uint = 0x66;
+pub const tag_crate_triple: uint = 0x105; // top-level only
-pub const tag_dylib_dependency_formats: uint = 0x67;
+pub const tag_dylib_dependency_formats: uint = 0x106; // top-level only
// Language items are a top-level directory (for speed). Hierarchy:
//
// - tag_lang_items_item_id: u32
// - tag_lang_items_item_node_id: u32
-pub const tag_lang_items: uint = 0x70;
-pub const tag_lang_items_item: uint = 0x71;
-pub const tag_lang_items_item_id: uint = 0x72;
-pub const tag_lang_items_item_node_id: uint = 0x73;
-pub const tag_lang_items_missing: uint = 0x74;
+pub const tag_lang_items: uint = 0x107; // top-level only
+pub const tag_lang_items_item: uint = 0x73;
+pub const tag_lang_items_item_id: uint = 0x74;
+pub const tag_lang_items_item_node_id: uint = 0x75;
+pub const tag_lang_items_missing: uint = 0x76;
-pub const tag_item_unnamed_field: uint = 0x75;
-pub const tag_items_data_item_visibility: uint = 0x76;
+pub const tag_item_unnamed_field: uint = 0x77;
+pub const tag_items_data_item_visibility: uint = 0x78;
pub const tag_item_method_tps: uint = 0x79;
pub const tag_item_method_fty: uint = 0x7a;
pub const tag_mod_child: uint = 0x7b;
-pub const tag_misc_info: uint = 0x7c;
-pub const tag_misc_info_crate_items: uint = 0x7d;
-
-pub const tag_item_method_provided_source: uint = 0x7e;
-pub const tag_item_impl_vtables: uint = 0x7f;
+pub const tag_misc_info: uint = 0x108; // top-level only
+pub const tag_misc_info_crate_items: uint = 0x7c;
-pub const tag_impls: uint = 0x80;
-pub const tag_impls_impl: uint = 0x81;
+pub const tag_item_method_provided_source: uint = 0x7d;
+pub const tag_item_impl_vtables: uint = 0x7e;
-pub const tag_items_data_item_inherent_impl: uint = 0x82;
-pub const tag_items_data_item_extension_impl: uint = 0x83;
+pub const tag_impls: uint = 0x109; // top-level only
+pub const tag_impls_impl: uint = 0x7f;
-// GAP 0x84, 0x85, 0x86
+pub const tag_items_data_item_inherent_impl: uint = 0x80;
+pub const tag_items_data_item_extension_impl: uint = 0x81;
-pub const tag_native_libraries: uint = 0x87;
-pub const tag_native_libraries_lib: uint = 0x88;
-pub const tag_native_libraries_name: uint = 0x89;
-pub const tag_native_libraries_kind: uint = 0x8a;
+pub const tag_native_libraries: uint = 0x10a; // top-level only
+pub const tag_native_libraries_lib: uint = 0x82;
+pub const tag_native_libraries_name: uint = 0x83;
+pub const tag_native_libraries_kind: uint = 0x84;
-pub const tag_plugin_registrar_fn: uint = 0x8b;
+pub const tag_plugin_registrar_fn: uint = 0x10b; // top-level only
-// GAP 0x8c, 0x8d
+pub const tag_method_argument_names: uint = 0x85;
+pub const tag_method_argument_name: uint = 0x86;
-pub const tag_method_argument_names: uint = 0x8e;
-pub const tag_method_argument_name: uint = 0x8f;
+pub const tag_reachable_extern_fns: uint = 0x10c; // top-level only
+pub const tag_reachable_extern_fn_id: uint = 0x87;
-pub const tag_reachable_extern_fns: uint = 0x90;
-pub const tag_reachable_extern_fn_id: uint = 0x91;
+pub const tag_items_data_item_stability: uint = 0x88;
-pub const tag_items_data_item_stability: uint = 0x92;
-
-pub const tag_items_data_item_repr: uint = 0x93;
+pub const tag_items_data_item_repr: uint = 0x89;
#[derive(Clone, Debug)]
pub struct LinkMeta {
pub crate_hash: Svh,
}
-// GAP 0x94...0x98
+pub const tag_struct_fields: uint = 0x10d; // top-level only
+pub const tag_struct_field: uint = 0x8a;
+pub const tag_struct_field_id: uint = 0x8b;
+
+pub const tag_attribute_is_sugared_doc: uint = 0x8c;
-pub const tag_struct_fields: uint = 0x99;
-pub const tag_struct_field: uint = 0x9a;
-pub const tag_struct_field_id: uint = 0x9b;
+pub const tag_items_data_region: uint = 0x8e;
-pub const tag_attribute_is_sugared_doc: uint = 0x9c;
+pub const tag_region_param_def: uint = 0x8f;
+pub const tag_region_param_def_ident: uint = 0x90;
+pub const tag_region_param_def_def_id: uint = 0x91;
+pub const tag_region_param_def_space: uint = 0x92;
+pub const tag_region_param_def_index: uint = 0x93;
-pub const tag_trait_def_bounds: uint = 0x9d;
+pub const tag_type_param_def: uint = 0x94;
-pub const tag_items_data_region: uint = 0x9e;
+pub const tag_item_generics: uint = 0x95;
+pub const tag_method_ty_generics: uint = 0x96;
-pub const tag_region_param_def: uint = 0xa0;
-pub const tag_region_param_def_ident: uint = 0xa1;
-pub const tag_region_param_def_def_id: uint = 0xa2;
-pub const tag_region_param_def_space: uint = 0xa3;
-pub const tag_region_param_def_index: uint = 0xa4;
+pub const tag_predicate: uint = 0x97;
+pub const tag_predicate_space: uint = 0x98;
+pub const tag_predicate_data: uint = 0x99;
-pub const tag_type_param_def: uint = 0xa5;
+pub const tag_unsafety: uint = 0x9a;
-pub const tag_item_generics: uint = 0xa6;
-pub const tag_method_ty_generics: uint = 0xa7;
+pub const tag_associated_type_names: uint = 0x9b;
+pub const tag_associated_type_name: uint = 0x9c;
-pub const tag_predicate: uint = 0xa8;
-pub const tag_predicate_space: uint = 0xa9;
-pub const tag_predicate_data: uint = 0xb0;
+pub const tag_polarity: uint = 0x9d;
-pub const tag_unsafety: uint = 0xb1;
+pub const tag_macro_defs: uint = 0x10e; // top-level only
+pub const tag_macro_def: uint = 0x9e;
+pub const tag_macro_def_body: uint = 0x9f;
-pub const tag_associated_type_names: uint = 0xb2;
-pub const tag_associated_type_name: uint = 0xb3;
+pub const tag_paren_sugar: uint = 0xa0;
-pub const tag_polarity: uint = 0xb4;
+pub const tag_codemap: uint = 0xa1;
+pub const tag_codemap_filemap: uint = 0xa2;
-pub const tag_macro_defs: uint = 0xb5;
-pub const tag_macro_def: uint = 0xb6;
-pub const tag_macro_def_body: uint = 0xb7;
+pub const tag_item_super_predicates: uint = 0xa3;
-pub const tag_paren_sugar: uint = 0xb8;
+pub const tag_defaulted_trait: uint = 0xa4;
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;
// Extra info about a crate loaded for plugins or exported macros.
struct ExtensionCrate {
metadata: PMDSource,
- dylib: Option<Path>,
+ dylib: Option<PathBuf>,
target_only: bool,
}
// 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,
});
};
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 {
// overridden in plugin/load.rs
export: false,
use_locally: false,
+ allow_internal_unstable: false,
body: body,
});
}
/// 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(),
.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",
}
}
}
+
+/// 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
+ }
+}
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);
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;
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)
}
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
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)]
// 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,
}
// 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>) {
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;
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;
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;
{
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);
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,
}
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>
{
_ => { /* empty */ }
}
let old_disr_val = disr_val;
- disr_val += 1;
+ disr_val = disr_val.wrapping_add(1);
Rc::new(ty::VariantInfo {
args: arg_tys,
arg_names: arg_names,
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());
}
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);
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));
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));
}
}
+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;
}
-// 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.
//
use syntax::visit::Visitor;
use syntax::visit;
use syntax;
-use rbml::writer;
+use rbml::writer::Encoder;
use rbml::io::SeekableMemWriter;
/// A borrowed version of `ast::InlinedItem`.
IIForeignRef(&'a ast::ForeignItem)
}
-pub type Encoder<'a> = writer::Encoder<'a, SeekableMemWriter>;
-
pub type EncodeInlinedItem<'a> =
Box<FnMut(&EncodeContext, &mut Encoder, InlinedItemRef) + 'a>;
};
rbml_w.start_tag(tag);
- tyencode::enc_trait_ref(rbml_w.writer, ty_str_ctxt, trait_ref);
+ tyencode::enc_trait_ref(rbml_w, ty_str_ctxt, trait_ref);
rbml_w.end_tag();
}
// Item info table encoding
fn encode_family(rbml_w: &mut Encoder, c: char) {
- rbml_w.start_tag(tag_items_data_item_family);
- rbml_w.writer.write_all(&[c as u8]);
- rbml_w.end_tag();
+ rbml_w.wr_tagged_u8(tag_items_data_item_family, c as u8);
}
pub fn def_to_string(did: DefId) -> String {
}
fn encode_variant_id(rbml_w: &mut Encoder, vid: DefId) {
- rbml_w.start_tag(tag_items_data_item_variant);
let s = def_to_string(vid);
- rbml_w.writer.write_all(s.as_bytes());
- rbml_w.end_tag();
-
- rbml_w.start_tag(tag_mod_child);
- rbml_w.wr_str(&s[..]);
- rbml_w.end_tag();
+ rbml_w.wr_tagged_str(tag_items_data_item_variant, &s[..]);
+ rbml_w.wr_tagged_str(tag_mod_child, &s[..]);
}
pub fn write_closure_type<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
tcx: ecx.tcx,
abbrevs: &ecx.type_abbrevs
};
- tyencode::enc_closure_ty(rbml_w.writer, ty_str_ctxt, closure_type);
+ tyencode::enc_closure_ty(rbml_w, ty_str_ctxt, closure_type);
}
pub fn write_type<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
tcx: ecx.tcx,
abbrevs: &ecx.type_abbrevs
};
- tyencode::enc_ty(rbml_w.writer, ty_str_ctxt, typ);
+ tyencode::enc_ty(rbml_w, ty_str_ctxt, typ);
}
pub fn write_trait_ref<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
tcx: ecx.tcx,
abbrevs: &ecx.type_abbrevs
};
- tyencode::enc_trait_ref(rbml_w.writer, ty_str_ctxt, trait_ref);
+ tyencode::enc_trait_ref(rbml_w, ty_str_ctxt, trait_ref);
}
pub fn write_region(ecx: &EncodeContext,
tcx: ecx.tcx,
abbrevs: &ecx.type_abbrevs
};
- tyencode::enc_region(rbml_w.writer, 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.writer, ty_str_ctxt, bounds);
-
- rbml_w.end_tag();
+ tyencode::enc_region(rbml_w, ty_str_ctxt, r);
}
fn encode_type<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
tcx: ecx.tcx,
abbrevs: &ecx.type_abbrevs
};
- tyencode::enc_bare_fn_ty(rbml_w.writer, ty_str_ctxt, typ);
+ tyencode::enc_bare_fn_ty(rbml_w, ty_str_ctxt, typ);
rbml_w.end_tag();
}
fn encode_symbol(ecx: &EncodeContext,
rbml_w: &mut Encoder,
id: NodeId) {
- rbml_w.start_tag(tag_items_data_item_symbol);
match ecx.item_symbols.borrow().get(&id) {
Some(x) => {
debug!("encode_symbol(id={}, str={})", id, *x);
- rbml_w.writer.write_all(x.as_bytes());
+ rbml_w.wr_tagged_str(tag_items_data_item_symbol, x);
}
None => {
ecx.diag.handler().bug(
&format!("encode_symbol: id not found {}", id));
}
}
- rbml_w.end_tag();
}
fn encode_disr_val(_: &EncodeContext,
rbml_w: &mut Encoder,
disr_val: ty::Disr) {
- rbml_w.start_tag(tag_disr_val);
- let s = disr_val.to_string();
- rbml_w.writer.write_all(s.as_bytes());
- rbml_w.end_tag();
+ rbml_w.wr_tagged_str(tag_disr_val, &disr_val.to_string());
}
fn encode_parent_item(rbml_w: &mut Encoder, id: DefId) {
- rbml_w.start_tag(tag_items_data_parent_item);
- let s = def_to_string(id);
- rbml_w.writer.write_all(s.as_bytes());
- rbml_w.end_tag();
+ rbml_w.wr_tagged_str(tag_items_data_parent_item, &def_to_string(id));
}
fn encode_struct_fields(rbml_w: &mut Encoder,
}
encode_struct_field_family(rbml_w, f.vis);
encode_def_id(rbml_w, f.id);
- rbml_w.start_tag(tag_item_field_origin);
- let s = def_to_string(origin);
- rbml_w.writer.write_all(s.as_bytes());
- rbml_w.end_tag();
+ rbml_w.wr_tagged_str(tag_item_field_origin, &def_to_string(origin));
rbml_w.end_tag();
}
}
let def_id = local_def(variant.node.id);
index.push(entry {
val: variant.node.id as i64,
- pos: rbml_w.writer.tell().unwrap(),
+ pos: rbml_w.mark_stable_position(),
});
rbml_w.start_tag(tag_items_data_item);
encode_def_id(rbml_w, def_id);
ecx.tcx.map.with_path(variant.node.id, |path| encode_path(rbml_w, path));
rbml_w.end_tag();
- disr_val += 1;
+ disr_val = disr_val.wrapping_add(1);
i += 1;
}
}
debug!("(encode reexported static method) {}::{}",
exp.name, token::get_name(method_name));
rbml_w.start_tag(tag_items_data_item_reexport);
- rbml_w.start_tag(tag_items_data_item_reexport_def_id);
- rbml_w.wr_str(&def_to_string(method_def_id));
- rbml_w.end_tag();
- rbml_w.start_tag(tag_items_data_item_reexport_name);
- rbml_w.wr_str(&format!("{}::{}",
- exp.name,
- token::get_name(method_name)));
- rbml_w.end_tag();
+ rbml_w.wr_tagged_str(tag_items_data_item_reexport_def_id,
+ &def_to_string(method_def_id));
+ rbml_w.wr_tagged_str(tag_items_data_item_reexport_name,
+ &format!("{}::{}", exp.name,
+ token::get_name(method_name)));
rbml_w.end_tag();
}
exp.def_id.node,
id);
rbml_w.start_tag(tag_items_data_item_reexport);
- rbml_w.start_tag(tag_items_data_item_reexport_def_id);
- rbml_w.wr_str(&def_to_string(exp.def_id));
- rbml_w.end_tag();
- rbml_w.start_tag(tag_items_data_item_reexport_name);
- rbml_w.wr_str(exp.name.as_str());
- rbml_w.end_tag();
+ rbml_w.wr_tagged_str(tag_items_data_item_reexport_def_id,
+ &def_to_string(exp.def_id));
+ rbml_w.wr_tagged_str(tag_items_data_item_reexport_name,
+ exp.name.as_str());
rbml_w.end_tag();
encode_reexported_static_methods(ecx, rbml_w, path.clone(), exp);
}
// Encode info about all the module children.
for item in &md.items {
- rbml_w.start_tag(tag_mod_child);
- rbml_w.wr_str(&def_to_string(local_def(item.id)));
- rbml_w.end_tag();
+ rbml_w.wr_tagged_str(tag_mod_child,
+ &def_to_string(local_def(item.id)));
each_auxiliary_node_id(&**item, |auxiliary_node_id| {
- rbml_w.start_tag(tag_mod_child);
- rbml_w.wr_str(&def_to_string(local_def(
- auxiliary_node_id)));
- rbml_w.end_tag();
+ rbml_w.wr_tagged_str(tag_mod_child,
+ &def_to_string(local_def(auxiliary_node_id)));
true
});
token::get_ident(ident),
did, ecx.tcx.map.node_to_string(did));
- rbml_w.start_tag(tag_mod_impl);
- rbml_w.wr_str(&def_to_string(local_def(did)));
- rbml_w.end_tag();
+ rbml_w.wr_tagged_str(tag_mod_impl,
+ &def_to_string(local_def(did)));
}
}
}
fn encode_visibility(rbml_w: &mut Encoder, visibility: ast::Visibility) {
- rbml_w.start_tag(tag_items_data_item_visibility);
let ch = match visibility {
ast::Public => 'y',
ast::Inherited => 'i',
};
- rbml_w.wr_str(&ch.to_string());
- rbml_w.end_tag();
+ rbml_w.wr_tagged_u8(tag_items_data_item_visibility, ch as u8);
}
fn encode_explicit_self(rbml_w: &mut Encoder,
explicit_self: &ty::ExplicitSelfCategory) {
- rbml_w.start_tag(tag_item_trait_method_explicit_self);
+ let tag = tag_item_trait_method_explicit_self;
// Encode the base self type.
match *explicit_self {
ty::StaticExplicitSelfCategory => {
- rbml_w.writer.write_all(&[ 's' as u8 ]);
+ rbml_w.wr_tagged_bytes(tag, &['s' as u8]);
}
ty::ByValueExplicitSelfCategory => {
- rbml_w.writer.write_all(&[ 'v' as u8 ]);
+ rbml_w.wr_tagged_bytes(tag, &['v' as u8]);
}
ty::ByBoxExplicitSelfCategory => {
- rbml_w.writer.write_all(&[ '~' as u8 ]);
+ rbml_w.wr_tagged_bytes(tag, &['~' as u8]);
}
ty::ByReferenceExplicitSelfCategory(_, m) => {
// FIXME(#4846) encode custom lifetime
- rbml_w.writer.write_all(&['&' as u8]);
- encode_mutability(rbml_w, m);
+ let ch = encode_mutability(m);
+ rbml_w.wr_tagged_bytes(tag, &['&' as u8, ch]);
}
}
- rbml_w.end_tag();
-
- fn encode_mutability(rbml_w: &mut Encoder,
- m: ast::Mutability) {
+ fn encode_mutability(m: ast::Mutability) -> u8 {
match m {
- ast::MutImmutable => { rbml_w.writer.write_all(&[ 'i' as u8 ]); }
- ast::MutMutable => { rbml_w.writer.write_all(&[ 'm' as u8 ]); }
+ ast::MutImmutable => 'i' as u8,
+ ast::MutMutable => 'm' as u8,
}
}
}
fn encode_item_sort(rbml_w: &mut Encoder, sort: char) {
- rbml_w.start_tag(tag_item_trait_item_sort);
- rbml_w.writer.write_all(&[ sort as u8 ]);
- rbml_w.end_tag();
+ rbml_w.wr_tagged_u8(tag_item_trait_item_sort, sort as u8);
}
fn encode_parent_sort(rbml_w: &mut Encoder, sort: char) {
- rbml_w.start_tag(tag_item_trait_parent_sort);
- rbml_w.writer.write_all(&[ sort as u8 ]);
- rbml_w.end_tag();
+ rbml_w.wr_tagged_u8(tag_item_trait_parent_sort, sort as u8);
}
fn encode_provided_source(rbml_w: &mut Encoder,
source_opt: Option<DefId>) {
if let Some(source) = source_opt {
- rbml_w.start_tag(tag_item_method_provided_source);
- let s = def_to_string(source);
- rbml_w.writer.write_all(s.as_bytes());
- rbml_w.end_tag();
+ rbml_w.wr_tagged_str(tag_item_method_provided_source,
+ &def_to_string(source));
}
}
let nm = field.name;
let id = field.id.node;
- index.push(entry {val: id as i64, pos: rbml_w.writer.tell().unwrap()});
+ let pos = rbml_w.mark_stable_position();
+ index.push(entry {val: id as i64, pos: pos});
global_index.push(entry {
val: id as i64,
- pos: rbml_w.writer.tell().unwrap(),
+ pos: pos,
});
rbml_w.start_tag(tag_items_data_item);
debug!("encode_info_for_struct: doing {} {}",
struct_id: NodeId) {
index.push(entry {
val: ctor_id as i64,
- pos: rbml_w.writer.tell().unwrap(),
+ pos: rbml_w.mark_stable_position(),
});
rbml_w.start_tag(tag_items_data_item);
// indicate that this is a tuple struct ctor, because downstream users will normally want
// the tuple struct definition, but without this there is no way for them to tell that
// they actually have a ctor rather than a normal function
- rbml_w.start_tag(tag_items_data_item_is_tuple_struct_ctor);
- rbml_w.end_tag();
+ rbml_w.wr_tagged_bytes(tag_items_data_item_is_tuple_struct_ctor, &[]);
rbml_w.end_tag();
}
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.writer, ty_str_ctxt, param);
+ tyencode::enc_type_param_def(rbml_w, ty_str_ctxt, param);
rbml_w.end_tag();
}
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);
rbml_w.wr_tagged_u8(tag_predicate_space, space as u8);
rbml_w.start_tag(tag_predicate_data);
- tyencode::enc_predicate(rbml_w.writer, ty_str_ctxt, predicate);
+ tyencode::enc_predicate(rbml_w, ty_str_ctxt, predicate);
rbml_w.end_tag();
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();
}
decl: &ast::FnDecl) {
rbml_w.start_tag(tag_method_argument_names);
for arg in &decl.inputs {
- rbml_w.start_tag(tag_method_argument_name);
+ let tag = tag_method_argument_name;
if let ast::PatIdent(_, ref path1, _) = arg.pat.node {
let name = token::get_ident(path1.node);
- rbml_w.writer.write_all(name.as_bytes());
+ rbml_w.wr_tagged_bytes(tag, name.as_bytes());
+ } else {
+ rbml_w.wr_tagged_bytes(tag, &[]);
}
- rbml_w.end_tag();
}
rbml_w.end_tag();
}
vis: ast::Visibility) {
let tcx = ecx.tcx;
- fn add_to_index(item: &ast::Item, rbml_w: &Encoder,
+ fn add_to_index(item: &ast::Item, rbml_w: &mut Encoder,
index: &mut Vec<entry<i64>>) {
index.push(entry {
val: item.id as i64,
- pos: rbml_w.writer.tell().unwrap(),
+ pos: rbml_w.mark_stable_position(),
});
}
// Encode all the items in this module.
for foreign_item in &fm.items {
- rbml_w.start_tag(tag_mod_child);
- rbml_w.wr_str(&def_to_string(local_def(foreign_item.id)));
- rbml_w.end_tag();
+ rbml_w.wr_tagged_str(tag_mod_child,
+ &def_to_string(local_def(foreign_item.id)));
}
encode_visibility(rbml_w, vis);
encode_stability(rbml_w, stab);
index.push(entry {
val: trait_item_def_id.def_id().node as i64,
- pos: rbml_w.writer.tell().unwrap(),
+ pos: rbml_w.mark_stable_position(),
});
let trait_item_type =
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);
}
rbml_w.end_tag();
- rbml_w.start_tag(tag_mod_child);
- rbml_w.wr_str(&def_to_string(method_def_id.def_id()));
- rbml_w.end_tag();
+ rbml_w.wr_tagged_str(tag_mod_child,
+ &def_to_string(method_def_id.def_id()));
}
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);
index.push(entry {
val: item_def_id.def_id().node as i64,
- pos: rbml_w.writer.tell().unwrap(),
+ pos: rbml_w.mark_stable_position(),
});
rbml_w.start_tag(tag_items_data_item);
abi: abi::Abi) {
index.push(entry {
val: nitem.id as i64,
- pos: rbml_w.writer.tell().unwrap(),
+ pos: rbml_w.mark_stable_position(),
});
rbml_w.start_tag(tag_items_data_item);
rbml_w.start_tag(tag_items_data);
index.push(entry {
val: ast::CRATE_NODE_ID as i64,
- pos: rbml_w.writer.tell().unwrap(),
+ pos: rbml_w.mark_stable_position(),
});
encode_info_for_mod(ecx,
rbml_w,
let mut bucket_locs = Vec::new();
rbml_w.start_tag(tag_index_buckets);
for bucket in &buckets {
- bucket_locs.push(rbml_w.writer.tell().unwrap());
+ bucket_locs.push(rbml_w.mark_stable_position());
rbml_w.start_tag(tag_index_buckets_bucket);
for elt in bucket {
rbml_w.start_tag(tag_index_buckets_bucket_elt);
match mi.node {
ast::MetaWord(ref name) => {
rbml_w.start_tag(tag_meta_item_word);
- rbml_w.start_tag(tag_meta_item_name);
- rbml_w.writer.write_all(name.as_bytes());
- rbml_w.end_tag();
+ rbml_w.wr_tagged_str(tag_meta_item_name, name);
rbml_w.end_tag();
}
ast::MetaNameValue(ref name, ref value) => {
match value.node {
ast::LitStr(ref value, _) => {
rbml_w.start_tag(tag_meta_item_name_value);
- rbml_w.start_tag(tag_meta_item_name);
- rbml_w.writer.write_all(name.as_bytes());
- rbml_w.end_tag();
- rbml_w.start_tag(tag_meta_item_value);
- rbml_w.writer.write_all(value.as_bytes());
- rbml_w.end_tag();
+ rbml_w.wr_tagged_str(tag_meta_item_name, name);
+ rbml_w.wr_tagged_str(tag_meta_item_value, value);
rbml_w.end_tag();
}
_ => {/* FIXME (#623): encode other variants */ }
}
ast::MetaList(ref name, ref items) => {
rbml_w.start_tag(tag_meta_item_list);
- rbml_w.start_tag(tag_meta_item_name);
- rbml_w.writer.write_all(name.as_bytes());
- rbml_w.end_tag();
+ rbml_w.wr_tagged_str(tag_meta_item_name, name);
for inner_item in items {
encode_meta_item(rbml_w, &**inner_item);
}
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 {
if let Some(id) = def_id {
if id.krate == ast::LOCAL_CRATE {
rbml_w.start_tag(tag_lang_items_item);
-
- rbml_w.start_tag(tag_lang_items_item_id);
- {
- let wr: &mut SeekableMemWriter = rbml_w.writer;
- wr.write_be_u32(i as u32);
- }
- rbml_w.end_tag(); // tag_lang_items_item_id
-
- rbml_w.start_tag(tag_lang_items_item_node_id);
- {
- let wr: &mut SeekableMemWriter = rbml_w.writer;
- wr.write_be_u32(id.node as u32);
- }
- rbml_w.end_tag(); // tag_lang_items_item_node_id
-
- rbml_w.end_tag(); // tag_lang_items_item
+ rbml_w.wr_tagged_u32(tag_lang_items_item_id, i as u32);
+ rbml_w.wr_tagged_u32(tag_lang_items_item_node_id, id.node as u32);
+ rbml_w.end_tag();
}
}
}
cstore::NativeStatic => {} // these libraries are not propagated
cstore::NativeFramework | cstore::NativeUnknown => {
rbml_w.start_tag(tag_native_libraries_lib);
-
- rbml_w.start_tag(tag_native_libraries_kind);
- rbml_w.writer.write_be_u32(kind as u32);
- rbml_w.end_tag();
-
- rbml_w.start_tag(tag_native_libraries_name);
- rbml_w.writer.write_all(lib.as_bytes());
- rbml_w.end_tag();
-
+ rbml_w.wr_tagged_u32(tag_native_libraries_kind, kind as u32);
+ rbml_w.wr_tagged_str(tag_native_libraries_name, lib);
rbml_w.end_tag();
}
}
}
}
+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) {
encode_name(rbml_w, def.ident.name);
encode_attributes(rbml_w, &def.attrs);
- rbml_w.start_tag(tag_macro_def_body);
- rbml_w.wr_str(&pprust::tts_to_string(&def.body));
- rbml_w.end_tag();
+ rbml_w.wr_tagged_str(tag_macro_def_body,
+ &pprust::tts_to_string(&def.body));
rbml_w.end_tag();
}
rbml_w.start_tag(tag_misc_info);
rbml_w.start_tag(tag_misc_info_crate_items);
for item in &krate.module.items {
- rbml_w.start_tag(tag_mod_child);
- rbml_w.wr_str(&def_to_string(local_def(item.id)));
- rbml_w.end_tag();
+ rbml_w.wr_tagged_str(tag_mod_child,
+ &def_to_string(local_def(item.id)));
each_auxiliary_node_id(&**item, |auxiliary_node_id| {
- rbml_w.start_tag(tag_mod_child);
- rbml_w.wr_str(&def_to_string(local_def(
- auxiliary_node_id)));
- rbml_w.end_tag();
+ rbml_w.wr_tagged_str(tag_mod_child,
+ &def_to_string(local_def(auxiliary_node_id)));
true
});
}
fn encode_crate_dep(rbml_w: &mut Encoder,
dep: decoder::CrateDep) {
rbml_w.start_tag(tag_crate_dep);
- rbml_w.start_tag(tag_crate_dep_crate_name);
- rbml_w.writer.write_all(dep.name.as_bytes());
- rbml_w.end_tag();
- rbml_w.start_tag(tag_crate_dep_hash);
- rbml_w.writer.write_all(dep.hash.as_str().as_bytes());
- rbml_w.end_tag();
+ rbml_w.wr_tagged_str(tag_crate_dep_crate_name, &dep.name);
+ rbml_w.wr_tagged_str(tag_crate_dep_hash, dep.hash.as_str());
rbml_w.end_tag();
}
fn encode_hash(rbml_w: &mut Encoder, hash: &Svh) {
- rbml_w.start_tag(tag_crate_hash);
- rbml_w.writer.write_all(hash.as_str().as_bytes());
- rbml_w.end_tag();
+ rbml_w.wr_tagged_str(tag_crate_hash, hash.as_str());
}
fn encode_crate_name(rbml_w: &mut Encoder, crate_name: &str) {
- rbml_w.start_tag(tag_crate_crate_name);
- rbml_w.writer.write_all(crate_name.as_bytes());
- rbml_w.end_tag();
+ rbml_w.wr_tagged_str(tag_crate_crate_name, crate_name);
}
fn encode_crate_triple(rbml_w: &mut Encoder, triple: &str) {
- rbml_w.start_tag(tag_crate_triple);
- rbml_w.writer.write_all(triple.as_bytes());
- rbml_w.end_tag();
+ rbml_w.wr_tagged_str(tag_crate_triple, triple);
}
fn encode_dylib_dependency_formats(rbml_w: &mut Encoder, ecx: &EncodeContext) {
- rbml_w.start_tag(tag_dylib_dependency_formats);
+ let tag = tag_dylib_dependency_formats;
match ecx.tcx.dependency_formats.borrow().get(&config::CrateTypeDylib) {
Some(arr) => {
let s = arr.iter().enumerate().filter_map(|(i, slot)| {
cstore::RequireStatic => "s",
})).to_string())
}).collect::<Vec<String>>();
- rbml_w.writer.write_all(s.connect(",").as_bytes());
+ rbml_w.wr_tagged_str(tag, &s.connect(","));
+ }
+ None => {
+ rbml_w.wr_tagged_str(tag, "");
}
- None => {}
}
- rbml_w.end_tag();
}
// NB: Increment this as you change the metadata encoding version.
#[allow(non_upper_case_globals)]
-pub const metadata_encoding_version : &'static [u8] = &[b'r', b'u', b's', b't', 0, 0, 0, 1 ];
+pub const metadata_encoding_version : &'static [u8] = &[b'r', b'u', b's', b't', 0, 0, 0, 2 ];
pub fn encode_metadata(parms: EncodeParams, krate: &ast::Crate) -> Vec<u8> {
let mut wr = SeekableMemWriter::new();
encode_metadata_inner(&mut wr, parms, krate);
+
+ // RBML compacts the encoded bytes whenever appropriate,
+ // so there are some garbages left after the end of the data.
+ let metalen = wr.tell().unwrap() as uint;
let mut v = wr.unwrap();
+ v.truncate(metalen);
+ assert_eq!(v.len(), metalen);
// And here we run into yet another obscure archive bug: in which metadata
// loaded from archives may have trailing garbage bytes. Awhile back one of
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,
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,
reachable: reachable,
};
- let mut rbml_w = writer::Encoder::new(wr);
+ let mut rbml_w = Encoder::new(wr);
encode_crate_name(&mut rbml_w, &ecx.link_meta.crate_name);
encode_crate_triple(&mut rbml_w,
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);
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);
// Get the encoded string for a type
pub fn encoded_ty<'tcx>(tcx: &ty::ctxt<'tcx>, t: Ty<'tcx>) -> String {
let mut wr = SeekableMemWriter::new();
- tyencode::enc_ty(&mut wr, &tyencode::ctxt {
+ tyencode::enc_ty(&mut Encoder::new(&mut wr), &tyencode::ctxt {
diag: tcx.sess.diagnostic(),
ds: def_to_string,
tcx: tcx,
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};
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();
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) {
}
}
- pub fn get_lib_path(&self) -> Path {
+ pub fn get_lib_path(&self) -> PathBuf {
make_target_lib_path(self.sysroot, self.triple)
}
{
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
}
// 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")
}
}
#[cfg(windows)]
-static PATH_ENTRY_SEPARATOR: &'static str = ";";
+const PATH_ENTRY_SEPARATOR: char = ';';
#[cfg(not(windows))]
-static PATH_ENTRY_SEPARATOR: &'static str = ":";
+const PATH_ENTRY_SEPARATOR: char = ':';
/// Returns RUST_PATH as a string, without default paths added
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) {
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);
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();
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;
use flate;
pub struct CrateMismatch {
- path: Path,
+ path: PathBuf,
got: String,
}
}
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,
}
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) |
}
}
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() {
//
// 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,
};
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()
});
}
// 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() {
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;
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
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: {}",
// 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 {
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();;
}
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.
};
}
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: '{}'",
// 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) => {
}
"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()));
}
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);
}
'k' => {
assert_eq!(next(st), '[');
let did = parse_def_(st, ClosureSource, conv);
- let region = parse_region_(st, conv);
let substs = parse_substs_(st, conv);
assert_eq!(next(st), ']');
- return ty::mk_closure(st.tcx, did,
- st.tcx.mk_region(region), st.tcx.mk_substs(substs));
+ return ty::mk_closure(st.tcx, did, st.tcx.mk_substs(substs));
}
'P' => {
assert_eq!(next(st), '[');
-// 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.
//
use syntax::diagnostic::SpanHandler;
use syntax::parse::token;
-use rbml::io::SeekableMemWriter;
+use rbml::writer::Encoder;
-macro_rules! mywrite { ($($arg:tt)*) => ({ write!($($arg)*); }) }
+macro_rules! mywrite { ($w:expr, $($arg:tt)*) => ({ write!($w.writer, $($arg)*); }) }
pub struct ctxt<'a, 'tcx: 'a> {
pub diag: &'a SpanHandler,
pub type abbrev_map<'tcx> = RefCell<FnvHashMap<Ty<'tcx>, ty_abbrev>>;
-pub fn enc_ty<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>, t: Ty<'tcx>) {
+pub fn enc_ty<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>, t: Ty<'tcx>) {
match cx.abbrevs.borrow_mut().get(&t) {
- Some(a) => { w.write_all(a.s.as_bytes()); return; }
+ Some(a) => { w.writer.write_all(a.s.as_bytes()); return; }
None => {}
}
- let pos = w.tell().unwrap();
+
+ // type abbreviations needs a stable position
+ let pos = w.mark_stable_position();
match t.sty {
ty::ty_bool => mywrite!(w, "b"),
enc_substs(w, cx, substs);
mywrite!(w, "]");
}
- ty::ty_closure(def, region, substs) => {
+ ty::ty_closure(def, substs) => {
mywrite!(w, "k[{}|", (cx.ds)(def));
- enc_region(w, cx, *region);
enc_substs(w, cx, substs);
mywrite!(w, "]");
}
}
}
- let end = w.tell().unwrap();
+ let end = w.mark_stable_position();
let len = end - pos;
fn estimate_sz(u: u64) -> u64 {
let mut n = u;
}
}
-fn enc_mutability(w: &mut SeekableMemWriter, mt: ast::Mutability) {
+fn enc_mutability(w: &mut Encoder, mt: ast::Mutability) {
match mt {
ast::MutImmutable => (),
ast::MutMutable => mywrite!(w, "m"),
}
}
-fn enc_mt<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>,
+fn enc_mt<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>,
mt: ty::mt<'tcx>) {
enc_mutability(w, mt.mutbl);
enc_ty(w, cx, mt.ty);
}
-fn enc_opt<T, F>(w: &mut SeekableMemWriter, t: Option<T>, enc_f: F) where
- F: FnOnce(&mut SeekableMemWriter, T),
+fn enc_opt<T, F>(w: &mut Encoder, t: Option<T>, enc_f: F) where
+ F: FnOnce(&mut Encoder, T),
{
match t {
None => mywrite!(w, "n"),
}
}
-fn enc_vec_per_param_space<'a, 'tcx, T, F>(w: &mut SeekableMemWriter,
+fn enc_vec_per_param_space<'a, 'tcx, T, F>(w: &mut Encoder,
cx: &ctxt<'a, 'tcx>,
v: &VecPerParamSpace<T>,
mut op: F) where
- F: FnMut(&mut SeekableMemWriter, &ctxt<'a, 'tcx>, &T),
+ F: FnMut(&mut Encoder, &ctxt<'a, 'tcx>, &T),
{
for &space in &subst::ParamSpace::all() {
mywrite!(w, "[");
}
}
-pub fn enc_substs<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>,
+pub fn enc_substs<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>,
substs: &subst::Substs<'tcx>) {
enc_region_substs(w, cx, &substs.regions);
enc_vec_per_param_space(w, cx, &substs.types,
|w, cx, &ty| enc_ty(w, cx, ty));
}
-fn enc_region_substs(w: &mut SeekableMemWriter, cx: &ctxt, substs: &subst::RegionSubsts) {
+fn enc_region_substs(w: &mut Encoder, cx: &ctxt, substs: &subst::RegionSubsts) {
match *substs {
subst::ErasedRegions => {
mywrite!(w, "e");
}
}
-pub fn enc_region(w: &mut SeekableMemWriter, cx: &ctxt, r: ty::Region) {
+pub fn enc_region(w: &mut Encoder, cx: &ctxt, r: ty::Region) {
match r {
ty::ReLateBound(id, br) => {
mywrite!(w, "b[{}|", id.depth);
}
}
-fn enc_scope(w: &mut SeekableMemWriter, _cx: &ctxt, scope: region::CodeExtent) {
+fn enc_scope(w: &mut Encoder, _cx: &ctxt, scope: region::CodeExtent) {
match scope {
region::CodeExtent::Misc(node_id) => mywrite!(w, "M{}", node_id),
region::CodeExtent::Remainder(region::BlockRemainder {
}
}
-fn enc_destruction_scope_data(w: &mut SeekableMemWriter,
+fn enc_destruction_scope_data(w: &mut Encoder,
d: region::DestructionScopeData) {
mywrite!(w, "{}", d.node_id);
}
-fn enc_bound_region(w: &mut SeekableMemWriter, cx: &ctxt, br: ty::BoundRegion) {
+fn enc_bound_region(w: &mut Encoder, cx: &ctxt, br: ty::BoundRegion) {
match br {
ty::BrAnon(idx) => {
mywrite!(w, "a{}|", idx);
}
}
-pub fn enc_trait_ref<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>,
+pub fn enc_trait_ref<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>,
s: &ty::TraitRef<'tcx>) {
mywrite!(w, "{}|", (cx.ds)(s.def_id));
enc_substs(w, cx, s.substs);
}
-fn enc_unsafety(w: &mut SeekableMemWriter, p: ast::Unsafety) {
+fn enc_unsafety(w: &mut Encoder, p: ast::Unsafety) {
match p {
ast::Unsafety::Normal => mywrite!(w, "n"),
ast::Unsafety::Unsafe => mywrite!(w, "u"),
}
}
-fn enc_abi(w: &mut SeekableMemWriter, abi: Abi) {
+fn enc_abi(w: &mut Encoder, abi: Abi) {
mywrite!(w, "[");
mywrite!(w, "{}", abi.name());
mywrite!(w, "]")
}
-pub fn enc_bare_fn_ty<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>,
+pub fn enc_bare_fn_ty<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>,
ft: &ty::BareFnTy<'tcx>) {
enc_unsafety(w, ft.unsafety);
enc_abi(w, ft.abi);
enc_fn_sig(w, cx, &ft.sig);
}
-pub fn enc_closure_ty<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>,
+pub fn enc_closure_ty<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>,
ft: &ty::ClosureTy<'tcx>) {
enc_unsafety(w, ft.unsafety);
enc_fn_sig(w, cx, &ft.sig);
enc_abi(w, ft.abi);
}
-fn enc_fn_sig<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>,
+fn enc_fn_sig<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>,
fsig: &ty::PolyFnSig<'tcx>) {
mywrite!(w, "[");
for ty in &fsig.0.inputs {
}
}
-pub fn enc_builtin_bounds(w: &mut SeekableMemWriter, _cx: &ctxt, bs: &ty::BuiltinBounds) {
+pub fn enc_builtin_bounds(w: &mut Encoder, _cx: &ctxt, bs: &ty::BuiltinBounds) {
for bound in bs {
match bound {
ty::BoundSend => mywrite!(w, "S"),
mywrite!(w, ".");
}
-pub fn enc_existential_bounds<'a,'tcx>(w: &mut SeekableMemWriter,
+pub fn enc_existential_bounds<'a,'tcx>(w: &mut Encoder,
cx: &ctxt<'a,'tcx>,
bs: &ty::ExistentialBounds<'tcx>) {
let param_bounds = ty::ParamBounds { trait_bounds: vec!(),
enc_bounds(w, cx, ¶m_bounds);
}
-pub fn enc_bounds<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>,
+pub fn enc_bounds<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>,
bs: &ty::ParamBounds<'tcx>) {
enc_builtin_bounds(w, cx, &bs.builtin_bounds);
mywrite!(w, ".");
}
-pub fn enc_region_bounds<'a, 'tcx>(w: &mut SeekableMemWriter,
+pub fn enc_region_bounds<'a, 'tcx>(w: &mut Encoder,
cx: &ctxt<'a, 'tcx>,
rs: &[ty::Region]) {
for &r in rs {
mywrite!(w, ".");
}
-pub fn enc_type_param_def<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>,
+pub fn enc_type_param_def<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>,
v: &ty::TypeParameterDef<'tcx>) {
mywrite!(w, "{}:{}|{}|{}|",
token::get_name(v.name), (cx.ds)(v.def_id),
enc_object_lifetime_default(w, cx, v.object_lifetime_default);
}
-fn enc_object_lifetime_default<'a, 'tcx>(w: &mut SeekableMemWriter,
+fn enc_object_lifetime_default<'a, 'tcx>(w: &mut Encoder,
cx: &ctxt<'a, 'tcx>,
default: Option<ty::ObjectLifetimeDefault>)
{
}
}
-pub fn enc_predicate<'a, 'tcx>(w: &mut SeekableMemWriter,
+pub fn enc_predicate<'a, 'tcx>(w: &mut Encoder,
cx: &ctxt<'a, 'tcx>,
p: &ty::Predicate<'tcx>)
{
}
}
-fn enc_projection_predicate<'a, 'tcx>(w: &mut SeekableMemWriter,
+fn enc_projection_predicate<'a, 'tcx>(w: &mut Encoder,
cx: &ctxt<'a, 'tcx>,
data: &ty::ProjectionPredicate<'tcx>) {
enc_trait_ref(w, cx, &*data.projection_ty.trait_ref);
-// 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.
//
use std::old_io::Seek;
use std::num::FromPrimitive;
use std::rc::Rc;
+use std::cell::Cell;
-use rbml::io::SeekableMemWriter;
-use rbml::{reader, writer};
+use rbml::reader;
+use rbml::writer::Encoder;
use rbml;
use serialize;
use serialize::{Decodable, Decoder, DecoderHelpers, Encodable};
use serialize::{EncoderHelpers};
+#[cfg(test)] use rbml::io::SeekableMemWriter;
#[cfg(test)] use syntax::parse;
#[cfg(test)] use syntax::print::pprust;
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 {
fn tr_intern(&self, dcx: &DecodeContext) -> ast::DefId;
}
-pub type Encoder<'a> = writer::Encoder<'a, SeekableMemWriter>;
-
// ______________________________________________________________________
// Top-level methods.
}
}
+/// 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>,
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);
pub fn tr_id(&self, id: ast::NodeId) -> ast::NodeId {
// from_id_range should be non-empty
assert!(!self.from_id_range.empty());
- (id - self.from_id_range.min + self.to_id_range.min)
+ // Use wrapping arithmetic because otherwise it introduces control flow.
+ // Maybe we should just have the control flow? -- aatch
+ (id.wrapping_sub(self.from_id_range.min).wrapping_add(self.to_id_range.min))
}
/// Translates an EXTERNAL def-id, converting the crate number from the one used in the encoded
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)
}
}
// ______________________________________________________________________
// Encoding and decoding of ast::def
-fn decode_def(dcx: &DecodeContext, doc: rbml::Doc) -> def::Def {
- let mut dsr = reader::Decoder::new(doc);
- let def: def::Def = Decodable::decode(&mut dsr).unwrap();
+fn decode_def(dcx: &DecodeContext, dsr: &mut reader::Decoder) -> def::Def {
+ let def: def::Def = Decodable::decode(dsr).unwrap();
def.tr(dcx)
}
fn emit_type_param_def<'b>(&mut self, ecx: &e::EncodeContext<'b, 'tcx>,
type_param_def: &ty::TypeParameterDef<'tcx>) {
self.emit_opaque(|this| {
- Ok(tyencode::enc_type_param_def(this.writer,
+ Ok(tyencode::enc_type_param_def(this,
&ecx.ty_str_ctxt(),
type_param_def))
});
fn emit_predicate<'b>(&mut self, ecx: &e::EncodeContext<'b, 'tcx>,
predicate: &ty::Predicate<'tcx>) {
self.emit_opaque(|this| {
- Ok(tyencode::enc_predicate(this.writer,
+ Ok(tyencode::enc_predicate(this,
&ecx.ty_str_ctxt(),
predicate))
});
fn emit_existential_bounds<'b>(&mut self, ecx: &e::EncodeContext<'b,'tcx>,
bounds: &ty::ExistentialBounds<'tcx>) {
- self.emit_opaque(|this| Ok(tyencode::enc_existential_bounds(this.writer,
+ self.emit_opaque(|this| Ok(tyencode::enc_existential_bounds(this,
&ecx.ty_str_ctxt(),
bounds)));
}
fn emit_builtin_bounds(&mut self, ecx: &e::EncodeContext, bounds: &ty::BuiltinBounds) {
- self.emit_opaque(|this| Ok(tyencode::enc_builtin_bounds(this.writer,
+ self.emit_opaque(|this| Ok(tyencode::enc_builtin_bounds(this,
&ecx.ty_str_ctxt(),
bounds)));
}
fn emit_substs<'b>(&mut self, ecx: &e::EncodeContext<'b, 'tcx>,
substs: &subst::Substs<'tcx>) {
- self.emit_opaque(|this| Ok(tyencode::enc_substs(this.writer,
+ self.emit_opaque(|this| Ok(tyencode::enc_substs(this,
&ecx.ty_str_ctxt(),
substs)));
}
}
fn id(&mut self, id: ast::NodeId) {
- self.wr_tagged_u64(c::tag_table_id as uint, id as u64);
+ id.encode(self).unwrap();
}
}
if let Some(def) = tcx.def_map.borrow().get(&id).map(|d| d.full_def()) {
rbml_w.tag(c::tag_table_def, |rbml_w| {
rbml_w.id(id);
- rbml_w.tag(c::tag_table_val, |rbml_w| def.encode(rbml_w).unwrap());
+ def.encode(rbml_w).unwrap();
})
}
if let Some(ty) = tcx.node_types.borrow().get(&id) {
rbml_w.tag(c::tag_table_node_type, |rbml_w| {
rbml_w.id(id);
- rbml_w.tag(c::tag_table_val, |rbml_w| {
- rbml_w.emit_ty(ecx, *ty);
- })
+ rbml_w.emit_ty(ecx, *ty);
})
}
if let Some(item_substs) = tcx.item_substs.borrow().get(&id) {
rbml_w.tag(c::tag_table_item_subst, |rbml_w| {
rbml_w.id(id);
- rbml_w.tag(c::tag_table_val, |rbml_w| {
- rbml_w.emit_substs(ecx, &item_substs.substs);
- })
+ rbml_w.emit_substs(ecx, &item_substs.substs);
})
}
if let Some(fv) = tcx.freevars.borrow().get(&id) {
rbml_w.tag(c::tag_table_freevars, |rbml_w| {
rbml_w.id(id);
- rbml_w.tag(c::tag_table_val, |rbml_w| {
- rbml_w.emit_from_vec(fv, |rbml_w, fv_entry| {
- Ok(encode_freevar_entry(rbml_w, fv_entry))
- });
- })
+ rbml_w.emit_from_vec(fv, |rbml_w, fv_entry| {
+ Ok(encode_freevar_entry(rbml_w, fv_entry))
+ });
});
for freevar in fv {
rbml_w.tag(c::tag_table_upvar_capture_map, |rbml_w| {
rbml_w.id(id);
- rbml_w.tag(c::tag_table_val, |rbml_w| {
- let var_id = freevar.def.def_id().node;
- let upvar_id = ty::UpvarId {
- var_id: var_id,
- closure_expr_id: id
- };
- let upvar_capture = tcx.upvar_capture_map.borrow()[upvar_id].clone();
- var_id.encode(rbml_w);
- upvar_capture.encode(rbml_w);
- })
+
+ let var_id = freevar.def.def_id().node;
+ let upvar_id = ty::UpvarId {
+ var_id: var_id,
+ closure_expr_id: id
+ };
+ let upvar_capture = tcx.upvar_capture_map.borrow()[upvar_id].clone();
+ var_id.encode(rbml_w);
+ upvar_capture.encode(rbml_w);
})
}
}
if let Some(type_scheme) = tcx.tcache.borrow().get(&lid) {
rbml_w.tag(c::tag_table_tcache, |rbml_w| {
rbml_w.id(id);
- rbml_w.tag(c::tag_table_val, |rbml_w| {
- rbml_w.emit_type_scheme(ecx, type_scheme.clone());
- })
+ rbml_w.emit_type_scheme(ecx, type_scheme.clone());
})
}
if let Some(type_param_def) = tcx.ty_param_defs.borrow().get(&id) {
rbml_w.tag(c::tag_table_param_defs, |rbml_w| {
rbml_w.id(id);
- rbml_w.tag(c::tag_table_val, |rbml_w| {
- rbml_w.emit_type_param_def(ecx, type_param_def)
- })
+ rbml_w.emit_type_param_def(ecx, type_param_def)
})
}
if let Some(method) = tcx.method_map.borrow().get(&method_call) {
rbml_w.tag(c::tag_table_method_map, |rbml_w| {
rbml_w.id(id);
- rbml_w.tag(c::tag_table_val, |rbml_w| {
- encode_method_callee(ecx, rbml_w, method_call.adjustment, method)
- })
+ encode_method_callee(ecx, rbml_w, method_call.adjustment, method)
})
}
if let Some(trait_ref) = tcx.object_cast_map.borrow().get(&id) {
rbml_w.tag(c::tag_table_object_cast_map, |rbml_w| {
rbml_w.id(id);
- rbml_w.tag(c::tag_table_val, |rbml_w| {
- rbml_w.emit_trait_ref(ecx, &*trait_ref.0);
- })
+ rbml_w.emit_trait_ref(ecx, &*trait_ref.0);
})
}
if let Some(method) = tcx.method_map.borrow().get(&method_call) {
rbml_w.tag(c::tag_table_method_map, |rbml_w| {
rbml_w.id(id);
- rbml_w.tag(c::tag_table_val, |rbml_w| {
- encode_method_callee(ecx, rbml_w, method_call.adjustment, method)
- })
+ encode_method_callee(ecx, rbml_w, method_call.adjustment, method)
})
}
}
if let Some(method) = tcx.method_map.borrow().get(&method_call) {
rbml_w.tag(c::tag_table_method_map, |rbml_w| {
rbml_w.id(id);
- rbml_w.tag(c::tag_table_val, |rbml_w| {
- encode_method_callee(ecx, rbml_w,
- method_call.adjustment, method)
- })
+ encode_method_callee(ecx, rbml_w,
+ method_call.adjustment, method)
})
}
}
rbml_w.tag(c::tag_table_adjustments, |rbml_w| {
rbml_w.id(id);
- rbml_w.tag(c::tag_table_val, |rbml_w| {
- rbml_w.emit_auto_adjustment(ecx, adjustment);
- })
+ rbml_w.emit_auto_adjustment(ecx, adjustment);
})
}
if let Some(closure_type) = tcx.closure_tys.borrow().get(&ast_util::local_def(id)) {
rbml_w.tag(c::tag_table_closure_tys, |rbml_w| {
rbml_w.id(id);
- rbml_w.tag(c::tag_table_val, |rbml_w| {
- rbml_w.emit_closure_type(ecx, closure_type);
- })
+ rbml_w.emit_closure_type(ecx, closure_type);
})
}
if let Some(closure_kind) = tcx.closure_kinds.borrow().get(&ast_util::local_def(id)) {
rbml_w.tag(c::tag_table_closure_kinds, |rbml_w| {
rbml_w.id(id);
- rbml_w.tag(c::tag_table_val, |rbml_w| {
- encode_closure_kind(rbml_w, *closure_kind)
- })
+ encode_closure_kind(rbml_w, *closure_kind)
})
}
for &qualif in tcx.const_qualif_map.borrow().get(&id).iter() {
rbml_w.tag(c::tag_table_const_qualif, |rbml_w| {
rbml_w.id(id);
- rbml_w.tag(c::tag_table_val, |rbml_w| {
- qualif.encode(rbml_w).unwrap()
- })
+ qualif.encode(rbml_w).unwrap()
})
}
}
ast_doc: rbml::Doc) {
let tbl_doc = ast_doc.get(c::tag_table as uint);
reader::docs(tbl_doc, |tag, entry_doc| {
- let id0 = entry_doc.get(c::tag_table_id as uint).as_int();
- let id = dcx.tr_id(id0 as ast::NodeId);
+ let mut entry_dsr = reader::Decoder::new(entry_doc);
+ let id0: ast::NodeId = Decodable::decode(&mut entry_dsr).unwrap();
+ let id = dcx.tr_id(id0);
debug!(">> Side table document with tag 0x{:x} \
found for id {} (orig {})",
tag, id, id0);
- let decoded_tag: Option<c::astencode_tag> = FromPrimitive::from_uint(tag);
+ let decoded_tag: Option<c::astencode_tag> = FromPrimitive::from_usize(tag);
match decoded_tag {
None => {
dcx.tcx.sess.bug(
tag));
}
Some(value) => {
- let val_doc = entry_doc.get(c::tag_table_val as uint);
- let mut val_dsr = reader::Decoder::new(val_doc);
- let val_dsr = &mut val_dsr;
+ let val_dsr = &mut entry_dsr;
match value {
c::tag_table_def => {
- let def = decode_def(dcx, val_doc);
+ let def = decode_def(dcx, val_dsr);
dcx.tcx.def_map.borrow_mut().insert(id, def::PathResolution {
base_def: def,
// This doesn't matter cross-crate.
fn roundtrip(in_item: Option<P<ast::Item>>) {
let in_item = in_item.unwrap();
let mut wr = SeekableMemWriter::new();
- encode_item_ast(&mut writer::Encoder::new(&mut wr), &*in_item);
+ encode_item_ast(&mut Encoder::new(&mut wr), &*in_item);
let rbml_doc = rbml::Doc::new(wr.get_ref());
let out_item = decode_item_ast(rbml_doc);
match const_eval::eval_const_expr_partial(self.tcx, ex, None) {
Ok(_) => {}
Err(msg) => {
- span_err!(self.tcx.sess, ex.span, E0020,
- "{} in a constant expression", msg)
+ span_err!(self.tcx.sess, msg.span, E0020,
+ "{} in a constant expression",
+ msg.description())
}
}
}
use self::WitnessPreference::*;
use middle::const_eval::{compare_const_vals, const_bool, const_float, const_val};
-use middle::const_eval::{const_expr_to_pat, eval_const_expr, lookup_const_by_id};
+use middle::const_eval::{eval_const_expr, eval_const_expr_partial};
+use middle::const_eval::{const_expr_to_pat, lookup_const_by_id};
use middle::def::*;
use middle::expr_use_visitor::{ConsumeMode, Delegate, ExprUseVisitor, Init};
use middle::expr_use_visitor::{JustWrite, LoanCause, MutateMode};
}
}
-fn is_expr_const_nan(tcx: &ty::ctxt, expr: &ast::Expr) -> bool {
- match eval_const_expr(tcx, expr) {
- const_float(f) => f.is_nan(),
- _ => false
- }
-}
-
fn check_for_bindings_named_the_same_as_variants(cx: &MatchCheckCtxt, pat: &Pat) {
ast_util::walk_pat(pat, |p| {
match p.node {
"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));
// Check that we do not match against a static NaN (#6804)
fn check_for_static_nan(cx: &MatchCheckCtxt, pat: &Pat) {
ast_util::walk_pat(pat, |p| {
- match p.node {
- ast::PatLit(ref expr) if is_expr_const_nan(cx.tcx, &**expr) => {
- span_warn!(cx.tcx.sess, p.span, E0003,
- "unmatchable NaN in pattern, \
- use the is_nan method in a guard instead");
+ if let ast::PatLit(ref expr) = p.node {
+ match eval_const_expr_partial(cx.tcx, &**expr, None) {
+ Ok(const_float(f)) if f.is_nan() => {
+ span_warn!(cx.tcx.sess, p.span, E0003,
+ "unmatchable NaN in pattern, \
+ use the is_nan method in a guard instead");
+ }
+ Ok(_) => {}
+
+ Err(err) => {
+ 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()));
+ if !subspan {
+ cx.tcx.sess.span_note(p.span,
+ "in pattern here")
+ }
+ }
}
- _ => ()
}
true
});
use syntax::ptr::P;
use syntax::{ast_map, ast_util, codemap};
+use std::borrow::{Cow, IntoCow};
+use std::num::wrapping::OverflowingOps;
use std::cmp::Ordering;
use std::collections::hash_map::Entry::Vacant;
use std::{i8, i16, i32, i64};
None => {}
}
let expr_id = match csearch::maybe_get_item_ast(tcx, enum_def,
- box |a, b, c, d| astencode::decode_inlined_item(a, b, c, d)) {
+ Box::new(|a, b, c, d| astencode::decode_inlined_item(a, b, c, d))) {
csearch::FoundAst::Found(&ast::IIItem(ref item)) => match item.node {
ast::ItemEnum(ast::EnumDef { ref variants }, _) => {
// NOTE this doesn't do the right thing, it compares inlined
None => {}
}
let expr_id = match csearch::maybe_get_item_ast(tcx, def_id,
- box |a, b, c, d| astencode::decode_inlined_item(a, b, c, d)) {
+ Box::new(|a, b, c, d| astencode::decode_inlined_item(a, b, c, d))) {
csearch::FoundAst::Found(&ast::IIItem(ref item)) => match item.node {
ast::ItemConst(_, ref const_expr) => Some(const_expr.id),
_ => None
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(e.span, &s[..])
+ Err(s) => tcx.sess.span_fatal(s.span, &s.description())
}
}
+
+#[derive(Clone)]
+pub struct ConstEvalErr {
+ pub span: Span,
+ pub kind: ErrKind,
+}
+
+#[derive(Clone)]
+pub enum ErrKind {
+ CannotCast,
+ CannotCastTo(&'static str),
+ InvalidOpForBools(ast::BinOp_),
+ InvalidOpForFloats(ast::BinOp_),
+ InvalidOpForIntUint(ast::BinOp_),
+ InvalidOpForUintInt(ast::BinOp_),
+ NegateOnString,
+ NegateOnBoolean,
+ NegateOnBinary,
+ NotOnFloat,
+ NotOnString,
+ NotOnBinary,
+
+ AddiWithOverflow(i64, i64),
+ SubiWithOverflow(i64, i64),
+ MuliWithOverflow(i64, i64),
+ AdduWithOverflow(u64, u64),
+ SubuWithOverflow(u64, u64),
+ MuluWithOverflow(u64, u64),
+ DivideByZero,
+ DivideWithOverflow,
+ ModuloByZero,
+ ModuloWithOverflow,
+ MissingStructField,
+ NonConstPath,
+ NonConstStruct,
+ TupleIndexOutOfBounds,
+
+ MiscBinaryOp,
+ MiscCatchAll,
+}
+
+impl ConstEvalErr {
+ pub fn description(&self) -> Cow<str> {
+ use self::ErrKind::*;
+ match self.kind {
+ CannotCast => "can't cast this type".into_cow(),
+ CannotCastTo(s) => format!("can't cast this type to {}", s).into_cow(),
+ InvalidOpForBools(_) => "can't do this op on bools".into_cow(),
+ InvalidOpForFloats(_) => "can't do this op on floats".into_cow(),
+ InvalidOpForIntUint(..) => "can't do this op on an int and uint".into_cow(),
+ InvalidOpForUintInt(..) => "can't do this op on a uint and int".into_cow(),
+ NegateOnString => "negate on string".into_cow(),
+ NegateOnBoolean => "negate on boolean".into_cow(),
+ NegateOnBinary => "negate on binary literal".into_cow(),
+ NotOnFloat => "not on float or string".into_cow(),
+ NotOnString => "not on float or string".into_cow(),
+ NotOnBinary => "not on binary literal".into_cow(),
+
+ AddiWithOverflow(..) => "attempted to add with overflow".into_cow(),
+ SubiWithOverflow(..) => "attempted to sub with overflow".into_cow(),
+ MuliWithOverflow(..) => "attempted to mul with overflow".into_cow(),
+ AdduWithOverflow(..) => "attempted to add with overflow".into_cow(),
+ SubuWithOverflow(..) => "attempted to sub with overflow".into_cow(),
+ MuluWithOverflow(..) => "attempted to mul with overflow".into_cow(),
+ DivideByZero => "attempted to divide by zero".into_cow(),
+ DivideWithOverflow => "attempted to divide with overflow".into_cow(),
+ ModuloByZero => "attempted remainder with a divisor of zero".into_cow(),
+ ModuloWithOverflow => "attempted remainder with overflow".into_cow(),
+ MissingStructField => "nonexistent struct field".into_cow(),
+ NonConstPath => "non-constant path in constant expr".into_cow(),
+ NonConstStruct => "non-constant struct in constant expr".into_cow(),
+ TupleIndexOutOfBounds => "tuple index out of bounds".into_cow(),
+
+ MiscBinaryOp => "bad operands for binary".into_cow(),
+ MiscCatchAll => "unsupported constant expr".into_cow(),
+ }
+ }
+}
+
+macro_rules! signal {
+ ($e:expr, $ctor:ident) => {
+ return Err(ConstEvalErr { span: $e.span, kind: ErrKind::$ctor })
+ };
+
+ ($e:expr, $ctor:ident($($arg:expr),*)) => {
+ return Err(ConstEvalErr { span: $e.span, kind: ErrKind::$ctor($($arg),*) })
+ }
+}
+
+fn checked_add_int(e: &Expr, a: i64, b: i64) -> Result<const_val, ConstEvalErr> {
+ let (ret, oflo) = a.overflowing_add(b);
+ if !oflo { Ok(const_int(ret)) } else { signal!(e, AddiWithOverflow(a, b)) }
+}
+fn checked_sub_int(e: &Expr, a: i64, b: i64) -> Result<const_val, ConstEvalErr> {
+ let (ret, oflo) = a.overflowing_sub(b);
+ if !oflo { Ok(const_int(ret)) } else { signal!(e, SubiWithOverflow(a, b)) }
+}
+fn checked_mul_int(e: &Expr, a: i64, b: i64) -> Result<const_val, ConstEvalErr> {
+ let (ret, oflo) = a.overflowing_mul(b);
+ if !oflo { Ok(const_int(ret)) } else { signal!(e, MuliWithOverflow(a, b)) }
+}
+
+fn checked_add_uint(e: &Expr, a: u64, b: u64) -> Result<const_val, ConstEvalErr> {
+ let (ret, oflo) = a.overflowing_add(b);
+ if !oflo { Ok(const_uint(ret)) } else { signal!(e, AdduWithOverflow(a, b)) }
+}
+fn checked_sub_uint(e: &Expr, a: u64, b: u64) -> Result<const_val, ConstEvalErr> {
+ let (ret, oflo) = a.overflowing_sub(b);
+ if !oflo { Ok(const_uint(ret)) } else { signal!(e, SubuWithOverflow(a, b)) }
+}
+fn checked_mul_uint(e: &Expr, a: u64, b: u64) -> Result<const_val, ConstEvalErr> {
+ let (ret, oflo) = a.overflowing_mul(b);
+ if !oflo { Ok(const_uint(ret)) } else { signal!(e, MuluWithOverflow(a, b)) }
+}
+
+
pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
e: &Expr,
ty_hint: Option<Ty<'tcx>>)
- -> Result<const_val, String> {
- fn fromb(b: bool) -> Result<const_val, String> { Ok(const_int(b as i64)) }
+ -> Result<const_val, ConstEvalErr> {
+ fn fromb(b: bool) -> const_val { const_int(b as i64) }
let ety = ty_hint.or_else(|| ty::expr_ty_opt(tcx, e));
- match e.node {
+ let result = match e.node {
ast::ExprUnary(ast::UnNeg, ref inner) => {
- match eval_const_expr_partial(tcx, &**inner, ety) {
- Ok(const_float(f)) => Ok(const_float(-f)),
- Ok(const_int(i)) => Ok(const_int(-i)),
- Ok(const_uint(i)) => Ok(const_uint(-i)),
- Ok(const_str(_)) => Err("negate on string".to_string()),
- Ok(const_bool(_)) => Err("negate on boolean".to_string()),
- ref err => ((*err).clone())
+ match try!(eval_const_expr_partial(tcx, &**inner, ety)) {
+ const_float(f) => const_float(-f),
+ const_int(i) => const_int(-i),
+ const_uint(i) => const_uint(-i),
+ const_str(_) => signal!(e, NegateOnString),
+ const_bool(_) => signal!(e, NegateOnBoolean),
+ const_binary(_) => signal!(e, NegateOnBinary),
}
}
ast::ExprUnary(ast::UnNot, ref inner) => {
- match eval_const_expr_partial(tcx, &**inner, ety) {
- Ok(const_int(i)) => Ok(const_int(!i)),
- Ok(const_uint(i)) => Ok(const_uint(!i)),
- Ok(const_bool(b)) => Ok(const_bool(!b)),
- _ => Err("not on float or string".to_string())
+ match try!(eval_const_expr_partial(tcx, &**inner, ety)) {
+ const_int(i) => const_int(!i),
+ const_uint(i) => const_uint(!i),
+ const_bool(b) => const_bool(!b),
+ const_str(_) => signal!(e, NotOnString),
+ const_float(_) => signal!(e, NotOnFloat),
+ const_binary(_) => signal!(e, NotOnBinary),
}
}
ast::ExprBinary(op, ref a, ref b) => {
ast::BiShl | ast::BiShr => Some(tcx.types.uint),
_ => ety
};
- match (eval_const_expr_partial(tcx, &**a, ety),
- eval_const_expr_partial(tcx, &**b, b_ty)) {
- (Ok(const_float(a)), Ok(const_float(b))) => {
+ match (try!(eval_const_expr_partial(tcx, &**a, ety)),
+ try!(eval_const_expr_partial(tcx, &**b, b_ty))) {
+ (const_float(a), const_float(b)) => {
match op.node {
- ast::BiAdd => Ok(const_float(a + b)),
- ast::BiSub => Ok(const_float(a - b)),
- ast::BiMul => Ok(const_float(a * b)),
- ast::BiDiv => Ok(const_float(a / b)),
- ast::BiRem => Ok(const_float(a % b)),
+ ast::BiAdd => const_float(a + b),
+ ast::BiSub => const_float(a - b),
+ ast::BiMul => const_float(a * b),
+ ast::BiDiv => const_float(a / b),
+ ast::BiRem => const_float(a % b),
ast::BiEq => fromb(a == b),
ast::BiLt => fromb(a < b),
ast::BiLe => fromb(a <= b),
ast::BiNe => fromb(a != b),
ast::BiGe => fromb(a >= b),
ast::BiGt => fromb(a > b),
- _ => Err("can't do this op on floats".to_string())
+ _ => signal!(e, InvalidOpForFloats(op.node))
}
}
- (Ok(const_int(a)), Ok(const_int(b))) => {
+ (const_int(a), const_int(b)) => {
let is_a_min_value = || {
let int_ty = match ty::expr_ty_opt(tcx, e).map(|ty| &ty.sty) {
Some(&ty::ty_int(int_ty)) => int_ty,
}
};
match op.node {
- ast::BiAdd => Ok(const_int(a + b)),
- ast::BiSub => Ok(const_int(a - b)),
- ast::BiMul => Ok(const_int(a * b)),
+ ast::BiAdd => try!(checked_add_int(e, a, b)),
+ ast::BiSub => try!(checked_sub_int(e, a, b)),
+ ast::BiMul => try!(checked_mul_int(e, a, b)),
ast::BiDiv => {
if b == 0 {
- Err("attempted to divide by zero".to_string())
+ signal!(e, DivideByZero);
} else if b == -1 && is_a_min_value() {
- Err("attempted to divide with overflow".to_string())
+ signal!(e, DivideWithOverflow);
} else {
- Ok(const_int(a / b))
+ const_int(a / b)
}
}
ast::BiRem => {
if b == 0 {
- Err("attempted remainder with a divisor of zero".to_string())
+ signal!(e, ModuloByZero)
} else if b == -1 && is_a_min_value() {
- Err("attempted remainder with overflow".to_string())
+ signal!(e, ModuloWithOverflow)
} else {
- Ok(const_int(a % b))
+ const_int(a % b)
}
}
- ast::BiAnd | ast::BiBitAnd => Ok(const_int(a & b)),
- ast::BiOr | ast::BiBitOr => Ok(const_int(a | b)),
- ast::BiBitXor => Ok(const_int(a ^ b)),
- ast::BiShl => Ok(const_int(a << b as uint)),
- ast::BiShr => Ok(const_int(a >> b as uint)),
+ ast::BiAnd | ast::BiBitAnd => const_int(a & b),
+ ast::BiOr | ast::BiBitOr => const_int(a | b),
+ ast::BiBitXor => const_int(a ^ b),
+ ast::BiShl => const_int(a << b as uint),
+ ast::BiShr => const_int(a >> b as uint),
ast::BiEq => fromb(a == b),
ast::BiLt => fromb(a < b),
ast::BiLe => fromb(a <= b),
ast::BiGt => fromb(a > b)
}
}
- (Ok(const_uint(a)), Ok(const_uint(b))) => {
+ (const_uint(a), const_uint(b)) => {
match op.node {
- ast::BiAdd => Ok(const_uint(a + b)),
- ast::BiSub => Ok(const_uint(a - b)),
- ast::BiMul => Ok(const_uint(a * b)),
- ast::BiDiv if b == 0 => {
- Err("attempted to divide by zero".to_string())
- }
- ast::BiDiv => Ok(const_uint(a / b)),
- ast::BiRem if b == 0 => {
- Err("attempted remainder with a divisor of \
- zero".to_string())
- }
- ast::BiRem => Ok(const_uint(a % b)),
- ast::BiAnd | ast::BiBitAnd => Ok(const_uint(a & b)),
- ast::BiOr | ast::BiBitOr => Ok(const_uint(a | b)),
- ast::BiBitXor => Ok(const_uint(a ^ b)),
- ast::BiShl => Ok(const_uint(a << b as uint)),
- ast::BiShr => Ok(const_uint(a >> b as uint)),
+ ast::BiAdd => try!(checked_add_uint(e, a, b)),
+ ast::BiSub => try!(checked_sub_uint(e, a, b)),
+ ast::BiMul => try!(checked_mul_uint(e, a, b)),
+ ast::BiDiv if b == 0 => signal!(e, DivideByZero),
+ ast::BiDiv => const_uint(a / b),
+ ast::BiRem if b == 0 => signal!(e, ModuloByZero),
+ ast::BiRem => const_uint(a % b),
+ ast::BiAnd | ast::BiBitAnd => const_uint(a & b),
+ ast::BiOr | ast::BiBitOr => const_uint(a | b),
+ ast::BiBitXor => const_uint(a ^ b),
+ ast::BiShl => const_uint(a << b as uint),
+ ast::BiShr => const_uint(a >> b as uint),
ast::BiEq => fromb(a == b),
ast::BiLt => fromb(a < b),
ast::BiLe => fromb(a <= b),
}
}
// shifts can have any integral type as their rhs
- (Ok(const_int(a)), Ok(const_uint(b))) => {
+ (const_int(a), const_uint(b)) => {
match op.node {
- ast::BiShl => Ok(const_int(a << b as uint)),
- ast::BiShr => Ok(const_int(a >> b as uint)),
- _ => Err("can't do this op on an int and uint".to_string())
+ ast::BiShl => const_int(a << b as uint),
+ ast::BiShr => const_int(a >> b as uint),
+ _ => signal!(e, InvalidOpForIntUint(op.node)),
}
}
- (Ok(const_uint(a)), Ok(const_int(b))) => {
+ (const_uint(a), const_int(b)) => {
match op.node {
- ast::BiShl => Ok(const_uint(a << b as uint)),
- ast::BiShr => Ok(const_uint(a >> b as uint)),
- _ => Err("can't do this op on a uint and int".to_string())
+ ast::BiShl => const_uint(a << b as uint),
+ ast::BiShr => const_uint(a >> b as uint),
+ _ => signal!(e, InvalidOpForUintInt(op.node)),
}
}
- (Ok(const_bool(a)), Ok(const_bool(b))) => {
- Ok(const_bool(match op.node {
+ (const_bool(a), const_bool(b)) => {
+ const_bool(match op.node {
ast::BiAnd => a && b,
ast::BiOr => a || b,
ast::BiBitXor => a ^ b,
ast::BiBitOr => a | b,
ast::BiEq => a == b,
ast::BiNe => a != b,
- _ => return Err("can't do this op on bools".to_string())
- }))
+ _ => signal!(e, InvalidOpForBools(op.node)),
+ })
}
- _ => Err("bad operands for binary".to_string())
+
+ _ => signal!(e, MiscBinaryOp),
}
}
ast::ExprCast(ref base, ref target_ty) => {
// Prefer known type to noop, but always have a type hint.
let base_hint = ty::expr_ty_opt(tcx, &**base).unwrap_or(ety);
let val = try!(eval_const_expr_partial(tcx, &**base, Some(base_hint)));
- cast_const(val, ety)
+ match cast_const(val, ety) {
+ Ok(val) => val,
+ Err(kind) => return Err(ConstEvalErr { span: e.span, kind: kind }),
+ }
}
ast::ExprPath(..) => {
let opt_def = tcx.def_map.borrow().get(&e.id).map(|d| d.full_def());
};
let const_expr = match const_expr {
Some(actual_e) => actual_e,
- None => return Err("non-constant path in constant expr".to_string())
+ None => signal!(e, NonConstPath)
};
let ety = ety.or_else(|| const_ty.and_then(|ty| ast_ty_to_prim_ty(tcx, ty)));
- eval_const_expr_partial(tcx, const_expr, ety)
+ try!(eval_const_expr_partial(tcx, const_expr, ety))
}
ast::ExprLit(ref lit) => {
- Ok(lit_to_const(&**lit, ety))
+ lit_to_const(&**lit, ety)
}
- ast::ExprParen(ref e) => eval_const_expr_partial(tcx, &**e, ety),
+ ast::ExprParen(ref e) => try!(eval_const_expr_partial(tcx, &**e, ety)),
ast::ExprBlock(ref block) => {
match block.expr {
- Some(ref expr) => eval_const_expr_partial(tcx, &**expr, ety),
- None => Ok(const_int(0i64))
+ Some(ref expr) => try!(eval_const_expr_partial(tcx, &**expr, ety)),
+ None => const_int(0)
}
}
ast::ExprTupField(ref base, index) => {
if let Some(&ast::ExprTup(ref fields)) = lookup_const(tcx, &**base).map(|s| &s.node) {
// Check that the given index is within bounds and evaluate its value
if fields.len() > index.node {
- return eval_const_expr_partial(tcx, &*fields[index.node], None)
+ return eval_const_expr_partial(tcx, &*fields[index.node], None);
} else {
- return Err("tuple index out of bounds".to_string())
+ signal!(e, TupleIndexOutOfBounds);
}
}
- Err("non-constant struct in constant expr".to_string())
+ signal!(e, NonConstStruct);
}
ast::ExprField(ref base, field_name) => {
// Get the base expression if it is a struct and it is constant
// Check that the given field exists and evaluate it
if let Some(f) = fields.iter().find(|f|
f.ident.node.as_str() == field_name.node.as_str()) {
- return eval_const_expr_partial(tcx, &*f.expr, None)
+ return eval_const_expr_partial(tcx, &*f.expr, None);
} else {
- return Err("nonexistent struct field".to_string())
+ signal!(e, MissingStructField);
}
}
- Err("non-constant struct in constant expr".to_string())
+ signal!(e, NonConstStruct);
}
- _ => Err("unsupported constant expr".to_string())
- }
+ _ => signal!(e, MiscCatchAll)
+ };
+
+ Ok(result)
}
-fn cast_const(val: const_val, ty: Ty) -> Result<const_val, String> {
+fn cast_const(val: const_val, ty: Ty) -> Result<const_val, ErrKind> {
macro_rules! define_casts {
($($ty_pat:pat => (
$intermediate_ty:ty,
const_uint(u) => Ok($const_type(u as $intermediate_ty as $target_ty)),
const_int(i) => Ok($const_type(i as $intermediate_ty as $target_ty)),
const_float(f) => Ok($const_type(f as $intermediate_ty as $target_ty)),
- _ => Err(concat!("can't cast this type to ",
- stringify!($const_type)).to_string())
+ _ => Err(ErrKind::CannotCastTo(stringify!($const_type))),
}
},)*
- _ => Err("can't cast this type".to_string())
+ _ => Err(ErrKind::CannotCast),
})
}
-> Option<Ordering> {
let a = match eval_const_expr_partial(tcx, a, ty_hint) {
Ok(a) => a,
- Err(s) => {
- tcx.sess.span_err(a.span, &s[..]);
+ Err(e) => {
+ 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(s) => {
- tcx.sess.span_err(b.span, &s[..]);
+ Err(e) => {
+ tcx.sess.span_err(b.span, &e.description());
return None;
}
};
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;
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,
oper: O,
id_range: IdRange,
bits_per_id: uint) -> DataFlowContext<'a, 'tcx, O> {
- let words_per_id = (bits_per_id + usize::BITS - 1) / usize::BITS;
+ let words_per_id = (bits_per_id + usize::BITS as usize - 1) / usize::BITS as usize;
let num_nodes = cfg.graph.all_nodes().len();
debug!("DataFlowContext::new(analysis_name: {}, id_range={:?}, \
for (word_index, &word) in words.iter().enumerate() {
if word != 0 {
- let base_index = word_index * usize::BITS;
+ let base_index = word_index * usize::BITS as usize;
for offset in 0..usize::BITS {
let bit = 1 << offset;
if (word & bit) != 0 {
// whether the bit_index is greater than the
// actual value the user specified and stop
// iterating if so.
- let bit_index = base_index + offset;
+ let bit_index = base_index + offset as usize;
if bit_index >= self.bits_per_id {
return true;
} else if !f(bit_index) {
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));
fn set_bit(words: &mut [uint], bit: uint) -> bool {
debug!("set_bit: words={} bit={}",
mut_bits_to_string(words), bit_str(bit));
- let word = bit / usize::BITS;
- let bit_in_word = bit % usize::BITS;
+ let word = bit / usize::BITS as usize;
+ let bit_in_word = bit % usize::BITS as usize;
let bit_mask = 1 << bit_in_word;
debug!("word={} bit_in_word={} bit_mask={}", word, bit_in_word, word);
let oldv = words[word];
let def_id = tcx.lang_items.owned_box().unwrap();
Some(StructSimplifiedType(def_id))
}
- ty::ty_closure(def_id, _, _) => {
+ ty::ty_closure(def_id, _) => {
Some(ClosureSimplifiedType(def_id))
}
ty::ty_tup(ref tys) => {
Ok(ty::mk_struct(tcx, a_id, tcx.mk_substs(substs)))
}
- (&ty::ty_closure(a_id, a_region, a_substs),
- &ty::ty_closure(b_id, b_region, b_substs))
+ (&ty::ty_closure(a_id, a_substs),
+ &ty::ty_closure(b_id, b_substs))
if a_id == b_id => {
// All ty_closure types with the same id represent
// the (anonymous) type of the same closure expression. So
// all of their regions should be equated.
- let region = try!(this.equate().regions(*a_region, *b_region));
let substs = try!(this.substs_variances(None, a_substs, b_substs));
- Ok(ty::mk_closure(tcx, a_id, tcx.mk_region(region), tcx.mk_substs(substs)))
+ Ok(ty::mk_closure(tcx, a_id, tcx.mk_substs(substs)))
}
(&ty::ty_uniq(a_inner), &ty::ty_uniq(b_inner)) => {
// 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 `{}: {}`...",
// 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`...",
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 `{}`",
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;
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))
}
}
pub fn item_name(index: uint) -> &'static str {
- let item: Option<LangItem> = FromPrimitive::from_uint(index);
+ let item: Option<LangItem> = FromPrimitive::from_usize(index);
match item {
$( Some($variant) => $name, )*
None => "???"
clean_exit_var: Variable
}
-static ACC_READ: u32 = 1;
-static ACC_WRITE: u32 = 2;
-static ACC_USE: u32 = 4;
+const ACC_READ: u32 = 1;
+const ACC_WRITE: u32 = 2;
+const ACC_USE: u32 = 4;
struct Liveness<'a, 'tcx: 'a> {
ir: &'a mut IrMaps<'a, 'tcx>,
fn fn_ret(&self, id: NodeId) -> ty::PolyFnOutput<'tcx> {
let fn_ty = ty::node_id_to_type(self.ir.tcx, id);
match fn_ty.sty {
- ty::ty_closure(closure_def_id, _, substs) =>
+ ty::ty_closure(closure_def_id, substs) =>
self.ir.tcx.closure_type(closure_def_id, substs).sig.output(),
_ =>
ty::ty_fn_ret(fn_ty),
def::DefUpvar(var_id, fn_node_id) => {
let ty = try!(self.node_ty(fn_node_id));
match ty.sty {
- ty::ty_closure(closure_id, _, _) => {
+ ty::ty_closure(closure_id, _) => {
match self.typer.closure_kind(closure_id) {
Some(kind) => {
self.cat_upvar(id, span, var_id, fn_node_id, kind)
#[derive(Debug, Copy)]
pub struct Context {
+ /// the scope that contains any new variables declared
var_parent: InnermostDeclaringBlock,
+ /// region parent of expressions etc
parent: InnermostEnclosingExpr,
}
/// 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, _, _) => {
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 {
/// 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.
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;
{
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) => {
debug!("consider_unification_despite_ambiguity: self_ty.sty={:?}",
self_ty.sty);
match self_ty.sty {
- ty::ty_closure(closure_def_id, _, substs) => {
+ ty::ty_closure(closure_def_id, substs) => {
let closure_typer = selcx.closure_typer();
let closure_type = closure_typer.closure_type(closure_def_id, substs);
let ty::Binder((_, ret_type)) =
// lifetimes can appear inside the self-type.
let self_ty = self.infcx.shallow_resolve(obligation.self_ty());
let (closure_def_id, substs) = match self_ty.sty {
- ty::ty_closure(id, _, ref substs) => (id, substs.clone()),
+ ty::ty_closure(id, ref substs) => (id, substs.clone()),
_ => { return; }
};
assert!(!substs.has_escaping_regions());
let self_ty = self.infcx.shallow_resolve(obligation.self_ty());
let (closure_def_id, substs) = match self_ty.sty {
- ty::ty_closure(id, _, ref substs) => (id, substs.clone()),
+ ty::ty_closure(id, ref substs) => (id, substs.clone()),
ty::ty_infer(ty::TyVar(_)) => {
debug!("assemble_unboxed_closure_candidates: ambiguous self-type");
candidates.ambiguous = true;
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);
}
}
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()))
}
}
// (T1, ..., Tn) -- meets any bound that all of T1...Tn meet
ty::ty_tup(ref tys) => Ok(If(tys.clone())),
- ty::ty_closure(def_id, _, substs) => {
+ ty::ty_closure(def_id, substs) => {
// FIXME -- This case is tricky. In the case of by-ref
// closures particularly, we need the results of
// inference to decide how to reflect the type of each
Some(tys.clone())
}
- ty::ty_closure(def_id, _, substs) => {
+ ty::ty_closure(def_id, substs) => {
assert_eq!(def_id.krate, ast::LOCAL_CRATE);
match self.closure_typer.closure_upvars(def_id, substs) {
}
}
+ // 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)
}
};
- 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,
}
}
- VtableObjectData { object_ty: self_ty }
+ VtableObjectData { object_ty: self_ty,
+ upcast_trait_ref: upcast_trait_ref }
}
fn confirm_fn_pointer_candidate(&mut self,
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> {
/// '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>)
{
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
// 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
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);
}
}
// 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>)
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;
}
}
}
+
///////////////////////////////////////////////////////////////////////////
// Other
///////////////////////////////////////////////////////////////////////////
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
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::*;
use std::mem;
use std::ops;
use std::rc::Rc;
-use std::vec::{CowVec, IntoIter};
+use std::vec::IntoIter;
use collections::enum_set::{EnumSet, CLike};
use std::collections::{HashMap, HashSet};
use syntax::abi;
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>,
/// 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>,
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>>>,
/// 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.
/// 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,
ty_trait(Box<TyTrait<'tcx>>),
ty_struct(DefId, &'tcx Substs<'tcx>),
- ty_closure(DefId, &'tcx Region, &'tcx Substs<'tcx>),
+ ty_closure(DefId, &'tcx Substs<'tcx>),
ty_tup(Vec<Ty<'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),
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)]
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>>
/// 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
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()),
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()),
}
}
- &ty_closure(_, region, substs) => {
- self.add_region(*region);
+ &ty_closure(_, substs) => {
self.add_substs(substs);
}
mk_t(cx, ty_struct(struct_id, substs))
}
-pub fn mk_closure<'tcx>(cx: &ctxt<'tcx>, closure_id: ast::DefId,
- region: &'tcx Region, substs: &'tcx Substs<'tcx>)
+pub fn mk_closure<'tcx>(cx: &ctxt<'tcx>, closure_id: ast::DefId, substs: &'tcx Substs<'tcx>)
-> Ty<'tcx> {
- mk_t(cx, ty_closure(closure_id, region, substs))
+ mk_t(cx, ty_closure(closure_id, substs))
}
pub fn mk_var<'tcx>(cx: &ctxt<'tcx>, v: TyVid) -> Ty<'tcx> {
apply_lang_items(cx, did, res)
}
- ty_closure(did, r, substs) => {
+ ty_closure(did, substs) => {
// FIXME(#14449): `borrowed_contents` below assumes `&mut` closure.
let param_env = ty::empty_parameter_environment(cx);
let upvars = closure_upvars(¶m_env, did, substs).unwrap();
- TypeContents::union(&upvars,
- |f| tc_ty(cx, &f.ty, cache))
- | borrowed_contents(*r, MutMutable)
+ TypeContents::union(&upvars, |f| tc_ty(cx, &f.ty, cache))
}
ty_tup(ref tys) => {
Some(tt.principal_def_id()),
ty_struct(id, _) |
ty_enum(id, _) |
- ty_closure(id, _, _) =>
+ ty_closure(id, _) =>
Some(id),
_ =>
None
pub fn enum_variants<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId)
-> Rc<Vec<Rc<VariantInfo<'tcx>>>> {
+ use std::num::Int; // For checked_add
memoized(&cx.enum_var_cache, id, |id: ast::DefId| {
if ast::LOCAL_CRATE != id.krate {
Rc::new(csearch::get_enum_variants(cx, id))
let mut last_discriminant: Option<Disr> = None;
Rc::new(enum_definition.variants.iter().map(|variant| {
- let mut discriminant = match last_discriminant {
- Some(val) => val + 1,
- None => INITIAL_DISCRIMINANT_VALUE
- };
-
+ let mut discriminant = INITIAL_DISCRIMINANT_VALUE;
if let Some(ref e) = variant.node.disr_expr {
// Preserve all values, and prefer signed.
let ty = Some(cx.types.i64);
"expected signed integer constant");
}
Err(err) => {
- span_err!(cx.sess, e.span, E0305,
- "expected constant: {}", err);
+ span_err!(cx.sess, err.span, E0305,
+ "constant evaluation error: {}",
+ err.description());
+ }
+ }
+ } else {
+ if let Some(val) = last_discriminant {
+ if let Some(v) = val.checked_add(1) {
+ discriminant = v
+ } else {
+ cx.sess.span_err(
+ variant.span,
+ &format!("Discriminant overflowed!"));
}
+ } else {
+ discriminant = INITIAL_DISCRIMINANT_VALUE;
}
- };
+ }
last_discriminant = Some(discriminant);
Rc::new(VariantInfo::from_ast_variant(cx, &**variant,
})
}
-/// 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>
{
})
}
-/// 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>(
/// Get the attributes of a definition.
pub fn get_attrs<'tcx>(tcx: &'tcx ctxt, did: DefId)
- -> CowVec<'tcx, ast::Attribute> {
+ -> Cow<'tcx, [ast::Attribute]> {
if is_local(did) {
- let item = tcx.map.expect_item(did.node);
- Cow::Borrowed(&item.attrs)
+ Cow::Borrowed(tcx.map.attrs(did.node))
} else {
Cow::Owned(csearch::get_item_attrs(&tcx.sess.cstore, did))
}
pub fn is_binopable<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>, op: ast::BinOp) -> bool {
#![allow(non_upper_case_globals)]
- static tycat_other: int = 0;
- static tycat_bool: int = 1;
- static tycat_char: int = 2;
- static tycat_int: int = 3;
- static tycat_float: int = 4;
- static tycat_raw_ptr: int = 6;
-
- static opcat_add: int = 0;
- static opcat_sub: int = 1;
- static opcat_mult: int = 2;
- static opcat_shift: int = 3;
- static opcat_rel: int = 4;
- static opcat_eq: int = 5;
- static opcat_bit: int = 6;
- static opcat_logic: int = 7;
- static opcat_mod: int = 8;
+ const tycat_other: int = 0;
+ const tycat_bool: int = 1;
+ const tycat_char: int = 2;
+ const tycat_int: int = 3;
+ const tycat_float: int = 4;
+ const tycat_raw_ptr: int = 6;
+
+ const opcat_add: int = 0;
+ const opcat_sub: int = 1;
+ const opcat_mult: int = 2;
+ const opcat_shift: int = 3;
+ const opcat_rel: int = 4;
+ const opcat_eq: int = 5;
+ const opcat_bit: int = 6;
+ const opcat_logic: int = 7;
+ const opcat_mod: int = 8;
fn opcat(op: ast::BinOp) -> int {
match op.node {
}
}
- static t: bool = true;
- static f: bool = false;
+ const t: bool = true;
+ const f: bool = false;
let tbl = [
// +, -, *, shift, rel, ==, bit, logic, mod
|| 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,
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.
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.
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(_) => {}
}
ty_infer(_) => unreachable!(),
ty_err => byte!(21),
- ty_closure(d, r, _) => {
+ ty_closure(d, _) => {
byte!(22);
did(state, d);
- region(state, *r);
}
ty_projection(ref data) => {
byte!(23);
ty_struct(_, substs) => {
accum_substs(accumulator, substs);
}
- ty_closure(_, region, substs) => {
- accumulator.push(*region);
+ ty_closure(_, substs) => {
accum_substs(accumulator, substs);
}
ty_bool |
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),
}
}
}
let substs = substs.fold_with(this);
ty::ty_struct(did, this.tcx().mk_substs(substs))
}
- ty::ty_closure(did, ref region, ref substs) => {
- let r = region.fold_with(this);
+ ty::ty_closure(did, ref substs) => {
let s = substs.fold_with(this);
- ty::ty_closure(did, this.tcx().mk_region(r), this.tcx().mk_substs(s))
+ ty::ty_closure(did, this.tcx().mk_substs(s))
}
ty::ty_projection(ref data) => {
ty::ty_projection(data.fold_with(this))
}
ty::ty_enum(_, ref substs) |
ty::ty_struct(_, ref substs) |
- ty::ty_closure(_, _, ref substs) => {
+ ty::ty_closure(_, ref substs) => {
self.push_reversed(substs.types.as_slice());
}
ty::ty_tup(ref ts) => {
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;
// 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,
/// 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),
/// 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 expander, None));
+ self.register_syntax_extension(token::intern(name),
+ NormalTT(Box::new(expander), None, false));
}
/// Register a compiler lint pass.
use std::collections::hash_map::Entry::{Occupied, Vacant};
use std::env;
use std::fmt;
+use std::path::PathBuf;
use llvm;
pub gc: bool,
pub optimize: OptLevel,
+ pub debug_assertions: bool,
pub debuginfo: DebugInfoLevel,
pub lint_opts: Vec<(String, lint::Level)>,
pub describe_lints: bool,
// 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
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,
pub enum Input {
/// Load source from file
- File(Path),
+ File(PathBuf),
/// The string is the source
Str(String)
}
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(),
}
}
#[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 => {}
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"),
}
}
- 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 {
crate_name: None,
alt_std_name: None,
libs: Vec::new(),
- unstable_features: UnstableFeatures::Disallow
+ unstable_features: UnstableFeatures::Disallow,
+ debug_assertions: true,
}
}
CrateTypeStaticlib,
}
-
#[derive(Clone)]
pub enum Passes {
SomePasses(Vec<String>),
#[allow(non_upper_case_globals, dead_code)]
mod $mod_desc {
pub const parse_bool: Option<&'static str> = None;
- pub const parse_opt_bool: Option<&'static str> = None;
+ pub const parse_opt_bool: Option<&'static str> =
+ Some("one of: `y`, `yes`, `on`, `n`, `no`, or `off`");
pub const parse_string: Option<&'static str> = Some("a string");
pub const parse_opt_string: Option<&'static str> = Some("a string");
pub const parse_list: Option<&'static str> = Some("a space-separated list of strings");
fn parse_opt_bool(slot: &mut Option<bool>, v: Option<&str>) -> bool {
match v {
- Some(..) => false,
+ Some(s) => {
+ match s {
+ "n" | "no" | "off" => {
+ *slot = Some(false);
+ }
+ "y" | "yes" | "on" => {
+ *slot = Some(true);
+ }
+ _ => { return false; }
+ }
+
+ true
+ },
None => { *slot = Some(true); true }
}
}
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"),
}
"Adds unstable command line options to rustc interface"),
print_enum_sizes: bool = (false, parse_bool,
"Print the size of enums and their variants"),
+ force_overflow_checks: Option<bool> = (None, parse_opt_bool,
+ "Force overflow checks on or off"),
}
pub fn default_lib_output() -> CrateType {
};
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),
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,
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 = {
}
}
};
+ 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() {
alt_std_name: None,
libs: libs,
unstable_features: get_unstable_features_setting(),
+ debug_assertions: debug_assertions,
}
}
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;
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>>,
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) {
}
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
}
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()) {
if path.is_absolute() {
path.clone()
} else {
- os::getcwd().unwrap().join(&path)
+ env::current_dir().unwrap().join(&path)
}
);
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()),
// 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)]
} 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 {
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;
}
}
}
+
+#[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()
+}
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);
let FnvHasher(mut hash) = *self;
for byte in bytes {
hash = hash ^ (*byte as u64);
- hash = hash * 0x100000001b3;
+ hash = hash.wrapping_mul(0x100000001b3);
}
*self = FnvHasher(hash);
}
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 {}",
data.item_name.user_string(cx))
}
ty_str => "str".to_string(),
- ty_closure(ref did, _, substs) => {
+ ty_closure(ref did, substs) => {
let closure_tys = cx.closure_tys.borrow();
closure_tys.get(did).map(|closure_type| {
closure_to_string(cx, &closure_type.subst(cx, substs))
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))
}
}
//! 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;
-pub static METADATA_FILENAME: &'static str = "rust.metadata.bin";
+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>
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>
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 => {}
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();
}
}
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 {
/// 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()
/// 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,
/// 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
}
/// 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(())
}
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
// Don't allow the total size of `args` to grow beyond 32,000 bytes.
// Windows will raise an error if the argument string is longer than
// 32,768, and we leave a bit of extra space for the program name.
- static ARG_LENGTH_LIMIT: uint = 32000;
+ 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
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);
}
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();
// 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]);
// 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 }
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(())
}
// 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> {
- static 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
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]
//! 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]
#![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;
pub mod abi;
pub mod archive;
+pub mod tempdir;
pub mod arm;
pub mod fs;
pub mod mips;
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();
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 {
// 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));
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"
"$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
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() {
}
#[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");
+ }
}
}
/// Create a new FixedBuffer64
fn new() -> FixedBuffer64 {
return FixedBuffer64 {
- buffer: [0u8; 64],
+ buffer: [0; 64],
buffer_idx: 0
};
}
/// 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
}
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.
macro_rules! schedule_round { ($t:expr) => (
- w[$t] = sigma1(w[$t - 2]) + w[$t - 7] + sigma0(w[$t - 15]) + w[$t - 16];
- )
+ w[$t] = sigma1(w[$t - 2]).wrapping_add(w[$t - 7])
+ .wrapping_add(sigma0(w[$t - 15])).wrapping_add(w[$t - 16]);
+ )
}
macro_rules! sha2_round {
($A:ident, $B:ident, $C:ident, $D:ident,
$E:ident, $F:ident, $G:ident, $H:ident, $K:ident, $t:expr) => (
{
- $H += sum1($E) + ch($E, $F, $G) + $K[$t] + w[$t];
- $D += $H;
- $H += sum0($A) + maj($A, $B, $C);
+ $H = $H.wrapping_add(sum1($E)).wrapping_add(ch($E, $F, $G))
+ .wrapping_add($K[$t]).wrapping_add(w[$t]);
+ $D = $D.wrapping_add($H);
+ $H = $H.wrapping_add(sum0($A)).wrapping_add(maj($A, $B, $C));
}
)
}
sha2_round!(b, c, d, e, f, g, h, a, K32, t + 7);
}
- self.h0 += a;
- self.h1 += b;
- self.h2 += c;
- self.h3 += d;
- self.h4 += e;
- self.h5 += f;
- self.h6 += g;
- self.h7 += h;
+ self.h0 = self.h0.wrapping_add(a);
+ self.h1 = self.h1.wrapping_add(b);
+ self.h2 = self.h2.wrapping_add(c);
+ self.h3 = self.h3.wrapping_add(d);
+ self.h4 = self.h4.wrapping_add(e);
+ self.h5 = self.h5.wrapping_add(f);
+ self.h6 = self.h6.wrapping_add(g);
+ self.h7 = self.h7.wrapping_add(h);
}
}
// 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);
}
let tests = wikipedia_tests;
- let mut sh = box Sha256::new();
+ let mut sh: Box<_> = box Sha256::new();
test_hash(&mut *sh, &tests);
}
#[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);
});
#[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);
});
#[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);
});
// 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::*;
.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()))
}
});
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;
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))
}
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);
}
--- /dev/null
+// 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
// 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]
/// 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!");
/// }
/// ```
///
bitflags! {
flags AnotherSetOfFlags: i8 {
- const AnotherFlag = -1_i8,
+ const AnotherFlag = -1,
}
}
assert_eq!(FlagABC.bits(), 0b00000111);
assert_eq!(AnotherSetOfFlags::empty().bits(), 0b00);
- assert_eq!(AnotherFlag.bits(), !0_i8);
+ assert_eq!(AnotherFlag.bits(), !0);
}
#[test]
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]
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]
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 \
// FIXME (pnkfelix): See discussion here
// https://github.com/pnkfelix/rust/commit/
// b2b39e8700e37ad32b486b9a8409b50a8a53aa51#commitcomment-7892003
-static DOWNCAST_PRINTED_OPERATOR : &'static str = " as ";
+const DOWNCAST_PRINTED_OPERATOR: &'static str = " as ";
// A local, "cleaned" version of `mc::InteriorKind` that drops
// information that is not relevant to loan-path analysis. (In
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");
}
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);
}
}
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,
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 => {
}
if is_closure {
- self.tcx.sess.span_help(
+ self.tcx.sess.fileline_help(
span,
"closures behind references must be called via `&mut`");
}
}
#[allow(non_upper_case_globals)]
-static InvalidMovePathIndex: MovePathIndex =
- MovePathIndex(usize::MAX);
+const InvalidMovePathIndex: MovePathIndex = MovePathIndex(usize::MAX);
/// Index into `MoveData.moves`, used like a pointer
#[derive(Copy, PartialEq)]
}
#[allow(non_upper_case_globals)]
-static InvalidMoveIndex: MoveIndex =
- MoveIndex(usize::MAX);
+const InvalidMoveIndex: MoveIndex = MoveIndex(usize::MAX);
pub struct MovePath<'tcx> {
/// Loan path corresponding to this move path
// 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]
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;
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) => ({
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()
}
}
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,
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 {
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> {
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)
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>)
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 {
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();
}
);
- // 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();
});
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)
}
// 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", (), |_|
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", (), |_|
_ => 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(())
})();
}
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 {
// 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
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(),
}
//!
//! 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]
#![feature(int_uint)]
#![feature(old_io)]
#![feature(libc)]
-#![feature(os)]
-#![feature(old_path)]
#![feature(quote)]
#![feature(rustc_diagnostic_macros)]
#![feature(rustc_private)]
#![feature(unsafe_destructor)]
#![feature(staged_api)]
-#![feature(unicode)]
#![feature(exit_status)]
+#![feature(path)]
+#![feature(io)]
extern crate arena;
extern crate flate;
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;
pub mod pretty;
-static BUG_REPORT_URL: &'static str =
+const BUG_REPORT_URL: &'static str =
"https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports";
}
// 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 == "-" {
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
&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)
}
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
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 {
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))
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");
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;
style,
&id,
&t_outputs.with_extension(""));
- println!("{}", fname.filename_display());
+ println!("{}", fname.file_name().unwrap()
+ .to_string_lossy());
}
}
}
let print_lint_groups = |lints: Vec<(&'static str, Vec<lint::LintId>)>| {
for (name, to) in lints {
- let name = name.chars().map(|x| x.to_lowercase())
- .collect::<String>().replace("_", "-");
+ let name = name.to_lowercase().replace("_", "-");
let desc = to.into_iter().map(|x| x.as_str().replace("_", "-"))
.collect::<Vec<String>>().connect(", ");
println!(" {} {}",
///
/// 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) {
- static STACK_SIZE: uint = 8 * 1024 * 1024; // 8MB
+ const STACK_SIZE: uint = 8 * 1024 * 1024; // 8MB
let (tx, rx) = channel();
let w = old_io::ChanWriter::new(tx);
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)]
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(())
}
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(()),
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));
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(())
}
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) => {
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 {
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(),
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);
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) {
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);
});
let code = blocks::Code::from_node(node);
+ let out: &mut Writer = &mut out;
match code {
Some(code) => {
let variants = gather_flowgraph_variants(&sess);
}
}
}
- }.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),
}
}
- 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()))
})
}
}
sub: &'a [RH<'a>]
}
-static EMPTY_SOURCE_STR: &'static str = "#![feature(no_std)] #![no_std]";
+const EMPTY_SOURCE_STR: &'static str = "#![feature(no_std)] #![no_std]";
struct ExpectErrorEmitter {
messages: Vec<String>
}
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) {
impl<'a, 'tcx, 'v> Visitor<'v> for RawPtrDeriveVisitor<'a, 'tcx> {
fn visit_ty(&mut self, ty: &ast::Ty) {
- static MSG: &'static str = "use of `#[derive]` with a raw pointer";
+ const MSG: &'static str = "use of `#[derive]` with a raw pointer";
if let ast::TyPtr(..) = ty.node {
self.cx.span_lint(RAW_POINTER_DERIVE, ty.span, MSG);
}
fn to_camel_case(s: &str) -> String {
s.split('_').flat_map(|word| word.chars().enumerate().map(|(i, c)|
if i == 0 {
- c.to_uppercase()
+ c.to_uppercase().collect::<String>()
} else {
- c
+ c.to_string()
}
- )).collect()
+ )).collect::<Vec<_>>().concat()
}
let s = token::get_ident(ident);
buf = String::new();
}
last_upper = ch.is_uppercase();
- buf.push(ch.to_lowercase());
+ buf.extend(ch.to_lowercase());
}
words.push(buf);
}
let s = token::get_ident(ident);
if s.chars().any(|c| c.is_lowercase()) {
- let uc: String = NonSnakeCase::to_snake_case(&s).chars()
- .map(|c| c.to_uppercase()).collect();
+ let uc = NonSnakeCase::to_snake_case(&s).to_uppercase();
if uc != &s[..] {
cx.span_lint(NON_UPPER_CASE_GLOBALS, span,
&format!("{} `{}` should have an upper case name such as `{}`",
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")
}
}
!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(..) => {
//!
//! 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]
#![feature(unsafe_destructor)]
#![feature(staged_api)]
#![feature(std_misc)]
-#![feature(unicode)]
#![cfg_attr(test, feature(test))]
extern crate syntax;
use std::ffi::CString;
use std::mem;
use std::raw;
+use std::path::Path;
pub struct ArchiveRO {
ptr: ArchiveRef,
/// 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()
}
}
// 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)]
#![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;
// 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]
}
}
Some(ref tr) => {
- // Any private types in a trait impl fall into two
+ // Any private types in a trait impl fall into three
// categories.
// 1. mentioned in the trait definition
// 2. mentioned in the type params/generics
+ // 3. mentioned in the associated types of the impl
//
// Those in 1. can only occur if the trait is in
// this crate and will've been warned about on the
// Those in 2. are warned via walk_generics and this
// call here.
visit::walk_path(self, &tr.path);
+
+ // Those in 3. are warned with this call.
+ for impl_item in impl_items {
+ match *impl_item {
+ ast::MethodImplItem(..) => {},
+ ast::TypeImplItem(ref typedef) => {
+ self.visit_ty(&typedef.typ);
+ }
+ }
+ }
}
}
} else if trait_ref.is_none() && self_is_public_path {
// 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]
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 `{}`",
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);
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;
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);
}
}
// e.g. `fn foo() { { fn a() {} } { fn a() {} } }`, so we
// generate unique characters from the node id. For now
// hopefully 3 characters is enough to avoid collisions.
- static EXTRA_CHARS: &'static str =
+ const EXTRA_CHARS: &'static str =
"abcdefghijklmnopqrstuvwxyz\
ABCDEFGHIJKLMNOPQRSTUVWXYZ\
0123456789";
}
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 {}: {}",
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) {
}
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))
}
}
}
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(),
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;
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(),
// 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 {}: {}",
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: \
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
// 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(());
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 `{}`: {}",
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"]);
}
// 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 {
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");
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
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.
&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 {
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[..]);
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
// 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
// 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) => {
// 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 \
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 {
}
// 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)));
}
}
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");
};
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) {
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;
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 {
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());
}
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());
}
},
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());
}
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());
})
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);
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() {
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) => {
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();
}
//!
//! 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]
#![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;
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};
}
}
+#[allow(deprecated)]
pub fn process_crate(sess: &Session,
krate: &ast::Crate,
analysis: &ty::CrateAnalysis,
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)),
_ => (),
// 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) => {
collected_paths: vec!(),
collecting: false,
fmt: FmtStrs::new(box Recorder {
- out: output_file as Box<Writer+'static>,
+ out: output_file,
dump_spans: false,
},
SpanUtils {
use super::escape;
use super::span_utils::SpanUtils;
-use std::vec::Vec;
+use std::io::Write;
use syntax::ast;
use syntax::ast::{NodeId,DefId};
pub struct Recorder {
// output file
- pub out: Box<Writer+'static>,
+ pub out: Box<Write+'static>,
pub dump_spans: bool,
}
Univariant(mk_struct(cx, &ftys[..], packed, t), dtor)
}
- ty::ty_closure(def_id, _, substs) => {
+ ty::ty_closure(def_id, substs) => {
let typer = NormalizingClosureTyper::new(cx.tcx());
let upvars = typer.closure_upvars(def_id, substs).unwrap();
let upvar_types = upvars.iter().map(|u| u.ty).collect::<Vec<_>>();
debug!("range_to_inttype: {:?} {:?}", hint, bounds);
// Lists of sizes to try. u64 is always allowed as a fallback.
#[allow(non_upper_case_globals)]
- static choose_shortest: &'static[IntType] = &[
+ const choose_shortest: &'static [IntType] = &[
attr::UnsignedInt(ast::TyU8), attr::SignedInt(ast::TyI8),
attr::UnsignedInt(ast::TyU16), attr::SignedInt(ast::TyI16),
attr::UnsignedInt(ast::TyU32), attr::SignedInt(ast::TyI32)];
#[allow(non_upper_case_globals)]
- static at_least_32: &'static[IntType] = &[
+ const at_least_32: &'static [IntType] = &[
attr::UnsignedInt(ast::TyU32), attr::SignedInt(ast::TyI32)];
let attempts;
assert!(bits <= 64);
let bits = bits as uint;
let mask = (-1u64 >> (64 - bits)) as Disr;
- if (max + 1) & mask == min & mask {
+ // For a (max) discr of -1, max will be `-1 as usize`, which overflows.
+ // However, that is fine here (it would still represent the full range),
+ if (max.wrapping_add(1)) & mask == min & mask {
// i.e., if the range is everything. The lo==hi case would be
// rejected by the LLVM verifier (it would mean either an
// empty set, which is impossible, or the entire range of the
} else {
// llvm::ConstantRange can deal with ranges that wrap around,
// so an overflow on (max + 1) is fine.
- LoadRangeAssert(bcx, ptr, min, (max+1), /* signed: */ True)
+ LoadRangeAssert(bcx, ptr, min, (max.wrapping_add(1)), /* signed: */ True)
}
}
let fcx = bcx.fcx;
let custom_cleanup_scope = fcx.push_custom_cleanup_scope();
let scratch = unpack_datum!(bcx, datum::lvalue_scratch_datum(
- bcx, tcx.types.bool, "drop_flag", false,
+ bcx, tcx.types.bool, "drop_flag",
cleanup::CustomScope(custom_cleanup_scope), (), |_, bcx, _| bcx
));
bcx = fold_variants(bcx, r, val, |variant_cx, st, value| {
ty::ty_bare_fn(_, ref f) => {
(&f.sig, f.abi, None)
}
- ty::ty_closure(closure_did, _, substs) => {
+ ty::ty_closure(closure_did, substs) => {
let typer = common::NormalizingClosureTyper::new(ccx.tcx());
function_type = typer.closure_type(closure_did, substs);
let self_type = self_type_for_closure(ccx, closure_did, fn_ty);
}
})
}
- ty::ty_closure(def_id, _, substs) => {
+ ty::ty_closure(def_id, substs) => {
let repr = adt::represent_type(cx.ccx(), t);
let typer = common::NormalizingClosureTyper::new(cx.tcx());
let upvars = typer.closure_upvars(def_id, substs).unwrap();
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)
}
_ => {
Alloca(cx, ty, name)
}
-pub fn alloca_zeroed<'blk, 'tcx>(cx: Block<'blk, 'tcx>, ty: Ty<'tcx>,
- name: &str) -> ValueRef {
- let llty = type_of::type_of(cx.ccx(), ty);
- if cx.unreachable.get() {
- unsafe {
- return llvm::LLVMGetUndef(llty.ptr_to().to_ref());
- }
- }
- let p = alloca_no_lifetime(cx, llty, name);
- let b = cx.fcx.ccx.builder();
- b.position_before(cx.fcx.alloca_insert_pt.get().unwrap());
- memzero(&b, p, ty);
- p
-}
-
// Creates the alloca slot which holds the pointer to the slot for the final return value
pub fn make_return_slot_pointer<'a, 'tcx>(fcx: &FunctionContext<'a, 'tcx>,
output_type: Ty<'tcx>) -> ValueRef {
datum::lvalue_scratch_datum(bcx,
arg_ty,
"tupled_args",
- false,
tuple_args_scope_id,
(),
|(),
let function_type;
let (fn_sig, abi, env_ty) = match fn_ty.sty {
ty::ty_bare_fn(_, ref f) => (&f.sig, f.abi, None),
- ty::ty_closure(closure_did, _, substs) => {
+ ty::ty_closure(closure_did, substs) => {
let typer = common::NormalizingClosureTyper::new(ccx.tcx());
function_type = typer.closure_type(closure_did, substs);
let self_type = self_type_for_closure(ccx, closure_did, fn_ty);
// These have an odd calling convention, so we need to manually
// unpack the input ty's
let input_tys = match fn_ty.sty {
- ty::ty_closure(_, _, _) => {
+ ty::ty_closure(..) => {
assert!(abi == RustCall);
match fn_sig.inputs[0].sty {
}
let encode_inlined_item: encoder::EncodeInlinedItem =
- box |ecx, rbml_w, ii| astencode::encode_inlined_item(ecx, rbml_w, ii);
+ Box::new(|ecx, rbml_w, ii| astencode::encode_inlined_item(ecx, rbml_w, ii));
let encode_parms = crate_ctxt_to_encode_parms(cx, encode_inlined_item);
let metadata = encoder::encode_metadata(encode_parms, krate);
let ty::CrateAnalysis { ty_cx: tcx, export_map, reachable, name, .. } = analysis;
let krate = tcx.map.krate();
+ let check_overflow = if let Some(v) = tcx.sess.opts.debugging_opts.force_overflow_checks {
+ v
+ } else {
+ tcx.sess.opts.debug_assertions
+ };
+
// Before we touch LLVM, make sure that multithreading is enabled.
unsafe {
use std::sync::{Once, ONCE_INIT};
export_map,
Sha256::new(),
link_meta.clone(),
- reachable);
+ reachable,
+ check_overflow);
{
let ccx = shared_ccx.get_ccx(0);
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 {
// duplicate declarations
let function_type = erase_regions(ccx.tcx(), &function_type);
let params = match function_type.sty {
- ty::ty_closure(_, _, substs) => &substs.types,
+ ty::ty_closure(_, substs) => &substs.types,
_ => unreachable!()
};
let mono_id = MonoId {
&**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())));
}
}
ast::ExprIndex(ref base, ref index) => {
let (bv, bt) = const_expr(cx, &**base, param_substs);
- let iv = match const_eval::eval_const_expr(cx.tcx(), &**index) {
- const_eval::const_int(i) => i as u64,
- const_eval::const_uint(u) => u,
+ let iv = match const_eval::eval_const_expr_partial(cx.tcx(), &**index, None) {
+ Ok(const_eval::const_int(i)) => i as u64,
+ Ok(const_eval::const_uint(u)) => u,
_ => cx.sess().span_bug(index.span,
"index is not an integer-constant expression")
};
ast::ExprRepeat(ref elem, ref count) => {
let unit_ty = ty::sequence_element_type(cx.tcx(), ety);
let llunitty = type_of::type_of(cx, unit_ty);
- let n = match const_eval::eval_const_expr(cx.tcx(), &**count) {
- const_eval::const_int(i) => i as uint,
- const_eval::const_uint(i) => i as uint,
+ let n = match const_eval::eval_const_expr_partial(cx.tcx(), &**count, None) {
+ Ok(const_eval::const_int(i)) => i as uint,
+ Ok(const_eval::const_uint(i)) => i as uint,
_ => cx.sess().span_bug(count.span, "count must be integral const expression.")
};
let unit_val = const_expr(cx, &**elem, param_substs).0;
symbol_hasher: RefCell<Sha256>,
tcx: ty::ctxt<'tcx>,
stats: Stats,
+ check_overflow: bool,
available_monomorphizations: RefCell<FnvHashSet<String>>,
available_drop_glues: RefCell<FnvHashMap<Ty<'tcx>, String>>,
export_map: ExportMap,
symbol_hasher: Sha256,
link_meta: LinkMeta,
- reachable: NodeSet)
+ reachable: NodeSet,
+ check_overflow: bool)
-> SharedCrateContext<'tcx> {
let (metadata_llcx, metadata_llmod) = unsafe {
create_context_and_module(&tcx.sess, "metadata")
llvm_insns: RefCell::new(FnvHashMap()),
fn_stats: RefCell::new(Vec::new()),
},
+ check_overflow: check_overflow,
available_monomorphizations: RefCell::new(FnvHashSet()),
available_drop_glues: RefCell::new(FnvHashMap()),
};
&format!("the type `{}` is too big for the current architecture",
obj.repr(self.tcx())))
}
+
+ pub fn check_overflow(&self) -> bool {
+ self.shared.check_overflow
+ }
}
fn declare_intrinsic(ccx: &CrateContext, key: & &'static str) -> Option<ValueRef> {
/// Allocates temporary space on the stack using alloca() and returns a by-ref Datum pointing to
/// it. The memory will be dropped upon exit from `scope`. The callback `populate` should
-/// initialize the memory. If `zero` is true, the space will be zeroed when it is allocated; this
-/// is not necessary unless `bcx` does not dominate the end of `scope`.
+/// initialize the memory.
pub fn lvalue_scratch_datum<'blk, 'tcx, A, F>(bcx: Block<'blk, 'tcx>,
ty: Ty<'tcx>,
name: &str,
- zero: bool,
scope: cleanup::ScopeId,
arg: A,
populate: F)
-> DatumBlock<'blk, 'tcx, Lvalue> where
F: FnOnce(A, Block<'blk, 'tcx>, ValueRef) -> Block<'blk, 'tcx>,
{
- let scratch = if zero {
- alloca_zeroed(bcx, ty, name)
- } else {
- let llty = type_of::type_of(bcx.ccx(), ty);
- alloca(bcx, llty, name)
- };
+ let llty = type_of::type_of(bcx.ccx(), ty);
+ let scratch = alloca(bcx, llty, name);
// Subtle. Populate the scratch memory *before* scheduling cleanup.
let bcx = populate(arg, bcx, scratch);
ByValue => {
lvalue_scratch_datum(
- bcx, self.ty, name, false, scope, self,
+ bcx, self.ty, name, scope, self,
|this, bcx, llval| this.store_to(bcx, llval))
}
}
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;
}
}
},
- ty::ty_closure(def_id, _, substs) => {
+ ty::ty_closure(def_id, substs) => {
let typer = NormalizingClosureTyper::new(cx.tcx());
let closure_ty = typer.closure_type(def_id, substs);
self.get_unique_type_id_of_closure_type(cx,
fn_metadata: DISubprogram,
argument_counter: Cell<uint>,
source_locations_enabled: Cell<bool>,
+ source_location_override: Cell<bool>,
}
enum VariableAccess<'a> {
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));
}
}
+/// 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.
fn_metadata: fn_metadata,
argument_counter: Cell::new(1),
source_locations_enabled: Cell::new(false),
+ source_location_override: Cell::new(false),
};
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)
}
(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";
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()]
ty::ty_bare_fn(_, ref barefnty) => {
subroutine_type_metadata(cx, unique_type_id, &barefnty.sig, usage_site_span)
}
- ty::ty_closure(def_id, _, substs) => {
+ ty::ty_closure(def_id, substs) => {
let typer = NormalizingClosureTyper::new(cx.tcx());
let sig = typer.closure_type(def_id, substs).sig;
subroutine_type_metadata(cx, unique_type_id, &sig, usage_site_span)
use trans::type_::Type;
use syntax::{ast, ast_util, codemap};
+use syntax::parse::token::InternedString;
use syntax::ptr::P;
use syntax::parse::token;
use std::iter::repeat;
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.
// 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());
// 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) {
}
}
}
- }
-
- 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);
};
let is_float = ty::type_is_fp(intype);
let is_signed = ty::type_is_signed(intype);
-
let rhs = base::cast_shift_expr_rhs(bcx, op, lhs, rhs);
+ let info = expr_info(binop_expr);
let binop_debug_loc = binop_expr.debug_loc();
if is_float {
FAdd(bcx, lhs, rhs, binop_debug_loc)
} else {
- Add(bcx, lhs, rhs, binop_debug_loc)
+ let (newbcx, res) = with_overflow_check(
+ bcx, OverflowOp::Add, info, lhs_t, lhs, rhs, binop_debug_loc);
+ bcx = newbcx;
+ res
}
}
ast::BiSub => {
if is_float {
FSub(bcx, lhs, rhs, binop_debug_loc)
} else {
- Sub(bcx, lhs, rhs, binop_debug_loc)
+ let (newbcx, res) = with_overflow_check(
+ bcx, OverflowOp::Sub, info, lhs_t, lhs, rhs, binop_debug_loc);
+ bcx = newbcx;
+ res
}
}
ast::BiMul => {
if is_float {
FMul(bcx, lhs, rhs, binop_debug_loc)
} else {
- Mul(bcx, lhs, rhs, binop_debug_loc)
+ let (newbcx, res) = with_overflow_check(
+ bcx, OverflowOp::Mul, info, lhs_t, lhs, rhs, binop_debug_loc);
+ bcx = newbcx;
+ res
}
}
ast::BiDiv => {
DatumBlock { bcx: bcx, datum: datum }
}
}
+
+enum OverflowOp {
+ Add,
+ Sub,
+ Mul,
+}
+
+impl OverflowOp {
+ fn to_intrinsic_name(&self, tcx: &ty::ctxt, ty: Ty) -> &'static str {
+ use syntax::ast::IntTy::*;
+ use syntax::ast::UintTy::*;
+ use middle::ty::{ty_int, ty_uint};
+
+ let new_sty = match ty.sty {
+ ty_int(TyIs(_)) => match &tcx.sess.target.target.target_pointer_width[..] {
+ "32" => ty_int(TyI32),
+ "64" => ty_int(TyI64),
+ _ => panic!("unsupported target word size")
+ },
+ ty_uint(TyUs(_)) => match &tcx.sess.target.target.target_pointer_width[..] {
+ "32" => ty_uint(TyU32),
+ "64" => ty_uint(TyU64),
+ _ => panic!("unsupported target word size")
+ },
+ ref t @ ty_uint(_) | ref t @ ty_int(_) => t.clone(),
+ _ => panic!("tried to get overflow intrinsic for non-int type")
+ };
+
+ match *self {
+ OverflowOp::Add => match new_sty {
+ ty_int(TyI8) => "llvm.sadd.with.overflow.i8",
+ ty_int(TyI16) => "llvm.sadd.with.overflow.i16",
+ ty_int(TyI32) => "llvm.sadd.with.overflow.i32",
+ ty_int(TyI64) => "llvm.sadd.with.overflow.i64",
+
+ ty_uint(TyU8) => "llvm.uadd.with.overflow.i8",
+ ty_uint(TyU16) => "llvm.uadd.with.overflow.i16",
+ ty_uint(TyU32) => "llvm.uadd.with.overflow.i32",
+ ty_uint(TyU64) => "llvm.uadd.with.overflow.i64",
+
+ _ => unreachable!(),
+ },
+ OverflowOp::Sub => match new_sty {
+ ty_int(TyI8) => "llvm.ssub.with.overflow.i8",
+ ty_int(TyI16) => "llvm.ssub.with.overflow.i16",
+ ty_int(TyI32) => "llvm.ssub.with.overflow.i32",
+ ty_int(TyI64) => "llvm.ssub.with.overflow.i64",
+
+ ty_uint(TyU8) => "llvm.usub.with.overflow.i8",
+ ty_uint(TyU16) => "llvm.usub.with.overflow.i16",
+ ty_uint(TyU32) => "llvm.usub.with.overflow.i32",
+ ty_uint(TyU64) => "llvm.usub.with.overflow.i64",
+
+ _ => unreachable!(),
+ },
+ OverflowOp::Mul => match new_sty {
+ ty_int(TyI8) => "llvm.smul.with.overflow.i8",
+ ty_int(TyI16) => "llvm.smul.with.overflow.i16",
+ ty_int(TyI32) => "llvm.smul.with.overflow.i32",
+ ty_int(TyI64) => "llvm.smul.with.overflow.i64",
+
+ ty_uint(TyU8) => "llvm.umul.with.overflow.i8",
+ ty_uint(TyU16) => "llvm.umul.with.overflow.i16",
+ ty_uint(TyU32) => "llvm.umul.with.overflow.i32",
+ ty_uint(TyU64) => "llvm.umul.with.overflow.i64",
+
+ _ => unreachable!(),
+ },
+ }
+ }
+}
+
+
+fn with_overflow_check<'a, 'b>(bcx: Block<'a, 'b>, oop: OverflowOp, info: NodeIdAndSpan,
+ lhs_t: Ty, lhs: ValueRef, rhs: ValueRef, binop_debug_loc: DebugLoc)
+ -> (Block<'a, 'b>, ValueRef) {
+ if bcx.unreachable.get() { return (bcx, _Undef(lhs)); }
+ if bcx.ccx().check_overflow() {
+ let name = oop.to_intrinsic_name(bcx.tcx(), lhs_t);
+ let llfn = bcx.ccx().get_intrinsic(&name);
+
+ let val = Call(bcx, llfn, &[lhs, rhs], None, binop_debug_loc);
+ let result = ExtractValue(bcx, val, 0); // iN operation result
+ let overflow = ExtractValue(bcx, val, 1); // i1 "did it overflow?"
+
+ let cond = ICmp(bcx, llvm::IntEQ, overflow, C_integral(Type::i1(bcx.ccx()), 1, false),
+ binop_debug_loc);
+
+ let expect = bcx.ccx().get_intrinsic(&"llvm.expect.i1");
+ Call(bcx, expect, &[cond, C_integral(Type::i1(bcx.ccx()), 0, false)],
+ None, binop_debug_loc);
+
+ let bcx =
+ base::with_cond(bcx, cond, |bcx|
+ controlflow::trans_fail(bcx, info,
+ InternedString::new("arithmetic operation overflowed")));
+
+ (bcx, result)
+ } else {
+ let res = match oop {
+ OverflowOp::Add => Add(bcx, lhs, rhs, binop_debug_loc),
+ OverflowOp::Sub => Sub(bcx, lhs, rhs, binop_debug_loc),
+ OverflowOp::Mul => Mul(bcx, lhs, rhs, binop_debug_loc),
+ };
+ (bcx, res)
+ }
+}
&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");
}
};
ty::mk_nil(bcx.tcx()));
let (_, variant_cx) = invoke(variant_cx, dtor_addr, &args[..], dtor_ty, DebugLoc::None);
- variant_cx.fcx.pop_and_trans_custom_cleanup_scope(variant_cx, field_scope);
- variant_cx
+ variant_cx.fcx.pop_and_trans_custom_cleanup_scope(variant_cx, field_scope)
})
}
let csearch_result =
csearch::maybe_get_item_ast(
ccx.tcx(), fn_id,
- box |a,b,c,d| astencode::decode_inlined_item(a, b, c, d));
+ Box::new(|a,b,c,d| astencode::decode_inlined_item(a, b, c, d)));
let inline_def = match csearch_result {
csearch::FoundAst::NotFound => {
llargs[0],
llargs[1],
call_debug_location),
+
+ (_, "overflowing_add") => Add(bcx, llargs[0], llargs[1], call_debug_location),
+ (_, "overflowing_sub") => Sub(bcx, llargs[0], llargs[1], call_debug_location),
+ (_, "overflowing_mul") => Mul(bcx, llargs[0], llargs[1], call_debug_location),
+
(_, "return_address") => {
if !fcx.caller_expects_out_pointer {
tcx.sess.span_err(call_info.span,
use syntax::codemap::DUMMY_SP;
// drop_glue pointer, size, align.
-static VTABLE_OFFSET: uint = 3;
+const VTABLE_OFFSET: uint = 3;
/// The main "translation" pass for methods. Generates code
/// for non-monomorphized methods only. Other methods will
.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)
}
_ => {
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(..) |
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 =
};
// 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));
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};
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.
if len == 2 && i == 0 {
m.push_str(" or ");
- } else if i == len - 2 {
+ } else if i + 2 == len {
m.push_str(", or ");
- } else if i != len - 1 {
+ } else if i + 1 != len {
m.push_str(", ");
}
}
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);
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");
}
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");
}
// 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,
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.
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),
}
_ => {
- span_help!(this.tcx().sess, ty.span,
+ fileline_help!(this.tcx().sess, ty.span,
"perhaps you forgot parentheses? (per RFC 438)");
}
}
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 {
(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,
if segments.is_empty() {
opt_self_ty.expect("missing T in <T>::a::b::c")
} else {
- tcx.sess.span_bug(span,
- &format!("found module name used as a type: {}",
- tcx.map.node_to_string(id.node)));
+ span_err!(tcx.sess, span, E0247, "found module name used as a type: {}",
+ tcx.map.node_to_string(id.node));
+ return this.tcx().types.err;
}
}
def::DefPrimTy(prim_ty) => {
prim_ty_to_ty(tcx, segments, prim_ty)
}
_ => {
- span_fatal!(tcx.sess, span, E0248,
- "found value name used as a type: {:?}", *def);
+ span_err!(tcx.sess, span, E0248,
+ "found value name used as a type: {:?}", *def);
+ return this.tcx().types.err;
}
};
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_fatal!(tcx.sess, ast_ty.span, E0246,
- "illegal recursive type; insert an enum \
- or struct in the cycle, if this is \
- desired");
- }
- 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) => {
ty::mk_vec(tcx, ast_ty_to_ty(this, rscope, &**ty),
Some(i as uint)),
_ => {
- span_fatal!(tcx.sess, ast_ty.span, E0249,
- "expected constant expr for array length");
+ span_err!(tcx.sess, ast_ty.span, E0249,
+ "expected constant expr for array length");
+ this.tcx().types.err
}
}
}
- Err(r) => {
- span_fatal!(tcx.sess, ast_ty.span, E0250,
- "expected constant expr for array length: {}", r);
+ Err(ref r) => {
+ let subspan =
+ 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());
+ if !subspan {
+ span_note!(tcx.sess, ast_ty.span, "for array length here")
+ }
+ this.tcx().types.err
}
}
}
}
};
- 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;
}
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 =
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) {
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");
}
}
return Some(CallStep::Builtin);
}
- ty::ty_closure(def_id, _, substs) => {
+ ty::ty_closure(def_id, substs) => {
assert_eq!(def_id.krate, ast::LOCAL_CRATE);
// Check whether this is a call to a closure where we
&closure_ty.sig).0;
fcx.record_deferred_call_resolution(
def_id,
- box CallResolution {call_expr: call_expr,
- callee_expr: callee_expr,
- adjusted_ty: adjusted_ty,
- autoderefref: autoderefref,
- fn_sig: fn_sig.clone(),
- closure_def_id: def_id});
+ Box::new(CallResolution {call_expr: call_expr,
+ callee_expr: callee_expr,
+ adjusted_ty: adjusted_ty,
+ autoderefref: autoderefref,
+ fn_sig: fn_sig.clone(),
+ closure_def_id: def_id}));
return Some(CallStep::DeferredClosure(fn_sig));
}
}
use middle::region;
use middle::subst;
use middle::ty::{self, ToPolyTraitRef, Ty};
-use rscope::RegionScope;
use syntax::abi;
use syntax::ast;
use syntax::ast_util;
abi::RustCall,
expected_sig);
- let region = match fcx.anon_regions(expr.span, 1) {
- Err(_) => {
- fcx.ccx.tcx.sess.span_bug(expr.span,
- "can't make anon regions here?!")
- }
- Ok(regions) => regions[0],
- };
-
let closure_type = ty::mk_closure(fcx.ccx.tcx,
expr_def_id,
- fcx.ccx.tcx.mk_region(region),
fcx.ccx.tcx.mk_substs(
fcx.inh.param_env.free_substs.clone()));
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);
use syntax::codemap::Span;
use util::common::ErrorReported;
+use util::nodemap::FnvHashSet;
use util::ppaux::Repr;
// Helper functions related to manipulating region types.
pub enum Implication<'tcx> {
RegionSubRegion(Option<Ty<'tcx>>, ty::Region, ty::Region),
RegionSubGeneric(Option<Ty<'tcx>>, ty::Region, GenericKind<'tcx>),
+ RegionSubClosure(Option<Ty<'tcx>>, ty::Region, ast::DefId, &'tcx Substs<'tcx>),
Predicate(ast::DefId, ty::Predicate<'tcx>),
}
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
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
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 |
// No borrowed content reachable here.
}
- ty::ty_closure(_, region, _) => {
- // An "closure type" is basically
- // modeled here as equivalent to a struct like
- //
- // struct TheClosure<'b> {
- // ...
- // }
- //
- // where the `'b` is the lifetime bound of the
- // contents (i.e., all contents must outlive 'b).
- //
- // Even though closures are glorified structs
- // of upvars, we do not need to consider them as they
- // can't generate any new constraints. The
- // substitutions on the closure are equal to the free
- // substitutions of the enclosing parameter
- // environment. An upvar captured by value has the
- // same type as the original local variable which is
- // already checked for consistency. If the upvar is
- // captured by reference it must also outlive the
- // region bound on the closure, but this is explicitly
- // handled by logic in regionck.
- self.push_region_constraint_from_top(*region);
+ ty::ty_closure(def_id, substs) => {
+ let &(r_a, opt_ty) = self.stack.last().unwrap();
+ self.out.push(Implication::RegionSubClosure(opt_ty, r_a, def_id, substs));
}
ty::ty_trait(ref t) => {
p.repr(tcx))
}
+ Implication::RegionSubClosure(_, ref a, ref b, ref c) => {
+ format!("RegionSubClosure({}, {}, {})",
+ a.repr(tcx),
+ b.repr(tcx),
+ c.repr(tcx))
+ }
+
Implication::Predicate(ref def_id, ref p) => {
format!("Predicate({}, {})",
def_id.repr(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
}
ty::ty_enum(did, _) |
ty::ty_struct(did, _) |
- ty::ty_closure(did, _, _) => {
+ ty::ty_closure(did, _) => {
self.assemble_inherent_impl_candidates_for_type(did);
}
ty::ty_uniq(_) => {
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) {
// If so, add "synthetic impls".
let steps = self.steps.clone();
for step in &*steps {
- let (closure_def_id, _, _) = match step.self_ty.sty {
- ty::ty_closure(a, b, ref c) => (a, b, c),
+ let closure_def_id = match step.self_ty.sty {
+ ty::ty_closure(a, _) => a,
_ => continue,
};
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))
}
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)
}
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()
}
match self.inh.locals.borrow().get(&nid) {
Some(&t) => t,
None => {
- self.tcx().sess.span_bug(
+ self.tcx().sess.span_err(
span,
- &format!("no type for local variable {}",
- nid));
+ &format!("no type for local variable {}", nid));
+ self.tcx().types.err
}
}
}
},
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 {
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 {
id: ast::NodeId,
hint: attr::ReprAttr)
-> Vec<Rc<ty::VariantInfo<'tcx>>> {
+ use std::num::Int;
let rty = ty::node_id_to_type(ccx.tcx, id);
let mut variants: Vec<Rc<ty::VariantInfo>> = Vec::new();
// If the discriminant value is specified explicitly in the enum check whether the
// initialization expression is valid, otherwise use the last value plus one.
let mut current_disr_val = match prev_disr_val {
- Some(prev_disr_val) => prev_disr_val + 1,
+ Some(prev_disr_val) => {
+ if let Some(v) = prev_disr_val.checked_add(1) {
+ v
+ } else {
+ ty::INITIAL_DISCRIMINANT_VALUE
+ }
+ }
None => ty::INITIAL_DISCRIMINANT_VALUE
};
"expected signed integer constant");
}
Err(ref err) => {
- span_err!(ccx.tcx.sess, e.span, E0080,
- "expected constant: {}", *err);
+ span_err!(ccx.tcx.sess, err.span, E0080,
+ "constant evaluation error: {}",
+ err.description());
}
}
},
(0, vec!(tcx.types.u64, tcx.types.u64),
ty::mk_tup(tcx, vec!(tcx.types.u64, tcx.types.bool))),
+ "overflowing_add" | "overflowing_sub" | "overflowing_mul" =>
+ (1, vec![param(ccx, 0), param(ccx, 0)], param(ccx, 0)),
+
"return_address" => (0, vec![], ty::mk_imm_ptr(tcx, tcx.types.u8)),
"assume" => (0, vec![tcx.types.bool], ty::mk_nil(tcx)),
use check::FnCtxt;
use check::implicator;
use check::vtable;
-use middle::def;
use middle::mem_categorization as mc;
use middle::region::CodeExtent;
+use middle::subst::Substs;
use middle::traits;
-use middle::ty::{ReScope};
-use middle::ty::{self, Ty, MethodCall};
+use middle::ty::{self, ClosureTyper, ReScope, Ty, MethodCall};
use middle::infer::{self, GenericKind};
use middle::pat_util;
use util::ppaux::{ty_to_string, Repr};
}
-/// Returns the validity region of `def` -- that is, how long is `def` valid?
-fn region_of_def(fcx: &FnCtxt, def: def::Def) -> ty::Region {
- let tcx = fcx.tcx();
- match def {
- def::DefLocal(node_id) | def::DefUpvar(node_id, _) => {
- tcx.region_maps.var_region(node_id)
- }
- _ => {
- tcx.sess.bug(&format!("unexpected def in region_of_def: {:?}",
- def))
- }
- }
-}
-
struct RepeatingScope(ast::NodeId);
pub enum SubjectNode { Subject(ast::NodeId), None }
ty::ReInfer(ty::ReVar(vid_b))) => {
self.fcx.inh.infcx.add_given(free_a, vid_b);
}
- implicator::Implication::RegionSubRegion(..) => {
+ implicator::Implication::RegionSubGeneric(_, r_a, ref generic_b) => {
+ debug!("RegionSubGeneric: {} <= {}",
+ r_a.repr(tcx), generic_b.repr(tcx));
+
+ self.region_bound_pairs.push((r_a, generic_b.clone()));
+ }
+ implicator::Implication::RegionSubRegion(..) |
+ implicator::Implication::RegionSubClosure(..) |
+ implicator::Implication::Predicate(..) => {
// In principle, we could record (and take
// advantage of) every relationship here, but
// we are also free not to -- it simply means
// relationship that arises here, but
// presently we do not.)
}
- implicator::Implication::RegionSubGeneric(_, r_a, ref generic_b) => {
- debug!("RegionSubGeneric: {} <= {}",
- r_a.repr(tcx), generic_b.repr(tcx));
-
- self.region_bound_pairs.push((r_a, generic_b.clone()));
- }
- implicator::Implication::Predicate(..) => { }
}
}
}
fn check_expr_fn_block(rcx: &mut Rcx,
expr: &ast::Expr,
body: &ast::Block) {
- let tcx = rcx.fcx.tcx();
- let function_type = rcx.resolve_node_type(expr.id);
-
- match function_type.sty {
- ty::ty_closure(_, region, _) => {
- ty::with_freevars(tcx, expr.id, |freevars| {
- constrain_captured_variables(rcx, *region, expr, freevars);
- })
- }
- _ => { }
- }
-
let repeating_scope = rcx.set_repeating_scope(body.id);
visit::walk_expr(rcx, expr);
rcx.set_repeating_scope(repeating_scope);
-
- match function_type.sty {
- ty::ty_closure(_, region, _) => {
- ty::with_freevars(tcx, expr.id, |freevars| {
- let bounds = ty::region_existential_bound(*region);
- ensure_free_variable_types_outlive_closure_bound(rcx, &bounds, expr, freevars);
- })
- }
- _ => {}
- }
-
- /// Make sure that the type of all free variables referenced inside a closure/proc outlive the
- /// closure/proc's lifetime bound. This is just a special case of the usual rules about closed
- /// over values outliving the object's lifetime bound.
- fn ensure_free_variable_types_outlive_closure_bound(
- rcx: &mut Rcx,
- bounds: &ty::ExistentialBounds,
- expr: &ast::Expr,
- freevars: &[ty::Freevar])
- {
- let tcx = rcx.fcx.ccx.tcx;
-
- debug!("ensure_free_variable_types_outlive_closure_bound({}, {})",
- bounds.region_bound.repr(tcx), expr.repr(tcx));
-
- for freevar in freevars {
- let var_node_id = {
- let def_id = freevar.def.def_id();
- assert!(def_id.krate == ast::LOCAL_CRATE);
- def_id.node
- };
-
- // Compute the type of the field in the environment that
- // represents `var_node_id`. For a by-value closure, this
- // will be the same as the type of the variable. For a
- // by-reference closure, this will be `&T` where `T` is
- // the type of the variable.
- let raw_var_ty = rcx.resolve_node_type(var_node_id);
- let upvar_id = ty::UpvarId { var_id: var_node_id,
- closure_expr_id: expr.id };
- let var_ty = match rcx.fcx.inh.upvar_capture_map.borrow()[upvar_id] {
- ty::UpvarCapture::ByRef(ref upvar_borrow) => {
- ty::mk_rptr(rcx.tcx(),
- rcx.tcx().mk_region(upvar_borrow.region),
- ty::mt { mutbl: upvar_borrow.kind.to_mutbl_lossy(),
- ty: raw_var_ty })
- }
- ty::UpvarCapture::ByValue => raw_var_ty,
- };
-
- // Check that the type meets the criteria of the existential bounds:
- for builtin_bound in &bounds.builtin_bounds {
- let code = traits::ClosureCapture(var_node_id, expr.span, builtin_bound);
- let cause = traits::ObligationCause::new(freevar.span, rcx.fcx.body_id, code);
- rcx.fcx.register_builtin_bound(var_ty, builtin_bound, cause);
- }
-
- type_must_outlive(
- rcx, infer::FreeVariable(expr.span, var_node_id),
- var_ty, bounds.region_bound);
- }
- }
-
- /// Make sure that all free variables referenced inside the closure outlive the closure's
- /// lifetime bound. Also, create an entry in the upvar_borrows map with a region.
- fn constrain_captured_variables(
- rcx: &mut Rcx,
- region_bound: ty::Region,
- expr: &ast::Expr,
- freevars: &[ty::Freevar])
- {
- let tcx = rcx.fcx.ccx.tcx;
- debug!("constrain_captured_variables({}, {})",
- region_bound.repr(tcx), expr.repr(tcx));
- for freevar in freevars {
- debug!("constrain_captured_variables: freevar.def={:?}", freevar.def);
-
- // Identify the variable being closed over and its node-id.
- let def = freevar.def;
- let var_node_id = {
- let def_id = def.def_id();
- assert!(def_id.krate == ast::LOCAL_CRATE);
- def_id.node
- };
- let upvar_id = ty::UpvarId { var_id: var_node_id,
- closure_expr_id: expr.id };
-
- match rcx.fcx.inh.upvar_capture_map.borrow()[upvar_id] {
- ty::UpvarCapture::ByValue => { }
- ty::UpvarCapture::ByRef(upvar_borrow) => {
- rcx.fcx.mk_subr(infer::FreeVariable(freevar.span, var_node_id),
- region_bound, upvar_borrow.region);
-
- // Guarantee that the closure does not outlive the variable itself.
- let enclosing_region = region_of_def(rcx.fcx, def);
- debug!("constrain_captured_variables: enclosing_region = {}",
- enclosing_region.repr(tcx));
- rcx.fcx.mk_subr(infer::FreeVariable(freevar.span, var_node_id),
- region_bound, enclosing_region);
- }
- }
- }
- }
}
fn constrain_callee(rcx: &mut Rcx,
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())));
}
}
}
let o1 = infer::ReferenceOutlivesReferent(ty, origin.span());
generic_must_outlive(rcx, o1, r_a, generic_b);
}
+ implicator::Implication::RegionSubClosure(_, r_a, def_id, substs) => {
+ closure_must_outlive(rcx, origin.clone(), r_a, def_id, substs);
+ }
implicator::Implication::Predicate(def_id, predicate) => {
let cause = traits::ObligationCause::new(origin.span(),
rcx.body_id,
}
}
+fn closure_must_outlive<'a, 'tcx>(rcx: &mut Rcx<'a, 'tcx>,
+ origin: infer::SubregionOrigin<'tcx>,
+ region: ty::Region,
+ def_id: ast::DefId,
+ substs: &'tcx Substs<'tcx>) {
+ debug!("closure_must_outlive(region={}, def_id={}, substs={})",
+ region.repr(rcx.tcx()), def_id.repr(rcx.tcx()), substs.repr(rcx.tcx()));
+
+ let upvars = rcx.fcx.closure_upvars(def_id, substs).unwrap();
+ for upvar in upvars {
+ let var_id = upvar.def.def_id().local_id();
+ type_must_outlive(
+ rcx, infer::FreeVariable(origin.span(), var_id),
+ upvar.ty, region);
+ }
+}
+
fn generic_must_outlive<'a, 'tcx>(rcx: &Rcx<'a, 'tcx>,
origin: infer::SubregionOrigin<'tcx>,
region: ty::Region,
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(
&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")
+ }
+ }
}
_ => {}
}
// 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 {
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!
+++ /dev/null
-// 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");
- }
- }
- }
- }
- _ => {}
- }
- }
-}
use util::nodemap::{DefIdMap, FnvHashMap};
use util::ppaux::Repr;
-mod impls;
mod orphan;
mod overlap;
mod unsafety;
match self_type.ty.sty {
ty::ty_enum(type_def_id, _) |
ty::ty_struct(type_def_id, _) |
- ty::ty_closure(type_def_id, _, _) => {
+ ty::ty_closure(type_def_id, _) => {
tcx.destructor_for_type
.borrow_mut()
.insert(type_def_id, method_def_id.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");
}
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);
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, _, _) => {
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) => {
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)) => {
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
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);
}
}
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
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> {
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 => { }
}
}
_ => {}
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
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.
enum AstConvRequest {
GetItemTypeScheme(ast::DefId),
GetTraitDef(ast::DefId),
+ EnsureSuperPredicates(ast::DefId),
GetTypeParameterBounds(ast::NodeId),
}
request: AstConvRequest,
code: F)
-> Result<R,ErrorReported>
- where F: FnOnce() -> R
+ where F: FnOnce() -> Result<R,ErrorReported>
{
{
let mut stack = self.stack.borrow_mut();
let result = code();
self.stack.borrow_mut().pop();
- Ok(result)
+ result
}
fn report_cycle(&self,
&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(
&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(
&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(
}
}
}
+
+ /// 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> {
-> 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))
})
}
-> 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");
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.
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());
_astconv: &AstConv<'tcx>,
_span: Span,
_node_id: ast::NodeId)
- -> Vec<ty::PolyTraitRef<'tcx>>
+ -> Vec<ty::Predicate<'tcx>>
{
Vec::new()
}
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()
}
}
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
.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
})
.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()
}
{
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
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();
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,
},
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));
}
}
-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>,
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");
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");
}
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| {
paren_sugar: paren_sugar,
unsafety: unsafety,
generics: ty_generics,
- bounds: bounds,
trait_ref: trait_ref,
associated_type_names: associated_type_names,
});
}
}
+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);
}
};
- 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.
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));
}
}
}
}
}
-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
&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()));
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()
}
}
}
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 }
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]
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);
_ => 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
}
}
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;
#[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>,
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 {
// 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{
}
}
-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(),
#[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;
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)
#[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;
- static LOCKFILE_EXCLUSIVE_LOCK: libc::DWORD = 0x00000002;
+ const LOCKFILE_EXCLUSIVE_LOCK: libc::DWORD = 0x00000002;
#[allow(non_snake_case)]
extern "system" {
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(),
// except according to those terms.
use std::fmt;
-use std::old_io;
+use std::io::prelude::*;
+use std::io;
use externalfiles::ExternalHtml;
}
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>
)
}
-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>
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;
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
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`.
/// 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
/// 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(),
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();
}
// 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();
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.
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
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 {
}
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));
/// 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(())
}
/// 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)
}
}
}
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
// 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,
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(());
/// 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(())
// 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();
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)
/// 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| {
// 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 },
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);
}
// 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)
}
}
}
- 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,
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(plain_summary_line(item.doc_value()))));
}
for (_, items) in &mut map {
// 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());
});
}
#[inline]
-fn shorter_line(s: Option<&str>) -> String {
- shorter(s).replace("\n", " ")
+fn plain_summary_line(s: Option<&str>) -> String {
+ let line = shorter(s).replace("\n", " ");
+ markdown::plain_summary_line(&line[..])
}
fn document(w: &mut fmt::Formatter, item: &clean::Item) -> fmt::Result {
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>"));
}
}
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(())
}
}
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;
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 {
"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() {
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;
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);
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');
// 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]
#![feature(test)]
#![feature(unicode)]
#![feature(str_words)]
+#![feature(io)]
+#![feature(path)]
+#![feature(file_path)]
+#![feature(path_ext)]
extern crate arena;
extern crate getopts;
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;
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};
fn(clean::Crate) -> plugins::PluginResult, // fn
&'static str); // description
-static PASSES: &'static [Pass] = &[
+const PASSES: &'static [Pass] = &[
("strip-hidden", passes::strip_hidden,
"strips all doc(hidden) items from the output"),
("unindent-comments", passes::unindent_comments,
"strips all private items from a crate which cannot be seen externally"),
];
-static DEFAULT_PASSES: &'static [&'static str] = &[
+const DEFAULT_PASSES: &'static [&'static str] = &[
"strip-hidden",
"strip-private",
"collapse-docs",
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(
(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) => {}
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),
}
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),
}
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");
/// 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;
/// 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 ... },
// 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;
/// 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();
}
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: {}",
// 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;
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(),
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),
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();
// 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));
}
}
}
}
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)
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);
}))
fn to_hex(&self) -> String;
}
-static CHARS: &'static[u8] = b"0123456789abcdef";
+const CHARS: &'static [u8] = b"0123456789abcdef";
impl ToHex for [u8] {
/// Turn a vector of `u8` bytes into a hexadecimal string.
// 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;
//! 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();
//! }
//! ```
while !self.eof() {
match self.ch_or_null() {
c @ '0' ... '9' => {
- accum *= 10;
- accum += (c as u64) - ('0' as u64);
+ accum = accum.wrapping_mul(10);
+ accum = accum.wrapping_add((c as u64) - ('0' as u64));
// Detect overflow by comparing to the last value.
if accum <= last_accum { return self.error(InvalidNumber); }
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() {
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")]
#![feature(staged_api)]
#![feature(std_misc)]
#![feature(unicode)]
+#![feature(path)]
#![cfg_attr(test, feature(test))]
// test harness access
*/
use std::old_path;
+use std::path;
use std::rc::Rc;
use std::cell::{Cell, RefCell};
use std::sync::Arc;
}
}
+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)
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]
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(),
// 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(),
"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(),
// 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(),
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(
M: Deref<Target=RawTable<K, V>>,
F: FnMut(&K) -> bool,
{
+ // This is the only function where capacity can be zero. To avoid
+ // undefined behaviour when Bucket::new gets the raw bucket in this
+ // case, immediately return the appropriate search result.
+ if table.capacity() == 0 {
+ return TableRef(table);
+ }
+
let size = table.size();
let mut probe = Bucket::new(table, hash);
let ib = probe.index();
}
#[test]
- #[should_fail]
+ #[should_panic]
fn test_index_nonexistent() {
let mut map = HashMap::new();
use mem::{min_align_of, size_of};
use mem;
use num::{Int, UnsignedInt};
+use num::wrapping::{OverflowingOps, WrappingOps};
use ops::{Deref, DerefMut, Drop};
use option::Option;
use option::Option::{Some, None};
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.
{
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.
}
pub fn at_index(table: M, ib_index: usize) -> Bucket<K, V, M> {
+ // if capacity is 0, then the RawBucket will be populated with bogus pointers.
+ // This is an uncommon case though, so avoid it in release builds.
+ debug_assert!(table.capacity() > 0, "Table should have capacity at this point");
let ib_index = ib_index & (table.capacity() - 1);
Bucket {
raw: unsafe {
// Calculates the distance one has to travel when going from
// `hash mod capacity` onwards to `idx mod capacity`, wrapping around
// if the destination is not reached before the end of the table.
- (self.idx - self.hash().inspect() as usize) & (self.table.capacity() - 1)
+ (self.idx.wrapping_sub(self.hash().inspect() as usize)) & (self.table.capacity() - 1)
}
#[inline]
fn calculate_offsets(hashes_size: usize,
keys_size: usize, keys_align: usize,
vals_align: usize)
- -> (usize, usize) {
+ -> (usize, usize, bool) {
let keys_offset = round_up_to_next(hashes_size, keys_align);
- let end_of_keys = keys_offset + keys_size;
+ let (end_of_keys, oflo) = keys_offset.overflowing_add(keys_size);
let vals_offset = round_up_to_next(end_of_keys, vals_align);
- (keys_offset, vals_offset)
+ (keys_offset, vals_offset, oflo)
}
// Returns a tuple of (minimum required malloc alignment, hash_offset,
fn calculate_allocation(hash_size: usize, hash_align: usize,
keys_size: usize, keys_align: usize,
vals_size: usize, vals_align: usize)
- -> (usize, usize, usize) {
+ -> (usize, usize, usize, bool) {
let hash_offset = 0;
- let (_, vals_offset) = calculate_offsets(hash_size,
- keys_size, keys_align,
- vals_align);
- let end_of_vals = vals_offset + vals_size;
+ let (_, vals_offset, oflo) = calculate_offsets(hash_size,
+ keys_size, keys_align,
+ vals_align);
+ let (end_of_vals, oflo2) = vals_offset.overflowing_add(vals_size);
let min_align = cmp::max(hash_align, cmp::max(keys_align, vals_align));
- (min_align, hash_offset, end_of_vals)
+ (min_align, hash_offset, end_of_vals, oflo || oflo2)
}
#[test]
fn test_offset_calculation() {
- assert_eq!(calculate_allocation(128, 8, 15, 1, 4, 4), (8, 0, 148));
- assert_eq!(calculate_allocation(3, 1, 2, 1, 1, 1), (1, 0, 6));
- assert_eq!(calculate_allocation(6, 2, 12, 4, 24, 8), (8, 0, 48));
- assert_eq!(calculate_offsets(128, 15, 1, 4), (128, 144));
- assert_eq!(calculate_offsets(3, 2, 1, 1), (3, 5));
- assert_eq!(calculate_offsets(6, 12, 4, 8), (8, 24));
+ assert_eq!(calculate_allocation(128, 8, 15, 1, 4, 4), (8, 0, 148, false));
+ assert_eq!(calculate_allocation(3, 1, 2, 1, 1, 1), (1, 0, 6, false));
+ assert_eq!(calculate_allocation(6, 2, 12, 4, 24, 8), (8, 0, 48, false));
+ assert_eq!(calculate_offsets(128, 15, 1, 4), (128, 144, false));
+ assert_eq!(calculate_offsets(3, 2, 1, 1), (3, 5, false));
+ assert_eq!(calculate_offsets(6, 12, 4, 8), (8, 24, false));
}
impl<K, V> RawTable<K, V> {
// This is great in theory, but in practice getting the alignment
// right is a little subtle. Therefore, calculating offsets has been
// factored out into a different function.
- let (malloc_alignment, hash_offset, size) =
+ let (malloc_alignment, hash_offset, size, oflo) =
calculate_allocation(
hashes_size, min_align_of::<u64>(),
keys_size, min_align_of::< K >(),
vals_size, min_align_of::< V >());
+ assert!(!oflo, "capacity overflow");
+
// One check for overflow that covers calculation and rounding of size.
let size_of_bucket = size_of::<u64>().checked_add(size_of::<K>()).unwrap()
.checked_add(size_of::<V>()).unwrap();
let keys_size = self.capacity * size_of::<K>();
let buffer = *self.hashes as *mut u8;
- let (keys_offset, vals_offset) = calculate_offsets(hashes_size,
- keys_size, min_align_of::<K>(),
- min_align_of::<V>());
-
+ let (keys_offset, vals_offset, oflo) =
+ calculate_offsets(hashes_size,
+ keys_size, min_align_of::<K>(),
+ min_align_of::<V>());
+ debug_assert!(!oflo, "capacity overflow");
unsafe {
RawBucket {
hash: *self.hashes,
let hashes_size = self.capacity * size_of::<u64>();
let keys_size = self.capacity * size_of::<K>();
let vals_size = self.capacity * size_of::<V>();
- let (align, _, size) = calculate_allocation(hashes_size, min_align_of::<u64>(),
- keys_size, min_align_of::<K>(),
- vals_size, min_align_of::<V>());
+ let (align, _, size, oflo) =
+ calculate_allocation(hashes_size, min_align_of::<u64>(),
+ keys_size, min_align_of::<K>(),
+ vals_size, min_align_of::<V>());
+
+ debug_assert!(!oflo, "should be impossible");
unsafe {
deallocate(*self.hashes as *mut u8, size, align);
//! * 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"
//!
//! 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
//! 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
//!
//! 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];
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 = "";
}
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]
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);
}
// 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;
/// # }
/// ```
#[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
+#[stable(feature = "rust1", since = "1.0.0")]
pub struct CString {
inner: Vec<u8>,
}
/// }
/// ```
#[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
/// 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) {
///
/// 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 }
///
/// 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;
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,
}
}
+#[stable(feature = "rust1", since = "1.0.0")]
impl FromError<NulError> for old_io::IoError {
fn from_error(_: NulError) -> old_io::IoError {
old_io::IoError {
/// }
/// # }
/// ```
+ #[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))
/// 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()
}
/// > **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]
/// > **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())
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");
}
}
//! 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;
// 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;
use core::prelude::*;
-use borrow::{Borrow, ToOwned};
+use borrow::{Borrow, Cow, ToOwned};
use fmt::{self, Debug};
use mem;
-use string::{String, CowString};
+use string::String;
use ops;
use cmp;
use hash::{Hash, Hasher};
/// 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) }
}
/// 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()) }
}
/// 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;
}
}
+#[stable(feature = "rust1", since = "1.0.0")]
impl ops::Deref for OsString {
type Target = OsStr;
}
}
+#[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> {
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> {
}
}
+#[stable(feature = "rust1", since = "1.0.0")]
impl Ord for OsString {
#[inline]
fn cmp(&self, other: &OsString) -> cmp::Ordering {
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)) }
}
/// 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()
}
- /// Convert an `OsStr` to a `CowString`.
+ /// Convert an `OsStr` to a `Cow<str>`.
///
/// Any non-Unicode sequences are replaced with U+FFFD REPLACEMENT CHARACTER.
- pub fn to_string_lossy(&self) -> CowString {
+ #[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() }
}
}
}
+#[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> {
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> {
// 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()) }
}
}
+#[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()
}
}
-#[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())
//! 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::*;
use sys_common::{AsInnerMut, FromInner, AsInner};
use vec::Vec;
+#[allow(deprecated)]
pub use self::tempdir::TempDir;
mod tempdir;
/// # Ok(())
/// # }
/// ```
+#[stable(feature = "rust1", since = "1.0.0")]
pub struct File {
inner: fs_imp::File,
path: PathBuf,
/// 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.
/// 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.
/// 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>>,
/// `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.
/// 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 {
///
/// 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)
}
/// 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)
}
///
/// 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()
}
///
/// 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()
}
/// 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)
}
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)
/// 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())
}
///
/// 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
}
///
/// 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
}
///
/// 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
}
///
/// 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
}
///
/// 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
}
/// * 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())
}
/// 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)
}
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>;
}
}
+#[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() }
}
/// 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,
/// 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)
}
/// 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())
/// * 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();
///
/// 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())
/// 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())
/// 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())
}
///
/// 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())
}
/// 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(()) }
///
/// 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())
}
/// # 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)) {
/// 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)
}
///
/// 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>;
}
/// 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.
///
/// 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)
/// 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)
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))
}
) }
-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));
}
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();
{
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));
}
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();
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?
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]
}
#[test]
+ #[cfg(not(windows))]
fn unlink_readonly() {
let tmpdir = tmpdir();
let path = tmpdir.join("file");
// 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::*;
#[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('ß')));
// 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::*;
/// 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,
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; }
}
}
}
+#[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 {
}
}
+#[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 {
}
}
+#[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);
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
#[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);
#[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]);
#[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));
#[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));
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));
#[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];
// =============================================================================
// 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());
}
}
+#[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());
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);
}
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
- try!(self.write(buf));
+ self.push_all(buf);
Ok(())
}
/// 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.
/// 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 }
}
///
/// 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 }
}
/// 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 }
}
/// `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 }
}
/// 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 }
}
/// 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
/// 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
///
/// 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 }
}
///
/// 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.
/// 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 {
/// 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.
///
/// 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
}
}
+#[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());
/// 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>;
/// 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>;
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))
}
}
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)
}
}
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.
///
/// 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;
}
/// 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() {
}
/// 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(()) }
//! 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]
#![feature(unsafe_no_drop_flag)]
#![feature(macro_reexport)]
#![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)]
}
// 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");
#[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)));
}
#[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]
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());
+ }
}
}
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) {
}
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() {
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])
(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 {
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]))
}
}
}
- // 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),
}
}
#[test]
fn multiple_connect_interleaved_lazy_schedule_ip4() {
- static MAX: usize = 10;
+ const MAX: usize = 10;
each_ip(&mut |addr| {
let acceptor = t!(TcpListener::bind(&addr));
-// 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.
//
use num::*;
use num::FpCategory as Fp;
+ #[test]
+ fn test_num_f32() {
+ test_num(10f32, 2f32);
+ }
+
#[test]
fn test_min_nan() {
assert_eq!(NAN.min(2.0), 2.0);
}
#[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]
assert_approx_eq!((-1.7f32).fract(), -0.7f32);
}
+ #[test]
+ fn test_abs() {
+ assert_eq!(INFINITY.abs(), INFINITY);
+ assert_eq!(1f32.abs(), 1f32);
+ assert_eq!(0f32.abs(), 0f32);
+ assert_eq!((-0f32).abs(), 0f32);
+ assert_eq!((-1f32).abs(), 1f32);
+ assert_eq!(NEG_INFINITY.abs(), INFINITY);
+ assert_eq!((1f32/NEG_INFINITY).abs(), 0f32);
+ assert!(NAN.abs().is_nan());
+ }
+
+ #[test]
+ fn test_signum() {
+ assert_eq!(INFINITY.signum(), 1f32);
+ assert_eq!(1f32.signum(), 1f32);
+ assert_eq!(0f32.signum(), 1f32);
+ assert_eq!((-0f32).signum(), -1f32);
+ assert_eq!((-1f32).signum(), -1f32);
+ assert_eq!(NEG_INFINITY.signum(), -1f32);
+ assert_eq!((1f32/NEG_INFINITY).signum(), -1f32);
+ assert!(NAN.signum().is_nan());
+ }
+
+ #[test]
+ fn test_is_positive() {
+ assert!(INFINITY.is_positive());
+ assert!(1f32.is_positive());
+ assert!(0f32.is_positive());
+ assert!(!(-0f32).is_positive());
+ assert!(!(-1f32).is_positive());
+ assert!(!NEG_INFINITY.is_positive());
+ assert!(!(1f32/NEG_INFINITY).is_positive());
+ assert!(!NAN.is_positive());
+ }
+
+ #[test]
+ fn test_is_negative() {
+ assert!(!INFINITY.is_negative());
+ assert!(!1f32.is_negative());
+ assert!(!0f32.is_negative());
+ assert!((-0f32).is_negative());
+ assert!((-1f32).is_negative());
+ assert!(NEG_INFINITY.is_negative());
+ assert!((1f32/NEG_INFINITY).is_negative());
+ assert!(!NAN.is_negative());
+ }
+
+ #[test]
+ fn test_mul_add() {
+ let nan: f32 = Float::nan();
+ let inf: f32 = Float::infinity();
+ let neg_inf: f32 = Float::neg_infinity();
+ assert_approx_eq!(12.3f32.mul_add(4.5, 6.7), 62.05);
+ assert_approx_eq!((-12.3f32).mul_add(-4.5, -6.7), 48.65);
+ assert_approx_eq!(0.0f32.mul_add(8.9, 1.2), 1.2);
+ assert_approx_eq!(3.4f32.mul_add(-0.0, 5.6), 5.6);
+ assert!(nan.mul_add(7.8, 9.0).is_nan());
+ assert_eq!(inf.mul_add(7.8, 9.0), inf);
+ assert_eq!(neg_inf.mul_add(7.8, 9.0), neg_inf);
+ assert_eq!(8.9f32.mul_add(inf, 3.2), inf);
+ assert_eq!((-3.2f32).mul_add(2.4, neg_inf), neg_inf);
+ }
+
+ #[test]
+ fn test_recip() {
+ let nan: f32 = Float::nan();
+ let inf: f32 = Float::infinity();
+ let neg_inf: f32 = Float::neg_infinity();
+ assert_eq!(1.0f32.recip(), 1.0);
+ assert_eq!(2.0f32.recip(), 0.5);
+ assert_eq!((-0.4f32).recip(), -2.5);
+ assert_eq!(0.0f32.recip(), inf);
+ assert!(nan.recip().is_nan());
+ assert_eq!(inf.recip(), 0.0);
+ assert_eq!(neg_inf.recip(), 0.0);
+ }
+
+ #[test]
+ fn test_powi() {
+ let nan: f32 = Float::nan();
+ let inf: f32 = Float::infinity();
+ let neg_inf: f32 = Float::neg_infinity();
+ assert_eq!(1.0f32.powi(1), 1.0);
+ assert_approx_eq!((-3.1f32).powi(2), 9.61);
+ assert_approx_eq!(5.9f32.powi(-2), 0.028727);
+ assert_eq!(8.3f32.powi(0), 1.0);
+ assert!(nan.powi(2).is_nan());
+ assert_eq!(inf.powi(3), inf);
+ assert_eq!(neg_inf.powi(2), inf);
+ }
+
+ #[test]
+ fn test_powf() {
+ let nan: f32 = Float::nan();
+ let inf: f32 = Float::infinity();
+ let neg_inf: f32 = Float::neg_infinity();
+ assert_eq!(1.0f32.powf(1.0), 1.0);
+ assert_approx_eq!(3.4f32.powf(4.5), 246.408218);
+ assert_approx_eq!(2.7f32.powf(-3.2), 0.041652);
+ assert_approx_eq!((-3.1f32).powf(2.0), 9.61);
+ assert_approx_eq!(5.9f32.powf(-2.0), 0.028727);
+ assert_eq!(8.3f32.powf(0.0), 1.0);
+ assert!(nan.powf(2.0).is_nan());
+ assert_eq!(inf.powf(2.0), inf);
+ assert_eq!(neg_inf.powf(3.0), neg_inf);
+ }
+
+ #[test]
+ fn test_sqrt_domain() {
+ assert!(NAN.sqrt().is_nan());
+ assert!(NEG_INFINITY.sqrt().is_nan());
+ assert!((-1.0f32).sqrt().is_nan());
+ assert_eq!((-0.0f32).sqrt(), -0.0);
+ assert_eq!(0.0f32.sqrt(), 0.0);
+ assert_eq!(1.0f32.sqrt(), 1.0);
+ assert_eq!(INFINITY.sqrt(), INFINITY);
+ }
+
+ #[test]
+ fn test_rsqrt() {
+ let nan: f32 = Float::nan();
+ let inf: f32 = Float::infinity();
+ let neg_inf: f32 = Float::neg_infinity();
+ assert!(nan.rsqrt().is_nan());
+ assert_eq!(inf.rsqrt(), 0.0);
+ assert!(neg_inf.rsqrt().is_nan());
+ assert!((-1.0f32).rsqrt().is_nan());
+ assert_eq!((-0.0f32).rsqrt(), neg_inf);
+ assert_eq!(0.0f32.rsqrt(), inf);
+ assert_eq!(1.0f32.rsqrt(), 1.0);
+ assert_eq!(4.0f32.rsqrt(), 0.5);
+ }
+
#[test]
fn test_exp() {
assert_eq!(1.0, 0.0f32.exp());
assert!(nan.exp2().is_nan());
}
+ #[test]
+ fn test_ln() {
+ let nan: f32 = Float::nan();
+ let inf: f32 = Float::infinity();
+ let neg_inf: f32 = Float::neg_infinity();
+ assert_approx_eq!(1.0f32.exp().ln(), 1.0);
+ assert!(nan.ln().is_nan());
+ assert_eq!(inf.ln(), inf);
+ assert!(neg_inf.ln().is_nan());
+ assert!((-2.3f32).ln().is_nan());
+ assert_eq!((-0.0f32).ln(), neg_inf);
+ assert_eq!(0.0f32.ln(), neg_inf);
+ assert_approx_eq!(4.0f32.ln(), 1.386294);
+ }
+
+ #[test]
+ fn test_log() {
+ let nan: f32 = Float::nan();
+ let inf: f32 = Float::infinity();
+ let neg_inf: f32 = Float::neg_infinity();
+ assert_eq!(10.0f32.log(10.0), 1.0);
+ assert_approx_eq!(2.3f32.log(3.5), 0.664858);
+ assert_eq!(1.0f32.exp().log(1.0.exp()), 1.0);
+ assert!(1.0f32.log(1.0).is_nan());
+ assert!(1.0f32.log(-13.9).is_nan());
+ assert!(nan.log(2.3).is_nan());
+ assert_eq!(inf.log(10.0), inf);
+ assert!(neg_inf.log(8.8).is_nan());
+ assert!((-2.3f32).log(0.1).is_nan());
+ assert_eq!((-0.0f32).log(2.0), neg_inf);
+ assert_eq!(0.0f32.log(7.0), neg_inf);
+ }
+
+ #[test]
+ fn test_log2() {
+ let nan: f32 = Float::nan();
+ let inf: f32 = Float::infinity();
+ let neg_inf: f32 = Float::neg_infinity();
+ assert_approx_eq!(10.0f32.log2(), 3.321928);
+ assert_approx_eq!(2.3f32.log2(), 1.201634);
+ assert_approx_eq!(1.0f32.exp().log2(), 1.442695);
+ assert!(nan.log2().is_nan());
+ assert_eq!(inf.log2(), inf);
+ assert!(neg_inf.log2().is_nan());
+ assert!((-2.3f32).log2().is_nan());
+ assert_eq!((-0.0f32).log2(), neg_inf);
+ assert_eq!(0.0f32.log2(), neg_inf);
+ }
+
+ #[test]
+ fn test_log10() {
+ let nan: f32 = Float::nan();
+ let inf: f32 = Float::infinity();
+ let neg_inf: f32 = Float::neg_infinity();
+ assert_eq!(10.0f32.log10(), 1.0);
+ assert_approx_eq!(2.3f32.log10(), 0.361728);
+ assert_approx_eq!(1.0f32.exp().log10(), 0.434294);
+ assert_eq!(1.0f32.log10(), 0.0);
+ assert!(nan.log10().is_nan());
+ assert_eq!(inf.log10(), inf);
+ assert!(neg_inf.log10().is_nan());
+ assert!((-2.3f32).log10().is_nan());
+ assert_eq!((-0.0f32).log10(), neg_inf);
+ assert_eq!(0.0f32.log10(), neg_inf);
+ }
+
+ #[test]
+ fn test_to_degrees() {
+ let pi: f32 = consts::PI;
+ let nan: f32 = Float::nan();
+ let inf: f32 = Float::infinity();
+ let neg_inf: f32 = Float::neg_infinity();
+ assert_eq!(0.0f32.to_degrees(), 0.0);
+ assert_approx_eq!((-5.8f32).to_degrees(), -332.315521);
+ assert_eq!(pi.to_degrees(), 180.0);
+ assert!(nan.to_degrees().is_nan());
+ assert_eq!(inf.to_degrees(), inf);
+ assert_eq!(neg_inf.to_degrees(), neg_inf);
+ }
+
+ #[test]
+ fn test_to_radians() {
+ let pi: f32 = consts::PI;
+ let nan: f32 = Float::nan();
+ let inf: f32 = Float::infinity();
+ let neg_inf: f32 = Float::neg_infinity();
+ assert_eq!(0.0f32.to_radians(), 0.0);
+ assert_approx_eq!(154.6f32.to_radians(), 2.698279);
+ assert_approx_eq!((-332.31f32).to_radians(), -5.799903);
+ assert_eq!(180.0f32.to_radians(), pi);
+ assert!(nan.to_radians().is_nan());
+ assert_eq!(inf.to_radians(), inf);
+ assert_eq!(neg_inf.to_radians(), neg_inf);
+ }
+
+ #[test]
+ fn test_ldexp() {
+ // We have to use from_str until base-2 exponents
+ // are supported in floating-point literals
+ let f1: f32 = FromStrRadix::from_str_radix("1p-123", 16).unwrap();
+ let f2: f32 = FromStrRadix::from_str_radix("1p-111", 16).unwrap();
+ let f3: f32 = FromStrRadix::from_str_radix("1.Cp-12", 16).unwrap();
+ assert_eq!(Float::ldexp(1f32, -123), f1);
+ assert_eq!(Float::ldexp(1f32, -111), f2);
+ assert_eq!(Float::ldexp(1.75f32, -12), f3);
+
+ assert_eq!(Float::ldexp(0f32, -123), 0f32);
+ assert_eq!(Float::ldexp(-0f32, -123), -0f32);
+
+ let inf: f32 = Float::infinity();
+ let neg_inf: f32 = Float::neg_infinity();
+ let nan: f32 = Float::nan();
+ assert_eq!(Float::ldexp(inf, -123), inf);
+ assert_eq!(Float::ldexp(neg_inf, -123), neg_inf);
+ assert!(Float::ldexp(nan, -123).is_nan());
+ }
+
+ #[test]
+ fn test_frexp() {
+ // We have to use from_str until base-2 exponents
+ // are supported in floating-point literals
+ let f1: f32 = FromStrRadix::from_str_radix("1p-123", 16).unwrap();
+ let f2: f32 = FromStrRadix::from_str_radix("1p-111", 16).unwrap();
+ let f3: f32 = FromStrRadix::from_str_radix("1.Cp-123", 16).unwrap();
+ let (x1, exp1) = f1.frexp();
+ let (x2, exp2) = f2.frexp();
+ let (x3, exp3) = f3.frexp();
+ assert_eq!((x1, exp1), (0.5f32, -122));
+ assert_eq!((x2, exp2), (0.5f32, -110));
+ assert_eq!((x3, exp3), (0.875f32, -122));
+ assert_eq!(Float::ldexp(x1, exp1), f1);
+ assert_eq!(Float::ldexp(x2, exp2), f2);
+ assert_eq!(Float::ldexp(x3, exp3), f3);
+
+ assert_eq!(0f32.frexp(), (0f32, 0));
+ assert_eq!((-0f32).frexp(), (-0f32, 0));
+ }
+
+ #[test] #[cfg_attr(windows, ignore)] // FIXME #8755
+ fn test_frexp_nowin() {
+ let inf: f32 = Float::infinity();
+ let neg_inf: f32 = Float::neg_infinity();
+ let nan: f32 = Float::nan();
+ assert_eq!(match inf.frexp() { (x, _) => x }, inf);
+ assert_eq!(match neg_inf.frexp() { (x, _) => x }, neg_inf);
+ assert!(match nan.frexp() { (x, _) => x.is_nan() })
+ }
+
+ #[test]
+ fn test_abs_sub() {
+ assert_eq!((-1f32).abs_sub(1f32), 0f32);
+ assert_eq!(1f32.abs_sub(1f32), 0f32);
+ assert_eq!(1f32.abs_sub(0f32), 1f32);
+ assert_eq!(1f32.abs_sub(-1f32), 2f32);
+ assert_eq!(NEG_INFINITY.abs_sub(0f32), 0f32);
+ assert_eq!(INFINITY.abs_sub(1f32), INFINITY);
+ assert_eq!(0f32.abs_sub(NEG_INFINITY), INFINITY);
+ assert_eq!(0f32.abs_sub(INFINITY), 0f32);
+ }
+
+ #[test]
+ fn test_abs_sub_nowin() {
+ assert!(NAN.abs_sub(-1f32).is_nan());
+ assert!(1f32.abs_sub(NAN).is_nan());
+ }
+
#[test]
fn test_asinh() {
assert_eq!(0.0f32.asinh(), 0.0f32);
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);
- }
}
-// 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.
//
use num::*;
use num::FpCategory as Fp;
+ #[test]
+ fn test_num_f64() {
+ test_num(10f64, 2f64);
+ }
+
#[test]
fn test_min_nan() {
assert_eq!(NAN.min(2.0), 2.0);
}
#[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]
assert_approx_eq!((-1.7f64).fract(), -0.7f64);
}
+ #[test]
+ fn test_abs() {
+ assert_eq!(INFINITY.abs(), INFINITY);
+ assert_eq!(1f64.abs(), 1f64);
+ assert_eq!(0f64.abs(), 0f64);
+ assert_eq!((-0f64).abs(), 0f64);
+ assert_eq!((-1f64).abs(), 1f64);
+ assert_eq!(NEG_INFINITY.abs(), INFINITY);
+ assert_eq!((1f64/NEG_INFINITY).abs(), 0f64);
+ assert!(NAN.abs().is_nan());
+ }
+
+ #[test]
+ fn test_signum() {
+ assert_eq!(INFINITY.signum(), 1f64);
+ assert_eq!(1f64.signum(), 1f64);
+ assert_eq!(0f64.signum(), 1f64);
+ assert_eq!((-0f64).signum(), -1f64);
+ assert_eq!((-1f64).signum(), -1f64);
+ assert_eq!(NEG_INFINITY.signum(), -1f64);
+ assert_eq!((1f64/NEG_INFINITY).signum(), -1f64);
+ assert!(NAN.signum().is_nan());
+ }
+
+ #[test]
+ fn test_is_positive() {
+ assert!(INFINITY.is_positive());
+ assert!(1f64.is_positive());
+ assert!(0f64.is_positive());
+ assert!(!(-0f64).is_positive());
+ assert!(!(-1f64).is_positive());
+ assert!(!NEG_INFINITY.is_positive());
+ assert!(!(1f64/NEG_INFINITY).is_positive());
+ assert!(!NAN.is_positive());
+ }
+
+ #[test]
+ fn test_is_negative() {
+ assert!(!INFINITY.is_negative());
+ assert!(!1f64.is_negative());
+ assert!(!0f64.is_negative());
+ assert!((-0f64).is_negative());
+ assert!((-1f64).is_negative());
+ assert!(NEG_INFINITY.is_negative());
+ assert!((1f64/NEG_INFINITY).is_negative());
+ assert!(!NAN.is_negative());
+ }
+
+ #[test]
+ fn test_mul_add() {
+ let nan: f64 = Float::nan();
+ let inf: f64 = Float::infinity();
+ let neg_inf: f64 = Float::neg_infinity();
+ assert_approx_eq!(12.3f64.mul_add(4.5, 6.7), 62.05);
+ assert_approx_eq!((-12.3f64).mul_add(-4.5, -6.7), 48.65);
+ assert_approx_eq!(0.0f64.mul_add(8.9, 1.2), 1.2);
+ assert_approx_eq!(3.4f64.mul_add(-0.0, 5.6), 5.6);
+ assert!(nan.mul_add(7.8, 9.0).is_nan());
+ assert_eq!(inf.mul_add(7.8, 9.0), inf);
+ assert_eq!(neg_inf.mul_add(7.8, 9.0), neg_inf);
+ assert_eq!(8.9f64.mul_add(inf, 3.2), inf);
+ assert_eq!((-3.2f64).mul_add(2.4, neg_inf), neg_inf);
+ }
+
+ #[test]
+ fn test_recip() {
+ let nan: f64 = Float::nan();
+ let inf: f64 = Float::infinity();
+ let neg_inf: f64 = Float::neg_infinity();
+ assert_eq!(1.0f64.recip(), 1.0);
+ assert_eq!(2.0f64.recip(), 0.5);
+ assert_eq!((-0.4f64).recip(), -2.5);
+ assert_eq!(0.0f64.recip(), inf);
+ assert!(nan.recip().is_nan());
+ assert_eq!(inf.recip(), 0.0);
+ assert_eq!(neg_inf.recip(), 0.0);
+ }
+
+ #[test]
+ fn test_powi() {
+ let nan: f64 = Float::nan();
+ let inf: f64 = Float::infinity();
+ let neg_inf: f64 = Float::neg_infinity();
+ assert_eq!(1.0f64.powi(1), 1.0);
+ assert_approx_eq!((-3.1f64).powi(2), 9.61);
+ assert_approx_eq!(5.9f64.powi(-2), 0.028727);
+ assert_eq!(8.3f64.powi(0), 1.0);
+ assert!(nan.powi(2).is_nan());
+ assert_eq!(inf.powi(3), inf);
+ assert_eq!(neg_inf.powi(2), inf);
+ }
+
+ #[test]
+ fn test_powf() {
+ let nan: f64 = Float::nan();
+ let inf: f64 = Float::infinity();
+ let neg_inf: f64 = Float::neg_infinity();
+ assert_eq!(1.0f64.powf(1.0), 1.0);
+ assert_approx_eq!(3.4f64.powf(4.5), 246.408183);
+ assert_approx_eq!(2.7f64.powf(-3.2), 0.041652);
+ assert_approx_eq!((-3.1f64).powf(2.0), 9.61);
+ assert_approx_eq!(5.9f64.powf(-2.0), 0.028727);
+ assert_eq!(8.3f64.powf(0.0), 1.0);
+ assert!(nan.powf(2.0).is_nan());
+ assert_eq!(inf.powf(2.0), inf);
+ assert_eq!(neg_inf.powf(3.0), neg_inf);
+ }
+
+ #[test]
+ fn test_sqrt_domain() {
+ assert!(NAN.sqrt().is_nan());
+ assert!(NEG_INFINITY.sqrt().is_nan());
+ assert!((-1.0f64).sqrt().is_nan());
+ assert_eq!((-0.0f64).sqrt(), -0.0);
+ assert_eq!(0.0f64.sqrt(), 0.0);
+ assert_eq!(1.0f64.sqrt(), 1.0);
+ assert_eq!(INFINITY.sqrt(), INFINITY);
+ }
+
+ #[test]
+ fn test_rsqrt() {
+ let nan: f64 = Float::nan();
+ let inf: f64 = Float::infinity();
+ let neg_inf: f64 = Float::neg_infinity();
+ assert!(nan.rsqrt().is_nan());
+ assert_eq!(inf.rsqrt(), 0.0);
+ assert!(neg_inf.rsqrt().is_nan());
+ assert!((-1.0f64).rsqrt().is_nan());
+ assert_eq!((-0.0f64).rsqrt(), neg_inf);
+ assert_eq!(0.0f64.rsqrt(), inf);
+ assert_eq!(1.0f64.rsqrt(), 1.0);
+ assert_eq!(4.0f64.rsqrt(), 0.5);
+ }
+
#[test]
fn test_exp() {
assert_eq!(1.0, 0.0f64.exp());
assert!(nan.exp2().is_nan());
}
+ #[test]
+ fn test_ln() {
+ let nan: f64 = Float::nan();
+ let inf: f64 = Float::infinity();
+ let neg_inf: f64 = Float::neg_infinity();
+ assert_approx_eq!(1.0f64.exp().ln(), 1.0);
+ assert!(nan.ln().is_nan());
+ assert_eq!(inf.ln(), inf);
+ assert!(neg_inf.ln().is_nan());
+ assert!((-2.3f64).ln().is_nan());
+ assert_eq!((-0.0f64).ln(), neg_inf);
+ assert_eq!(0.0f64.ln(), neg_inf);
+ assert_approx_eq!(4.0f64.ln(), 1.386294);
+ }
+
+ #[test]
+ fn test_log() {
+ let nan: f64 = Float::nan();
+ let inf: f64 = Float::infinity();
+ let neg_inf: f64 = Float::neg_infinity();
+ assert_eq!(10.0f64.log(10.0), 1.0);
+ assert_approx_eq!(2.3f64.log(3.5), 0.664858);
+ assert_eq!(1.0f64.exp().log(1.0.exp()), 1.0);
+ assert!(1.0f64.log(1.0).is_nan());
+ assert!(1.0f64.log(-13.9).is_nan());
+ assert!(nan.log(2.3).is_nan());
+ assert_eq!(inf.log(10.0), inf);
+ assert!(neg_inf.log(8.8).is_nan());
+ assert!((-2.3f64).log(0.1).is_nan());
+ assert_eq!((-0.0f64).log(2.0), neg_inf);
+ assert_eq!(0.0f64.log(7.0), neg_inf);
+ }
+
+ #[test]
+ fn test_log2() {
+ let nan: f64 = Float::nan();
+ let inf: f64 = Float::infinity();
+ let neg_inf: f64 = Float::neg_infinity();
+ assert_approx_eq!(10.0f64.log2(), 3.321928);
+ assert_approx_eq!(2.3f64.log2(), 1.201634);
+ assert_approx_eq!(1.0f64.exp().log2(), 1.442695);
+ assert!(nan.log2().is_nan());
+ assert_eq!(inf.log2(), inf);
+ assert!(neg_inf.log2().is_nan());
+ assert!((-2.3f64).log2().is_nan());
+ assert_eq!((-0.0f64).log2(), neg_inf);
+ assert_eq!(0.0f64.log2(), neg_inf);
+ }
+
+ #[test]
+ fn test_log10() {
+ let nan: f64 = Float::nan();
+ let inf: f64 = Float::infinity();
+ let neg_inf: f64 = Float::neg_infinity();
+ assert_eq!(10.0f64.log10(), 1.0);
+ assert_approx_eq!(2.3f64.log10(), 0.361728);
+ assert_approx_eq!(1.0f64.exp().log10(), 0.434294);
+ assert_eq!(1.0f64.log10(), 0.0);
+ assert!(nan.log10().is_nan());
+ assert_eq!(inf.log10(), inf);
+ assert!(neg_inf.log10().is_nan());
+ assert!((-2.3f64).log10().is_nan());
+ assert_eq!((-0.0f64).log10(), neg_inf);
+ assert_eq!(0.0f64.log10(), neg_inf);
+ }
+
+ #[test]
+ fn test_to_degrees() {
+ let pi: f64 = consts::PI;
+ let nan: f64 = Float::nan();
+ let inf: f64 = Float::infinity();
+ let neg_inf: f64 = Float::neg_infinity();
+ assert_eq!(0.0f64.to_degrees(), 0.0);
+ assert_approx_eq!((-5.8f64).to_degrees(), -332.315521);
+ assert_eq!(pi.to_degrees(), 180.0);
+ assert!(nan.to_degrees().is_nan());
+ assert_eq!(inf.to_degrees(), inf);
+ assert_eq!(neg_inf.to_degrees(), neg_inf);
+ }
+
+ #[test]
+ fn test_to_radians() {
+ let pi: f64 = consts::PI;
+ let nan: f64 = Float::nan();
+ let inf: f64 = Float::infinity();
+ let neg_inf: f64 = Float::neg_infinity();
+ assert_eq!(0.0f64.to_radians(), 0.0);
+ assert_approx_eq!(154.6f64.to_radians(), 2.698279);
+ assert_approx_eq!((-332.31f64).to_radians(), -5.799903);
+ assert_eq!(180.0f64.to_radians(), pi);
+ assert!(nan.to_radians().is_nan());
+ assert_eq!(inf.to_radians(), inf);
+ assert_eq!(neg_inf.to_radians(), neg_inf);
+ }
+
+ #[test]
+ fn test_ldexp() {
+ // We have to use from_str until base-2 exponents
+ // are supported in floating-point literals
+ let f1: f64 = FromStrRadix::from_str_radix("1p-123", 16).unwrap();
+ let f2: f64 = FromStrRadix::from_str_radix("1p-111", 16).unwrap();
+ let f3: f64 = FromStrRadix::from_str_radix("1.Cp-12", 16).unwrap();
+ assert_eq!(Float::ldexp(1f64, -123), f1);
+ assert_eq!(Float::ldexp(1f64, -111), f2);
+ assert_eq!(Float::ldexp(1.75f64, -12), f3);
+
+ assert_eq!(Float::ldexp(0f64, -123), 0f64);
+ assert_eq!(Float::ldexp(-0f64, -123), -0f64);
+
+ let inf: f64 = Float::infinity();
+ let neg_inf: f64 = Float::neg_infinity();
+ let nan: f64 = Float::nan();
+ assert_eq!(Float::ldexp(inf, -123), inf);
+ assert_eq!(Float::ldexp(neg_inf, -123), neg_inf);
+ assert!(Float::ldexp(nan, -123).is_nan());
+ }
+
+ #[test]
+ fn test_frexp() {
+ // We have to use from_str until base-2 exponents
+ // are supported in floating-point literals
+ let f1: f64 = FromStrRadix::from_str_radix("1p-123", 16).unwrap();
+ let f2: f64 = FromStrRadix::from_str_radix("1p-111", 16).unwrap();
+ let f3: f64 = FromStrRadix::from_str_radix("1.Cp-123", 16).unwrap();
+ let (x1, exp1) = f1.frexp();
+ let (x2, exp2) = f2.frexp();
+ let (x3, exp3) = f3.frexp();
+ assert_eq!((x1, exp1), (0.5f64, -122));
+ assert_eq!((x2, exp2), (0.5f64, -110));
+ assert_eq!((x3, exp3), (0.875f64, -122));
+ assert_eq!(Float::ldexp(x1, exp1), f1);
+ assert_eq!(Float::ldexp(x2, exp2), f2);
+ assert_eq!(Float::ldexp(x3, exp3), f3);
+
+ assert_eq!(0f64.frexp(), (0f64, 0));
+ assert_eq!((-0f64).frexp(), (-0f64, 0));
+ }
+
+ #[test] #[cfg_attr(windows, ignore)] // FIXME #8755
+ fn test_frexp_nowin() {
+ let inf: f64 = Float::infinity();
+ let neg_inf: f64 = Float::neg_infinity();
+ let nan: f64 = Float::nan();
+ assert_eq!(match inf.frexp() { (x, _) => x }, inf);
+ assert_eq!(match neg_inf.frexp() { (x, _) => x }, neg_inf);
+ assert!(match nan.frexp() { (x, _) => x.is_nan() })
+ }
+
+ #[test]
+ fn test_abs_sub() {
+ assert_eq!((-1f64).abs_sub(1f64), 0f64);
+ assert_eq!(1f64.abs_sub(1f64), 0f64);
+ assert_eq!(1f64.abs_sub(0f64), 1f64);
+ assert_eq!(1f64.abs_sub(-1f64), 2f64);
+ assert_eq!(NEG_INFINITY.abs_sub(0f64), 0f64);
+ assert_eq!(INFINITY.abs_sub(1f64), INFINITY);
+ assert_eq!(0f64.abs_sub(NEG_INFINITY), INFINITY);
+ assert_eq!(0f64.abs_sub(INFINITY), 0f64);
+ }
+
+ #[test]
+ fn test_abs_sub_nowin() {
+ assert!(NAN.abs_sub(-1f64).is_nan());
+ assert!(1f64.abs_sub(NAN).is_nan());
+ }
+
#[test]
fn test_asinh() {
assert_eq!(0.0f64.asinh(), 0.0f64);
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);
- }
}
pub use core::num::{from_f32, from_f64};
pub use core::num::{FromStrRadix, from_str_radix};
pub use core::num::{FpCategory, ParseIntError, ParseFloatError};
+pub use core::num::wrapping;
use option::Option;
///
/// 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;
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);
}
)
}
#[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 += 1 as u8;
+ 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 += 1 as u16;
+ 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 += 1 as u32;
+ 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 += 1 as u64;
+ u64_val = u64_val.wrapping_add(1);
assert_eq!(u64_val.to_string(), "0");
}
#[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);
- u8_val += 1 as u8;
+ u8_val = u8_val.wrapping_add(1);
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);
- u16_val += 1 as u16;
+ u16_val = u16_val.wrapping_add(1);
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);
- u32_val += 1 as u32;
+ u32_val = u32_val.wrapping_add(1);
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);
- u64_val += 1 as u64;
+ u64_val = u64_val.wrapping_add(1);
assert_eq!(from_str::<u64>("0"), Some(u64_val));
assert_eq!(from_str::<u64>("-1"), None);
}
// 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.
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()),
deccum = deccum / radix_gen;
deccum = deccum.trunc();
- buf.push(char::from_digit(current_digit.to_int().unwrap() as u32, radix)
+ buf.push(char::from_digit(current_digit.to_isize().unwrap() as u32, radix)
.unwrap() as u8);
// No more digits to calculate for the non-fractional part -> break
let current_digit = deccum.trunc().abs();
buf.push(char::from_digit(
- current_digit.to_int().unwrap() as u32, radix).unwrap() as u8);
+ current_digit.to_isize().unwrap() as u32, radix).unwrap() as u8);
// Decrease the deccumulator one fractional digit at a time
deccum = deccum.fract();
// Some constants for from_str_bytes_common's input validation,
// they define minimum radix values for which the character is a valid digit.
-static DIGIT_P_RADIX: u32 = ('p' as u32) - ('a' as u32) + 11;
-static DIGIT_E_RADIX: u32 = ('e' as u32) - ('a' as u32) + 11;
+const DIGIT_P_RADIX: u32 = ('p' as u32) - ('a' as u32) + 11;
+const DIGIT_E_RADIX: u32 = ('e' as u32) - ('a' as u32) + 11;
#[cfg(test)]
mod tests {
+ use core::num::wrapping::WrappingOps;
use string::ToString;
#[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 += 1 as i8;
+ 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 += 1 as i16;
+ 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 += 1 as i32;
+ 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 += 1 as i64;
+ i64_val = i64_val.wrapping_add(1);
assert_eq!(i64_val.to_string(), "-9223372036854775808");
}
}
#[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('ß')));
}
#[test]
- #[should_fail]
+ #[should_panic]
fn dont_panic_in_drop_on_panicked_flush() {
struct FailFlushWriter;
/// # 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),
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 []));
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);
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;
}
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();
}
#[test]
- #[should_fail]
+ #[should_panic]
fn read_to_end_error() {
let mut reader = ThreeChunkReader {
count: 0,
({
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() {
/// 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,
}
}
+#[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
/// * 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> {
///
/// 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)
}
/// # 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
}
/// 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",
/// 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",
/// 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|
/// 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|
/// 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|
/// 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|
/// # 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|
/// 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|
/// 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| {
/// 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|
}
/// 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|
/// 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|
/// 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|
///
/// 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|
///
/// 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|
///
/// 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|
/// 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",
/// 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",
/// 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>,
}
/// # 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?
/// # 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());
/// `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|
}
/// 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.
///
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();
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';
pub fn from_errno(errno: i32, detail: bool) -> IoError {
let mut err = sys::decode_error(errno as i32);
if detail && err.kind == OtherIoError {
- err.detail = Some(os::error_string(errno).chars()
- .map(|c| c.to_lowercase()).collect())
+ err.detail = Some(os::error_string(errno).to_lowercase());
}
err
}
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 {
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;
///
/// The number of bytes returned is system-dependent.
fn read_le_uint(&mut self) -> IoResult<uint> {
- self.read_le_uint_n(usize::BYTES).map(|i| i as uint)
+ self.read_le_uint_n(usize::BYTES as usize).map(|i| i as uint)
}
/// Reads a little-endian integer.
///
/// The number of bytes returned is system-dependent.
fn read_le_int(&mut self) -> IoResult<int> {
- self.read_le_int_n(isize::BYTES).map(|i| i as int)
+ self.read_le_int_n(isize::BYTES as usize).map(|i| i as int)
}
/// Reads a big-endian unsigned integer.
///
/// The number of bytes returned is system-dependent.
fn read_be_uint(&mut self) -> IoResult<uint> {
- self.read_be_uint_n(usize::BYTES).map(|i| i as uint)
+ self.read_be_uint_n(usize::BYTES as usize).map(|i| i as uint)
}
/// Reads a big-endian integer.
///
/// The number of bytes returned is system-dependent.
fn read_be_int(&mut self) -> IoResult<int> {
- self.read_be_int_n(isize::BYTES).map(|i| i as int)
+ self.read_be_int_n(isize::BYTES as usize).map(|i| i as int)
}
/// Reads a big-endian `u64`.
/// 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])
}
/// Write a little-endian uint (number of bytes depends on system).
#[inline]
fn write_le_uint(&mut self, n: uint) -> IoResult<()> {
- extensions::u64_to_le_bytes(n as u64, usize::BYTES, |v| self.write_all(v))
+ extensions::u64_to_le_bytes(n as u64, usize::BYTES as usize, |v| self.write_all(v))
}
/// Write a little-endian int (number of bytes depends on system).
#[inline]
fn write_le_int(&mut self, n: int) -> IoResult<()> {
- extensions::u64_to_le_bytes(n as u64, isize::BYTES, |v| self.write_all(v))
+ extensions::u64_to_le_bytes(n as u64, isize::BYTES as usize, |v| self.write_all(v))
}
/// Write a big-endian uint (number of bytes depends on system).
#[inline]
fn write_be_uint(&mut self, n: uint) -> IoResult<()> {
- extensions::u64_to_be_bytes(n as u64, usize::BYTES, |v| self.write_all(v))
+ extensions::u64_to_be_bytes(n as u64, usize::BYTES as usize, |v| self.write_all(v))
}
/// Write a big-endian int (number of bytes depends on system).
#[inline]
fn write_be_int(&mut self, n: int) -> IoResult<()> {
- extensions::u64_to_be_bytes(n as u64, isize::BYTES, |v| self.write_all(v))
+ extensions::u64_to_be_bytes(n as u64, isize::BYTES as usize, |v| self.write_all(v))
}
/// Write a big-endian u64 (8 bytes).
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());
}
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) {
}
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() {
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])
(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 {
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]))
}
}
fn read_ip_addr(&mut self) -> Option<IpAddr> {
- let ipv4_addr = |p: &mut Parser| p.read_ipv4_addr();
- let ipv6_addr = |p: &mut Parser| p.read_ipv6_addr();
- self.read_or(&mut [box ipv4_addr, box ipv6_addr])
+ let ipv4_addr: Box<_> = box |p: &mut Parser| p.read_ipv4_addr();
+ let ipv6_addr: Box<_> = box |p: &mut Parser| p.read_ipv6_addr();
+ self.read_or(&mut [ipv4_addr, ipv6_addr])
}
fn read_socket_addr(&mut self) -> Option<SocketAddr> {
let ip_addr = |p: &mut Parser| {
- let ipv4_p = |p: &mut Parser| p.read_ip_addr();
- let ipv6_p = |p: &mut Parser| {
+ let ipv4_p: Box<_> = box |p: &mut Parser| p.read_ip_addr();
+ let ipv6_p: Box<_> = box |p: &mut Parser| {
let open_br = |p: &mut Parser| p.read_given_char('[');
let ip_addr = |p: &mut Parser| p.read_ipv6_addr();
let clos_br = |p: &mut Parser| p.read_given_char(']');
p.read_seq_3::<char, IpAddr, char, _, _, _>(open_br, ip_addr, clos_br)
.map(|t| match t { (_, ip, _) => ip })
};
- p.read_or(&mut [box ipv4_p, box ipv6_p])
+ p.read_or(&mut [ipv4_p, ipv6_p])
};
let colon = |p: &mut Parser| p.read_given_char(':');
let port = |p: &mut Parser| p.read_number(10, 5, 0x10000).map(|n| n as u16);
/// // 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 {
#[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());
#[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]
//! 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;
//! 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::*;
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 => {}
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,
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,
//! 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::*;
#[cfg(windows)]
impl hash::Hash for EnvKey {
fn hash<H: hash::Hasher>(&self, state: &mut H) {
+ use ascii::AsciiExt;
let &EnvKey(ref x) = self;
match str::from_utf8(x.as_bytes()) {
Ok(s) => for ch in s.chars() {
- (ch as u8 as char).to_lowercase().hash(state);
+ ch.to_ascii_lowercase().hash(state);
},
Err(..) => x.hash(state)
}
#[cfg(windows)]
impl PartialEq for EnvKey {
fn eq(&self, other: &EnvKey) -> bool {
+ use ascii::AsciiExt;
let &EnvKey(ref x) = self;
let &EnvKey(ref y) = other;
match (str::from_utf8(x.as_bytes()), str::from_utf8(y.as_bytes())) {
return false
} else {
for (xch, ych) in xs.chars().zip(ys.chars()) {
- if xch.to_lowercase() != ych.to_lowercase() {
+ if xch.to_ascii_lowercase() != ych.to_ascii_lowercase() {
return false;
}
}
let (tx, rx) = channel();
let (mut r, w) = (ChanReader::new(rx), ChanWriter::new(tx));
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
let _t = thread::spawn(move|| {
- set_stdout(box w);
+ set_stdout(Box::new(w));
println!("hello!");
});
assert_eq!(r.read_to_string().unwrap(), "hello!\n");
let (tx, rx) = channel();
let (mut r, w) = (ChanReader::new(rx), ChanWriter::new(tx));
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
let _t = thread::spawn(move || -> () {
- set_stderr(box w);
+ set_stderr(Box::new(w));
panic!("my special message");
});
let s = r.read_to_string().unwrap();
*/
fn base_port() -> u16 {
- let base = 9600u16;
- let range = 1000u16;
+ let base = 9600;
+ let range = 1000;
let bases = [
("32-opt", base + range * 1),
// FIXME: These functions take Durations but only pass ms to the backend impls.
+use boxed::Box;
use sync::mpsc::{Receiver, Sender, channel};
use time::Duration;
use old_io::IoResult;
let (tx, rx) = channel();
// Short-circuit the timer backend for 0 duration
if in_ms_u64(duration) != 0 {
- self.inner.oneshot(in_ms_u64(duration), box TimerCallback { tx: tx });
+ self.inner.oneshot(in_ms_u64(duration), Box::new(TimerCallback { tx: tx }));
} else {
tx.send(()).unwrap();
}
// not clear what use a 0ms period is anyway...
let ms = if ms == 0 { 1 } else { ms };
let (tx, rx) = channel();
- self.inner.period(ms, box TimerCallback { tx: tx });
+ self.inner.period(ms, Box::new(TimerCallback { tx: tx }));
return rx
}
}
}
#[test]
- #[should_fail]
+ #[should_panic]
fn oneshot_fail() {
let mut timer = Timer::new().unwrap();
let _rx = timer.oneshot(Duration::milliseconds(1));
}
#[test]
- #[should_fail]
+ #[should_panic]
fn period_fail() {
let mut timer = Timer::new().unwrap();
let _rx = timer.periodic(Duration::milliseconds(1));
}
#[test]
- #[should_fail]
+ #[should_panic]
fn normal_fail() {
let _timer = Timer::new().unwrap();
panic!();
//! Utility implementations of Reader and Writer
+#![allow(deprecated)]
+
use prelude::v1::*;
use cmp;
use old_io;
/// 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 }
}
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 {
}
}
+#[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());
/// 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(()) }
/// 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> {
}
}
+#[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];
/// 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> {
}
}
+#[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))
/// 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<()> {
/// 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>,
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 {
/// 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 }
}
}
}
+#[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| {
}
/// 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 {
#[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);
#[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));
}
}
#[test]
- #[should_fail]
+ #[should_panic]
fn test_not_utf8_panics() {
Path::new(b"hello\x80.txt");
}
//! * 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
// `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()`.
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);
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()
}
#[doc(no_inline)] pub use old_io::{Buffer, Writer, Reader, Seek, BufferPrelude};
// NB: remove when range syntax lands
#[doc(no_inline)] pub use iter::range;
+
+#[doc(no_inline)] pub use num::wrapping::{Wrapping, WrappingOps};
//! Working with processes.
-#![unstable(feature = "process", reason = "recently added via RFC 579")]
+#![stable(feature = "process", since = "1.0.0")]
#![allow(non_upper_case_globals)]
use prelude::v1::*;
/// let contents = output.stdout;
/// assert!(output.status.success());
/// ```
+#[stable(feature = "process", since = "1.0.0")]
pub struct Child {
handle: ProcessImp,
status: Option<ExitStatusImp>,
/// The handle for writing to the child's stdin, if it has been captured
+ #[stable(feature = "process", since = "1.0.0")]
pub stdin: Option<ChildStdin>,
/// The handle for reading from the child's stdout, if it has been captured
+ #[stable(feature = "process", since = "1.0.0")]
pub stdout: Option<ChildStdout>,
/// The handle for reading from the child's stderr, if it has been captured
+ #[stable(feature = "process", since = "1.0.0")]
pub stderr: Option<ChildStderr>,
}
/// A handle to a child procesess's stdin
+#[stable(feature = "process", since = "1.0.0")]
pub struct ChildStdin {
inner: AnonPipe
}
+#[stable(feature = "process", since = "1.0.0")]
impl Write for ChildStdin {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.inner.write(buf)
}
/// A handle to a child procesess's stdout
+#[stable(feature = "process", since = "1.0.0")]
pub struct ChildStdout {
inner: AnonPipe
}
+#[stable(feature = "process", since = "1.0.0")]
impl Read for ChildStdout {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.inner.read(buf)
}
/// A handle to a child procesess's stderr
+#[stable(feature = "process", since = "1.0.0")]
pub struct ChildStderr {
inner: AnonPipe
}
+#[stable(feature = "process", since = "1.0.0")]
impl Read for ChildStderr {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.inner.read(buf)
/// to be changed (for example, by adding arguments) prior to spawning:
///
/// ```
-/// # #![feature(process)]
-///
/// use std::process::Command;
///
/// let output = Command::new("sh").arg("-c").arg("echo hello").output().unwrap_or_else(|e| {
/// });
/// let hello = output.stdout;
/// ```
+#[stable(feature = "process", since = "1.0.0")]
pub struct Command {
inner: CommandImp,
///
/// Builder methods are provided to change these defaults and
/// otherwise configure the process.
+ #[stable(feature = "process", since = "1.0.0")]
pub fn new<S: AsOsStr + ?Sized>(program: &S) -> Command {
Command {
inner: CommandImp::new(program.as_os_str()),
}
/// Add an argument to pass to the program.
+ #[stable(feature = "process", since = "1.0.0")]
pub fn arg<S: AsOsStr + ?Sized>(&mut self, arg: &S) -> &mut Command {
self.inner.arg(arg.as_os_str());
self
}
/// Add multiple arguments to pass to the program.
+ #[stable(feature = "process", since = "1.0.0")]
pub fn args<S: AsOsStr>(&mut self, args: &[S]) -> &mut Command {
self.inner.args(args.iter().map(AsOsStr::as_os_str));
self
///
/// Note that environment variable names are case-insensitive (but case-preserving) on Windows,
/// and case-sensitive on all other platforms.
- pub fn env<S: ?Sized, T: ?Sized>(&mut self, key: &S, val: &T) -> &mut Command where
- S: AsOsStr, T: AsOsStr
+ #[stable(feature = "process", since = "1.0.0")]
+ pub fn env<K: ?Sized, V: ?Sized>(&mut self, key: &K, val: &V) -> &mut Command
+ where K: AsOsStr, V: AsOsStr
{
self.inner.env(key.as_os_str(), val.as_os_str());
self
}
/// Removes an environment variable mapping.
- pub fn env_remove<S: ?Sized + AsOsStr>(&mut self, key: &S) -> &mut Command {
+ #[stable(feature = "process", since = "1.0.0")]
+ pub fn env_remove<K: ?Sized + AsOsStr>(&mut self, key: &K) -> &mut Command {
self.inner.env_remove(key.as_os_str());
self
}
/// Clears the entire environment map for the child process.
+ #[stable(feature = "process", since = "1.0.0")]
pub fn env_clear(&mut self) -> &mut Command {
self.inner.env_clear();
self
}
/// Set the working directory for the child process.
+ #[stable(feature = "process", since = "1.0.0")]
pub fn current_dir<P: AsPath + ?Sized>(&mut self, dir: &P) -> &mut Command {
self.inner.cwd(dir.as_path().as_os_str());
self
/// Configuration for the child process's stdin handle (file descriptor 0).
/// Defaults to `CreatePipe(true, false)` so the input can be written to.
+ #[stable(feature = "process", since = "1.0.0")]
pub fn stdin(&mut self, cfg: Stdio) -> &mut Command {
self.stdin = Some(cfg.0);
self
/// Configuration for the child process's stdout handle (file descriptor 1).
/// Defaults to `CreatePipe(false, true)` so the output can be collected.
+ #[stable(feature = "process", since = "1.0.0")]
pub fn stdout(&mut self, cfg: Stdio) -> &mut Command {
self.stdout = Some(cfg.0);
self
/// Configuration for the child process's stderr handle (file descriptor 2).
/// Defaults to `CreatePipe(false, true)` so the output can be collected.
+ #[stable(feature = "process", since = "1.0.0")]
pub fn stderr(&mut self, cfg: Stdio) -> &mut Command {
self.stderr = Some(cfg.0);
self
/// Executes the command as a child process, returning a handle to it.
///
/// By default, stdin, stdout and stderr are inherited by the parent.
+ #[stable(feature = "process", since = "1.0.0")]
pub fn spawn(&mut self) -> io::Result<Child> {
self.spawn_inner(StdioImp::Inherit)
}
/// By default, stdin, stdout and stderr are captured (and used to
/// provide the resulting output).
///
- /// # Example
+ /// # Examples
///
/// ```
/// # #![feature(process)]
/// });
///
/// 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> {
- self.spawn_inner(StdioImp::Capture).and_then(|p| p.wait_with_output())
+ self.spawn_inner(StdioImp::Piped).and_then(|p| p.wait_with_output())
}
/// Executes a command as a child process, waiting for it to finish and
///
/// println!("process exited with: {}", status);
/// ```
+ #[stable(feature = "process", since = "1.0.0")]
pub fn status(&mut self) -> io::Result<ExitStatus> {
self.spawn().and_then(|mut p| p.wait())
}
Inherit => {
(Some(AnonPipe::from_fd(fd)), None)
}
- Capture => {
+ Piped => {
let (reader, writer) = try!(unsafe { pipe2::anon_pipe() });
if readable {
(Some(reader), Some(writer))
/// The output of a finished process.
#[derive(PartialEq, Eq, Clone)]
+#[stable(feature = "process", since = "1.0.0")]
pub struct Output {
/// The status (exit code) of the process.
+ #[stable(feature = "process", since = "1.0.0")]
pub status: ExitStatus,
/// The data that the process wrote to stdout.
+ #[stable(feature = "process", since = "1.0.0")]
pub stdout: Vec<u8>,
/// The data that the process wrote to stderr.
+ #[stable(feature = "process", since = "1.0.0")]
pub stderr: Vec<u8>,
}
/// Describes what to do with a standard io stream for a child process.
+#[stable(feature = "process", since = "1.0.0")]
pub struct Stdio(StdioImp);
// The internal enum for stdio setup; see below for descriptions.
#[derive(Clone)]
enum StdioImp {
- Capture,
+ Piped,
Inherit,
Null,
}
impl Stdio {
/// A new pipe should be arranged to connect the parent and child processes.
- pub fn capture() -> Stdio { Stdio(StdioImp::Capture) }
+ #[unstable(feature = "process_capture")]
+ #[deprecated(since = "1.0.0", reason = "renamed to `Stdio::piped`")]
+ pub fn capture() -> Stdio { Stdio::piped() }
+
+ /// A new pipe should be arranged to connect the parent and child processes.
+ #[stable(feature = "process", since = "1.0.0")]
+ pub fn piped() -> Stdio { Stdio(StdioImp::Piped) }
/// The child inherits from the corresponding parent descriptor.
+ #[stable(feature = "process", since = "1.0.0")]
pub fn inherit() -> Stdio { Stdio(StdioImp::Inherit) }
/// This stream will be ignored. This is the equivalent of attaching the
/// stream to `/dev/null`
+ #[stable(feature = "process", since = "1.0.0")]
pub fn null() -> Stdio { Stdio(StdioImp::Null) }
}
/// Describes the result of a process after it has terminated.
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
+#[stable(feature = "process", since = "1.0.0")]
pub struct ExitStatus(ExitStatusImp);
impl ExitStatus {
/// Was termination successful? Signal termination not considered a success,
/// and success is defined as a zero exit status.
+ #[stable(feature = "process", since = "1.0.0")]
pub fn success(&self) -> bool {
self.0.success()
}
/// On Unix, this will return `None` if the process was terminated
/// by a signal; `std::os::unix` provides an extension trait for
/// extracting the signal and other details from the `ExitStatus`.
+ #[stable(feature = "process", since = "1.0.0")]
pub fn code(&self) -> Option<i32> {
self.0.code()
}
fn as_inner(&self) -> &ExitStatusImp { &self.0 }
}
+#[stable(feature = "process", since = "1.0.0")]
impl fmt::Display for ExitStatus {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.0.fmt(f)
impl Child {
/// Forces the child to exit. This is equivalent to sending a
/// SIGKILL on unix platforms.
+ #[stable(feature = "process", since = "1.0.0")]
pub fn kill(&mut self) -> io::Result<()> {
#[cfg(unix)] fn collect_status(p: &mut Child) {
// On Linux (and possibly other unices), a process that has exited will
/// before waiting. This helps avoid deadlock: it ensures that the
/// child does not block waiting for input from the parent, while
/// the parent waits for the child to exit.
+ #[stable(feature = "process", since = "1.0.0")]
pub fn wait(&mut self) -> io::Result<ExitStatus> {
drop(self.stdin.take());
match self.status {
/// before waiting. This helps avoid deadlock: it ensures that the
/// child does not block waiting for input from the parent, while
/// the parent waits for the child to exit.
+ #[stable(feature = "process", since = "1.0.0")]
pub fn wait_with_output(mut self) -> io::Result<Output> {
drop(self.stdin.take());
fn read<T: Read + Send + 'static>(stream: Option<T>) -> Receiver<io::Result<Vec<u8>>> {
#[test]
fn stdout_works() {
let mut cmd = Command::new("echo");
- cmd.arg("foobar").stdout(Stdio::capture());
+ cmd.arg("foobar").stdout(Stdio::piped());
assert_eq!(run_output(cmd), "foobar\n");
}
let mut cmd = Command::new("/bin/sh");
cmd.arg("-c").arg("pwd")
.current_dir("/")
- .stdout(Stdio::capture());
+ .stdout(Stdio::piped());
assert_eq!(run_output(cmd), "/\n");
}
fn stdin_works() {
let mut p = Command::new("/bin/sh")
.arg("-c").arg("read line; echo $line")
- .stdin(Stdio::capture())
- .stdout(Stdio::capture())
+ .stdin(Stdio::piped())
+ .stdout(Stdio::piped())
.spawn().unwrap();
p.stdin.as_mut().unwrap().write("foobar".as_bytes()).unwrap();
drop(p.stdin.take());
#[cfg(not(target_os="android"))]
#[test]
fn test_wait_with_output_once() {
- let prog = Command::new("echo").arg("hello").stdout(Stdio::capture())
+ let prog = Command::new("echo").arg("hello").stdout(Stdio::piped())
.spawn().unwrap();
let Output {status, stdout, stderr} = prog.wait_with_output().unwrap();
let output_str = str::from_utf8(stdout.as_slice()).unwrap();
#[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);
}
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)));
}
}
}
}
}
}
-static THREAD_RNG_RESEED_THRESHOLD: usize = 32_768;
+const THREAD_RNG_RESEED_THRESHOLD: usize = 32_768;
type ThreadRngInner = reseeding::ReseedingRng<StdRng, ThreadRngReseeder>;
/// The thread-local RNG.
/// ```
/// use std::rand;
///
-/// let x = rand::random();
-/// println!("{}", 2u8 * x);
+/// let x: u8 = rand::random();
+/// println!("{}", 2 * x as u16);
///
/// let y = rand::random::<f64>();
/// println!("{}", y);
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.
}
#[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);
}
}
-#[cfg(test)]
-static RAND_BENCH_N: u64 = 100;
-
#[cfg(test)]
mod bench {
extern crate test;
use prelude::v1::*;
use self::test::Bencher;
- use super::{XorShiftRng, StdRng, IsaacRng, Isaac64Rng, Rng, RAND_BENCH_N};
+ use super::{XorShiftRng, StdRng, IsaacRng, Isaac64Rng, Rng};
use super::{OsRng, weak_rng};
use mem::size_of;
+ const RAND_BENCH_N: u64 = 100;
+
#[bench]
fn rand_xorshift(b: &mut Bencher) {
let mut rng: XorShiftRng = OsRng::new().unwrap().gen();
}
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) }
}
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) }
}
hcryptprov: HCRYPTPROV
}
- static PROV_RSA_FULL: DWORD = 1;
- static CRYPT_SILENT: DWORD = 64;
- static CRYPT_VERIFYCONTEXT: DWORD = 0xF0000000;
+ const PROV_RSA_FULL: DWORD = 1;
+ const CRYPT_SILENT: DWORD = 64;
+ const CRYPT_VERIFYCONTEXT: DWORD = 0xF0000000;
#[allow(non_snake_case)]
extern "system" {
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) }
}
r.next_u32();
r.next_u64();
- let mut v = [0u8; 1000];
+ let mut v = [0; 1000];
r.fill_bytes(&mut v);
}
// 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();
#[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);
}
#[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);
}
}
use ops::FnOnce;
use sys;
use thunk::Thunk;
+use usize;
// Reexport some of our utilities which are expected by other crates.
pub use self::util::{default_sched_threads, min_stack, running_on_valgrind};
// FIXME #11359 we just assume that this thread has a stack of a
// certain size, and estimate that there's at most 20KB of stack
// frames above our current position.
- let my_stack_bottom = my_stack_top + 20000 - OS_DEFAULT_STACK_ESTIMATE;
+ const TWENTY_KB: uint = 20000;
+
+ // saturating-add to sidestep overflow
+ let top_plus_spill = if usize::MAX - TWENTY_KB < my_stack_top {
+ usize::MAX
+ } else {
+ my_stack_top + TWENTY_KB
+ };
+ // saturating-sub to sidestep underflow
+ let my_stack_bottom = if top_plus_spill < OS_DEFAULT_STACK_ESTIMATE {
+ 0
+ } else {
+ top_plus_spill - OS_DEFAULT_STACK_ESTIMATE
+ };
let failed = unsafe {
// First, make sure we don't trigger any __morestack overflow checks,
rtdebug!("begin_unwind()");
unsafe {
- let exception = box Exception {
+ let exception: Box<_> = box Exception {
uwe: uw::_Unwind_Exception {
exception_class: rust_exception_class(),
exception_cleanup: exception_cleanup,
let mut s = String::new();
let _ = write!(&mut s, "{}", msg);
- begin_unwind_inner(box s, file_line)
+ begin_unwind_inner(Box::new(s), file_line)
}
/// This is the entry point of unwinding for panic!() and assert!().
// panicking.
// see below for why we do the `Any` coercion here.
- begin_unwind_inner(box msg, file_line)
+ begin_unwind_inner(Box::new(msg), file_line)
}
/// The core of the unwinding.
}
// 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");
}
#[test]
- #[should_fail]
+ #[should_panic]
fn two_mutexes() {
static M1: StaticMutex = MUTEX_INIT;
static M2: StaticMutex = MUTEX_INIT;
}
#[test]
- #[should_fail]
+ #[should_panic]
fn test_future_panic() {
let mut f = Future::spawn(move|| panic!());
let _x: String = f.get();
use prelude::v1::*;
use sync::Arc;
+use error;
use fmt;
use mem;
use cell::UnsafeCell;
}
}
+#[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 {
}
}
+#[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 {
}
}
+#[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 {
}
}
+#[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::*;
#[test]
fn drop_full() {
- let (tx, _rx) = channel();
+ let (tx, _rx) = channel::<Box<int>>();
tx.send(box 1).unwrap();
}
#[test]
fn drop_full_shared() {
- let (tx, _rx) = channel();
+ let (tx, _rx) = channel::<Box<int>>();
drop(tx.clone());
drop(tx.clone());
tx.send(box 1).unwrap();
#[test]
fn stress_shared() {
- static AMT: u32 = 10000;
- static NTHREADS: u32 = 8;
+ const AMT: u32 = 10000;
+ const NTHREADS: u32 = 8;
let (tx, rx) = channel::<i32>();
let t = thread::spawn(move|| {
#[test]
fn oneshot_multi_thread_send_recv_stress() {
for _ in 0..stress_factor() {
- let (tx, rx) = channel();
+ let (tx, rx) = channel::<Box<int>>();
let _t = thread::spawn(move|| {
tx.send(box 10).unwrap();
});
#[test]
fn drop_full() {
- let (tx, _rx) = sync_channel(1);
+ let (tx, _rx) = sync_channel::<Box<int>>(1);
tx.send(box 1).unwrap();
}
#[test]
fn stress_shared() {
- static AMT: u32 = 1000;
- static NTHREADS: u32 = 8;
+ const AMT: u32 = 1000;
+ const NTHREADS: u32 = 8;
let (tx, rx) = sync_channel::<i32>(0);
let (dtx, drx) = sync_channel::<()>(0);
#[test]
fn test_full() {
- let q = Queue::new();
+ let q: Queue<Box<_>> = Queue::new();
q.push(box 1);
q.push(box 2);
}
#[test]
fn stress() {
- static AMT: i32 = 10000;
+ const AMT: i32 = 10000;
let (tx1, rx1) = channel::<i32>();
let (tx2, rx2) = channel::<i32>();
let (tx3, rx3) = channel::<()>();
#[test]
fn drop_full() {
unsafe {
- let q = Queue::new(0);
+ let q: Queue<Box<_>> = Queue::new(0);
q.push(box 1);
q.push(box 2);
}
fn lots_and_lots() {
static M: StaticMutex = MUTEX_INIT;
static mut CNT: u32 = 0;
- static J: u32 = 1000;
- static K: u32 = 3;
+ const J: u32 = 1000;
+ const K: u32 = 3;
fn inc() {
for _ in 0..J {
#[test]
fn frob() {
static R: StaticRwLock = RW_LOCK_INIT;
- static N: usize = 10;
- static M: usize = 1000;
+ const N: usize = 10;
+ const M: usize = 1000;
let (tx, rx) = channel::<()>();
for _ in 0..N {
}
#[test]
- #[should_fail]
+ #[should_panic]
fn test_zero_tasks_panic() {
TaskPool::new(0);
}
// 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::*;
//! ```
#![allow(non_camel_case_types)]
+#![unstable(feature = "thread_local_internals")]
use prelude::v1::*;
/// 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)>,
}
/// 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,
/// 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,
};
use ops;
use slice;
use str;
-use string::{String, CowString};
+use string::String;
use sys_common::AsInner;
use unicode::str::{Utf16Item, utf16_items};
use vec::Vec;
-static UTF8_REPLACEMENT_CHARACTER: &'static [u8] = b"\xEF\xBF\xBD";
+const UTF8_REPLACEMENT_CHARACTER: &'static [u8] = b"\xEF\xBF\xBD";
/// A Unicode code point: from U+0000 to U+10FFFF.
///
/// Surrogates are replaced with `"\u{FFFD}"` (the replacement character “�”).
///
/// This only copies the data if necessary (if it contains any surrogate).
- pub fn to_string_lossy(&self) -> CowString {
+ pub fn to_string_lossy(&self) -> Cow<str> {
let surrogate_pos = match self.next_surrogate(0) {
None => return Cow::Borrowed(unsafe { str::from_utf8_unchecked(&self.bytes) }),
Some((pos, _)) => pos,
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,
}
}
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);
use borrow::Cow;
use super::*;
use mem::transmute;
- use string::CowString;
#[test]
fn code_point_from_u32() {
}
#[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);
}
#[test]
- #[should_fail]
+ #[should_panic]
fn wtf8_slice_not_code_point_boundary() {
&Wtf8::from_str("aé 💩")[2.. 4];
}
}
#[test]
- #[should_fail]
+ #[should_panic]
fn wtf8_slice_from_not_code_point_boundary() {
&Wtf8::from_str("aé 💩")[2..];
}
}
#[test]
- #[should_fail]
+ #[should_panic]
fn wtf8_slice_to_not_code_point_boundary() {
&Wtf8::from_str("aé 💩")[5..];
}
assert_eq!(Wtf8::from_str("aé 💩").to_string_lossy(), Cow::Borrowed("aé 💩"));
let mut string = Wtf8Buf::from_str("aé 💩");
string.push(CodePoint::from_u32(0xD800).unwrap());
- let expected: CowString = Cow::Owned(String::from_str("aé 💩�"));
+ let expected: Cow<str> = Cow::Owned(String::from_str("aé 💩�"));
assert_eq!(string.to_string_lossy(), expected);
}
let mut ip = unsafe {
uw::_Unwind_GetIPInfo(ctx, &mut ip_before_insn) as *mut libc::c_void
};
- if ip_before_insn == 0 {
+ if !ip.is_null() && ip_before_insn == 0 {
// this is a non-signaling frame, so `ip` refers to the address
// after the calling instruction. account for that.
ip = (ip as usize - 1) as *mut _;
// This function doesn't exist on Android or ARM/Linux, so make it same
// to _Unwind_GetIP
- #[cfg(any(target_os = "android",
+ #[cfg(any(all(target_os = "android", target_arch = "arm"),
all(target_os = "linux", target_arch = "arm")))]
pub unsafe fn _Unwind_GetIPInfo(ctx: *mut _Unwind_Context,
ip_before_insn: *mut libc::c_int)
#[repr(C)]
pub struct fd_set {
// FIXME: shouldn't this be a c_ulong?
- fds_bits: [libc::uintptr_t; (FD_SETSIZE / usize::BITS)]
+ fds_bits: [libc::uintptr_t; (FD_SETSIZE / usize::BITS as usize)]
}
pub fn fd_set(set: &mut fd_set, fd: i32) {
let fd = fd as uint;
- set.fds_bits[fd / usize::BITS] |= 1 << (fd % usize::BITS);
+ set.fds_bits[fd / usize::BITS as usize] |= 1 << (fd % usize::BITS as usize);
}
}
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()
}
}
+#[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()
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);
use core::prelude::*;
+use borrow::Cow;
use fmt::{self, Debug};
use vec::Vec;
use slice::SliceExt as StdSliceExt;
use str;
-use string::{String, CowString};
+use string::String;
use mem;
#[derive(Clone, Hash)]
str::from_utf8(&self.inner).ok()
}
- pub fn to_string_lossy(&self) -> CowString {
+ pub fn to_string_lossy(&self) -> Cow<str> {
String::from_utf8_lossy(&self.inner)
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
+#![allow(deprecated)]
+
use prelude::v1::*;
use self::Req::*;
// 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;
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()
}
}
+#[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()
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()
-> DWORD;
}
- static FORMAT_MESSAGE_FROM_SYSTEM: DWORD = 0x00001000;
- static FORMAT_MESSAGE_IGNORE_INSERTS: DWORD = 0x00000200;
+ const FORMAT_MESSAGE_FROM_SYSTEM: DWORD = 0x00001000;
+ const FORMAT_MESSAGE_IGNORE_INSERTS: DWORD = 0x00000200;
// This value is calculated from the macro
// MAKELANGID(LANG_SYSTEM_DEFAULT, SUBLANG_SYS_DEFAULT)
/// The underlying OsString/OsStr implementation on Windows is a
/// wrapper around the "WTF-8" encoding; see the `wtf8` module for more.
+use borrow::Cow;
use fmt::{self, Debug};
use sys_common::wtf8::{Wtf8, Wtf8Buf};
-use string::{String, CowString};
+use string::String;
use result::Result;
use option::Option;
use mem;
self.inner.as_str()
}
- pub fn to_string_lossy(&self) -> CowString {
+ pub fn to_string_lossy(&self) -> Cow<str> {
self.inner.to_string_lossy()
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
+#![allow(deprecated)]
+
use prelude::v1::*;
use collections;
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;
// 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;
//! a thread will unwind the stack, running destructors and freeing
//! owned resources. Thread panic is unrecoverable from within
//! the panicking thread (i.e. there is no 'try/catch' in Rust), but
-//! panic may optionally be detected from a different thread. If
-//! the main thread panics the application will exit with a non-zero
+//! the panic may optionally be detected from a different thread. If
+//! the main thread panics, the application will exit with a non-zero
//! exit code.
//!
//! When the main thread of a Rust program terminates, the entire program shuts
//! down, even if other threads are still running. However, this module provides
//! convenient facilities for automatically waiting for the termination of a
-//! child thread (i.e., join), described below.
+//! child thread (i.e., join).
//!
//! ## The `Thread` type
//!
-//! Already-running threads are represented via the `Thread` type, which you can
+//! Threads are represented via the `Thread` type, which you can
//! get in one of two ways:
//!
-//! * By spawning a new thread, e.g. using the `thread::spawn` constructor;
+//! * By spawning a new thread, e.g. using the `thread::spawn` function.
//! * By requesting the current thread, using the `thread::current` function.
//!
//! Threads can be named, and provide some built-in support for low-level
-//! synchronization described below.
+//! synchronization (described below).
//!
//! The `thread::current()` function is available even for threads not spawned
//! by the APIs of this module.
//! use std::thread;
//!
//! thread::spawn(move || {
-//! println!("Hello, World!");
-//! // some computation here
+//! // some work here
//! });
//! ```
//!
//! In this example, the spawned thread is "detached" from the current
-//! thread, meaning that it can outlive the thread that spawned
-//! it. (Note, however, that when the main thread terminates all
-//! detached threads are terminated as well.)
+//! thread. This means that it can outlive its parent (the thread that spawned
+//! it), unless this parent is the main thread.
//!
//! ## Scoped threads
//!
//! Often a parent thread uses a child thread to perform some particular task,
//! and at some point must wait for the child to complete before continuing.
-//! For this scenario, use the `scoped` constructor:
+//! For this scenario, use the `thread::scoped` function:
//!
//! ```rust
//! use std::thread;
//!
//! let guard = thread::scoped(move || {
-//! println!("Hello, World!");
-//! // some computation here
+//! // some work here
//! });
+//!
//! // do some other work in the meantime
//! let output = guard.join();
//! ```
//! terminates) when it is dropped. You can join the child thread in
//! advance by calling the `join` method on the guard, which will also
//! return the result produced by the thread. A handle to the thread
-//! itself is available via the `thread` method on the join guard.
-//!
-//! (Note: eventually, the `scoped` constructor will allow the parent and child
-//! threads to data that lives on the parent thread's stack, but some language
-//! changes are needed before this is possible.)
+//! itself is available via the `thread` method of the join guard.
//!
//! ## Configuring threads
//!
//! use std::thread;
//!
//! thread::Builder::new().name("child1".to_string()).spawn(move || {
-//! println!("Hello, world!")
+//! println!("Hello, world!");
//! });
//! ```
//!
//! initially not present:
//!
//! * The `thread::park()` function blocks the current thread unless or until
-//! the token is available for its thread handle, at which point It atomically
+//! the token is available for its thread handle, at which point it atomically
//! consumes the token. It may also return *spuriously*, without consuming the
//! token. `thread::park_timeout()` does the same, but allows specifying a
//! maximum time to block the thread for.
//! * It avoids the need to allocate mutexes and condvars when building new
//! synchronization primitives; the threads already provide basic blocking/signaling.
//!
-//! * It can be implemented highly efficiently on many platforms.
+//! * It can be implemented very efficiently on many platforms.
#![stable(feature = "rust1", since = "1.0.0")]
// address at which our stack started).
let main = move || {
let something_around_the_top_of_the_stack = 1;
- let addr = &something_around_the_top_of_the_stack as *const isize;
+ let addr = &something_around_the_top_of_the_stack as *const i32;
let my_stack_top = addr as usize;
let my_stack_bottom = my_stack_top - stack_size + 1024;
unsafe {
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(
}
fn avoid_copying_the_body<F>(spawnfn: F) where F: FnOnce(Thunk<'static>) {
- let (tx, rx) = channel::<u32>();
+ let (tx, rx) = channel();
- let x = box 1;
- let x_in_parent = (&*x) as *const isize as u32;
+ let x: Box<_> = box 1;
+ let x_in_parent = (&*x) as *const i32 as usize;
spawnfn(Thunk::new(move|| {
- let x_in_child = (&*x) as *const isize as u32;
+ let x_in_child = (&*x) as *const i32 as usize;
tx.send(x_in_child).unwrap();
}));
// climbing the task tree to dereference each ancestor. (See #1789)
// (well, it would if the constant were 8000+ - I lowered it to be more
// valgrind-friendly. try this at home, instead..!)
- static GENERATIONS: usize = 16;
- fn child_no(x: usize) -> Thunk<'static> {
+ const GENERATIONS: u32 = 16;
+ fn child_no(x: u32) -> Thunk<'static> {
return Thunk::new(move|| {
if x < GENERATIONS {
thread::spawn(move|| child_no(x+1).invoke(()));
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!()
}
// 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;
/// 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> = {
#[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"),
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
//
// 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
}
}
#[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
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,
}
}
#[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
/// 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);
#[macro_export]
#[doc(hidden)]
+#[allow_internal_unstable]
macro_rules! __scoped_thread_local_inner {
(static $name:ident: $t:ty) => (
#[cfg_attr(not(any(windows,
const _INIT: __Key<$t> = __Key {
inner: ::std::thread_local::scoped::__impl::KeyInner {
inner: ::std::thread_local::scoped::__impl::OS_INIT,
- marker: ::std::marker::InvariantType,
+ marker: ::std::marker::PhantomData::<::std::cell::Cell<$t>>,
}
};
target_arch = "aarch64"))]
mod imp {
use marker;
+ use std::cell::Cell;
use sys_common::thread_local::StaticKey as OsStaticKey;
#[doc(hidden)]
pub struct KeyInner<T> {
pub inner: OsStaticKey,
- pub marker: marker::InvariantType<T>,
+ pub marker: marker::PhantomData<Cell<T>>,
}
unsafe impl<T> ::marker::Sync for KeyInner<T> { }
where F : FnOnce(A) -> R, F : Send + 'a
{
Thunk {
- invoke: box func
+ invoke: Box::<F>::new(func)
}
}
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")]
//! assert!(b == c);
//!
//! let d : (u32, f32) = Default::default();
-//! assert_eq!(d, (0u32, 0.0f32));
+//! assert_eq!(d, (0, 0.0f32));
//! ```
#![doc(primitive = "tuple")]
}
#[allow(non_upper_case_globals)]
-static AbiDatas: &'static [AbiData] = &[
+const AbiDatas: &'static [AbiData] = &[
// Platform-specific ABIs
AbiData {abi: Cdecl, name: "cdecl" },
AbiData {abi: Stdcall, name: "stdcall" },
- AbiData {abi: Fastcall, name:"fastcall" },
+ AbiData {abi: Fastcall, name: "fastcall" },
AbiData {abi: Aapcs, name: "aapcs" },
AbiData {abi: Win64, name: "win64" },
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;
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_>;
/// 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),
pub imported_from: Option<Ident>,
pub export: bool,
pub use_locally: bool,
+ pub allow_internal_unstable: bool,
pub body: Vec<TokenTree>,
}
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;
}
}
- /// Given a node ID and a closure, apply the closure to the array
- /// of attributes associated with the AST corresponding to the Node ID
- pub fn with_attrs<T, F>(&self, id: NodeId, f: F) -> T where
- F: FnOnce(Option<&[Attribute]>) -> T,
- {
- let attrs = match self.get(id) {
- NodeItem(i) => Some(&i.attrs[..]),
- NodeForeignItem(fi) => Some(&fi.attrs[..]),
- NodeTraitItem(ref tm) => match **tm {
+ /// Given a node ID, get a list of of attributes associated with the AST
+ /// corresponding to the Node ID
+ pub fn attrs(&self, id: NodeId) -> &[Attribute] {
+ let attrs = match self.find(id) {
+ Some(NodeItem(i)) => Some(&i.attrs[..]),
+ Some(NodeForeignItem(fi)) => Some(&fi.attrs[..]),
+ Some(NodeTraitItem(ref tm)) => match **tm {
RequiredMethod(ref type_m) => Some(&type_m.attrs[..]),
ProvidedMethod(ref m) => Some(&m.attrs[..]),
TypeTraitItem(ref typ) => Some(&typ.attrs[..]),
},
- NodeImplItem(ref ii) => {
+ Some(NodeImplItem(ref ii)) => {
match **ii {
MethodImplItem(ref m) => Some(&m.attrs[..]),
TypeImplItem(ref t) => Some(&t.attrs[..]),
}
}
- NodeVariant(ref v) => Some(&v.node.attrs[..]),
+ Some(NodeVariant(ref v)) => Some(&v.node.attrs[..]),
// unit/tuple structs take the attributes straight from
// the struct definition.
- // FIXME(eddyb) make this work again (requires access to the map).
- NodeStructCtor(_) => {
- return self.with_attrs(self.get_parent(id), f);
+ Some(NodeStructCtor(_)) => {
+ return self.attrs(self.get_parent(id));
}
_ => None
};
- f(attrs)
+ attrs.unwrap_or(&[])
}
/// Returns an iterator that yields the node id's with paths that
}
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),
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
}
}
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
}
}
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;
}
}
+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 }
}
}
+// _____________________________________________________________________________
+// 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
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))
}
}
}
}
+// _____________________________________________________________________________
+// Loc, LocWithOpt, FileMapAndLine, FileMapAndBytePos
+//
+
/// A source code location used for error reporting
pub struct Loc {
/// Information about the original source
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 {
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.
}
}
+// _____________________________________________________________________________
+// FileMap, MultiByteChar, FileName, FileLines
+//
+
pub type FileName = String;
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,
/// 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 {
/// 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) {
!(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>>
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.
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()),
});
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!("<{}:{}:{}>",
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()
+ });
+ }
+ }
}
}
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();
}
}
- /// 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)]
end_pos: BytePos
}
+
+// _____________________________________________________________________________
+// Tests
+//
+
#[cfg(test)]
mod test {
use super::*;
}
#[test]
- #[should_fail]
+ #[should_panic]
fn t2 () {
let cm = CodeMap::new();
let fm = cm.new_filemap("blork.rs".to_string(),
use term;
/// maximum number of lines we will print for each error; arbitrary.
-static MAX_LINES: usize = 6;
+const MAX_LINES: usize = 6;
#[derive(Clone, Copy)]
pub enum RenderSpan {
pub fn default_handler(color_config: ColorConfig,
registry: Option<diagnostics::registry::Registry>,
can_emit_warnings: bool) -> Handler {
- mk_handler(can_emit_warnings, box EmitterWriter::stderr(color_config, registry))
+ mk_handler(can_emit_warnings, Box::new(EmitterWriter::stderr(color_config, registry)))
}
pub fn mk_handler(can_emit_warnings: bool, e: Box<Emitter + Send>) -> Handler {
if use_color {
let dst = match term::stderr() {
Some(t) => Terminal(t),
- None => Raw(box stderr),
+ None => Raw(Box::new(stderr)),
};
EmitterWriter { dst: dst, registry: registry }
} else {
- EmitterWriter { dst: Raw(box stderr), registry: registry }
+ EmitterWriter { dst: Raw(Box::new(stderr)), registry: registry }
}
}
})
}
+#[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),*) => (
}
}
-static OPTIONS: &'static [&'static str] = &["volatile", "alignstack", "intel"];
+const OPTIONS: &'static [&'static str] = &["volatile", "alignstack", "intel"];
pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
-> Box<base::MacResult+'cx> {
name: "asm".to_string(),
format: codemap::MacroBang,
span: None,
+ allow_internal_unstable: false,
},
});
-// 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.
//
/// 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,
-> SyntaxEnv {
// utility function to simplify creating NormalTT syntax extensions
fn builtin_normal_expander(f: MacroExpanderFn) -> SyntaxExtension {
- NormalTT(box 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));
syntax_expanders.insert(intern("log_syntax"),
builtin_normal_expander(
ext::log_syntax::expand_syntax_ext));
- syntax_expanders.insert(intern("derive"),
- Decorator(box ext::deriving::expand_meta_derive));
- syntax_expanders.insert(intern("deriving"),
- Decorator(box ext::deriving::expand_deprecated_deriving));
+
+ ext::deriving::register_all(&mut syntax_expanders);
if ecfg.enable_quotes() {
// Quasi-quoting expanders
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"),
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);
// 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 {
args: Vec::new(),
ret_ty: Self_,
attributes: attrs,
- combine_substructure: combine_substructure(box |c, s, sub| {
+ combine_substructure: combine_substructure(Box::new(|c, s, sub| {
cs_clone("Clone", c, s, sub)
- }),
+ })),
}
),
associated_types: Vec::new(),
cx.expr_binary(span, ast::BiAnd, subexpr, eq)
},
cx.expr_bool(span, true),
- box |cx, span, _, _| cx.expr_bool(span, false),
+ Box::new(|cx, span, _, _| cx.expr_bool(span, false)),
cx, span, substr)
}
fn cs_ne(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P<Expr> {
cx.expr_binary(span, ast::BiOr, subexpr, eq)
},
cx.expr_bool(span, false),
- box |cx, span, _, _| cx.expr_bool(span, true),
+ Box::new(|cx, span, _, _| cx.expr_bool(span, true)),
cx, span, substr)
}
args: vec!(borrowed_self()),
ret_ty: Literal(path_local!(bool)),
attributes: attrs,
- combine_substructure: combine_substructure(box |a, b, c| {
+ combine_substructure: combine_substructure(Box::new(|a, b, c| {
$f(a, b, c)
- })
+ }))
}
} }
}
args: vec!(borrowed_self()),
ret_ty: Literal(path_local!(bool)),
attributes: attrs,
- combine_substructure: combine_substructure(box |cx, span, substr| {
+ combine_substructure: combine_substructure(Box::new(|cx, span, substr| {
cs_op($op, $equal, cx, span, substr)
- })
+ }))
}
} }
}
args: vec![borrowed_self()],
ret_ty: ret_ty,
attributes: attrs,
- combine_substructure: combine_substructure(box |cx, span, substr| {
+ combine_substructure: combine_substructure(Box::new(|cx, span, substr| {
cs_partial_cmp(cx, span, substr)
- })
+ }))
};
let trait_def = TraitDef {
cx.expr_block(cx.block(span, vec!(assign), Some(if_)))
},
equals_expr.clone(),
- box |cx, span, (self_args, tag_tuple), _non_self_args| {
+ Box::new(|cx, span, (self_args, tag_tuple), _non_self_args| {
if self_args.len() != 2 {
cx.span_bug(span, "not exactly 2 arguments in `derive(PartialOrd)`")
} else {
some_ordering_collapsed(cx, span, PartialCmpOp, tag_tuple)
}
- },
+ }),
cx, span, substr)
}
cx.expr_binary(span, ast::BiOr, cmp, and)
},
cx.expr_bool(span, equal),
- box |cx, span, (self_args, tag_tuple), _non_self_args| {
+ Box::new(|cx, span, (self_args, tag_tuple), _non_self_args| {
if self_args.len() != 2 {
cx.span_bug(span, "not exactly 2 arguments in `derive(PartialOrd)`")
} else {
};
some_ordering_collapsed(cx, span, op, tag_tuple)
}
- },
+ }),
cx, span, substr)
}
let block = cx.block(span, stmts, None);
cx.expr_block(block)
},
- box |cx, sp, _, _| cx.span_bug(sp, "non matching enums in derive(Eq)?"),
+ Box::new(|cx, sp, _, _| {
+ cx.span_bug(sp, "non matching enums in derive(Eq)?") }),
cx,
span,
substr)
args: vec!(),
ret_ty: nil_ty(),
attributes: attrs,
- combine_substructure: combine_substructure(box |a, b, c| {
+ combine_substructure: combine_substructure(Box::new(|a, b, c| {
cs_total_eq_assert(a, b, c)
- })
+ }))
}
),
associated_types: Vec::new(),
args: vec!(borrowed_self()),
ret_ty: Literal(path_std!(cx, core::cmp::Ordering)),
attributes: attrs,
- combine_substructure: combine_substructure(box |a, b, c| {
+ combine_substructure: combine_substructure(Box::new(|a, b, c| {
cs_cmp(a, b, c)
- }),
+ })),
}
),
associated_types: Vec::new(),
cx.expr_block(cx.block(span, vec!(assign), Some(if_)))
},
cx.expr_path(equals_path.clone()),
- box |cx, span, (self_args, tag_tuple), _non_self_args| {
+ Box::new(|cx, span, (self_args, tag_tuple), _non_self_args| {
if self_args.len() != 2 {
cx.span_bug(span, "not exactly 2 arguments in `derives(Ord)`")
} else {
ordering_collapsed(cx, span, tag_tuple)
}
- },
+ }),
cx, span, substr)
}
true
)),
attributes: Vec::new(),
- combine_substructure: combine_substructure(box |a, b, c| {
+ combine_substructure: combine_substructure(Box::new(|a, b, c| {
decodable_substructure(a, b, c, krate)
- }),
+ })),
}
),
associated_types: Vec::new(),
args: Vec::new(),
ret_ty: Self_,
attributes: attrs,
- combine_substructure: combine_substructure(box |a, b, c| {
+ combine_substructure: combine_substructure(Box::new(|a, b, c| {
default_substructure(a, b, c)
- })
+ }))
}
),
associated_types: Vec::new(),
true
)),
attributes: Vec::new(),
- combine_substructure: combine_substructure(box |a, b, c| {
+ combine_substructure: combine_substructure(Box::new(|a, b, c| {
encodable_substructure(a, b, c)
- }),
+ })),
}
),
associated_types: Vec::new(),
Struct(ref fields) => {
let emit_struct_field = cx.ident_of("emit_struct_field");
let mut stmts = Vec::new();
- let last = fields.len() - 1;
for (i, &FieldInfo {
name,
ref self_,
lambda));
// last call doesn't need a try!
+ let last = fields.len() - 1;
let call = if i != last {
cx.expr_try(span, call)
} else {
let encoder = cx.expr_ident(trait_span, blkarg);
let emit_variant_arg = cx.ident_of("emit_enum_variant_arg");
let mut stmts = Vec::new();
- let last = fields.len() - 1;
- for (i, &FieldInfo { ref self_, span, .. }) in fields.iter().enumerate() {
- let enc = cx.expr_method_call(span, self_.clone(),
- encode, vec!(blkencoder.clone()));
- let lambda = cx.lambda_expr_1(span, enc, blkarg);
- let call = cx.expr_method_call(span, blkencoder.clone(),
- emit_variant_arg,
- vec!(cx.expr_usize(span, i),
- lambda));
- let call = if i != last {
- cx.expr_try(span, call)
- } else {
- cx.expr(span, ExprRet(Some(call)))
- };
- stmts.push(cx.stmt_expr(call));
- }
-
- // enums with no fields need to return Ok()
- if stmts.len() == 0 {
+ if fields.len() > 0 {
+ let last = fields.len() - 1;
+ for (i, &FieldInfo { ref self_, span, .. }) in fields.iter().enumerate() {
+ let enc = cx.expr_method_call(span, self_.clone(),
+ encode, vec!(blkencoder.clone()));
+ let lambda = cx.lambda_expr_1(span, enc, blkarg);
+ let call = cx.expr_method_call(span, blkencoder.clone(),
+ emit_variant_arg,
+ vec!(cx.expr_usize(span, i),
+ lambda));
+ let call = if i != last {
+ cx.expr_try(span, call)
+ } else {
+ cx.expr(span, ExprRet(Some(call)))
+ };
+ stmts.push(cx.stmt_expr(call));
+ }
+ } else {
let ret_ok = cx.expr(trait_span,
ExprRet(Some(cx.expr_ok(trait_span,
cx.expr_tuple(trait_span, vec![])))));
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
args: vec!(Ptr(box Literal(arg), Borrowed(None, MutMutable))),
ret_ty: nil_ty(),
attributes: vec![],
- combine_substructure: combine_substructure(box |a, b, c| {
+ combine_substructure: combine_substructure(Box::new(|a, b, c| {
hash_substructure(a, b, c)
- })
+ }))
}
),
associated_types: Vec::new(),
-// 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.
//
//! 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 {
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));
+ }
+}
true)),
// #[inline] liable to cause code-bloat
attributes: attrs.clone(),
- combine_substructure: combine_substructure(box |c, s, sub| {
+ combine_substructure: combine_substructure(Box::new(|c, s, sub| {
cs_from("i64", c, s, sub)
- }),
+ })),
},
MethodDef {
name: "from_u64",
true)),
// #[inline] liable to cause code-bloat
attributes: attrs,
- combine_substructure: combine_substructure(box |c, s, sub| {
+ combine_substructure: combine_substructure(Box::new(|c, s, sub| {
cs_from("u64", c, s, sub)
- }),
+ })),
}
),
associated_types: Vec::new(),
),
ret_ty: Self_,
attributes: Vec::new(),
- combine_substructure: combine_substructure(box |a, b, c| {
+ combine_substructure: combine_substructure(Box::new(|a, b, c| {
rand_substructure(a, b, c)
- })
+ }))
}
),
associated_types: Vec::new(),
args: vec!(fmtr),
ret_ty: Literal(path_std!(cx, core::fmt::Result)),
attributes: Vec::new(),
- combine_substructure: combine_substructure(box |a, b, c| {
+ combine_substructure: combine_substructure(Box::new(|a, b, c| {
show_substructure(a, b, c)
- })
+ }))
}
],
associated_types: Vec::new(),
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;
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();
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);
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 ...");
}
};
}
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,
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",
callee: NameAndSpan {
name: extnamestr.to_string(),
format: MacroBang,
- span: span
+ span: span,
+ allow_internal_unstable: allow_internal_unstable,
}
});
// mark before expansion:
);
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(),
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);
}
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,
}
});
callee: NameAndSpan {
name: mname.to_string(),
format: MacroAttribute,
- span: None
+ span: None,
+ // attributes can do whatever they like,
+ // for now.
+ allow_internal_unstable: true,
}
});
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);
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 {
}
}
- 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,
}
}
}
// 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();
}
// 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();
-// 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.
//
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)
}
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()
}
}
#[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),*]);
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"),
_ => ()
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())
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")),
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.
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
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,
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();
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"]])
+ }
}
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
cx.cfg(),
&res_rel_file(cx,
sp,
- &Path::new(file)),
+ Path::new(&file)),
true,
None,
sp);
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 {}: {}",
e));
return DummyResult::expr(sp);
}
- Ok(bytes) => bytes,
};
match String::from_utf8(bytes) {
Ok(src) => {
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))))
}
}
// 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()
}
}
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,
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()
}
rdr.next_token();
} else /* bb_eis.len() == 1 */ {
- let mut rust_parser = Parser::new(sess, cfg.clone(), box rdr.clone());
+ let mut rust_parser = Parser::new(sess, cfg.clone(), Box::new(rdr.clone()));
let mut ei = bb_eis.pop().unwrap();
match ei.top_elts.get_tt(ei.idx) {
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};
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?
Some(named_matches),
imported_from,
rhs);
- let mut p = Parser::new(cx.parse_sess(), cx.cfg(), box trncbr);
+ let mut p = Parser::new(cx.parse_sess(), cx.cfg(), Box::new(trncbr));
p.check_unknown_macro_variable();
// Let the context choose how to interpret the result.
// Weird, but useful for X-macros.
_ => cx.span_bug(def.span, "wrong-structured rhs")
};
- let exp = box MacroRulesMacroExpander {
+ let exp: Box<_> = box MacroRulesMacroExpander {
name: def.ident,
imported_from: def.imported_from,
lhses: lhses,
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) {
// stable (active).
// NB: The featureck.py script parses this information directly out of the source
// so take care when modifying it.
-static KNOWN_FEATURES: &'static [(&'static str, &'static str, Status)] = &[
+const KNOWN_FEATURES: &'static [(&'static str, &'static str, Status)] = &[
("globs", "1.0.0", Accepted),
("macro_rules", "1.0.0", Accepted),
("struct_variant", "1.0.0", Accepted),
// 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)
}
// Attributes that have a special meaning to rustc or rustdoc
-pub static KNOWN_ATTRIBUTES: &'static [(&'static str, AttributeType)] = &[
+pub const KNOWN_ATTRIBUTES: &'static [(&'static str, AttributeType)] = &[
// Normal attributes
("warn", Normal),
("plugin_registrar", Normal),
("cfg", Normal),
+ ("cfg_attr", Normal),
("main", Normal),
("start", Normal),
("test", Normal),
("no_mangle", Normal),
("no_link", Normal),
("derive", Normal),
+ ("deriving", Normal), // deprecation err in expansion
("should_fail", Normal),
("should_panic", Normal),
("ignore", Normal),
"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),
("no_split_stack", Whitelisted),
("no_stack_check", Whitelisted),
("packed", Whitelisted),
- ("static_assert", Whitelisted),
+ ("static_assert", Gated("static_assert",
+ "`#[static_assert]` is an experimental feature, and has a poor API")),
("no_debug", Whitelisted),
("omit_gdb_pretty_printer_section", Whitelisted),
("unsafe_no_drop_flag", Gated("unsafe_no_drop_flag",
("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
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,
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,
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));
}
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));
}
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>
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> {
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,
}
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."),
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() => {
}
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)
let mut cx = Context {
features: Vec::new(),
span_handler: span_handler,
+ do_warnings: do_warnings,
cm: cm,
};
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"),
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))
}
-
#[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;
// 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)
}
//!
//! 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]
#![feature(staged_api)]
#![feature(std_misc)]
#![feature(unicode)]
+#![feature(path)]
+#![feature(io)]
+#![feature(path_ext)]
extern crate arena;
extern crate fmt_macros;
impl<T> OwnedSlice<T> {
pub fn empty() -> OwnedSlice<T> {
- OwnedSlice { data: box [] }
+ OwnedSlice { data: Box::new([]) }
}
#[inline(never)]
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
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)]
}
// one-line comments lose their prefix
- static ONLINERS: &'static [&'static str] = &["///!", "///", "//!", "//"];
- for prefix in ONLINERS {
+ const ONELINERS: &'static [&'static str] = &["///!", "///", "//!", "//"];
+ for prefix in ONELINERS {
if comment.starts_with(*prefix) {
return (&comment[prefix.len()..]).to_string();
}
// 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);
// 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> {
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,
peek_tok: token::Eof,
peek_span: codemap::DUMMY_SP,
read_embedded_ident: false,
+ source_text: source_text
};
sr.bump();
sr
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[..]);
}
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.
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);
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
}
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() {
}
}
- 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.
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();
use std::old_io::util;
fn mk_sh() -> diagnostic::SpanHandler {
- let emitter = diagnostic::EmitterWriter::new(box util::NullWriter, None);
- let handler = diagnostic::mk_handler(true, box emitter);
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let emitter = diagnostic::EmitterWriter::new(Box::new(util::NullWriter), None);
+ let handler = diagnostic::mk_handler(true, Box::new(emitter));
diagnostic::mk_span_handler(handler, CodeMap::new())
}
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;
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>,
}
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
&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)");
}
#[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;
}))
}
- #[should_fail]
+ #[should_panic]
#[test] fn bad_path_expr_1() {
string_to_expr("::abc::def::return".to_string());
}
}
#[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() {
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;
}
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) {
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)
}
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..]));
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");
}
}
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 => (),
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);
}
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> ) {
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 => ()
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()));
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;
$( ($rk_name:expr, $rk_variant:ident, $rk_str:expr); )*
}
) => {
- static STRICT_KEYWORD_START: ast::Name = first!($( ast::Name($sk_name), )*);
- static STRICT_KEYWORD_FINAL: ast::Name = last!($( ast::Name($sk_name), )*);
- static RESERVED_KEYWORD_START: ast::Name = first!($( ast::Name($rk_name), )*);
- static RESERVED_KEYWORD_FINAL: ast::Name = last!($( ast::Name($rk_name), )*);
+ const STRICT_KEYWORD_START: ast::Name = first!($( ast::Name($sk_name), )*);
+ const STRICT_KEYWORD_FINAL: ast::Name = last!($( ast::Name($sk_name), )*);
+ const RESERVED_KEYWORD_START: ast::Name = first!($( ast::Name($rk_name), )*);
+ const RESERVED_KEYWORD_FINAL: ast::Name = last!($( ast::Name($rk_name), )*);
pub mod special_idents {
use ast;
//! 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;
pbreak: PrintStackBreak
}
-static SIZE_INFINITY: isize = 0xffff;
+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;
/// 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,
pending_indentation: isize,
}
-impl Printer {
+impl<'a> Printer<'a> {
pub fn last_token(&mut self) -> Token {
self.token[self.right].clone()
}
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 => {
}
}
}
- 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 {
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]);
}
}
}
- 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;
}
}
}
- 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,
// 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)
}
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> {
}
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)]
}
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> >,
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),
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,
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(
}
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> {
}
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);
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;
}
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
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, "}"));
}
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)
}
}
}
- 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 {
// 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[..]));
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;
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));
}
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));
}
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));
}
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());
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 {
}
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));
}
fn print_associated_type(&mut self, typedef: &ast::AssociatedType)
- -> IoResult<()>
+ -> io::Result<()>
{
try!(self.print_outer_attributes(&typedef.attrs));
try!(self.word_space("type"));
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));
}
/// 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));
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;
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)
}
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));
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());
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(())
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) {
/// 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)));
}
}
- 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() {
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) => {
}
}
- 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));
}
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),
}
}
- 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));
}
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 {
}
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 {
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 {
}
- 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, _) => {
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)
}
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 => ()
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 {
}
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));
}
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));
}
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, _) => {
}
- 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());
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)));
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[..]));
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));
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, "{"));
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 {
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)
}
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, "."));
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)));
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)));
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(":"));
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) => {
}
}
- 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[..]))
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"));
path: &ast::Path,
colons_before_params: bool,
depth: usize)
- -> IoResult<()>
+ -> io::Result<()>
{
try!(self.maybe_print_comment(path.span.lo));
path: &ast::Path,
qself: &ast::QSelf,
colons_before_params: bool)
- -> IoResult<()>
+ -> io::Result<()>
{
try!(word(&mut self.s, "<"));
try!(self.print_type(&qself.ty));
fn print_path_parameters(&mut self,
parameters: &ast::PathParameters,
colons_before_params: bool)
- -> IoResult<()>
+ -> io::Result<()>
{
if parameters.is_empty() {
return Ok(());
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
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() {
// 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); }
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());
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));
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 {
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, "|"));
}
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(()),
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;
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 = ":";
pub fn print_generics(&mut self,
generics: &ast::Generics)
- -> IoResult<()>
+ -> io::Result<()>
{
let total = generics.lifetimes.len() + generics.ty_params.len();
if total == 0 {
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 {
}
pub fn print_where_clause(&mut self, generics: &ast::Generics)
- -> IoResult<()> {
+ -> io::Result<()> {
if generics.where_clause.predicates.len() == 0 {
return Ok(())
}
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) => {
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));
}
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)),
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(());
}
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));
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(())
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() {
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) => {
}
}
- 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) => {
}
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);
}
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()))
}
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(())
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) => {
}
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"));
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));
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"),
use ptr::P;
use util::small_vector::SmallVector;
-enum ShouldFail {
+enum ShouldPanic {
No,
Yes(Option<InternedString>),
}
path: Vec<ast::Ident> ,
bench: bool,
ignore: bool,
- should_fail: ShouldFail
+ should_panic: ShouldPanic
}
struct TestCtxt<'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);
callee: NameAndSpan {
name: "test".to_string(),
format: MacroAttribute,
- span: None
+ span: None,
+ allow_internal_unstable: false,
}
});
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);
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,
}
}
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),
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 {
use ast::Name;
#[test]
- #[should_fail]
+ #[should_panic]
fn i1 () {
let i : Interner<RcStr> = Interner::new();
i.get(Name(13));
}
#[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("");
}
//! [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")]
#![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(path_ext)]
#![cfg_attr(windows, feature(libc))]
#[macro_use] extern crate log;
/// 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
// if c is 0, use 0200 (128) for ncurses compatibility
Number(c) => {
output.push(if c == 0 {
- 128u8
+ 128
} else {
c as u8
})
#[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());
//! 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.
"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 {
}
// 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);
}
// 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()),
.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);
}
}
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);
}
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 \
})
}
+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();
//!
//! 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"))
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:
// ~/.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"));
}
}
}
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);
}
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]
// 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]
#![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;
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};
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;
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
-pub enum ShouldFail {
+pub enum ShouldPanic {
No,
Yes(Option<&'static str>)
}
pub struct TestDesc {
pub name: TestName,
pub ignore: bool,
- pub should_fail: ShouldFail,
+ pub should_panic: ShouldPanic,
}
unsafe impl Send for TestDesc {}
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,
}
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
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 ||
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() {
}
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) => {
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,
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 {
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);
}
}
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))
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());
}
});
// 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
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,
+ };
}
}
}
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;
desc: TestDesc {
name: StaticTestName("whatever"),
ignore: true,
- should_fail: ShouldFail::No,
+ should_panic: ShouldPanic::No,
},
testfn: DynTestFn(Thunk::new(move|| f())),
};
desc: TestDesc {
name: StaticTestName("whatever"),
ignore: true,
- should_fail: ShouldFail::No,
+ should_panic: ShouldPanic::No,
},
testfn: DynTestFn(Thunk::new(move|| f())),
};
}
#[test]
- fn test_should_fail() {
+ fn test_should_panic() {
fn f() { panic!(); }
let desc = TestDescAndFn {
desc: TestDesc {
name: StaticTestName("whatever"),
ignore: false,
- should_fail: ShouldFail::Yes(None)
+ should_panic: ShouldPanic::Yes(None)
},
testfn: DynTestFn(Thunk::new(move|| f())),
};
}
#[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())),
};
}
#[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())),
};
}
#[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())),
};
desc: TestDesc {
name: StaticTestName("1"),
ignore: true,
- should_fail: ShouldFail::No,
+ should_panic: ShouldPanic::No,
},
testfn: DynTestFn(Thunk::new(move|| {})),
},
desc: TestDesc {
name: StaticTestName("2"),
ignore: false,
- should_fail: ShouldFail::No,
+ should_panic: ShouldPanic::No,
},
testfn: DynTestFn(Thunk::new(move|| {})),
});
desc: TestDesc {
name: DynTestName((*name).clone()),
ignore: false,
- should_fail: ShouldFail::No,
+ should_panic: ShouldPanic::No,
},
testfn: DynTestFn(Thunk::new(testfn)),
};
fn mean(&self) -> T {
assert!(self.len() != 0);
- self.sum() / FromPrimitive::from_uint(self.len()).unwrap()
+ self.sum() / FromPrimitive::from_usize(self.len()).unwrap()
}
fn median(&self) -> T {
- self.percentile(FromPrimitive::from_uint(50).unwrap())
+ self.percentile(FromPrimitive::from_usize(50).unwrap())
}
fn var(&self) -> T {
// NB: this is _supposed to be_ len-1, not len. If you
// change it back to len, you will be calculating a
// population variance, not a sample variance.
- let denom = FromPrimitive::from_uint(self.len()-1).unwrap();
+ let denom = FromPrimitive::from_usize(self.len()-1).unwrap();
v/denom
}
}
}
fn std_dev_pct(&self) -> T {
- let hundred = FromPrimitive::from_uint(100).unwrap();
+ let hundred = FromPrimitive::from_usize(100).unwrap();
(self.std_dev() / self.mean()) * hundred
}
}
fn median_abs_dev_pct(&self) -> T {
- let hundred = FromPrimitive::from_uint(100).unwrap();
+ let hundred = FromPrimitive::from_usize(100).unwrap();
(self.median_abs_dev() / self.median()) * hundred
}
fn quartiles(&self) -> (T,T,T) {
let mut tmp = self.to_vec();
local_sort(&mut tmp);
- let first = FromPrimitive::from_uint(25).unwrap();
+ let first = FromPrimitive::from_usize(25).unwrap();
let a = percentile_of_sorted(&tmp, first);
- let secound = FromPrimitive::from_uint(50).unwrap();
+ let secound = FromPrimitive::from_usize(50).unwrap();
let b = percentile_of_sorted(&tmp, secound);
- let third = FromPrimitive::from_uint(75).unwrap();
+ let third = FromPrimitive::from_usize(75).unwrap();
let c = percentile_of_sorted(&tmp, third);
(a,b,c)
}
}
let zero: T = Float::zero();
assert!(zero <= pct);
- let hundred = FromPrimitive::from_uint(100).unwrap();
+ let hundred = FromPrimitive::from_usize(100).unwrap();
assert!(pct <= hundred);
if pct == hundred {
return sorted_samples[sorted_samples.len() - 1];
}
- let length = FromPrimitive::from_uint(sorted_samples.len() - 1).unwrap();
+ let length = FromPrimitive::from_usize(sorted_samples.len() - 1).unwrap();
let rank = (pct / hundred) * length;
let lrank = rank.floor();
let d = rank - lrank;
- let n = lrank.to_uint().unwrap();
+ let n = lrank.to_usize().unwrap();
let lo = sorted_samples[n];
let hi = sorted_samples[n+1];
lo + (hi - lo) * d
let mut tmp = samples.to_vec();
local_sort(&mut tmp);
let lo = percentile_of_sorted(&tmp, pct);
- let hundred: T = FromPrimitive::from_uint(100).unwrap();
+ let hundred: T = FromPrimitive::from_usize(100).unwrap();
let hi = percentile_of_sorted(&tmp, hundred-pct);
for samp in samples {
if *samp > hi {
--- /dev/null
+// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Character manipulation (`char` type, Unicode Scalar Value)
+//!
+//! This module provides the `CharExt` trait, as well as its
+//! implementation for the primitive `char` type, in order to allow
+//! basic character manipulation.
+//!
+//! A `char` actually represents a
+//! *[Unicode Scalar
+//! Value](http://www.unicode.org/glossary/#unicode_scalar_value)*, as it can
+//! contain any Unicode code point except high-surrogate and low-surrogate code
+//! points.
+//!
+//! As such, only values in the ranges \[0x0,0xD7FF\] and \[0xE000,0x10FFFF\]
+//! (inclusive) are allowed. A `char` can always be safely cast to a `u32`;
+//! however the converse is not always true due to the above range limits
+//! and, as such, should be performed via the `from_u32` function.
+
+#![stable(feature = "rust1", since = "1.0.0")]
+#![doc(primitive = "char")]
+
+use core::char::CharExt as C;
+use core::option::Option::{self, Some};
+use core::iter::Iterator;
+use tables::{derived_property, property, general_category, conversions, charwidth};
+
+// stable reexports
+pub use core::char::{MAX, from_u32, from_digit, EscapeUnicode, EscapeDefault};
+
+// unstable reexports
+pub use normalize::{decompose_canonical, decompose_compatible, compose};
+pub use tables::normalization::canonical_combining_class;
+pub use tables::UNICODE_VERSION;
+
+/// Functionality for manipulating `char`.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub trait CharExt {
+ /// Checks if a `char` parses as a numeric digit in the given radix.
+ ///
+ /// Compared to `is_numeric()`, this function only recognizes the characters
+ /// `0-9`, `a-z` and `A-Z`.
+ ///
+ /// # Return value
+ ///
+ /// Returns `true` if `c` is a valid digit under `radix`, and `false`
+ /// otherwise.
+ ///
+ /// # Panics
+ ///
+ /// Panics if given a radix > 36.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let c = '1';
+ ///
+ /// assert!(c.is_digit(10));
+ ///
+ /// assert!('f'.is_digit(16));
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn is_digit(self, radix: u32) -> bool;
+
+ /// Converts a character to the corresponding digit.
+ ///
+ /// # Return value
+ ///
+ /// If `c` is between '0' and '9', the corresponding value between 0 and
+ /// 9. If `c` is 'a' or 'A', 10. If `c` is 'b' or 'B', 11, etc. Returns
+ /// none if the character does not refer to a digit in the given radix.
+ ///
+ /// # Panics
+ ///
+ /// Panics if given a radix outside the range [0..36].
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let c = '1';
+ ///
+ /// assert_eq!(c.to_digit(10), Some(1));
+ ///
+ /// assert_eq!('f'.to_digit(16), Some(15));
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn to_digit(self, radix: u32) -> Option<u32>;
+
+ /// Returns an iterator that yields the hexadecimal Unicode escape of a
+ /// character, as `char`s.
+ ///
+ /// All characters are escaped with Rust syntax of the form `\\u{NNNN}`
+ /// where `NNNN` is the shortest hexadecimal representation of the code
+ /// point.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// for i in '❤'.escape_unicode() {
+ /// println!("{}", i);
+ /// }
+ /// ```
+ ///
+ /// This prints:
+ ///
+ /// ```text
+ /// \
+ /// u
+ /// {
+ /// 2
+ /// 7
+ /// 6
+ /// 4
+ /// }
+ /// ```
+ ///
+ /// Collecting into a `String`:
+ ///
+ /// ```
+ /// let heart: String = '❤'.escape_unicode().collect();
+ ///
+ /// assert_eq!(heart, r"\u{2764}");
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn escape_unicode(self) -> EscapeUnicode;
+
+ /// Returns an iterator that yields the 'default' ASCII and
+ /// C++11-like literal escape of a character, as `char`s.
+ ///
+ /// The default is chosen with a bias toward producing literals that are
+ /// legal in a variety of languages, including C++11 and similar C-family
+ /// languages. The exact rules are:
+ ///
+ /// * Tab, CR and LF are escaped as '\t', '\r' and '\n' respectively.
+ /// * Single-quote, double-quote and backslash chars are backslash-
+ /// escaped.
+ /// * Any other chars in the range [0x20,0x7e] are not escaped.
+ /// * Any other chars are given hex Unicode escapes; see `escape_unicode`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// for i in '"'.escape_default() {
+ /// println!("{}", i);
+ /// }
+ /// ```
+ ///
+ /// This prints:
+ ///
+ /// ```text
+ /// \
+ /// "
+ /// ```
+ ///
+ /// Collecting into a `String`:
+ ///
+ /// ```
+ /// let quote: String = '"'.escape_default().collect();
+ ///
+ /// assert_eq!(quote, "\\\"");
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn escape_default(self) -> EscapeDefault;
+
+ /// Returns the number of bytes this character would need if encoded in
+ /// UTF-8.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let n = 'ß'.len_utf8();
+ ///
+ /// assert_eq!(n, 2);
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn len_utf8(self) -> usize;
+
+ /// Returns the number of 16-bit code units this character would need if
+ /// encoded in UTF-16.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let n = 'ß'.len_utf16();
+ ///
+ /// assert_eq!(n, 1);
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn len_utf16(self) -> usize;
+
+ /// Encodes this character as UTF-8 into the provided byte buffer, and then
+ /// returns the number of bytes written.
+ ///
+ /// If the buffer is not large enough, nothing will be written into it and a
+ /// `None` will be returned. A buffer of length four is large enough to
+ /// encode any `char`.
+ ///
+ /// # Examples
+ ///
+ /// In both of these examples, 'ß' takes two bytes to encode.
+ ///
+ /// ```
+ /// let mut b = [0; 2];
+ ///
+ /// let result = 'ß'.encode_utf8(&mut b);
+ ///
+ /// assert_eq!(result, Some(2));
+ /// ```
+ ///
+ /// A buffer that's too small:
+ ///
+ /// ```
+ /// let mut b = [0; 1];
+ ///
+ /// let result = 'ß'.encode_utf8(&mut b);
+ ///
+ /// assert_eq!(result, None);
+ /// ```
+ #[unstable(feature = "unicode",
+ reason = "pending decision about Iterator/Writer/Reader")]
+ fn encode_utf8(self, dst: &mut [u8]) -> Option<usize>;
+
+ /// Encodes this character as UTF-16 into the provided `u16` buffer, and
+ /// then returns the number of `u16`s written.
+ ///
+ /// If the buffer is not large enough, nothing will be written into it and a
+ /// `None` will be returned. A buffer of length 2 is large enough to encode
+ /// any `char`.
+ ///
+ /// # Examples
+ ///
+ /// In both of these examples, 'ß' takes one `u16` to encode.
+ ///
+ /// ```
+ /// let mut b = [0; 1];
+ ///
+ /// let result = 'ß'.encode_utf16(&mut b);
+ ///
+ /// assert_eq!(result, Some(1));
+ /// ```
+ ///
+ /// A buffer that's too small:
+ ///
+ /// ```
+ /// let mut b = [0; 0];
+ ///
+ /// let result = 'ß'.encode_utf8(&mut b);
+ ///
+ /// assert_eq!(result, None);
+ /// ```
+ #[unstable(feature = "unicode",
+ reason = "pending decision about Iterator/Writer/Reader")]
+ fn encode_utf16(self, dst: &mut [u16]) -> Option<usize>;
+
+ /// Returns whether the specified character is considered a Unicode
+ /// alphabetic code point.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn is_alphabetic(self) -> bool;
+
+ /// Returns whether the specified character satisfies the 'XID_Start'
+ /// Unicode property.
+ ///
+ /// 'XID_Start' is a Unicode Derived Property specified in
+ /// [UAX #31](http://unicode.org/reports/tr31/#NFKC_Modifications),
+ /// mostly similar to ID_Start but modified for closure under NFKx.
+ #[unstable(feature = "unicode",
+ reason = "mainly needed for compiler internals")]
+ fn is_xid_start(self) -> bool;
+
+ /// Returns whether the specified `char` satisfies the 'XID_Continue'
+ /// Unicode property.
+ ///
+ /// 'XID_Continue' is a Unicode Derived Property specified in
+ /// [UAX #31](http://unicode.org/reports/tr31/#NFKC_Modifications),
+ /// mostly similar to 'ID_Continue' but modified for closure under NFKx.
+ #[unstable(feature = "unicode",
+ reason = "mainly needed for compiler internals")]
+ fn is_xid_continue(self) -> bool;
+
+ /// Indicates whether a character is in lowercase.
+ ///
+ /// This is defined according to the terms of the Unicode Derived Core
+ /// Property `Lowercase`.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn is_lowercase(self) -> bool;
+
+ /// Indicates whether a character is in uppercase.
+ ///
+ /// This is defined according to the terms of the Unicode Derived Core
+ /// Property `Uppercase`.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn is_uppercase(self) -> bool;
+
+ /// Indicates whether a character is whitespace.
+ ///
+ /// Whitespace is defined in terms of the Unicode Property `White_Space`.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn is_whitespace(self) -> bool;
+
+ /// Indicates whether a character is alphanumeric.
+ ///
+ /// Alphanumericness is defined in terms of the Unicode General Categories
+ /// 'Nd', 'Nl', 'No' and the Derived Core Property 'Alphabetic'.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn is_alphanumeric(self) -> bool;
+
+ /// Indicates whether a character is a control code point.
+ ///
+ /// Control code points are defined in terms of the Unicode General
+ /// Category `Cc`.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn is_control(self) -> bool;
+
+ /// Indicates whether the character is numeric (Nd, Nl, or No).
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn is_numeric(self) -> bool;
+
+ /// Converts a character to its lowercase equivalent.
+ ///
+ /// The case-folding performed is the common or simple mapping. See
+ /// `to_uppercase()` for references and more information.
+ ///
+ /// # Return value
+ ///
+ /// Returns an iterator which yields the characters corresponding to the
+ /// lowercase equivalent of the character. If no conversion is possible then
+ /// the input character is returned.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn to_lowercase(self) -> ToLowercase;
+
+ /// Converts a character to its uppercase equivalent.
+ ///
+ /// The case-folding performed is the common or simple mapping: it maps
+ /// one Unicode codepoint to its uppercase equivalent according to the
+ /// Unicode database [1]. The additional [`SpecialCasing.txt`] is not yet
+ /// considered here, but the iterator returned will soon support this form
+ /// of case folding.
+ ///
+ /// A full reference can be found here [2].
+ ///
+ /// # Return value
+ ///
+ /// Returns an iterator which yields the characters corresponding to the
+ /// uppercase equivalent of the character. If no conversion is possible then
+ /// the input character is returned.
+ ///
+ /// [1]: ftp://ftp.unicode.org/Public/UNIDATA/UnicodeData.txt
+ ///
+ /// [`SpecialCasing`.txt`]: ftp://ftp.unicode.org/Public/UNIDATA/SpecialCasing.txt
+ ///
+ /// [2]: http://www.unicode.org/versions/Unicode4.0.0/ch03.pdf#G33992
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn to_uppercase(self) -> ToUppercase;
+
+ /// Returns this character's displayed width in columns, or `None` if it is a
+ /// control character other than `'\x00'`.
+ ///
+ /// `is_cjk` determines behavior for characters in the Ambiguous category:
+ /// if `is_cjk` is `true`, these are 2 columns wide; otherwise, they are 1.
+ /// In CJK contexts, `is_cjk` should be `true`, else it should be `false`.
+ /// [Unicode Standard Annex #11](http://www.unicode.org/reports/tr11/)
+ /// recommends that these characters be treated as 1 column (i.e.,
+ /// `is_cjk` = `false`) if the context cannot be reliably determined.
+ #[unstable(feature = "unicode",
+ reason = "needs expert opinion. is_cjk flag stands out as ugly")]
+ fn width(self, is_cjk: bool) -> Option<usize>;
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl CharExt for char {
+ fn is_digit(self, radix: u32) -> bool { C::is_digit(self, radix) }
+ fn to_digit(self, radix: u32) -> Option<u32> { C::to_digit(self, radix) }
+ fn escape_unicode(self) -> EscapeUnicode { C::escape_unicode(self) }
+ fn escape_default(self) -> EscapeDefault { C::escape_default(self) }
+ fn len_utf8(self) -> usize { C::len_utf8(self) }
+ fn len_utf16(self) -> usize { C::len_utf16(self) }
+ fn encode_utf8(self, dst: &mut [u8]) -> Option<usize> { C::encode_utf8(self, dst) }
+ fn encode_utf16(self, dst: &mut [u16]) -> Option<usize> { C::encode_utf16(self, dst) }
+
+ fn is_alphabetic(self) -> bool {
+ match self {
+ 'a' ... 'z' | 'A' ... 'Z' => true,
+ c if c > '\x7f' => derived_property::Alphabetic(c),
+ _ => false
+ }
+ }
+
+ fn is_xid_start(self) -> bool { derived_property::XID_Start(self) }
+
+ fn is_xid_continue(self) -> bool { derived_property::XID_Continue(self) }
+
+ fn is_lowercase(self) -> bool {
+ match self {
+ 'a' ... 'z' => true,
+ c if c > '\x7f' => derived_property::Lowercase(c),
+ _ => false
+ }
+ }
+
+ fn is_uppercase(self) -> bool {
+ match self {
+ 'A' ... 'Z' => true,
+ c if c > '\x7f' => derived_property::Uppercase(c),
+ _ => false
+ }
+ }
+
+ fn is_whitespace(self) -> bool {
+ match self {
+ ' ' | '\x09' ... '\x0d' => true,
+ c if c > '\x7f' => property::White_Space(c),
+ _ => false
+ }
+ }
+
+ fn is_alphanumeric(self) -> bool {
+ self.is_alphabetic() || self.is_numeric()
+ }
+
+ fn is_control(self) -> bool { general_category::Cc(self) }
+
+ fn is_numeric(self) -> bool {
+ match self {
+ '0' ... '9' => true,
+ c if c > '\x7f' => general_category::N(c),
+ _ => false
+ }
+ }
+
+ fn to_lowercase(self) -> ToLowercase {
+ ToLowercase(Some(conversions::to_lower(self)))
+ }
+
+ fn to_uppercase(self) -> ToUppercase {
+ ToUppercase(Some(conversions::to_upper(self)))
+ }
+
+ fn width(self, is_cjk: bool) -> Option<usize> { charwidth::width(self, is_cjk) }
+}
+
+/// An iterator over the lowercase mapping of a given character, returned from
+/// the `lowercase` method on characters.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct ToLowercase(Option<char>);
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl Iterator for ToLowercase {
+ type Item = char;
+ fn next(&mut self) -> Option<char> { self.0.take() }
+}
+
+/// An iterator over the uppercase mapping of a given character, returned from
+/// the `uppercase` method on characters.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct ToUppercase(Option<char>);
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl Iterator for ToUppercase {
+ type Item = char;
+ fn next(&mut self) -> Option<char> { self.0.take() }
+}
//! 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)]
mod normalize;
mod tables;
-mod u_char;
mod u_str;
-
-// re-export char so that std et al see it correctly
-/// Character manipulation (`char` type, Unicode Scalar Value)
-///
-/// This module provides the `CharExt` trait, as well as its
-/// implementation for the primitive `char` type, in order to allow
-/// basic character manipulation.
-///
-/// A `char` actually represents a
-/// *[Unicode Scalar Value](http://www.unicode.org/glossary/#unicode_scalar_value)*,
-/// as it can contain any Unicode code point except high-surrogate and
-/// low-surrogate code points.
-///
-/// As such, only values in the ranges \[0x0,0xD7FF\] and \[0xE000,0x10FFFF\]
-/// (inclusive) are allowed. A `char` can always be safely cast to a `u32`;
-/// however the converse is not always true due to the above range limits
-/// and, as such, should be performed via the `from_u32` function.
-#[stable(feature = "rust1", since = "1.0.0")]
-#[doc(primitive = "char")]
-pub mod char {
- pub use core::char::{MAX, from_u32, from_digit};
-
- pub use normalize::{decompose_canonical, decompose_compatible, compose};
-
- pub use tables::normalization::canonical_combining_class;
- pub use tables::UNICODE_VERSION;
-
- pub use u_char::CharExt;
-}
+pub mod char;
pub mod str {
pub use u_str::{UnicodeStr, Words, Graphemes, GraphemeIndices};
}
pub mod general_category {
- pub static C_table: &'static [(char, char)] = &[
+ pub const C_table: &'static [(char, char)] = &[
('\u{0}', '\u{1f}'), ('\u{7f}', '\u{9f}'), ('\u{ad}', '\u{ad}'), ('\u{378}', '\u{379}'),
('\u{380}', '\u{383}'), ('\u{38b}', '\u{38b}'), ('\u{38d}', '\u{38d}'), ('\u{3a2}',
'\u{3a2}'), ('\u{530}', '\u{530}'), ('\u{557}', '\u{558}'), ('\u{560}', '\u{560}'),
'\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}'),
('\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}')
];
- pub static Cc_table: &'static [(char, char)] = &[
+ pub const Cc_table: &'static [(char, char)] = &[
('\u{0}', '\u{1f}'), ('\u{7f}', '\u{9f}')
];
super::bsearch_range_table(c, Cc_table)
}
- pub static Cf_table: &'static [(char, char)] = &[
+ pub const Cf_table: &'static [(char, char)] = &[
('\u{ad}', '\u{ad}'), ('\u{600}', '\u{605}'), ('\u{61c}', '\u{61c}'), ('\u{6dd}',
'\u{6dd}'), ('\u{70f}', '\u{70f}'), ('\u{180e}', '\u{180e}'), ('\u{200b}', '\u{200f}'),
('\u{202a}', '\u{202e}'), ('\u{2060}', '\u{2064}'), ('\u{2066}', '\u{206f}'), ('\u{feff}',
'\u{e007f}')
];
- pub static Cn_table: &'static [(char, char)] = &[
+ pub const Cn_table: &'static [(char, char)] = &[
('\u{378}', '\u{379}'), ('\u{380}', '\u{383}'), ('\u{38b}', '\u{38b}'), ('\u{38d}',
'\u{38d}'), ('\u{3a2}', '\u{3a2}'), ('\u{530}', '\u{530}'), ('\u{557}', '\u{558}'),
('\u{560}', '\u{560}'), ('\u{588}', '\u{588}'), ('\u{58b}', '\u{58c}'), ('\u{590}',
('\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}')
- ];
-
- pub static 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}')
- ];
-
- pub static L_table: &'static [(char, char)] = &[
+ '\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{f8ff}'), ('\u{f0000}', '\u{ffffd}'), ('\u{100000}', '\u{10fffd}')
+ ];
+
+ pub const L_table: &'static [(char, char)] = &[
('\u{41}', '\u{5a}'), ('\u{61}', '\u{7a}'), ('\u{aa}', '\u{aa}'), ('\u{b5}', '\u{b5}'),
('\u{ba}', '\u{ba}'), ('\u{c0}', '\u{d6}'), ('\u{d8}', '\u{f6}'), ('\u{f8}', '\u{2c1}'),
('\u{2c6}', '\u{2d1}'), ('\u{2e0}', '\u{2e4}'), ('\u{2ec}', '\u{2ec}'), ('\u{2ee}',
('\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 static LC_table: &'static [(char, char)] = &[
+ pub const LC_table: &'static [(char, char)] = &[
('\u{41}', '\u{5a}'), ('\u{61}', '\u{7a}'), ('\u{b5}', '\u{b5}'), ('\u{c0}', '\u{d6}'),
('\u{d8}', '\u{f6}'), ('\u{f8}', '\u{1ba}'), ('\u{1bc}', '\u{1bf}'), ('\u{1c4}', '\u{293}'),
('\u{295}', '\u{2af}'), ('\u{370}', '\u{373}'), ('\u{376}', '\u{377}'), ('\u{37b}',
('\u{1d7aa}', '\u{1d7c2}'), ('\u{1d7c4}', '\u{1d7cb}')
];
- pub static Ll_table: &'static [(char, char)] = &[
+ pub const Ll_table: &'static [(char, char)] = &[
('\u{61}', '\u{7a}'), ('\u{b5}', '\u{b5}'), ('\u{df}', '\u{f6}'), ('\u{f8}', '\u{ff}'),
('\u{101}', '\u{101}'), ('\u{103}', '\u{103}'), ('\u{105}', '\u{105}'), ('\u{107}',
'\u{107}'), ('\u{109}', '\u{109}'), ('\u{10b}', '\u{10b}'), ('\u{10d}', '\u{10d}'),
'\u{1d7c2}'), ('\u{1d7c4}', '\u{1d7c9}'), ('\u{1d7cb}', '\u{1d7cb}')
];
- pub static Lm_table: &'static [(char, char)] = &[
+ pub const Lm_table: &'static [(char, char)] = &[
('\u{2b0}', '\u{2c1}'), ('\u{2c6}', '\u{2d1}'), ('\u{2e0}', '\u{2e4}'), ('\u{2ec}',
'\u{2ec}'), ('\u{2ee}', '\u{2ee}'), ('\u{374}', '\u{374}'), ('\u{37a}', '\u{37a}'),
('\u{559}', '\u{559}'), ('\u{640}', '\u{640}'), ('\u{6e5}', '\u{6e6}'), ('\u{7f4}',
'\u{16f9f}')
];
- pub static Lo_table: &'static [(char, char)] = &[
+ pub const Lo_table: &'static [(char, char)] = &[
('\u{aa}', '\u{aa}'), ('\u{ba}', '\u{ba}'), ('\u{1bb}', '\u{1bb}'), ('\u{1c0}', '\u{1c3}'),
('\u{294}', '\u{294}'), ('\u{5d0}', '\u{5ea}'), ('\u{5f0}', '\u{5f2}'), ('\u{620}',
'\u{63f}'), ('\u{641}', '\u{64a}'), ('\u{66e}', '\u{66f}'), ('\u{671}', '\u{6d3}'),
'\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 static Lt_table: &'static [(char, char)] = &[
+ pub const Lt_table: &'static [(char, char)] = &[
('\u{1c5}', '\u{1c5}'), ('\u{1c8}', '\u{1c8}'), ('\u{1cb}', '\u{1cb}'), ('\u{1f2}',
'\u{1f2}'), ('\u{1f88}', '\u{1f8f}'), ('\u{1f98}', '\u{1f9f}'), ('\u{1fa8}', '\u{1faf}'),
('\u{1fbc}', '\u{1fbc}'), ('\u{1fcc}', '\u{1fcc}'), ('\u{1ffc}', '\u{1ffc}')
];
- pub static Lu_table: &'static [(char, char)] = &[
+ pub const Lu_table: &'static [(char, char)] = &[
('\u{41}', '\u{5a}'), ('\u{c0}', '\u{d6}'), ('\u{d8}', '\u{de}'), ('\u{100}', '\u{100}'),
('\u{102}', '\u{102}'), ('\u{104}', '\u{104}'), ('\u{106}', '\u{106}'), ('\u{108}',
'\u{108}'), ('\u{10a}', '\u{10a}'), ('\u{10c}', '\u{10c}'), ('\u{10e}', '\u{10e}'),
'\u{1d7ca}')
];
- pub static M_table: &'static [(char, char)] = &[
+ pub const M_table: &'static [(char, char)] = &[
('\u{300}', '\u{36f}'), ('\u{483}', '\u{489}'), ('\u{591}', '\u{5bd}'), ('\u{5bf}',
'\u{5bf}'), ('\u{5c1}', '\u{5c2}'), ('\u{5c4}', '\u{5c5}'), ('\u{5c7}', '\u{5c7}'),
('\u{610}', '\u{61a}'), ('\u{64b}', '\u{65f}'), ('\u{670}', '\u{670}'), ('\u{6d6}',
('\u{1e8d0}', '\u{1e8d6}'), ('\u{e0100}', '\u{e01ef}')
];
- pub static Mc_table: &'static [(char, char)] = &[
+ pub const Mc_table: &'static [(char, char)] = &[
('\u{903}', '\u{903}'), ('\u{93b}', '\u{93b}'), ('\u{93e}', '\u{940}'), ('\u{949}',
'\u{94c}'), ('\u{94e}', '\u{94f}'), ('\u{982}', '\u{983}'), ('\u{9be}', '\u{9c0}'),
('\u{9c7}', '\u{9c8}'), ('\u{9cb}', '\u{9cc}'), ('\u{9d7}', '\u{9d7}'), ('\u{a03}',
('\u{1d165}', '\u{1d166}'), ('\u{1d16d}', '\u{1d172}')
];
- pub static Me_table: &'static [(char, char)] = &[
+ pub const Me_table: &'static [(char, char)] = &[
('\u{488}', '\u{489}'), ('\u{1abe}', '\u{1abe}'), ('\u{20dd}', '\u{20e0}'), ('\u{20e2}',
'\u{20e4}'), ('\u{a670}', '\u{a672}')
];
- pub static Mn_table: &'static [(char, char)] = &[
+ pub const Mn_table: &'static [(char, char)] = &[
('\u{300}', '\u{36f}'), ('\u{483}', '\u{487}'), ('\u{591}', '\u{5bd}'), ('\u{5bf}',
'\u{5bf}'), ('\u{5c1}', '\u{5c2}'), ('\u{5c4}', '\u{5c5}'), ('\u{5c7}', '\u{5c7}'),
('\u{610}', '\u{61a}'), ('\u{64b}', '\u{65f}'), ('\u{670}', '\u{670}'), ('\u{6d6}',
'\u{1e8d6}'), ('\u{e0100}', '\u{e01ef}')
];
- pub static N_table: &'static [(char, char)] = &[
+ pub const N_table: &'static [(char, char)] = &[
('\u{30}', '\u{39}'), ('\u{660}', '\u{669}'), ('\u{6f0}', '\u{6f9}'), ('\u{7c0}',
'\u{7c9}'), ('\u{966}', '\u{96f}'), ('\u{9e6}', '\u{9ef}'), ('\u{a66}', '\u{a6f}'),
('\u{ae6}', '\u{aef}'), ('\u{b66}', '\u{b6f}'), ('\u{be6}', '\u{bef}'), ('\u{c66}',
super::bsearch_range_table(c, N_table)
}
- pub static Nd_table: &'static [(char, char)] = &[
+ pub const Nd_table: &'static [(char, char)] = &[
('\u{30}', '\u{39}'), ('\u{660}', '\u{669}'), ('\u{6f0}', '\u{6f9}'), ('\u{7c0}',
'\u{7c9}'), ('\u{966}', '\u{96f}'), ('\u{9e6}', '\u{9ef}'), ('\u{a66}', '\u{a6f}'),
('\u{ae6}', '\u{aef}'), ('\u{b66}', '\u{b6f}'), ('\u{be6}', '\u{bef}'), ('\u{c66}',
('\u{16a60}', '\u{16a69}'), ('\u{16b50}', '\u{16b59}'), ('\u{1d7ce}', '\u{1d7ff}')
];
- pub static Nl_table: &'static [(char, char)] = &[
+ pub const Nl_table: &'static [(char, char)] = &[
('\u{16ee}', '\u{16f0}'), ('\u{2160}', '\u{2182}'), ('\u{2185}', '\u{2188}'), ('\u{3007}',
'\u{3007}'), ('\u{3021}', '\u{3029}'), ('\u{3038}', '\u{303a}'), ('\u{a6e6}', '\u{a6ef}'),
('\u{10140}', '\u{10174}'), ('\u{10341}', '\u{10341}'), ('\u{1034a}', '\u{1034a}'),
('\u{103d1}', '\u{103d5}'), ('\u{12400}', '\u{1246e}')
];
- pub static No_table: &'static [(char, char)] = &[
+ pub const No_table: &'static [(char, char)] = &[
('\u{b2}', '\u{b3}'), ('\u{b9}', '\u{b9}'), ('\u{bc}', '\u{be}'), ('\u{9f4}', '\u{9f9}'),
('\u{b72}', '\u{b77}'), ('\u{bf0}', '\u{bf2}'), ('\u{c78}', '\u{c7e}'), ('\u{d70}',
'\u{d75}'), ('\u{f2a}', '\u{f33}'), ('\u{1369}', '\u{137c}'), ('\u{17f0}', '\u{17f9}'),
'\u{1d371}'), ('\u{1e8c7}', '\u{1e8cf}'), ('\u{1f100}', '\u{1f10c}')
];
- pub static P_table: &'static [(char, char)] = &[
+ pub const P_table: &'static [(char, char)] = &[
('\u{21}', '\u{23}'), ('\u{25}', '\u{2a}'), ('\u{2c}', '\u{2f}'), ('\u{3a}', '\u{3b}'),
('\u{3f}', '\u{40}'), ('\u{5b}', '\u{5d}'), ('\u{5f}', '\u{5f}'), ('\u{7b}', '\u{7b}'),
('\u{7d}', '\u{7d}'), ('\u{a1}', '\u{a1}'), ('\u{a7}', '\u{a7}'), ('\u{ab}', '\u{ab}'),
'\u{1bc9f}')
];
- pub static Pc_table: &'static [(char, char)] = &[
+ pub const Pc_table: &'static [(char, char)] = &[
('\u{5f}', '\u{5f}'), ('\u{203f}', '\u{2040}'), ('\u{2054}', '\u{2054}'), ('\u{fe33}',
'\u{fe34}'), ('\u{fe4d}', '\u{fe4f}'), ('\u{ff3f}', '\u{ff3f}')
];
- pub static Pd_table: &'static [(char, char)] = &[
+ pub const Pd_table: &'static [(char, char)] = &[
('\u{2d}', '\u{2d}'), ('\u{58a}', '\u{58a}'), ('\u{5be}', '\u{5be}'), ('\u{1400}',
'\u{1400}'), ('\u{1806}', '\u{1806}'), ('\u{2010}', '\u{2015}'), ('\u{2e17}', '\u{2e17}'),
('\u{2e1a}', '\u{2e1a}'), ('\u{2e3a}', '\u{2e3b}'), ('\u{2e40}', '\u{2e40}'), ('\u{301c}',
('\u{fe58}', '\u{fe58}'), ('\u{fe63}', '\u{fe63}'), ('\u{ff0d}', '\u{ff0d}')
];
- pub static Pe_table: &'static [(char, char)] = &[
+ pub const Pe_table: &'static [(char, char)] = &[
('\u{29}', '\u{29}'), ('\u{5d}', '\u{5d}'), ('\u{7d}', '\u{7d}'), ('\u{f3b}', '\u{f3b}'),
('\u{f3d}', '\u{f3d}'), ('\u{169c}', '\u{169c}'), ('\u{2046}', '\u{2046}'), ('\u{207e}',
'\u{207e}'), ('\u{208e}', '\u{208e}'), ('\u{2309}', '\u{2309}'), ('\u{230b}', '\u{230b}'),
'\u{ff60}'), ('\u{ff63}', '\u{ff63}')
];
- pub static Pf_table: &'static [(char, char)] = &[
+ pub const Pf_table: &'static [(char, char)] = &[
('\u{bb}', '\u{bb}'), ('\u{2019}', '\u{2019}'), ('\u{201d}', '\u{201d}'), ('\u{203a}',
'\u{203a}'), ('\u{2e03}', '\u{2e03}'), ('\u{2e05}', '\u{2e05}'), ('\u{2e0a}', '\u{2e0a}'),
('\u{2e0d}', '\u{2e0d}'), ('\u{2e1d}', '\u{2e1d}'), ('\u{2e21}', '\u{2e21}')
];
- pub static Pi_table: &'static [(char, char)] = &[
+ pub const Pi_table: &'static [(char, char)] = &[
('\u{ab}', '\u{ab}'), ('\u{2018}', '\u{2018}'), ('\u{201b}', '\u{201c}'), ('\u{201f}',
'\u{201f}'), ('\u{2039}', '\u{2039}'), ('\u{2e02}', '\u{2e02}'), ('\u{2e04}', '\u{2e04}'),
('\u{2e09}', '\u{2e09}'), ('\u{2e0c}', '\u{2e0c}'), ('\u{2e1c}', '\u{2e1c}'), ('\u{2e20}',
'\u{2e20}')
];
- pub static Po_table: &'static [(char, char)] = &[
+ pub const Po_table: &'static [(char, char)] = &[
('\u{21}', '\u{23}'), ('\u{25}', '\u{27}'), ('\u{2a}', '\u{2a}'), ('\u{2c}', '\u{2c}'),
('\u{2e}', '\u{2f}'), ('\u{3a}', '\u{3b}'), ('\u{3f}', '\u{40}'), ('\u{5c}', '\u{5c}'),
('\u{a1}', '\u{a1}'), ('\u{a7}', '\u{a7}'), ('\u{b6}', '\u{b7}'), ('\u{bf}', '\u{bf}'),
'\u{1bc9f}')
];
- pub static Ps_table: &'static [(char, char)] = &[
+ pub const Ps_table: &'static [(char, char)] = &[
('\u{28}', '\u{28}'), ('\u{5b}', '\u{5b}'), ('\u{7b}', '\u{7b}'), ('\u{f3a}', '\u{f3a}'),
('\u{f3c}', '\u{f3c}'), ('\u{169b}', '\u{169b}'), ('\u{201a}', '\u{201a}'), ('\u{201e}',
'\u{201e}'), ('\u{2045}', '\u{2045}'), ('\u{207d}', '\u{207d}'), ('\u{208d}', '\u{208d}'),
('\u{ff62}', '\u{ff62}')
];
- pub static S_table: &'static [(char, char)] = &[
+ pub const S_table: &'static [(char, char)] = &[
('\u{24}', '\u{24}'), ('\u{2b}', '\u{2b}'), ('\u{3c}', '\u{3e}'), ('\u{5e}', '\u{5e}'),
('\u{60}', '\u{60}'), ('\u{7c}', '\u{7c}'), ('\u{7e}', '\u{7e}'), ('\u{a2}', '\u{a6}'),
('\u{a8}', '\u{a9}'), ('\u{ac}', '\u{ac}'), ('\u{ae}', '\u{b1}'), ('\u{b4}', '\u{b4}'),
'\u{1f887}'), ('\u{1f890}', '\u{1f8ad}')
];
- pub static Sc_table: &'static [(char, char)] = &[
+ pub const Sc_table: &'static [(char, char)] = &[
('\u{24}', '\u{24}'), ('\u{a2}', '\u{a5}'), ('\u{58f}', '\u{58f}'), ('\u{60b}', '\u{60b}'),
('\u{9f2}', '\u{9f3}'), ('\u{9fb}', '\u{9fb}'), ('\u{af1}', '\u{af1}'), ('\u{bf9}',
'\u{bf9}'), ('\u{e3f}', '\u{e3f}'), ('\u{17db}', '\u{17db}'), ('\u{20a0}', '\u{20bd}'),
'\u{ff04}'), ('\u{ffe0}', '\u{ffe1}'), ('\u{ffe5}', '\u{ffe6}')
];
- pub static Sk_table: &'static [(char, char)] = &[
+ pub const Sk_table: &'static [(char, char)] = &[
('\u{5e}', '\u{5e}'), ('\u{60}', '\u{60}'), ('\u{a8}', '\u{a8}'), ('\u{af}', '\u{af}'),
('\u{b4}', '\u{b4}'), ('\u{b8}', '\u{b8}'), ('\u{2c2}', '\u{2c5}'), ('\u{2d2}', '\u{2df}'),
('\u{2e5}', '\u{2eb}'), ('\u{2ed}', '\u{2ed}'), ('\u{2ef}', '\u{2ff}'), ('\u{375}',
'\u{ff3e}'), ('\u{ff40}', '\u{ff40}'), ('\u{ffe3}', '\u{ffe3}')
];
- pub static Sm_table: &'static [(char, char)] = &[
+ pub const Sm_table: &'static [(char, char)] = &[
('\u{2b}', '\u{2b}'), ('\u{3c}', '\u{3e}'), ('\u{7c}', '\u{7c}'), ('\u{7e}', '\u{7e}'),
('\u{ac}', '\u{ac}'), ('\u{b1}', '\u{b1}'), ('\u{d7}', '\u{d7}'), ('\u{f7}', '\u{f7}'),
('\u{3f6}', '\u{3f6}'), ('\u{606}', '\u{608}'), ('\u{2044}', '\u{2044}'), ('\u{2052}',
'\u{1d7c3}'), ('\u{1eef0}', '\u{1eef1}')
];
- pub static So_table: &'static [(char, char)] = &[
+ pub const So_table: &'static [(char, char)] = &[
('\u{a6}', '\u{a6}'), ('\u{a9}', '\u{a9}'), ('\u{ae}', '\u{ae}'), ('\u{b0}', '\u{b0}'),
('\u{482}', '\u{482}'), ('\u{58d}', '\u{58e}'), ('\u{60e}', '\u{60f}'), ('\u{6de}',
'\u{6de}'), ('\u{6e9}', '\u{6e9}'), ('\u{6fd}', '\u{6fe}'), ('\u{7f6}', '\u{7f6}'),
'\u{1f887}'), ('\u{1f890}', '\u{1f8ad}')
];
- pub static Z_table: &'static [(char, char)] = &[
+ pub const Z_table: &'static [(char, char)] = &[
('\u{20}', '\u{20}'), ('\u{a0}', '\u{a0}'), ('\u{1680}', '\u{1680}'), ('\u{2000}',
'\u{200a}'), ('\u{2028}', '\u{2029}'), ('\u{202f}', '\u{202f}'), ('\u{205f}', '\u{205f}'),
('\u{3000}', '\u{3000}')
];
- pub static Zl_table: &'static [(char, char)] = &[
+ pub const Zl_table: &'static [(char, char)] = &[
('\u{2028}', '\u{2028}')
];
- pub static Zp_table: &'static [(char, char)] = &[
+ pub const Zp_table: &'static [(char, char)] = &[
('\u{2029}', '\u{2029}')
];
- pub static Zs_table: &'static [(char, char)] = &[
+ pub const Zs_table: &'static [(char, char)] = &[
('\u{20}', '\u{20}'), ('\u{a0}', '\u{a0}'), ('\u{1680}', '\u{1680}'), ('\u{2000}',
'\u{200a}'), ('\u{202f}', '\u{202f}'), ('\u{205f}', '\u{205f}'), ('\u{3000}', '\u{3000}')
];
}
pub mod derived_property {
- pub static Alphabetic_table: &'static [(char, char)] = &[
+ pub const Alphabetic_table: &'static [(char, char)] = &[
('\u{41}', '\u{5a}'), ('\u{61}', '\u{7a}'), ('\u{aa}', '\u{aa}'), ('\u{b5}', '\u{b5}'),
('\u{ba}', '\u{ba}'), ('\u{c0}', '\u{d6}'), ('\u{d8}', '\u{f6}'), ('\u{f8}', '\u{1ba}'),
('\u{1bb}', '\u{1bb}'), ('\u{1bc}', '\u{1bf}'), ('\u{1c0}', '\u{1c3}'), ('\u{1c4}',
super::bsearch_range_table(c, Alphabetic_table)
}
- pub static Default_Ignorable_Code_Point_table: &'static [(char, char)] = &[
+ pub const Default_Ignorable_Code_Point_table: &'static [(char, char)] = &[
('\u{ad}', '\u{ad}'), ('\u{34f}', '\u{34f}'), ('\u{61c}', '\u{61c}'), ('\u{115f}',
'\u{1160}'), ('\u{17b4}', '\u{17b5}'), ('\u{180b}', '\u{180d}'), ('\u{180e}', '\u{180e}'),
('\u{200b}', '\u{200f}'), ('\u{202a}', '\u{202e}'), ('\u{2060}', '\u{2064}'), ('\u{2065}',
'\u{e00ff}'), ('\u{e0100}', '\u{e01ef}'), ('\u{e01f0}', '\u{e0fff}')
];
- pub static Lowercase_table: &'static [(char, char)] = &[
+ pub const Lowercase_table: &'static [(char, char)] = &[
('\u{61}', '\u{7a}'), ('\u{aa}', '\u{aa}'), ('\u{b5}', '\u{b5}'), ('\u{ba}', '\u{ba}'),
('\u{df}', '\u{f6}'), ('\u{f8}', '\u{ff}'), ('\u{101}', '\u{101}'), ('\u{103}', '\u{103}'),
('\u{105}', '\u{105}'), ('\u{107}', '\u{107}'), ('\u{109}', '\u{109}'), ('\u{10b}',
super::bsearch_range_table(c, Lowercase_table)
}
- pub static Uppercase_table: &'static [(char, char)] = &[
+ pub const Uppercase_table: &'static [(char, char)] = &[
('\u{41}', '\u{5a}'), ('\u{c0}', '\u{d6}'), ('\u{d8}', '\u{de}'), ('\u{100}', '\u{100}'),
('\u{102}', '\u{102}'), ('\u{104}', '\u{104}'), ('\u{106}', '\u{106}'), ('\u{108}',
'\u{108}'), ('\u{10a}', '\u{10a}'), ('\u{10c}', '\u{10c}'), ('\u{10e}', '\u{10e}'),
super::bsearch_range_table(c, Uppercase_table)
}
- pub static XID_Continue_table: &'static [(char, char)] = &[
+ pub const XID_Continue_table: &'static [(char, char)] = &[
('\u{30}', '\u{39}'), ('\u{41}', '\u{5a}'), ('\u{5f}', '\u{5f}'), ('\u{61}', '\u{7a}'),
('\u{aa}', '\u{aa}'), ('\u{b5}', '\u{b5}'), ('\u{b7}', '\u{b7}'), ('\u{ba}', '\u{ba}'),
('\u{c0}', '\u{d6}'), ('\u{d8}', '\u{f6}'), ('\u{f8}', '\u{1ba}'), ('\u{1bb}', '\u{1bb}'),
super::bsearch_range_table(c, XID_Continue_table)
}
- pub static XID_Start_table: &'static [(char, char)] = &[
+ pub const XID_Start_table: &'static [(char, char)] = &[
('\u{41}', '\u{5a}'), ('\u{61}', '\u{7a}'), ('\u{aa}', '\u{aa}'), ('\u{b5}', '\u{b5}'),
('\u{ba}', '\u{ba}'), ('\u{c0}', '\u{d6}'), ('\u{d8}', '\u{f6}'), ('\u{f8}', '\u{1ba}'),
('\u{1bb}', '\u{1bb}'), ('\u{1bc}', '\u{1bf}'), ('\u{1c0}', '\u{1c3}'), ('\u{1c4}',
}
pub mod script {
- pub static Arabic_table: &'static [(char, char)] = &[
+ pub const Arabic_table: &'static [(char, char)] = &[
('\u{600}', '\u{604}'), ('\u{606}', '\u{608}'), ('\u{609}', '\u{60a}'), ('\u{60b}',
'\u{60b}'), ('\u{60d}', '\u{60d}'), ('\u{60e}', '\u{60f}'), ('\u{610}', '\u{61a}'),
('\u{61e}', '\u{61e}'), ('\u{620}', '\u{63f}'), ('\u{641}', '\u{64a}'), ('\u{656}',
('\u{1eef0}', '\u{1eef1}')
];
- pub static Armenian_table: &'static [(char, char)] = &[
+ pub const Armenian_table: &'static [(char, char)] = &[
('\u{531}', '\u{556}'), ('\u{559}', '\u{559}'), ('\u{55a}', '\u{55f}'), ('\u{561}',
'\u{587}'), ('\u{58a}', '\u{58a}'), ('\u{58d}', '\u{58e}'), ('\u{58f}', '\u{58f}'),
('\u{fb13}', '\u{fb17}')
];
- pub static Avestan_table: &'static [(char, char)] = &[
+ pub const Avestan_table: &'static [(char, char)] = &[
('\u{10b00}', '\u{10b35}'), ('\u{10b39}', '\u{10b3f}')
];
- pub static Balinese_table: &'static [(char, char)] = &[
+ pub const Balinese_table: &'static [(char, char)] = &[
('\u{1b00}', '\u{1b03}'), ('\u{1b04}', '\u{1b04}'), ('\u{1b05}', '\u{1b33}'), ('\u{1b34}',
'\u{1b34}'), ('\u{1b35}', '\u{1b35}'), ('\u{1b36}', '\u{1b3a}'), ('\u{1b3b}', '\u{1b3b}'),
('\u{1b3c}', '\u{1b3c}'), ('\u{1b3d}', '\u{1b41}'), ('\u{1b42}', '\u{1b42}'), ('\u{1b43}',
('\u{1b61}', '\u{1b6a}'), ('\u{1b6b}', '\u{1b73}'), ('\u{1b74}', '\u{1b7c}')
];
- pub static Bamum_table: &'static [(char, char)] = &[
+ pub const Bamum_table: &'static [(char, char)] = &[
('\u{a6a0}', '\u{a6e5}'), ('\u{a6e6}', '\u{a6ef}'), ('\u{a6f0}', '\u{a6f1}'), ('\u{a6f2}',
'\u{a6f7}'), ('\u{16800}', '\u{16a38}')
];
- pub static Bassa_Vah_table: &'static [(char, char)] = &[
+ pub const Bassa_Vah_table: &'static [(char, char)] = &[
('\u{16ad0}', '\u{16aed}'), ('\u{16af0}', '\u{16af4}'), ('\u{16af5}', '\u{16af5}')
];
- pub static Batak_table: &'static [(char, char)] = &[
+ pub const Batak_table: &'static [(char, char)] = &[
('\u{1bc0}', '\u{1be5}'), ('\u{1be6}', '\u{1be6}'), ('\u{1be7}', '\u{1be7}'), ('\u{1be8}',
'\u{1be9}'), ('\u{1bea}', '\u{1bec}'), ('\u{1bed}', '\u{1bed}'), ('\u{1bee}', '\u{1bee}'),
('\u{1bef}', '\u{1bf1}'), ('\u{1bf2}', '\u{1bf3}'), ('\u{1bfc}', '\u{1bff}')
];
- pub static Bengali_table: &'static [(char, char)] = &[
+ pub const Bengali_table: &'static [(char, char)] = &[
('\u{980}', '\u{980}'), ('\u{981}', '\u{981}'), ('\u{982}', '\u{983}'), ('\u{985}',
'\u{98c}'), ('\u{98f}', '\u{990}'), ('\u{993}', '\u{9a8}'), ('\u{9aa}', '\u{9b0}'),
('\u{9b2}', '\u{9b2}'), ('\u{9b6}', '\u{9b9}'), ('\u{9bc}', '\u{9bc}'), ('\u{9bd}',
'\u{9f9}'), ('\u{9fa}', '\u{9fa}'), ('\u{9fb}', '\u{9fb}')
];
- pub static Bopomofo_table: &'static [(char, char)] = &[
+ pub const Bopomofo_table: &'static [(char, char)] = &[
('\u{2ea}', '\u{2eb}'), ('\u{3105}', '\u{312d}'), ('\u{31a0}', '\u{31ba}')
];
- pub static Brahmi_table: &'static [(char, char)] = &[
+ pub const Brahmi_table: &'static [(char, char)] = &[
('\u{11000}', '\u{11000}'), ('\u{11001}', '\u{11001}'), ('\u{11002}', '\u{11002}'),
('\u{11003}', '\u{11037}'), ('\u{11038}', '\u{11046}'), ('\u{11047}', '\u{1104d}'),
('\u{11052}', '\u{11065}'), ('\u{11066}', '\u{1106f}'), ('\u{1107f}', '\u{1107f}')
];
- pub static Braille_table: &'static [(char, char)] = &[
+ pub const Braille_table: &'static [(char, char)] = &[
('\u{2800}', '\u{28ff}')
];
- pub static Buginese_table: &'static [(char, char)] = &[
+ pub const Buginese_table: &'static [(char, char)] = &[
('\u{1a00}', '\u{1a16}'), ('\u{1a17}', '\u{1a18}'), ('\u{1a19}', '\u{1a1a}'), ('\u{1a1b}',
'\u{1a1b}'), ('\u{1a1e}', '\u{1a1f}')
];
- pub static Buhid_table: &'static [(char, char)] = &[
+ pub const Buhid_table: &'static [(char, char)] = &[
('\u{1740}', '\u{1751}'), ('\u{1752}', '\u{1753}')
];
- pub static Canadian_Aboriginal_table: &'static [(char, char)] = &[
+ pub const Canadian_Aboriginal_table: &'static [(char, char)] = &[
('\u{1400}', '\u{1400}'), ('\u{1401}', '\u{166c}'), ('\u{166d}', '\u{166e}'), ('\u{166f}',
'\u{167f}'), ('\u{18b0}', '\u{18f5}')
];
- pub static Carian_table: &'static [(char, char)] = &[
+ pub const Carian_table: &'static [(char, char)] = &[
('\u{102a0}', '\u{102d0}')
];
- pub static Caucasian_Albanian_table: &'static [(char, char)] = &[
+ pub const Caucasian_Albanian_table: &'static [(char, char)] = &[
('\u{10530}', '\u{10563}'), ('\u{1056f}', '\u{1056f}')
];
- pub static Chakma_table: &'static [(char, char)] = &[
+ pub const Chakma_table: &'static [(char, char)] = &[
('\u{11100}', '\u{11102}'), ('\u{11103}', '\u{11126}'), ('\u{11127}', '\u{1112b}'),
('\u{1112c}', '\u{1112c}'), ('\u{1112d}', '\u{11134}'), ('\u{11136}', '\u{1113f}'),
('\u{11140}', '\u{11143}')
];
- pub static Cham_table: &'static [(char, char)] = &[
+ pub const Cham_table: &'static [(char, char)] = &[
('\u{aa00}', '\u{aa28}'), ('\u{aa29}', '\u{aa2e}'), ('\u{aa2f}', '\u{aa30}'), ('\u{aa31}',
'\u{aa32}'), ('\u{aa33}', '\u{aa34}'), ('\u{aa35}', '\u{aa36}'), ('\u{aa40}', '\u{aa42}'),
('\u{aa43}', '\u{aa43}'), ('\u{aa44}', '\u{aa4b}'), ('\u{aa4c}', '\u{aa4c}'), ('\u{aa4d}',
'\u{aa4d}'), ('\u{aa50}', '\u{aa59}'), ('\u{aa5c}', '\u{aa5f}')
];
- pub static Cherokee_table: &'static [(char, char)] = &[
+ pub const Cherokee_table: &'static [(char, char)] = &[
('\u{13a0}', '\u{13f4}')
];
- pub static Common_table: &'static [(char, char)] = &[
+ pub const Common_table: &'static [(char, char)] = &[
('\u{0}', '\u{1f}'), ('\u{20}', '\u{20}'), ('\u{21}', '\u{23}'), ('\u{24}', '\u{24}'),
('\u{25}', '\u{27}'), ('\u{28}', '\u{28}'), ('\u{29}', '\u{29}'), ('\u{2a}', '\u{2a}'),
('\u{2b}', '\u{2b}'), ('\u{2c}', '\u{2c}'), ('\u{2d}', '\u{2d}'), ('\u{2e}', '\u{2f}'),
('\u{1f890}', '\u{1f8ad}'), ('\u{e0001}', '\u{e0001}'), ('\u{e0020}', '\u{e007f}')
];
- pub static Coptic_table: &'static [(char, char)] = &[
+ pub const Coptic_table: &'static [(char, char)] = &[
('\u{3e2}', '\u{3ef}'), ('\u{2c80}', '\u{2ce4}'), ('\u{2ce5}', '\u{2cea}'), ('\u{2ceb}',
'\u{2cee}'), ('\u{2cef}', '\u{2cf1}'), ('\u{2cf2}', '\u{2cf3}'), ('\u{2cf9}', '\u{2cfc}'),
('\u{2cfd}', '\u{2cfd}'), ('\u{2cfe}', '\u{2cff}')
];
- pub static Cuneiform_table: &'static [(char, char)] = &[
+ pub const Cuneiform_table: &'static [(char, char)] = &[
('\u{12000}', '\u{12398}'), ('\u{12400}', '\u{1246e}'), ('\u{12470}', '\u{12474}')
];
- pub static Cypriot_table: &'static [(char, char)] = &[
+ pub const Cypriot_table: &'static [(char, char)] = &[
('\u{10800}', '\u{10805}'), ('\u{10808}', '\u{10808}'), ('\u{1080a}', '\u{10835}'),
('\u{10837}', '\u{10838}'), ('\u{1083c}', '\u{1083c}'), ('\u{1083f}', '\u{1083f}')
];
- pub static Cyrillic_table: &'static [(char, char)] = &[
+ pub const Cyrillic_table: &'static [(char, char)] = &[
('\u{400}', '\u{481}'), ('\u{482}', '\u{482}'), ('\u{483}', '\u{484}'), ('\u{487}',
'\u{487}'), ('\u{488}', '\u{489}'), ('\u{48a}', '\u{52f}'), ('\u{1d2b}', '\u{1d2b}'),
('\u{1d78}', '\u{1d78}'), ('\u{2de0}', '\u{2dff}'), ('\u{a640}', '\u{a66d}'), ('\u{a66e}',
'\u{a69b}'), ('\u{a69c}', '\u{a69d}'), ('\u{a69f}', '\u{a69f}')
];
- pub static Deseret_table: &'static [(char, char)] = &[
+ pub const Deseret_table: &'static [(char, char)] = &[
('\u{10400}', '\u{1044f}')
];
- pub static Devanagari_table: &'static [(char, char)] = &[
+ pub const Devanagari_table: &'static [(char, char)] = &[
('\u{900}', '\u{902}'), ('\u{903}', '\u{903}'), ('\u{904}', '\u{939}'), ('\u{93a}',
'\u{93a}'), ('\u{93b}', '\u{93b}'), ('\u{93c}', '\u{93c}'), ('\u{93d}', '\u{93d}'),
('\u{93e}', '\u{940}'), ('\u{941}', '\u{948}'), ('\u{949}', '\u{94c}'), ('\u{94d}',
('\u{a8f2}', '\u{a8f7}'), ('\u{a8f8}', '\u{a8fa}'), ('\u{a8fb}', '\u{a8fb}')
];
- pub static Duployan_table: &'static [(char, char)] = &[
+ pub const Duployan_table: &'static [(char, char)] = &[
('\u{1bc00}', '\u{1bc6a}'), ('\u{1bc70}', '\u{1bc7c}'), ('\u{1bc80}', '\u{1bc88}'),
('\u{1bc90}', '\u{1bc99}'), ('\u{1bc9c}', '\u{1bc9c}'), ('\u{1bc9d}', '\u{1bc9e}'),
('\u{1bc9f}', '\u{1bc9f}')
];
- pub static Egyptian_Hieroglyphs_table: &'static [(char, char)] = &[
+ pub const Egyptian_Hieroglyphs_table: &'static [(char, char)] = &[
('\u{13000}', '\u{1342e}')
];
- pub static Elbasan_table: &'static [(char, char)] = &[
+ pub const Elbasan_table: &'static [(char, char)] = &[
('\u{10500}', '\u{10527}')
];
- pub static Ethiopic_table: &'static [(char, char)] = &[
+ pub const Ethiopic_table: &'static [(char, char)] = &[
('\u{1200}', '\u{1248}'), ('\u{124a}', '\u{124d}'), ('\u{1250}', '\u{1256}'), ('\u{1258}',
'\u{1258}'), ('\u{125a}', '\u{125d}'), ('\u{1260}', '\u{1288}'), ('\u{128a}', '\u{128d}'),
('\u{1290}', '\u{12b0}'), ('\u{12b2}', '\u{12b5}'), ('\u{12b8}', '\u{12be}'), ('\u{12c0}',
'\u{ab0e}'), ('\u{ab11}', '\u{ab16}'), ('\u{ab20}', '\u{ab26}'), ('\u{ab28}', '\u{ab2e}')
];
- pub static Georgian_table: &'static [(char, char)] = &[
+ pub const Georgian_table: &'static [(char, char)] = &[
('\u{10a0}', '\u{10c5}'), ('\u{10c7}', '\u{10c7}'), ('\u{10cd}', '\u{10cd}'), ('\u{10d0}',
'\u{10fa}'), ('\u{10fc}', '\u{10fc}'), ('\u{10fd}', '\u{10ff}'), ('\u{2d00}', '\u{2d25}'),
('\u{2d27}', '\u{2d27}'), ('\u{2d2d}', '\u{2d2d}')
];
- pub static Glagolitic_table: &'static [(char, char)] = &[
+ pub const Glagolitic_table: &'static [(char, char)] = &[
('\u{2c00}', '\u{2c2e}'), ('\u{2c30}', '\u{2c5e}')
];
- pub static Gothic_table: &'static [(char, char)] = &[
+ pub const Gothic_table: &'static [(char, char)] = &[
('\u{10330}', '\u{10340}'), ('\u{10341}', '\u{10341}'), ('\u{10342}', '\u{10349}'),
('\u{1034a}', '\u{1034a}')
];
- pub static Grantha_table: &'static [(char, char)] = &[
+ pub const Grantha_table: &'static [(char, char)] = &[
('\u{11301}', '\u{11301}'), ('\u{11302}', '\u{11303}'), ('\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{1133c}', '\u{1133c}'),
('\u{11366}', '\u{1136c}'), ('\u{11370}', '\u{11374}')
];
- pub static Greek_table: &'static [(char, char)] = &[
+ pub const Greek_table: &'static [(char, char)] = &[
('\u{370}', '\u{373}'), ('\u{375}', '\u{375}'), ('\u{376}', '\u{377}'), ('\u{37a}',
'\u{37a}'), ('\u{37b}', '\u{37d}'), ('\u{37f}', '\u{37f}'), ('\u{384}', '\u{384}'),
('\u{386}', '\u{386}'), ('\u{388}', '\u{38a}'), ('\u{38c}', '\u{38c}'), ('\u{38e}',
'\u{1d245}')
];
- pub static Gujarati_table: &'static [(char, char)] = &[
+ pub const Gujarati_table: &'static [(char, char)] = &[
('\u{a81}', '\u{a82}'), ('\u{a83}', '\u{a83}'), ('\u{a85}', '\u{a8d}'), ('\u{a8f}',
'\u{a91}'), ('\u{a93}', '\u{aa8}'), ('\u{aaa}', '\u{ab0}'), ('\u{ab2}', '\u{ab3}'),
('\u{ab5}', '\u{ab9}'), ('\u{abc}', '\u{abc}'), ('\u{abd}', '\u{abd}'), ('\u{abe}',
('\u{af1}', '\u{af1}')
];
- pub static Gurmukhi_table: &'static [(char, char)] = &[
+ pub const Gurmukhi_table: &'static [(char, char)] = &[
('\u{a01}', '\u{a02}'), ('\u{a03}', '\u{a03}'), ('\u{a05}', '\u{a0a}'), ('\u{a0f}',
'\u{a10}'), ('\u{a13}', '\u{a28}'), ('\u{a2a}', '\u{a30}'), ('\u{a32}', '\u{a33}'),
('\u{a35}', '\u{a36}'), ('\u{a38}', '\u{a39}'), ('\u{a3c}', '\u{a3c}'), ('\u{a3e}',
'\u{a6f}'), ('\u{a70}', '\u{a71}'), ('\u{a72}', '\u{a74}'), ('\u{a75}', '\u{a75}')
];
- pub static Han_table: &'static [(char, char)] = &[
+ pub const Han_table: &'static [(char, char)] = &[
('\u{2e80}', '\u{2e99}'), ('\u{2e9b}', '\u{2ef3}'), ('\u{2f00}', '\u{2fd5}'), ('\u{3005}',
'\u{3005}'), ('\u{3007}', '\u{3007}'), ('\u{3021}', '\u{3029}'), ('\u{3038}', '\u{303a}'),
('\u{303b}', '\u{303b}'), ('\u{3400}', '\u{4db5}'), ('\u{4e00}', '\u{9fcc}'), ('\u{f900}',
'\u{2b734}'), ('\u{2b740}', '\u{2b81d}'), ('\u{2f800}', '\u{2fa1d}')
];
- pub static Hangul_table: &'static [(char, char)] = &[
+ pub const Hangul_table: &'static [(char, char)] = &[
('\u{1100}', '\u{11ff}'), ('\u{302e}', '\u{302f}'), ('\u{3131}', '\u{318e}'), ('\u{3200}',
'\u{321e}'), ('\u{3260}', '\u{327e}'), ('\u{a960}', '\u{a97c}'), ('\u{ac00}', '\u{d7a3}'),
('\u{d7b0}', '\u{d7c6}'), ('\u{d7cb}', '\u{d7fb}'), ('\u{ffa0}', '\u{ffbe}'), ('\u{ffc2}',
'\u{ffc7}'), ('\u{ffca}', '\u{ffcf}'), ('\u{ffd2}', '\u{ffd7}'), ('\u{ffda}', '\u{ffdc}')
];
- pub static Hanunoo_table: &'static [(char, char)] = &[
+ pub const Hanunoo_table: &'static [(char, char)] = &[
('\u{1720}', '\u{1731}'), ('\u{1732}', '\u{1734}')
];
- pub static Hebrew_table: &'static [(char, char)] = &[
+ pub const Hebrew_table: &'static [(char, char)] = &[
('\u{591}', '\u{5bd}'), ('\u{5be}', '\u{5be}'), ('\u{5bf}', '\u{5bf}'), ('\u{5c0}',
'\u{5c0}'), ('\u{5c1}', '\u{5c2}'), ('\u{5c3}', '\u{5c3}'), ('\u{5c4}', '\u{5c5}'),
('\u{5c6}', '\u{5c6}'), ('\u{5c7}', '\u{5c7}'), ('\u{5d0}', '\u{5ea}'), ('\u{5f0}',
('\u{fb46}', '\u{fb4f}')
];
- pub static Hiragana_table: &'static [(char, char)] = &[
+ pub const Hiragana_table: &'static [(char, char)] = &[
('\u{3041}', '\u{3096}'), ('\u{309d}', '\u{309e}'), ('\u{309f}', '\u{309f}'), ('\u{1b001}',
'\u{1b001}'), ('\u{1f200}', '\u{1f200}')
];
- pub static Imperial_Aramaic_table: &'static [(char, char)] = &[
+ pub const Imperial_Aramaic_table: &'static [(char, char)] = &[
('\u{10840}', '\u{10855}'), ('\u{10857}', '\u{10857}'), ('\u{10858}', '\u{1085f}')
];
- pub static Inherited_table: &'static [(char, char)] = &[
+ pub const Inherited_table: &'static [(char, char)] = &[
('\u{300}', '\u{36f}'), ('\u{485}', '\u{486}'), ('\u{64b}', '\u{655}'), ('\u{670}',
'\u{670}'), ('\u{951}', '\u{952}'), ('\u{1ab0}', '\u{1abd}'), ('\u{1abe}', '\u{1abe}'),
('\u{1cd0}', '\u{1cd2}'), ('\u{1cd4}', '\u{1ce0}'), ('\u{1ce2}', '\u{1ce8}'), ('\u{1ced}',
'\u{1d1ad}'), ('\u{e0100}', '\u{e01ef}')
];
- pub static Inscriptional_Pahlavi_table: &'static [(char, char)] = &[
+ pub const Inscriptional_Pahlavi_table: &'static [(char, char)] = &[
('\u{10b60}', '\u{10b72}'), ('\u{10b78}', '\u{10b7f}')
];
- pub static Inscriptional_Parthian_table: &'static [(char, char)] = &[
+ pub const Inscriptional_Parthian_table: &'static [(char, char)] = &[
('\u{10b40}', '\u{10b55}'), ('\u{10b58}', '\u{10b5f}')
];
- pub static Javanese_table: &'static [(char, char)] = &[
+ pub const Javanese_table: &'static [(char, char)] = &[
('\u{a980}', '\u{a982}'), ('\u{a983}', '\u{a983}'), ('\u{a984}', '\u{a9b2}'), ('\u{a9b3}',
'\u{a9b3}'), ('\u{a9b4}', '\u{a9b5}'), ('\u{a9b6}', '\u{a9b9}'), ('\u{a9ba}', '\u{a9bb}'),
('\u{a9bc}', '\u{a9bc}'), ('\u{a9bd}', '\u{a9c0}'), ('\u{a9c1}', '\u{a9cd}'), ('\u{a9d0}',
'\u{a9d9}'), ('\u{a9de}', '\u{a9df}')
];
- pub static Kaithi_table: &'static [(char, char)] = &[
+ pub const Kaithi_table: &'static [(char, char)] = &[
('\u{11080}', '\u{11081}'), ('\u{11082}', '\u{11082}'), ('\u{11083}', '\u{110af}'),
('\u{110b0}', '\u{110b2}'), ('\u{110b3}', '\u{110b6}'), ('\u{110b7}', '\u{110b8}'),
('\u{110b9}', '\u{110ba}'), ('\u{110bb}', '\u{110bc}'), ('\u{110bd}', '\u{110bd}'),
('\u{110be}', '\u{110c1}')
];
- pub static Kannada_table: &'static [(char, char)] = &[
+ pub const Kannada_table: &'static [(char, char)] = &[
('\u{c81}', '\u{c81}'), ('\u{c82}', '\u{c83}'), ('\u{c85}', '\u{c8c}'), ('\u{c8e}',
'\u{c90}'), ('\u{c92}', '\u{ca8}'), ('\u{caa}', '\u{cb3}'), ('\u{cb5}', '\u{cb9}'),
('\u{cbc}', '\u{cbc}'), ('\u{cbd}', '\u{cbd}'), ('\u{cbe}', '\u{cbe}'), ('\u{cbf}',
('\u{cf1}', '\u{cf2}')
];
- pub static Katakana_table: &'static [(char, char)] = &[
+ pub const Katakana_table: &'static [(char, char)] = &[
('\u{30a1}', '\u{30fa}'), ('\u{30fd}', '\u{30fe}'), ('\u{30ff}', '\u{30ff}'), ('\u{31f0}',
'\u{31ff}'), ('\u{32d0}', '\u{32fe}'), ('\u{3300}', '\u{3357}'), ('\u{ff66}', '\u{ff6f}'),
('\u{ff71}', '\u{ff9d}'), ('\u{1b000}', '\u{1b000}')
];
- pub static Kayah_Li_table: &'static [(char, char)] = &[
+ pub const Kayah_Li_table: &'static [(char, char)] = &[
('\u{a900}', '\u{a909}'), ('\u{a90a}', '\u{a925}'), ('\u{a926}', '\u{a92d}'), ('\u{a92f}',
'\u{a92f}')
];
- pub static Kharoshthi_table: &'static [(char, char)] = &[
+ pub const Kharoshthi_table: &'static [(char, char)] = &[
('\u{10a00}', '\u{10a00}'), ('\u{10a01}', '\u{10a03}'), ('\u{10a05}', '\u{10a06}'),
('\u{10a0c}', '\u{10a0f}'), ('\u{10a10}', '\u{10a13}'), ('\u{10a15}', '\u{10a17}'),
('\u{10a19}', '\u{10a33}'), ('\u{10a38}', '\u{10a3a}'), ('\u{10a3f}', '\u{10a3f}'),
('\u{10a40}', '\u{10a47}'), ('\u{10a50}', '\u{10a58}')
];
- pub static Khmer_table: &'static [(char, char)] = &[
+ pub const Khmer_table: &'static [(char, char)] = &[
('\u{1780}', '\u{17b3}'), ('\u{17b4}', '\u{17b5}'), ('\u{17b6}', '\u{17b6}'), ('\u{17b7}',
'\u{17bd}'), ('\u{17be}', '\u{17c5}'), ('\u{17c6}', '\u{17c6}'), ('\u{17c7}', '\u{17c8}'),
('\u{17c9}', '\u{17d3}'), ('\u{17d4}', '\u{17d6}'), ('\u{17d7}', '\u{17d7}'), ('\u{17d8}',
('\u{17e0}', '\u{17e9}'), ('\u{17f0}', '\u{17f9}'), ('\u{19e0}', '\u{19ff}')
];
- pub static Khojki_table: &'static [(char, char)] = &[
+ pub const Khojki_table: &'static [(char, char)] = &[
('\u{11200}', '\u{11211}'), ('\u{11213}', '\u{1122b}'), ('\u{1122c}', '\u{1122e}'),
('\u{1122f}', '\u{11231}'), ('\u{11232}', '\u{11233}'), ('\u{11234}', '\u{11234}'),
('\u{11235}', '\u{11235}'), ('\u{11236}', '\u{11237}'), ('\u{11238}', '\u{1123d}')
];
- pub static Khudawadi_table: &'static [(char, char)] = &[
+ pub const Khudawadi_table: &'static [(char, char)] = &[
('\u{112b0}', '\u{112de}'), ('\u{112df}', '\u{112df}'), ('\u{112e0}', '\u{112e2}'),
('\u{112e3}', '\u{112ea}'), ('\u{112f0}', '\u{112f9}')
];
- pub static Lao_table: &'static [(char, char)] = &[
+ pub const Lao_table: &'static [(char, char)] = &[
('\u{e81}', '\u{e82}'), ('\u{e84}', '\u{e84}'), ('\u{e87}', '\u{e88}'), ('\u{e8a}',
'\u{e8a}'), ('\u{e8d}', '\u{e8d}'), ('\u{e94}', '\u{e97}'), ('\u{e99}', '\u{e9f}'),
('\u{ea1}', '\u{ea3}'), ('\u{ea5}', '\u{ea5}'), ('\u{ea7}', '\u{ea7}'), ('\u{eaa}',
('\u{edc}', '\u{edf}')
];
- pub static Latin_table: &'static [(char, char)] = &[
+ pub const Latin_table: &'static [(char, char)] = &[
('\u{41}', '\u{5a}'), ('\u{61}', '\u{7a}'), ('\u{aa}', '\u{aa}'), ('\u{ba}', '\u{ba}'),
('\u{c0}', '\u{d6}'), ('\u{d8}', '\u{f6}'), ('\u{f8}', '\u{1ba}'), ('\u{1bb}', '\u{1bb}'),
('\u{1bc}', '\u{1bf}'), ('\u{1c0}', '\u{1c3}'), ('\u{1c4}', '\u{293}'), ('\u{294}',
'\u{ab64}'), ('\u{fb00}', '\u{fb06}'), ('\u{ff21}', '\u{ff3a}'), ('\u{ff41}', '\u{ff5a}')
];
- pub static Lepcha_table: &'static [(char, char)] = &[
+ pub const Lepcha_table: &'static [(char, char)] = &[
('\u{1c00}', '\u{1c23}'), ('\u{1c24}', '\u{1c2b}'), ('\u{1c2c}', '\u{1c33}'), ('\u{1c34}',
'\u{1c35}'), ('\u{1c36}', '\u{1c37}'), ('\u{1c3b}', '\u{1c3f}'), ('\u{1c40}', '\u{1c49}'),
('\u{1c4d}', '\u{1c4f}')
];
- pub static Limbu_table: &'static [(char, char)] = &[
+ pub const Limbu_table: &'static [(char, char)] = &[
('\u{1900}', '\u{191e}'), ('\u{1920}', '\u{1922}'), ('\u{1923}', '\u{1926}'), ('\u{1927}',
'\u{1928}'), ('\u{1929}', '\u{192b}'), ('\u{1930}', '\u{1931}'), ('\u{1932}', '\u{1932}'),
('\u{1933}', '\u{1938}'), ('\u{1939}', '\u{193b}'), ('\u{1940}', '\u{1940}'), ('\u{1944}',
'\u{1945}'), ('\u{1946}', '\u{194f}')
];
- pub static Linear_A_table: &'static [(char, char)] = &[
+ pub const Linear_A_table: &'static [(char, char)] = &[
('\u{10600}', '\u{10736}'), ('\u{10740}', '\u{10755}'), ('\u{10760}', '\u{10767}')
];
- pub static Linear_B_table: &'static [(char, char)] = &[
+ pub const Linear_B_table: &'static [(char, char)] = &[
('\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}')
];
- pub static Lisu_table: &'static [(char, char)] = &[
+ pub const Lisu_table: &'static [(char, char)] = &[
('\u{a4d0}', '\u{a4f7}'), ('\u{a4f8}', '\u{a4fd}'), ('\u{a4fe}', '\u{a4ff}')
];
- pub static Lycian_table: &'static [(char, char)] = &[
+ pub const Lycian_table: &'static [(char, char)] = &[
('\u{10280}', '\u{1029c}')
];
- pub static Lydian_table: &'static [(char, char)] = &[
+ pub const Lydian_table: &'static [(char, char)] = &[
('\u{10920}', '\u{10939}'), ('\u{1093f}', '\u{1093f}')
];
- pub static Mahajani_table: &'static [(char, char)] = &[
+ pub const Mahajani_table: &'static [(char, char)] = &[
('\u{11150}', '\u{11172}'), ('\u{11173}', '\u{11173}'), ('\u{11174}', '\u{11175}'),
('\u{11176}', '\u{11176}')
];
- pub static Malayalam_table: &'static [(char, char)] = &[
+ pub const Malayalam_table: &'static [(char, char)] = &[
('\u{d01}', '\u{d01}'), ('\u{d02}', '\u{d03}'), ('\u{d05}', '\u{d0c}'), ('\u{d0e}',
'\u{d10}'), ('\u{d12}', '\u{d3a}'), ('\u{d3d}', '\u{d3d}'), ('\u{d3e}', '\u{d40}'),
('\u{d41}', '\u{d44}'), ('\u{d46}', '\u{d48}'), ('\u{d4a}', '\u{d4c}'), ('\u{d4d}',
'\u{d79}'), ('\u{d7a}', '\u{d7f}')
];
- pub static Mandaic_table: &'static [(char, char)] = &[
+ pub const Mandaic_table: &'static [(char, char)] = &[
('\u{840}', '\u{858}'), ('\u{859}', '\u{85b}'), ('\u{85e}', '\u{85e}')
];
- pub static Manichaean_table: &'static [(char, char)] = &[
+ pub const Manichaean_table: &'static [(char, char)] = &[
('\u{10ac0}', '\u{10ac7}'), ('\u{10ac8}', '\u{10ac8}'), ('\u{10ac9}', '\u{10ae4}'),
('\u{10ae5}', '\u{10ae6}'), ('\u{10aeb}', '\u{10aef}'), ('\u{10af0}', '\u{10af6}')
];
- pub static Meetei_Mayek_table: &'static [(char, char)] = &[
+ pub const Meetei_Mayek_table: &'static [(char, char)] = &[
('\u{aae0}', '\u{aaea}'), ('\u{aaeb}', '\u{aaeb}'), ('\u{aaec}', '\u{aaed}'), ('\u{aaee}',
'\u{aaef}'), ('\u{aaf0}', '\u{aaf1}'), ('\u{aaf2}', '\u{aaf2}'), ('\u{aaf3}', '\u{aaf4}'),
('\u{aaf5}', '\u{aaf5}'), ('\u{aaf6}', '\u{aaf6}'), ('\u{abc0}', '\u{abe2}'), ('\u{abe3}',
'\u{abed}'), ('\u{abf0}', '\u{abf9}')
];
- pub static Mende_Kikakui_table: &'static [(char, char)] = &[
+ pub const Mende_Kikakui_table: &'static [(char, char)] = &[
('\u{1e800}', '\u{1e8c4}'), ('\u{1e8c7}', '\u{1e8cf}'), ('\u{1e8d0}', '\u{1e8d6}')
];
- pub static Meroitic_Cursive_table: &'static [(char, char)] = &[
+ pub const Meroitic_Cursive_table: &'static [(char, char)] = &[
('\u{109a0}', '\u{109b7}'), ('\u{109be}', '\u{109bf}')
];
- pub static Meroitic_Hieroglyphs_table: &'static [(char, char)] = &[
+ pub const Meroitic_Hieroglyphs_table: &'static [(char, char)] = &[
('\u{10980}', '\u{1099f}')
];
- pub static Miao_table: &'static [(char, char)] = &[
+ pub const Miao_table: &'static [(char, char)] = &[
('\u{16f00}', '\u{16f44}'), ('\u{16f50}', '\u{16f50}'), ('\u{16f51}', '\u{16f7e}'),
('\u{16f8f}', '\u{16f92}'), ('\u{16f93}', '\u{16f9f}')
];
- pub static Modi_table: &'static [(char, char)] = &[
+ pub const Modi_table: &'static [(char, char)] = &[
('\u{11600}', '\u{1162f}'), ('\u{11630}', '\u{11632}'), ('\u{11633}', '\u{1163a}'),
('\u{1163b}', '\u{1163c}'), ('\u{1163d}', '\u{1163d}'), ('\u{1163e}', '\u{1163e}'),
('\u{1163f}', '\u{11640}'), ('\u{11641}', '\u{11643}'), ('\u{11644}', '\u{11644}'),
('\u{11650}', '\u{11659}')
];
- pub static Mongolian_table: &'static [(char, char)] = &[
+ pub const Mongolian_table: &'static [(char, char)] = &[
('\u{1800}', '\u{1801}'), ('\u{1804}', '\u{1804}'), ('\u{1806}', '\u{1806}'), ('\u{1807}',
'\u{180a}'), ('\u{180b}', '\u{180d}'), ('\u{180e}', '\u{180e}'), ('\u{1810}', '\u{1819}'),
('\u{1820}', '\u{1842}'), ('\u{1843}', '\u{1843}'), ('\u{1844}', '\u{1877}'), ('\u{1880}',
'\u{18a8}'), ('\u{18a9}', '\u{18a9}'), ('\u{18aa}', '\u{18aa}')
];
- pub static Mro_table: &'static [(char, char)] = &[
+ pub const Mro_table: &'static [(char, char)] = &[
('\u{16a40}', '\u{16a5e}'), ('\u{16a60}', '\u{16a69}'), ('\u{16a6e}', '\u{16a6f}')
];
- pub static Myanmar_table: &'static [(char, char)] = &[
+ pub const Myanmar_table: &'static [(char, char)] = &[
('\u{1000}', '\u{102a}'), ('\u{102b}', '\u{102c}'), ('\u{102d}', '\u{1030}'), ('\u{1031}',
'\u{1031}'), ('\u{1032}', '\u{1037}'), ('\u{1038}', '\u{1038}'), ('\u{1039}', '\u{103a}'),
('\u{103b}', '\u{103c}'), ('\u{103d}', '\u{103e}'), ('\u{103f}', '\u{103f}'), ('\u{1040}',
('\u{aa7e}', '\u{aa7f}')
];
- pub static Nabataean_table: &'static [(char, char)] = &[
+ pub const Nabataean_table: &'static [(char, char)] = &[
('\u{10880}', '\u{1089e}'), ('\u{108a7}', '\u{108af}')
];
- pub static New_Tai_Lue_table: &'static [(char, char)] = &[
+ pub const New_Tai_Lue_table: &'static [(char, char)] = &[
('\u{1980}', '\u{19ab}'), ('\u{19b0}', '\u{19c0}'), ('\u{19c1}', '\u{19c7}'), ('\u{19c8}',
'\u{19c9}'), ('\u{19d0}', '\u{19d9}'), ('\u{19da}', '\u{19da}'), ('\u{19de}', '\u{19df}')
];
- pub static Nko_table: &'static [(char, char)] = &[
+ pub const Nko_table: &'static [(char, char)] = &[
('\u{7c0}', '\u{7c9}'), ('\u{7ca}', '\u{7ea}'), ('\u{7eb}', '\u{7f3}'), ('\u{7f4}',
'\u{7f5}'), ('\u{7f6}', '\u{7f6}'), ('\u{7f7}', '\u{7f9}'), ('\u{7fa}', '\u{7fa}')
];
- pub static Ogham_table: &'static [(char, char)] = &[
+ pub const Ogham_table: &'static [(char, char)] = &[
('\u{1680}', '\u{1680}'), ('\u{1681}', '\u{169a}'), ('\u{169b}', '\u{169b}'), ('\u{169c}',
'\u{169c}')
];
- pub static Ol_Chiki_table: &'static [(char, char)] = &[
+ pub const Ol_Chiki_table: &'static [(char, char)] = &[
('\u{1c50}', '\u{1c59}'), ('\u{1c5a}', '\u{1c77}'), ('\u{1c78}', '\u{1c7d}'), ('\u{1c7e}',
'\u{1c7f}')
];
- pub static Old_Italic_table: &'static [(char, char)] = &[
+ pub const Old_Italic_table: &'static [(char, char)] = &[
('\u{10300}', '\u{1031f}'), ('\u{10320}', '\u{10323}')
];
- pub static Old_North_Arabian_table: &'static [(char, char)] = &[
+ pub const Old_North_Arabian_table: &'static [(char, char)] = &[
('\u{10a80}', '\u{10a9c}'), ('\u{10a9d}', '\u{10a9f}')
];
- pub static Old_Permic_table: &'static [(char, char)] = &[
+ pub const Old_Permic_table: &'static [(char, char)] = &[
('\u{10350}', '\u{10375}'), ('\u{10376}', '\u{1037a}')
];
- pub static Old_Persian_table: &'static [(char, char)] = &[
+ pub const Old_Persian_table: &'static [(char, char)] = &[
('\u{103a0}', '\u{103c3}'), ('\u{103c8}', '\u{103cf}'), ('\u{103d0}', '\u{103d0}'),
('\u{103d1}', '\u{103d5}')
];
- pub static Old_South_Arabian_table: &'static [(char, char)] = &[
+ pub const Old_South_Arabian_table: &'static [(char, char)] = &[
('\u{10a60}', '\u{10a7c}'), ('\u{10a7d}', '\u{10a7e}'), ('\u{10a7f}', '\u{10a7f}')
];
- pub static Old_Turkic_table: &'static [(char, char)] = &[
+ pub const Old_Turkic_table: &'static [(char, char)] = &[
('\u{10c00}', '\u{10c48}')
];
- pub static Oriya_table: &'static [(char, char)] = &[
+ pub const Oriya_table: &'static [(char, char)] = &[
('\u{b01}', '\u{b01}'), ('\u{b02}', '\u{b03}'), ('\u{b05}', '\u{b0c}'), ('\u{b0f}',
'\u{b10}'), ('\u{b13}', '\u{b28}'), ('\u{b2a}', '\u{b30}'), ('\u{b32}', '\u{b33}'),
('\u{b35}', '\u{b39}'), ('\u{b3c}', '\u{b3c}'), ('\u{b3d}', '\u{b3d}'), ('\u{b3e}',
'\u{b71}'), ('\u{b72}', '\u{b77}')
];
- pub static Osmanya_table: &'static [(char, char)] = &[
+ pub const Osmanya_table: &'static [(char, char)] = &[
('\u{10480}', '\u{1049d}'), ('\u{104a0}', '\u{104a9}')
];
- pub static Pahawh_Hmong_table: &'static [(char, char)] = &[
+ pub const Pahawh_Hmong_table: &'static [(char, char)] = &[
('\u{16b00}', '\u{16b2f}'), ('\u{16b30}', '\u{16b36}'), ('\u{16b37}', '\u{16b3b}'),
('\u{16b3c}', '\u{16b3f}'), ('\u{16b40}', '\u{16b43}'), ('\u{16b44}', '\u{16b44}'),
('\u{16b45}', '\u{16b45}'), ('\u{16b50}', '\u{16b59}'), ('\u{16b5b}', '\u{16b61}'),
('\u{16b63}', '\u{16b77}'), ('\u{16b7d}', '\u{16b8f}')
];
- pub static Palmyrene_table: &'static [(char, char)] = &[
+ pub const Palmyrene_table: &'static [(char, char)] = &[
('\u{10860}', '\u{10876}'), ('\u{10877}', '\u{10878}'), ('\u{10879}', '\u{1087f}')
];
- pub static Pau_Cin_Hau_table: &'static [(char, char)] = &[
+ pub const Pau_Cin_Hau_table: &'static [(char, char)] = &[
('\u{11ac0}', '\u{11af8}')
];
- pub static Phags_Pa_table: &'static [(char, char)] = &[
+ pub const Phags_Pa_table: &'static [(char, char)] = &[
('\u{a840}', '\u{a873}'), ('\u{a874}', '\u{a877}')
];
- pub static Phoenician_table: &'static [(char, char)] = &[
+ pub const Phoenician_table: &'static [(char, char)] = &[
('\u{10900}', '\u{10915}'), ('\u{10916}', '\u{1091b}'), ('\u{1091f}', '\u{1091f}')
];
- pub static Psalter_Pahlavi_table: &'static [(char, char)] = &[
+ pub const Psalter_Pahlavi_table: &'static [(char, char)] = &[
('\u{10b80}', '\u{10b91}'), ('\u{10b99}', '\u{10b9c}'), ('\u{10ba9}', '\u{10baf}')
];
- pub static Rejang_table: &'static [(char, char)] = &[
+ pub const Rejang_table: &'static [(char, char)] = &[
('\u{a930}', '\u{a946}'), ('\u{a947}', '\u{a951}'), ('\u{a952}', '\u{a953}'), ('\u{a95f}',
'\u{a95f}')
];
- pub static Runic_table: &'static [(char, char)] = &[
+ pub const Runic_table: &'static [(char, char)] = &[
('\u{16a0}', '\u{16ea}'), ('\u{16ee}', '\u{16f0}'), ('\u{16f1}', '\u{16f8}')
];
- pub static Samaritan_table: &'static [(char, char)] = &[
+ pub const Samaritan_table: &'static [(char, char)] = &[
('\u{800}', '\u{815}'), ('\u{816}', '\u{819}'), ('\u{81a}', '\u{81a}'), ('\u{81b}',
'\u{823}'), ('\u{824}', '\u{824}'), ('\u{825}', '\u{827}'), ('\u{828}', '\u{828}'),
('\u{829}', '\u{82d}'), ('\u{830}', '\u{83e}')
];
- pub static Saurashtra_table: &'static [(char, char)] = &[
+ pub const Saurashtra_table: &'static [(char, char)] = &[
('\u{a880}', '\u{a881}'), ('\u{a882}', '\u{a8b3}'), ('\u{a8b4}', '\u{a8c3}'), ('\u{a8c4}',
'\u{a8c4}'), ('\u{a8ce}', '\u{a8cf}'), ('\u{a8d0}', '\u{a8d9}')
];
- pub static Sharada_table: &'static [(char, char)] = &[
+ pub const Sharada_table: &'static [(char, char)] = &[
('\u{11180}', '\u{11181}'), ('\u{11182}', '\u{11182}'), ('\u{11183}', '\u{111b2}'),
('\u{111b3}', '\u{111b5}'), ('\u{111b6}', '\u{111be}'), ('\u{111bf}', '\u{111c0}'),
('\u{111c1}', '\u{111c4}'), ('\u{111c5}', '\u{111c8}'), ('\u{111cd}', '\u{111cd}'),
('\u{111d0}', '\u{111d9}'), ('\u{111da}', '\u{111da}')
];
- pub static Shavian_table: &'static [(char, char)] = &[
+ pub const Shavian_table: &'static [(char, char)] = &[
('\u{10450}', '\u{1047f}')
];
- pub static Siddham_table: &'static [(char, char)] = &[
+ pub const Siddham_table: &'static [(char, char)] = &[
('\u{11580}', '\u{115ae}'), ('\u{115af}', '\u{115b1}'), ('\u{115b2}', '\u{115b5}'),
('\u{115b8}', '\u{115bb}'), ('\u{115bc}', '\u{115bd}'), ('\u{115be}', '\u{115be}'),
('\u{115bf}', '\u{115c0}'), ('\u{115c1}', '\u{115c9}')
];
- pub static Sinhala_table: &'static [(char, char)] = &[
+ pub const Sinhala_table: &'static [(char, char)] = &[
('\u{d82}', '\u{d83}'), ('\u{d85}', '\u{d96}'), ('\u{d9a}', '\u{db1}'), ('\u{db3}',
'\u{dbb}'), ('\u{dbd}', '\u{dbd}'), ('\u{dc0}', '\u{dc6}'), ('\u{dca}', '\u{dca}'),
('\u{dcf}', '\u{dd1}'), ('\u{dd2}', '\u{dd4}'), ('\u{dd6}', '\u{dd6}'), ('\u{dd8}',
('\u{111e1}', '\u{111f4}')
];
- pub static Sora_Sompeng_table: &'static [(char, char)] = &[
+ pub const Sora_Sompeng_table: &'static [(char, char)] = &[
('\u{110d0}', '\u{110e8}'), ('\u{110f0}', '\u{110f9}')
];
- pub static Sundanese_table: &'static [(char, char)] = &[
+ pub const Sundanese_table: &'static [(char, char)] = &[
('\u{1b80}', '\u{1b81}'), ('\u{1b82}', '\u{1b82}'), ('\u{1b83}', '\u{1ba0}'), ('\u{1ba1}',
'\u{1ba1}'), ('\u{1ba2}', '\u{1ba5}'), ('\u{1ba6}', '\u{1ba7}'), ('\u{1ba8}', '\u{1ba9}'),
('\u{1baa}', '\u{1baa}'), ('\u{1bab}', '\u{1bad}'), ('\u{1bae}', '\u{1baf}'), ('\u{1bb0}',
'\u{1bb9}'), ('\u{1bba}', '\u{1bbf}'), ('\u{1cc0}', '\u{1cc7}')
];
- pub static Syloti_Nagri_table: &'static [(char, char)] = &[
+ pub const Syloti_Nagri_table: &'static [(char, char)] = &[
('\u{a800}', '\u{a801}'), ('\u{a802}', '\u{a802}'), ('\u{a803}', '\u{a805}'), ('\u{a806}',
'\u{a806}'), ('\u{a807}', '\u{a80a}'), ('\u{a80b}', '\u{a80b}'), ('\u{a80c}', '\u{a822}'),
('\u{a823}', '\u{a824}'), ('\u{a825}', '\u{a826}'), ('\u{a827}', '\u{a827}'), ('\u{a828}',
'\u{a82b}')
];
- pub static Syriac_table: &'static [(char, char)] = &[
+ pub const Syriac_table: &'static [(char, char)] = &[
('\u{700}', '\u{70d}'), ('\u{70f}', '\u{70f}'), ('\u{710}', '\u{710}'), ('\u{711}',
'\u{711}'), ('\u{712}', '\u{72f}'), ('\u{730}', '\u{74a}'), ('\u{74d}', '\u{74f}')
];
- pub static Tagalog_table: &'static [(char, char)] = &[
+ pub const Tagalog_table: &'static [(char, char)] = &[
('\u{1700}', '\u{170c}'), ('\u{170e}', '\u{1711}'), ('\u{1712}', '\u{1714}')
];
- pub static Tagbanwa_table: &'static [(char, char)] = &[
+ pub const Tagbanwa_table: &'static [(char, char)] = &[
('\u{1760}', '\u{176c}'), ('\u{176e}', '\u{1770}'), ('\u{1772}', '\u{1773}')
];
- pub static Tai_Le_table: &'static [(char, char)] = &[
+ pub const Tai_Le_table: &'static [(char, char)] = &[
('\u{1950}', '\u{196d}'), ('\u{1970}', '\u{1974}')
];
- pub static Tai_Tham_table: &'static [(char, char)] = &[
+ pub const Tai_Tham_table: &'static [(char, char)] = &[
('\u{1a20}', '\u{1a54}'), ('\u{1a55}', '\u{1a55}'), ('\u{1a56}', '\u{1a56}'), ('\u{1a57}',
'\u{1a57}'), ('\u{1a58}', '\u{1a5e}'), ('\u{1a60}', '\u{1a60}'), ('\u{1a61}', '\u{1a61}'),
('\u{1a62}', '\u{1a62}'), ('\u{1a63}', '\u{1a64}'), ('\u{1a65}', '\u{1a6c}'), ('\u{1a6d}',
'\u{1aad}')
];
- pub static Tai_Viet_table: &'static [(char, char)] = &[
+ pub const Tai_Viet_table: &'static [(char, char)] = &[
('\u{aa80}', '\u{aaaf}'), ('\u{aab0}', '\u{aab0}'), ('\u{aab1}', '\u{aab1}'), ('\u{aab2}',
'\u{aab4}'), ('\u{aab5}', '\u{aab6}'), ('\u{aab7}', '\u{aab8}'), ('\u{aab9}', '\u{aabd}'),
('\u{aabe}', '\u{aabf}'), ('\u{aac0}', '\u{aac0}'), ('\u{aac1}', '\u{aac1}'), ('\u{aac2}',
'\u{aac2}'), ('\u{aadb}', '\u{aadc}'), ('\u{aadd}', '\u{aadd}'), ('\u{aade}', '\u{aadf}')
];
- pub static Takri_table: &'static [(char, char)] = &[
+ pub const Takri_table: &'static [(char, char)] = &[
('\u{11680}', '\u{116aa}'), ('\u{116ab}', '\u{116ab}'), ('\u{116ac}', '\u{116ac}'),
('\u{116ad}', '\u{116ad}'), ('\u{116ae}', '\u{116af}'), ('\u{116b0}', '\u{116b5}'),
('\u{116b6}', '\u{116b6}'), ('\u{116b7}', '\u{116b7}'), ('\u{116c0}', '\u{116c9}')
];
- pub static Tamil_table: &'static [(char, char)] = &[
+ pub const Tamil_table: &'static [(char, char)] = &[
('\u{b82}', '\u{b82}'), ('\u{b83}', '\u{b83}'), ('\u{b85}', '\u{b8a}'), ('\u{b8e}',
'\u{b90}'), ('\u{b92}', '\u{b95}'), ('\u{b99}', '\u{b9a}'), ('\u{b9c}', '\u{b9c}'),
('\u{b9e}', '\u{b9f}'), ('\u{ba3}', '\u{ba4}'), ('\u{ba8}', '\u{baa}'), ('\u{bae}',
('\u{bf3}', '\u{bf8}'), ('\u{bf9}', '\u{bf9}'), ('\u{bfa}', '\u{bfa}')
];
- pub static Telugu_table: &'static [(char, char)] = &[
+ pub const Telugu_table: &'static [(char, char)] = &[
('\u{c00}', '\u{c00}'), ('\u{c01}', '\u{c03}'), ('\u{c05}', '\u{c0c}'), ('\u{c0e}',
'\u{c10}'), ('\u{c12}', '\u{c28}'), ('\u{c2a}', '\u{c39}'), ('\u{c3d}', '\u{c3d}'),
('\u{c3e}', '\u{c40}'), ('\u{c41}', '\u{c44}'), ('\u{c46}', '\u{c48}'), ('\u{c4a}',
'\u{c7f}')
];
- pub static Thaana_table: &'static [(char, char)] = &[
+ pub const Thaana_table: &'static [(char, char)] = &[
('\u{780}', '\u{7a5}'), ('\u{7a6}', '\u{7b0}'), ('\u{7b1}', '\u{7b1}')
];
- pub static Thai_table: &'static [(char, char)] = &[
+ pub const Thai_table: &'static [(char, char)] = &[
('\u{e01}', '\u{e30}'), ('\u{e31}', '\u{e31}'), ('\u{e32}', '\u{e33}'), ('\u{e34}',
'\u{e3a}'), ('\u{e40}', '\u{e45}'), ('\u{e46}', '\u{e46}'), ('\u{e47}', '\u{e4e}'),
('\u{e4f}', '\u{e4f}'), ('\u{e50}', '\u{e59}'), ('\u{e5a}', '\u{e5b}')
];
- pub static Tibetan_table: &'static [(char, char)] = &[
+ pub const Tibetan_table: &'static [(char, char)] = &[
('\u{f00}', '\u{f00}'), ('\u{f01}', '\u{f03}'), ('\u{f04}', '\u{f12}'), ('\u{f13}',
'\u{f13}'), ('\u{f14}', '\u{f14}'), ('\u{f15}', '\u{f17}'), ('\u{f18}', '\u{f19}'),
('\u{f1a}', '\u{f1f}'), ('\u{f20}', '\u{f29}'), ('\u{f2a}', '\u{f33}'), ('\u{f34}',
('\u{fd0}', '\u{fd4}'), ('\u{fd9}', '\u{fda}')
];
- pub static Tifinagh_table: &'static [(char, char)] = &[
+ pub const Tifinagh_table: &'static [(char, char)] = &[
('\u{2d30}', '\u{2d67}'), ('\u{2d6f}', '\u{2d6f}'), ('\u{2d70}', '\u{2d70}'), ('\u{2d7f}',
'\u{2d7f}')
];
- pub static Tirhuta_table: &'static [(char, char)] = &[
+ pub const Tirhuta_table: &'static [(char, char)] = &[
('\u{11480}', '\u{114af}'), ('\u{114b0}', '\u{114b2}'), ('\u{114b3}', '\u{114b8}'),
('\u{114b9}', '\u{114b9}'), ('\u{114ba}', '\u{114ba}'), ('\u{114bb}', '\u{114be}'),
('\u{114bf}', '\u{114c0}'), ('\u{114c1}', '\u{114c1}'), ('\u{114c2}', '\u{114c3}'),
('\u{114d0}', '\u{114d9}')
];
- pub static Ugaritic_table: &'static [(char, char)] = &[
+ pub const Ugaritic_table: &'static [(char, char)] = &[
('\u{10380}', '\u{1039d}'), ('\u{1039f}', '\u{1039f}')
];
- pub static Vai_table: &'static [(char, char)] = &[
+ pub const Vai_table: &'static [(char, char)] = &[
('\u{a500}', '\u{a60b}'), ('\u{a60c}', '\u{a60c}'), ('\u{a60d}', '\u{a60f}'), ('\u{a610}',
'\u{a61f}'), ('\u{a620}', '\u{a629}'), ('\u{a62a}', '\u{a62b}')
];
- pub static Warang_Citi_table: &'static [(char, char)] = &[
+ pub const Warang_Citi_table: &'static [(char, char)] = &[
('\u{118a0}', '\u{118df}'), ('\u{118e0}', '\u{118e9}'), ('\u{118ea}', '\u{118f2}'),
('\u{118ff}', '\u{118ff}')
];
- pub static Yi_table: &'static [(char, char)] = &[
+ pub const Yi_table: &'static [(char, char)] = &[
('\u{a000}', '\u{a014}'), ('\u{a015}', '\u{a015}'), ('\u{a016}', '\u{a48c}'), ('\u{a490}',
'\u{a4c6}')
];
}
pub mod property {
- pub static Join_Control_table: &'static [(char, char)] = &[
+ pub const Join_Control_table: &'static [(char, char)] = &[
('\u{200c}', '\u{200d}')
];
- pub static Noncharacter_Code_Point_table: &'static [(char, char)] = &[
+ pub const Noncharacter_Code_Point_table: &'static [(char, char)] = &[
('\u{fdd0}', '\u{fdef}'), ('\u{fffe}', '\u{ffff}'), ('\u{1fffe}', '\u{1ffff}'),
('\u{2fffe}', '\u{2ffff}'), ('\u{3fffe}', '\u{3ffff}'), ('\u{4fffe}', '\u{4ffff}'),
('\u{5fffe}', '\u{5ffff}'), ('\u{6fffe}', '\u{6ffff}'), ('\u{7fffe}', '\u{7ffff}'),
('\u{efffe}', '\u{effff}'), ('\u{ffffe}', '\u{fffff}')
];
- pub static White_Space_table: &'static [(char, char)] = &[
+ pub const White_Space_table: &'static [(char, char)] = &[
('\u{9}', '\u{d}'), ('\u{20}', '\u{20}'), ('\u{85}', '\u{85}'), ('\u{a0}', '\u{a0}'),
('\u{1680}', '\u{1680}'), ('\u{2000}', '\u{200a}'), ('\u{2028}', '\u{2028}'), ('\u{2029}',
'\u{2029}'), ('\u{202f}', '\u{202f}'), ('\u{205f}', '\u{205f}'), ('\u{3000}', '\u{3000}')
}
pub mod regex {
- pub static UNICODE_CLASSES: &'static [(&'static str, &'static &'static [(char, char)])] = &[
- ("Alphabetic", &super::derived_property::Alphabetic_table), ("Arabic",
- &super::script::Arabic_table), ("Armenian", &super::script::Armenian_table), ("Avestan",
- &super::script::Avestan_table), ("Balinese", &super::script::Balinese_table), ("Bamum",
- &super::script::Bamum_table), ("Bassa_Vah", &super::script::Bassa_Vah_table), ("Batak",
- &super::script::Batak_table), ("Bengali", &super::script::Bengali_table), ("Bopomofo",
- &super::script::Bopomofo_table), ("Brahmi", &super::script::Brahmi_table), ("Braille",
- &super::script::Braille_table), ("Buginese", &super::script::Buginese_table), ("Buhid",
- &super::script::Buhid_table), ("C", &super::general_category::C_table),
- ("Canadian_Aboriginal", &super::script::Canadian_Aboriginal_table), ("Carian",
- &super::script::Carian_table), ("Caucasian_Albanian",
- &super::script::Caucasian_Albanian_table), ("Cc", &super::general_category::Cc_table),
- ("Cf", &super::general_category::Cf_table), ("Chakma", &super::script::Chakma_table),
- ("Cham", &super::script::Cham_table), ("Cherokee", &super::script::Cherokee_table), ("Cn",
- &super::general_category::Cn_table), ("Co", &super::general_category::Co_table), ("Common",
- &super::script::Common_table), ("Coptic", &super::script::Coptic_table), ("Cuneiform",
- &super::script::Cuneiform_table), ("Cypriot", &super::script::Cypriot_table), ("Cyrillic",
- &super::script::Cyrillic_table), ("Default_Ignorable_Code_Point",
- &super::derived_property::Default_Ignorable_Code_Point_table), ("Deseret",
- &super::script::Deseret_table), ("Devanagari", &super::script::Devanagari_table),
- ("Duployan", &super::script::Duployan_table), ("Egyptian_Hieroglyphs",
- &super::script::Egyptian_Hieroglyphs_table), ("Elbasan", &super::script::Elbasan_table),
- ("Ethiopic", &super::script::Ethiopic_table), ("Georgian", &super::script::Georgian_table),
- ("Glagolitic", &super::script::Glagolitic_table), ("Gothic", &super::script::Gothic_table),
- ("Grantha", &super::script::Grantha_table), ("Greek", &super::script::Greek_table),
- ("Gujarati", &super::script::Gujarati_table), ("Gurmukhi", &super::script::Gurmukhi_table),
- ("Han", &super::script::Han_table), ("Hangul", &super::script::Hangul_table), ("Hanunoo",
- &super::script::Hanunoo_table), ("Hebrew", &super::script::Hebrew_table), ("Hiragana",
- &super::script::Hiragana_table), ("Imperial_Aramaic",
- &super::script::Imperial_Aramaic_table), ("Inherited", &super::script::Inherited_table),
- ("Inscriptional_Pahlavi", &super::script::Inscriptional_Pahlavi_table),
- ("Inscriptional_Parthian", &super::script::Inscriptional_Parthian_table), ("Javanese",
- &super::script::Javanese_table), ("Join_Control", &super::property::Join_Control_table),
- ("Kaithi", &super::script::Kaithi_table), ("Kannada", &super::script::Kannada_table),
- ("Katakana", &super::script::Katakana_table), ("Kayah_Li", &super::script::Kayah_Li_table),
- ("Kharoshthi", &super::script::Kharoshthi_table), ("Khmer", &super::script::Khmer_table),
- ("Khojki", &super::script::Khojki_table), ("Khudawadi", &super::script::Khudawadi_table),
- ("L", &super::general_category::L_table), ("LC", &super::general_category::LC_table),
- ("Lao", &super::script::Lao_table), ("Latin", &super::script::Latin_table), ("Lepcha",
- &super::script::Lepcha_table), ("Limbu", &super::script::Limbu_table), ("Linear_A",
- &super::script::Linear_A_table), ("Linear_B", &super::script::Linear_B_table), ("Lisu",
- &super::script::Lisu_table), ("Ll", &super::general_category::Ll_table), ("Lm",
- &super::general_category::Lm_table), ("Lo", &super::general_category::Lo_table),
- ("Lowercase", &super::derived_property::Lowercase_table), ("Lt",
- &super::general_category::Lt_table), ("Lu", &super::general_category::Lu_table), ("Lycian",
- &super::script::Lycian_table), ("Lydian", &super::script::Lydian_table), ("M",
- &super::general_category::M_table), ("Mahajani", &super::script::Mahajani_table),
- ("Malayalam", &super::script::Malayalam_table), ("Mandaic", &super::script::Mandaic_table),
- ("Manichaean", &super::script::Manichaean_table), ("Mc",
- &super::general_category::Mc_table), ("Me", &super::general_category::Me_table),
- ("Meetei_Mayek", &super::script::Meetei_Mayek_table), ("Mende_Kikakui",
- &super::script::Mende_Kikakui_table), ("Meroitic_Cursive",
- &super::script::Meroitic_Cursive_table), ("Meroitic_Hieroglyphs",
- &super::script::Meroitic_Hieroglyphs_table), ("Miao", &super::script::Miao_table), ("Mn",
- &super::general_category::Mn_table), ("Modi", &super::script::Modi_table), ("Mongolian",
- &super::script::Mongolian_table), ("Mro", &super::script::Mro_table), ("Myanmar",
- &super::script::Myanmar_table), ("N", &super::general_category::N_table), ("Nabataean",
- &super::script::Nabataean_table), ("Nd", &super::general_category::Nd_table),
- ("New_Tai_Lue", &super::script::New_Tai_Lue_table), ("Nko", &super::script::Nko_table),
- ("Nl", &super::general_category::Nl_table), ("No", &super::general_category::No_table),
- ("Noncharacter_Code_Point", &super::property::Noncharacter_Code_Point_table), ("Ogham",
- &super::script::Ogham_table), ("Ol_Chiki", &super::script::Ol_Chiki_table), ("Old_Italic",
- &super::script::Old_Italic_table), ("Old_North_Arabian",
- &super::script::Old_North_Arabian_table), ("Old_Permic", &super::script::Old_Permic_table),
- ("Old_Persian", &super::script::Old_Persian_table), ("Old_South_Arabian",
- &super::script::Old_South_Arabian_table), ("Old_Turkic", &super::script::Old_Turkic_table),
- ("Oriya", &super::script::Oriya_table), ("Osmanya", &super::script::Osmanya_table), ("P",
- &super::general_category::P_table), ("Pahawh_Hmong", &super::script::Pahawh_Hmong_table),
- ("Palmyrene", &super::script::Palmyrene_table), ("Pau_Cin_Hau",
- &super::script::Pau_Cin_Hau_table), ("Pc", &super::general_category::Pc_table), ("Pd",
- &super::general_category::Pd_table), ("Pe", &super::general_category::Pe_table), ("Pf",
- &super::general_category::Pf_table), ("Phags_Pa", &super::script::Phags_Pa_table),
- ("Phoenician", &super::script::Phoenician_table), ("Pi",
- &super::general_category::Pi_table), ("Po", &super::general_category::Po_table), ("Ps",
- &super::general_category::Ps_table), ("Psalter_Pahlavi",
- &super::script::Psalter_Pahlavi_table), ("Rejang", &super::script::Rejang_table), ("Runic",
- &super::script::Runic_table), ("S", &super::general_category::S_table), ("Samaritan",
- &super::script::Samaritan_table), ("Saurashtra", &super::script::Saurashtra_table), ("Sc",
- &super::general_category::Sc_table), ("Sharada", &super::script::Sharada_table), ("Shavian",
- &super::script::Shavian_table), ("Siddham", &super::script::Siddham_table), ("Sinhala",
- &super::script::Sinhala_table), ("Sk", &super::general_category::Sk_table), ("Sm",
- &super::general_category::Sm_table), ("So", &super::general_category::So_table),
- ("Sora_Sompeng", &super::script::Sora_Sompeng_table), ("Sundanese",
- &super::script::Sundanese_table), ("Syloti_Nagri", &super::script::Syloti_Nagri_table),
- ("Syriac", &super::script::Syriac_table), ("Tagalog", &super::script::Tagalog_table),
- ("Tagbanwa", &super::script::Tagbanwa_table), ("Tai_Le", &super::script::Tai_Le_table),
- ("Tai_Tham", &super::script::Tai_Tham_table), ("Tai_Viet", &super::script::Tai_Viet_table),
- ("Takri", &super::script::Takri_table), ("Tamil", &super::script::Tamil_table), ("Telugu",
- &super::script::Telugu_table), ("Thaana", &super::script::Thaana_table), ("Thai",
- &super::script::Thai_table), ("Tibetan", &super::script::Tibetan_table), ("Tifinagh",
- &super::script::Tifinagh_table), ("Tirhuta", &super::script::Tirhuta_table), ("Ugaritic",
- &super::script::Ugaritic_table), ("Uppercase", &super::derived_property::Uppercase_table),
- ("Vai", &super::script::Vai_table), ("Warang_Citi", &super::script::Warang_Citi_table),
- ("White_Space", &super::property::White_Space_table), ("XID_Continue",
- &super::derived_property::XID_Continue_table), ("XID_Start",
- &super::derived_property::XID_Start_table), ("Yi", &super::script::Yi_table), ("Z",
- &super::general_category::Z_table), ("Zl", &super::general_category::Zl_table), ("Zp",
- &super::general_category::Zp_table), ("Zs", &super::general_category::Zs_table)
- ];
-
- pub static PERLD: &'static &'static [(char, char)] = &super::general_category::Nd_table;
-
- pub static PERLS: &'static &'static [(char, char)] = &super::property::White_Space_table;
-
- pub static PERLW: &'static [(char, char)] = &[
+ pub const UNICODE_CLASSES: &'static [(&'static str, &'static [(char, char)])] = &[
+ ("Alphabetic", super::derived_property::Alphabetic_table), ("Arabic",
+ super::script::Arabic_table), ("Armenian", super::script::Armenian_table), ("Avestan",
+ super::script::Avestan_table), ("Balinese", super::script::Balinese_table), ("Bamum",
+ super::script::Bamum_table), ("Bassa_Vah", super::script::Bassa_Vah_table), ("Batak",
+ super::script::Batak_table), ("Bengali", super::script::Bengali_table), ("Bopomofo",
+ super::script::Bopomofo_table), ("Brahmi", super::script::Brahmi_table), ("Braille",
+ super::script::Braille_table), ("Buginese", super::script::Buginese_table), ("Buhid",
+ super::script::Buhid_table), ("C", super::general_category::C_table),
+ ("Canadian_Aboriginal", super::script::Canadian_Aboriginal_table), ("Carian",
+ super::script::Carian_table), ("Caucasian_Albanian",
+ super::script::Caucasian_Albanian_table), ("Cc", super::general_category::Cc_table), ("Cf",
+ super::general_category::Cf_table), ("Chakma", super::script::Chakma_table), ("Cham",
+ super::script::Cham_table), ("Cherokee", super::script::Cherokee_table), ("Cn",
+ super::general_category::Cn_table), ("Co", super::general_category::Co_table), ("Common",
+ super::script::Common_table), ("Coptic", super::script::Coptic_table), ("Cuneiform",
+ super::script::Cuneiform_table), ("Cypriot", super::script::Cypriot_table), ("Cyrillic",
+ super::script::Cyrillic_table), ("Default_Ignorable_Code_Point",
+ super::derived_property::Default_Ignorable_Code_Point_table), ("Deseret",
+ super::script::Deseret_table), ("Devanagari", super::script::Devanagari_table), ("Duployan",
+ super::script::Duployan_table), ("Egyptian_Hieroglyphs",
+ super::script::Egyptian_Hieroglyphs_table), ("Elbasan", super::script::Elbasan_table),
+ ("Ethiopic", super::script::Ethiopic_table), ("Georgian", super::script::Georgian_table),
+ ("Glagolitic", super::script::Glagolitic_table), ("Gothic", super::script::Gothic_table),
+ ("Grantha", super::script::Grantha_table), ("Greek", super::script::Greek_table),
+ ("Gujarati", super::script::Gujarati_table), ("Gurmukhi", super::script::Gurmukhi_table),
+ ("Han", super::script::Han_table), ("Hangul", super::script::Hangul_table), ("Hanunoo",
+ super::script::Hanunoo_table), ("Hebrew", super::script::Hebrew_table), ("Hiragana",
+ super::script::Hiragana_table), ("Imperial_Aramaic", super::script::Imperial_Aramaic_table),
+ ("Inherited", super::script::Inherited_table), ("Inscriptional_Pahlavi",
+ super::script::Inscriptional_Pahlavi_table), ("Inscriptional_Parthian",
+ super::script::Inscriptional_Parthian_table), ("Javanese", super::script::Javanese_table),
+ ("Join_Control", super::property::Join_Control_table), ("Kaithi",
+ super::script::Kaithi_table), ("Kannada", super::script::Kannada_table), ("Katakana",
+ super::script::Katakana_table), ("Kayah_Li", super::script::Kayah_Li_table), ("Kharoshthi",
+ super::script::Kharoshthi_table), ("Khmer", super::script::Khmer_table), ("Khojki",
+ super::script::Khojki_table), ("Khudawadi", super::script::Khudawadi_table), ("L",
+ super::general_category::L_table), ("LC", super::general_category::LC_table), ("Lao",
+ super::script::Lao_table), ("Latin", super::script::Latin_table), ("Lepcha",
+ super::script::Lepcha_table), ("Limbu", super::script::Limbu_table), ("Linear_A",
+ super::script::Linear_A_table), ("Linear_B", super::script::Linear_B_table), ("Lisu",
+ super::script::Lisu_table), ("Ll", super::general_category::Ll_table), ("Lm",
+ super::general_category::Lm_table), ("Lo", super::general_category::Lo_table), ("Lowercase",
+ super::derived_property::Lowercase_table), ("Lt", super::general_category::Lt_table), ("Lu",
+ super::general_category::Lu_table), ("Lycian", super::script::Lycian_table), ("Lydian",
+ super::script::Lydian_table), ("M", super::general_category::M_table), ("Mahajani",
+ super::script::Mahajani_table), ("Malayalam", super::script::Malayalam_table), ("Mandaic",
+ super::script::Mandaic_table), ("Manichaean", super::script::Manichaean_table), ("Mc",
+ super::general_category::Mc_table), ("Me", super::general_category::Me_table),
+ ("Meetei_Mayek", super::script::Meetei_Mayek_table), ("Mende_Kikakui",
+ super::script::Mende_Kikakui_table), ("Meroitic_Cursive",
+ super::script::Meroitic_Cursive_table), ("Meroitic_Hieroglyphs",
+ super::script::Meroitic_Hieroglyphs_table), ("Miao", super::script::Miao_table), ("Mn",
+ super::general_category::Mn_table), ("Modi", super::script::Modi_table), ("Mongolian",
+ super::script::Mongolian_table), ("Mro", super::script::Mro_table), ("Myanmar",
+ super::script::Myanmar_table), ("N", super::general_category::N_table), ("Nabataean",
+ super::script::Nabataean_table), ("Nd", super::general_category::Nd_table), ("New_Tai_Lue",
+ super::script::New_Tai_Lue_table), ("Nko", super::script::Nko_table), ("Nl",
+ super::general_category::Nl_table), ("No", super::general_category::No_table),
+ ("Noncharacter_Code_Point", super::property::Noncharacter_Code_Point_table), ("Ogham",
+ super::script::Ogham_table), ("Ol_Chiki", super::script::Ol_Chiki_table), ("Old_Italic",
+ super::script::Old_Italic_table), ("Old_North_Arabian",
+ super::script::Old_North_Arabian_table), ("Old_Permic", super::script::Old_Permic_table),
+ ("Old_Persian", super::script::Old_Persian_table), ("Old_South_Arabian",
+ super::script::Old_South_Arabian_table), ("Old_Turkic", super::script::Old_Turkic_table),
+ ("Oriya", super::script::Oriya_table), ("Osmanya", super::script::Osmanya_table), ("P",
+ super::general_category::P_table), ("Pahawh_Hmong", super::script::Pahawh_Hmong_table),
+ ("Palmyrene", super::script::Palmyrene_table), ("Pau_Cin_Hau",
+ super::script::Pau_Cin_Hau_table), ("Pc", super::general_category::Pc_table), ("Pd",
+ super::general_category::Pd_table), ("Pe", super::general_category::Pe_table), ("Pf",
+ super::general_category::Pf_table), ("Phags_Pa", super::script::Phags_Pa_table),
+ ("Phoenician", super::script::Phoenician_table), ("Pi", super::general_category::Pi_table),
+ ("Po", super::general_category::Po_table), ("Ps", super::general_category::Ps_table),
+ ("Psalter_Pahlavi", super::script::Psalter_Pahlavi_table), ("Rejang",
+ super::script::Rejang_table), ("Runic", super::script::Runic_table), ("S",
+ super::general_category::S_table), ("Samaritan", super::script::Samaritan_table),
+ ("Saurashtra", super::script::Saurashtra_table), ("Sc", super::general_category::Sc_table),
+ ("Sharada", super::script::Sharada_table), ("Shavian", super::script::Shavian_table),
+ ("Siddham", super::script::Siddham_table), ("Sinhala", super::script::Sinhala_table), ("Sk",
+ super::general_category::Sk_table), ("Sm", super::general_category::Sm_table), ("So",
+ super::general_category::So_table), ("Sora_Sompeng", super::script::Sora_Sompeng_table),
+ ("Sundanese", super::script::Sundanese_table), ("Syloti_Nagri",
+ super::script::Syloti_Nagri_table), ("Syriac", super::script::Syriac_table), ("Tagalog",
+ super::script::Tagalog_table), ("Tagbanwa", super::script::Tagbanwa_table), ("Tai_Le",
+ super::script::Tai_Le_table), ("Tai_Tham", super::script::Tai_Tham_table), ("Tai_Viet",
+ super::script::Tai_Viet_table), ("Takri", super::script::Takri_table), ("Tamil",
+ super::script::Tamil_table), ("Telugu", super::script::Telugu_table), ("Thaana",
+ super::script::Thaana_table), ("Thai", super::script::Thai_table), ("Tibetan",
+ super::script::Tibetan_table), ("Tifinagh", super::script::Tifinagh_table), ("Tirhuta",
+ super::script::Tirhuta_table), ("Ugaritic", super::script::Ugaritic_table), ("Uppercase",
+ super::derived_property::Uppercase_table), ("Vai", super::script::Vai_table),
+ ("Warang_Citi", super::script::Warang_Citi_table), ("White_Space",
+ super::property::White_Space_table), ("XID_Continue",
+ super::derived_property::XID_Continue_table), ("XID_Start",
+ super::derived_property::XID_Start_table), ("Yi", super::script::Yi_table), ("Z",
+ super::general_category::Z_table), ("Zl", super::general_category::Zl_table), ("Zp",
+ super::general_category::Zp_table), ("Zs", super::general_category::Zs_table)
+ ];
+
+ pub const PERLD: &'static [(char, char)] = super::general_category::Nd_table;
+
+ pub const PERLS: &'static [(char, char)] = super::property::White_Space_table;
+
+ pub const PERLW: &'static [(char, char)] = &[
('\u{30}', '\u{39}'), ('\u{41}', '\u{5a}'), ('\u{5f}', '\u{5f}'), ('\u{61}', '\u{7a}'),
('\u{aa}', '\u{aa}'), ('\u{b5}', '\u{b5}'), ('\u{ba}', '\u{ba}'), ('\u{c0}', '\u{d6}'),
('\u{d8}', '\u{f6}'), ('\u{f8}', '\u{2c1}'), ('\u{2c6}', '\u{2d1}'), ('\u{2e0}', '\u{2e4}'),
pub mod normalization {
// Canonical decompositions
- pub static canonical_table: &'static [(char, &'static [char])] = &[
+ pub const canonical_table: &'static [(char, &'static [char])] = &[
('\u{c0}', &['\u{41}', '\u{300}']), ('\u{c1}', &['\u{41}', '\u{301}']), ('\u{c2}',
&['\u{41}', '\u{302}']), ('\u{c3}', &['\u{41}', '\u{303}']), ('\u{c4}', &['\u{41}',
'\u{308}']), ('\u{c5}', &['\u{41}', '\u{30a}']), ('\u{c7}', &['\u{43}', '\u{327}']),
];
// Compatibility decompositions
- pub static compatibility_table: &'static [(char, &'static [char])] = &[
+ pub const compatibility_table: &'static [(char, &'static [char])] = &[
('\u{a0}', &['\u{20}']), ('\u{a8}', &['\u{20}', '\u{308}']), ('\u{aa}', &['\u{61}']),
('\u{af}', &['\u{20}', '\u{304}']), ('\u{b2}', &['\u{32}']), ('\u{b3}', &['\u{33}']),
('\u{b4}', &['\u{20}', '\u{301}']), ('\u{b5}', &['\u{3bc}']), ('\u{b8}', &['\u{20}',
];
// Canonical compositions
- pub static composition_table: &'static [(char, &'static [(char, char)])] = &[
+ pub const composition_table: &'static [(char, &'static [(char, char)])] = &[
('\u{3c}', &[('\u{338}', '\u{226e}')]), ('\u{3d}', &[('\u{338}', '\u{2260}')]), ('\u{3e}',
&[('\u{338}', '\u{226f}')]), ('\u{41}', &[('\u{300}', '\u{c0}'), ('\u{301}', '\u{c1}'),
('\u{302}', '\u{c2}'), ('\u{303}', '\u{c3}'), ('\u{304}', '\u{100}'), ('\u{306}',
}
}
- static combining_class_table: &'static [(char, char, u8)] = &[
+ const combining_class_table: &'static [(char, char, u8)] = &[
('\u{300}', '\u{314}', 230), ('\u{315}', '\u{315}', 232), ('\u{316}', '\u{319}', 220),
('\u{31a}', '\u{31a}', 232), ('\u{31b}', '\u{31b}', 216), ('\u{31c}', '\u{320}', 220),
('\u{321}', '\u{322}', 202), ('\u{323}', '\u{326}', 220), ('\u{327}', '\u{328}', 202),
}
}
- static LuLl_table: &'static [(char, char)] = &[
+ const LuLl_table: &'static [(char, char)] = &[
('\u{41}', '\u{61}'), ('\u{42}', '\u{62}'), ('\u{43}', '\u{63}'), ('\u{44}', '\u{64}'),
('\u{45}', '\u{65}'), ('\u{46}', '\u{66}'), ('\u{47}', '\u{67}'), ('\u{48}', '\u{68}'),
('\u{49}', '\u{69}'), ('\u{4a}', '\u{6a}'), ('\u{4b}', '\u{6b}'), ('\u{4c}', '\u{6c}'),
('\u{118be}', '\u{118de}'), ('\u{118bf}', '\u{118df}')
];
- static LlLu_table: &'static [(char, char)] = &[
+ const LlLu_table: &'static [(char, char)] = &[
('\u{61}', '\u{41}'), ('\u{62}', '\u{42}'), ('\u{63}', '\u{43}'), ('\u{64}', '\u{44}'),
('\u{65}', '\u{45}'), ('\u{66}', '\u{46}'), ('\u{67}', '\u{47}'), ('\u{68}', '\u{48}'),
('\u{69}', '\u{49}'), ('\u{6a}', '\u{4a}'), ('\u{6b}', '\u{4b}'), ('\u{6c}', '\u{4c}'),
// character width table. Based on Markus Kuhn's free wcwidth() implementation,
// http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c
- static charwidth_table: &'static [(char, char, u8, u8)] = &[
+ const charwidth_table: &'static [(char, char, u8, u8)] = &[
('\u{a1}', '\u{a1}', 1, 2), ('\u{a4}', '\u{a4}', 1, 2), ('\u{a7}', '\u{a8}', 1, 2),
('\u{aa}', '\u{aa}', 1, 2), ('\u{ae}', '\u{ae}', 1, 2), ('\u{b0}', '\u{b4}', 1, 2),
('\u{b6}', '\u{ba}', 1, 2), ('\u{bc}', '\u{bf}', 1, 2), ('\u{c6}', '\u{c6}', 1, 2),
bsearch_range_value_table(c, grapheme_cat_table)
}
- static grapheme_cat_table: &'static [(char, char, GraphemeCat)] = &[
+ const grapheme_cat_table: &'static [(char, char, GraphemeCat)] = &[
('\u{0}', '\u{1f}', GC_Control), ('\u{7f}', '\u{9f}', GC_Control), ('\u{ad}', '\u{ad}',
GC_Control), ('\u{300}', '\u{36f}', GC_Extend), ('\u{483}', '\u{487}', GC_Extend),
('\u{488}', '\u{489}', GC_Extend), ('\u{591}', '\u{5bd}', GC_Extend), ('\u{5bf}', '\u{5bf}',
+++ /dev/null
-// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Unicode-intensive `char` methods along with the `core` methods.
-//!
-//! These methods implement functionality for `char` that requires knowledge of
-//! Unicode definitions, including normalization, categorization, and display information.
-
-use core::char;
-use core::char::CharExt as C;
-use core::option::Option;
-use tables::{derived_property, property, general_category, conversions, charwidth};
-
-/// Functionality for manipulating `char`.
-#[stable(feature = "rust1", since = "1.0.0")]
-pub trait CharExt {
- /// Checks if a `char` parses as a numeric digit in the given radix.
- ///
- /// Compared to `is_numeric()`, this function only recognizes the characters
- /// `0-9`, `a-z` and `A-Z`.
- ///
- /// # Return value
- ///
- /// Returns `true` if `c` is a valid digit under `radix`, and `false`
- /// otherwise.
- ///
- /// # Panics
- ///
- /// Panics if given a radix > 36.
- #[unstable(feature = "unicode",
- reason = "pending integer conventions")]
- fn is_digit(self, radix: u32) -> bool;
-
- /// Converts a character to the corresponding digit.
- ///
- /// # Return value
- ///
- /// If `c` is between '0' and '9', the corresponding value between 0 and
- /// 9. If `c` is 'a' or 'A', 10. If `c` is 'b' or 'B', 11, etc. Returns
- /// none if the character does not refer to a digit in the given radix.
- ///
- /// # Panics
- ///
- /// Panics if given a radix outside the range [0..36].
- #[unstable(feature = "unicode",
- reason = "pending integer conventions")]
- fn to_digit(self, radix: u32) -> Option<u32>;
-
- /// Returns an iterator that yields the hexadecimal Unicode escape
- /// of a character, as `char`s.
- ///
- /// All characters are escaped with Rust syntax of the form `\\u{NNNN}`
- /// where `NNNN` is the shortest hexadecimal representation of the code
- /// point.
- #[stable(feature = "rust1", since = "1.0.0")]
- fn escape_unicode(self) -> char::EscapeUnicode;
-
- /// Returns an iterator that yields the 'default' ASCII and
- /// C++11-like literal escape of a character, as `char`s.
- ///
- /// The default is chosen with a bias toward producing literals that are
- /// legal in a variety of languages, including C++11 and similar C-family
- /// languages. The exact rules are:
- ///
- /// * Tab, CR and LF are escaped as '\t', '\r' and '\n' respectively.
- /// * Single-quote, double-quote and backslash chars are backslash-
- /// escaped.
- /// * Any other chars in the range [0x20,0x7e] are not escaped.
- /// * Any other chars are given hex Unicode escapes; see `escape_unicode`.
- #[stable(feature = "rust1", since = "1.0.0")]
- fn escape_default(self) -> char::EscapeDefault;
-
- /// Returns the amount of bytes this character would need if encoded in
- /// UTF-8.
- #[stable(feature = "rust1", since = "1.0.0")]
- fn len_utf8(self) -> usize;
-
- /// Returns the amount of bytes this character would need if encoded in
- /// UTF-16.
- #[stable(feature = "rust1", since = "1.0.0")]
- fn len_utf16(self) -> usize;
-
- /// Encodes this character as UTF-8 into the provided byte buffer,
- /// and then returns the number of bytes written.
- ///
- /// If the buffer is not large enough, nothing will be written into it
- /// and a `None` will be returned.
- #[unstable(feature = "unicode",
- reason = "pending decision about Iterator/Writer/Reader")]
- fn encode_utf8(self, dst: &mut [u8]) -> Option<usize>;
-
- /// Encodes this character as UTF-16 into the provided `u16` buffer,
- /// and then returns the number of `u16`s written.
- ///
- /// If the buffer is not large enough, nothing will be written into it
- /// and a `None` will be returned.
- #[unstable(feature = "unicode",
- reason = "pending decision about Iterator/Writer/Reader")]
- fn encode_utf16(self, dst: &mut [u16]) -> Option<usize>;
-
- /// Returns whether the specified character is considered a Unicode
- /// alphabetic code point.
- #[stable(feature = "rust1", since = "1.0.0")]
- fn is_alphabetic(self) -> bool;
-
- /// Returns whether the specified character satisfies the 'XID_Start'
- /// Unicode property.
- ///
- /// 'XID_Start' is a Unicode Derived Property specified in
- /// [UAX #31](http://unicode.org/reports/tr31/#NFKC_Modifications),
- /// mostly similar to ID_Start but modified for closure under NFKx.
- #[unstable(feature = "unicode",
- reason = "mainly needed for compiler internals")]
- fn is_xid_start(self) -> bool;
-
- /// Returns whether the specified `char` satisfies the 'XID_Continue'
- /// Unicode property.
- ///
- /// 'XID_Continue' is a Unicode Derived Property specified in
- /// [UAX #31](http://unicode.org/reports/tr31/#NFKC_Modifications),
- /// mostly similar to 'ID_Continue' but modified for closure under NFKx.
- #[unstable(feature = "unicode",
- reason = "mainly needed for compiler internals")]
- fn is_xid_continue(self) -> bool;
-
- /// Indicates whether a character is in lowercase.
- ///
- /// This is defined according to the terms of the Unicode Derived Core
- /// Property `Lowercase`.
- #[stable(feature = "rust1", since = "1.0.0")]
- fn is_lowercase(self) -> bool;
-
- /// Indicates whether a character is in uppercase.
- ///
- /// This is defined according to the terms of the Unicode Derived Core
- /// Property `Uppercase`.
- #[stable(feature = "rust1", since = "1.0.0")]
- fn is_uppercase(self) -> bool;
-
- /// Indicates whether a character is whitespace.
- ///
- /// Whitespace is defined in terms of the Unicode Property `White_Space`.
- #[stable(feature = "rust1", since = "1.0.0")]
- fn is_whitespace(self) -> bool;
-
- /// Indicates whether a character is alphanumeric.
- ///
- /// Alphanumericness is defined in terms of the Unicode General Categories
- /// 'Nd', 'Nl', 'No' and the Derived Core Property 'Alphabetic'.
- #[stable(feature = "rust1", since = "1.0.0")]
- fn is_alphanumeric(self) -> bool;
-
- /// Indicates whether a character is a control code point.
- ///
- /// Control code points are defined in terms of the Unicode General
- /// Category `Cc`.
- #[stable(feature = "rust1", since = "1.0.0")]
- fn is_control(self) -> bool;
-
- /// Indicates whether the character is numeric (Nd, Nl, or No).
- #[stable(feature = "rust1", since = "1.0.0")]
- fn is_numeric(self) -> bool;
-
- /// Converts a character to its lowercase equivalent.
- ///
- /// The case-folding performed is the common or simple mapping. See
- /// `to_uppercase()` for references and more information.
- ///
- /// # Return value
- ///
- /// Returns the lowercase equivalent of the character, or the character
- /// itself if no conversion is possible.
- #[unstable(feature = "unicode",
- reason = "pending case transformation decisions")]
- fn to_lowercase(self) -> char;
-
- /// Converts a character to its uppercase equivalent.
- ///
- /// The case-folding performed is the common or simple mapping: it maps
- /// one Unicode codepoint (one character in Rust) to its uppercase
- /// equivalent according to the Unicode database [1]. The additional
- /// [`SpecialCasing.txt`] is not considered here, as it expands to multiple
- /// codepoints in some cases.
- ///
- /// A full reference can be found here [2].
- ///
- /// # Return value
- ///
- /// Returns the uppercase equivalent of the character, or the character
- /// itself if no conversion was made.
- ///
- /// [1]: ftp://ftp.unicode.org/Public/UNIDATA/UnicodeData.txt
- ///
- /// [`SpecialCasing`.txt`]: ftp://ftp.unicode.org/Public/UNIDATA/SpecialCasing.txt
- ///
- /// [2]: http://www.unicode.org/versions/Unicode4.0.0/ch03.pdf#G33992
- #[unstable(feature = "unicode",
- reason = "pending case transformation decisions")]
- fn to_uppercase(self) -> char;
-
- /// Returns this character's displayed width in columns, or `None` if it is a
- /// control character other than `'\x00'`.
- ///
- /// `is_cjk` determines behavior for characters in the Ambiguous category:
- /// if `is_cjk` is `true`, these are 2 columns wide; otherwise, they are 1.
- /// In CJK contexts, `is_cjk` should be `true`, else it should be `false`.
- /// [Unicode Standard Annex #11](http://www.unicode.org/reports/tr11/)
- /// recommends that these characters be treated as 1 column (i.e.,
- /// `is_cjk` = `false`) if the context cannot be reliably determined.
- #[unstable(feature = "unicode",
- reason = "needs expert opinion. is_cjk flag stands out as ugly")]
- fn width(self, is_cjk: bool) -> Option<usize>;
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl CharExt for char {
- #[unstable(feature = "unicode",
- reason = "pending integer conventions")]
- fn is_digit(self, radix: u32) -> bool { C::is_digit(self, radix) }
- #[unstable(feature = "unicode",
- reason = "pending integer conventions")]
- fn to_digit(self, radix: u32) -> Option<u32> { C::to_digit(self, radix) }
- #[stable(feature = "rust1", since = "1.0.0")]
- fn escape_unicode(self) -> char::EscapeUnicode { C::escape_unicode(self) }
- #[stable(feature = "rust1", since = "1.0.0")]
- fn escape_default(self) -> char::EscapeDefault { C::escape_default(self) }
- #[stable(feature = "rust1", since = "1.0.0")]
- fn len_utf8(self) -> usize { C::len_utf8(self) }
- #[stable(feature = "rust1", since = "1.0.0")]
- fn len_utf16(self) -> usize { C::len_utf16(self) }
- #[unstable(feature = "unicode",
- reason = "pending decision about Iterator/Writer/Reader")]
- fn encode_utf8(self, dst: &mut [u8]) -> Option<usize> { C::encode_utf8(self, dst) }
- #[unstable(feature = "unicode",
- reason = "pending decision about Iterator/Writer/Reader")]
- fn encode_utf16(self, dst: &mut [u16]) -> Option<usize> { C::encode_utf16(self, dst) }
-
- #[stable(feature = "rust1", since = "1.0.0")]
- fn is_alphabetic(self) -> bool {
- match self {
- 'a' ... 'z' | 'A' ... 'Z' => true,
- c if c > '\x7f' => derived_property::Alphabetic(c),
- _ => false
- }
- }
-
- #[unstable(feature = "unicode",
- reason = "mainly needed for compiler internals")]
- fn is_xid_start(self) -> bool { derived_property::XID_Start(self) }
-
- #[unstable(feature = "unicode",
- reason = "mainly needed for compiler internals")]
- fn is_xid_continue(self) -> bool { derived_property::XID_Continue(self) }
-
- #[stable(feature = "rust1", since = "1.0.0")]
- fn is_lowercase(self) -> bool {
- match self {
- 'a' ... 'z' => true,
- c if c > '\x7f' => derived_property::Lowercase(c),
- _ => false
- }
- }
-
- #[stable(feature = "rust1", since = "1.0.0")]
- fn is_uppercase(self) -> bool {
- match self {
- 'A' ... 'Z' => true,
- c if c > '\x7f' => derived_property::Uppercase(c),
- _ => false
- }
- }
-
- #[stable(feature = "rust1", since = "1.0.0")]
- fn is_whitespace(self) -> bool {
- match self {
- ' ' | '\x09' ... '\x0d' => true,
- c if c > '\x7f' => property::White_Space(c),
- _ => false
- }
- }
-
- #[stable(feature = "rust1", since = "1.0.0")]
- fn is_alphanumeric(self) -> bool {
- self.is_alphabetic() || self.is_numeric()
- }
-
- #[stable(feature = "rust1", since = "1.0.0")]
- fn is_control(self) -> bool { general_category::Cc(self) }
-
- #[stable(feature = "rust1", since = "1.0.0")]
- fn is_numeric(self) -> bool {
- match self {
- '0' ... '9' => true,
- c if c > '\x7f' => general_category::N(c),
- _ => false
- }
- }
-
- #[unstable(feature = "unicode",
- reason = "pending case transformation decisions")]
- fn to_lowercase(self) -> char { conversions::to_lower(self) }
-
- #[unstable(feature = "unicode",
- reason = "pending case transformation decisions")]
- fn to_uppercase(self) -> char { conversions::to_upper(self) }
-
- #[unstable(feature = "unicode",
- reason = "needs expert opinion. is_cjk flag stands out as ugly")]
- fn width(self, is_cjk: bool) -> Option<usize> { charwidth::width(self, is_cjk) }
-}
use core::slice;
use core::str::Split;
-use u_char::CharExt as UCharExt; // conflicts with core::prelude::CharExt
+use char::CharExt as UCharExt; // conflicts with core::prelude::CharExt
use tables::grapheme::GraphemeCat;
/// An iterator over the words of a string, separated by a sequence of whitespace
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]; }
-Subproject commit b89c3f039b61edbb077771eda2ee8a718dbec7e0
+Subproject commit bff69076975642c64e76dbeaa53476bfa7212086
//! 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>,
}
}
/// 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) {
// 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);
}
};
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 {
//! 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;
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));
}
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() {
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>
// 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(),
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));
}
}
}
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)
term.err(&format!("error: {}", err)[..]);
}
- Err(box format!("{} errors occurred", n) as Box<Error>)
+ Err(err(&format!("{} errors occurred", n)))
}
}
}
//! 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>;
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,
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
}
}
// 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;
} 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));
}
}
}
pub fn parse_cmd(name: &str) -> Option<Box<Subcommand>> {
if name == "serve" {
- Some(box Serve as Box<Subcommand>)
+ Some(Box::new(Serve))
} else {
None
}
impl Term {
pub fn new() -> Term {
Term {
- err: box stdio::stderr() as Box<Writer>,
+ err: Box::new(stdio::stderr())
}
}
//! 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
}
}
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")
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))
}
}
}
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
# 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
+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
}
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 }
}
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;
}
}
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;
}
}
let mut i = *self;
while i < v {
f(i);
- i += 1_usize;
+ i += 1;
}
}
}
#[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;
}
}
// 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;
}
}
--- /dev/null
+// 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
--- /dev/null
+// 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))
+}
--- /dev/null
+// 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 }
+}
--- /dev/null
+// 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)]
+
+extern crate syntax;
+#[macro_use] extern crate rustc;
+
+use syntax::{ast, attr};
+use rustc::lint::{Context, LintPass, LintPassObject, LintArray};
+use rustc::plugin::Registry;
+
+declare_lint!(CRATE_NOT_OKAY, Warn, "crate not marked with #![crate_okay]");
+
+struct Pass;
+
+impl LintPass for Pass {
+ fn get_lints(&self) -> LintArray {
+ lint_array!(CRATE_NOT_OKAY)
+ }
+
+ fn check_crate(&mut self, cx: &Context, krate: &ast::Crate) {
+ if !attr::contains_name(&krate.attrs, "crate_okay") {
+ cx.span_lint(CRATE_NOT_OKAY, krate.span,
+ "crate is not marked with #![crate_okay]");
+ }
+ }
+}
+
+#[plugin_registrar]
+pub fn plugin_registrar(reg: &mut Registry) {
+ reg.register_lint_pass(box Pass as LintPassObject);
+}
reg.register_macro("identity", expand_identity);
reg.register_syntax_extension(
token::intern("into_foo"),
- Modifier(box expand_into_foo));
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ Modifier(Box::new(expand_into_foo)));
reg.register_syntax_extension(
token::intern("into_multi_foo"),
- MultiModifier(box expand_into_foo_multi));
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ MultiModifier(Box::new(expand_into_foo_multi)));
}
fn expand_make_a_1(cx: &mut ExtCtxt, sp: Span, tts: &[TokenTree])
#![crate_type = "dylib"]
#[macro_export]
macro_rules! reexported {
- () => ( 3_usize )
+ () => ( 3 )
}
pub fn plugin_registrar(reg: &mut Registry) {
let args = reg.args().clone();
reg.register_syntax_extension(token::intern("plugin_args"),
- NormalTT(box Expander { args: args, }, None));
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ NormalTT(Box::new(Expander { args: args, }), None, false));
}
--- /dev/null
+// 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);
+}
};
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)) => {
--- /dev/null
+// 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 }
#[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()
}
*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;
}
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();
}
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;
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);
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);
-> 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 {
}
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 {
fn search_remainder<C:TableCallback>(item: &mut Entry, key: Code, c: C) {
match item.next {
None => {
- let mut entry = box Entry {
+ let mut entry: Box<_> = box Entry {
code: key,
count: 0,
next: None,
{
if self.items[index as usize].is_none() {
- let mut entry = box Entry {
+ let mut entry: Box<_> = box Entry {
code: key,
count: 0,
next: None,
.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()
// 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);
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();
// 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));
}
}
}
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 Colors::new(start_color);
+ let mut avail: Box<_> = box Colors::new(start_color);
// drop colors already in use in neighbourhood
self.drop_colors(&mut *avail, row, col);
// 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 */
}
// 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]);
}
}
// 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);
}
}
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]
colors.remove(1);
// THEN
- assert_eq!(colors.next(), 2u8);
+ assert_eq!(colors.next(), 2);
}
#[test]
--- /dev/null
+// 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!'
+}
--- /dev/null
+// 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:lint_for_crate.rs
+// ignore-stage1
+// compile-flags: -D crate-not-okay
+
+#![feature(plugin, custom_attribute)] //~ ERROR crate is not marked with #![crate_okay]
+#![plugin(lint_for_crate)]
+
+pub fn main() { }
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
}
}
// 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`
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);
// ignore-android
-#![feature(asm)]
+#![feature(asm, rustc_attrs)]
#![allow(dead_code, non_upper_case_globals)]
#[cfg(any(target_arch = "x86",
target_arch = "x86_64"))]
-pub fn main() {
+#[rustc_error]
+pub fn main() { //~ ERROR compilation successful
// assignment not dead
let mut x: isize = 0;
unsafe {
}
assert_eq!(x, 13);
}
-
-// At least one error is needed so that compilation fails
-#[static_assert]
-static b: bool = false; //~ ERROR static assertion failed
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);
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);
}
}
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 {
}
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
}
// 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); }
// 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); }
// 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); }
// 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 {
// 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; }
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
}
}
struct Bar(isize, isize);
fn main() {
- let x = (box 1, 2);
+ let x: (Box<_>, _) = (box 1, 2);
let r = &x.0;
let y = x; //~ ERROR cannot move out of `x` because it is borrowed
}
fn implicit() {
- let mut a = box 1;
+ let mut a: Box<_> = box 1;
// Note the danger here:
//
}
fn explicit() {
- let mut a = box 1;
+ let mut a: Box<_> = box 1;
add(
&*a,
rewrite(&mut a)); //~ ERROR cannot borrow
}
fn implicit() {
- let mut a = box 1;
+ let mut a: Box<_> = box 1;
// Note the danger here:
//
}
fn explicit() {
- let mut a = box 1;
+ let mut a: Box<_> = box 1;
add(
&*a,
a); //~ ERROR cannot move
}
pub fn main() {
- let a = box A;
+ let a: Box<_> = box A;
a.foo();
//~^ ERROR cannot borrow immutable `Box` content `*a` as mutable
}
use std::collections::HashMap;
fn main() {
- let tmp;
+ let tmp: Box<_>;
let mut buggy_map: HashMap<usize, &usize> = HashMap::new();
- buggy_map.insert(42, &*box 1); //~ ERROR borrowed value does not live long enough
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ buggy_map.insert(42, &*Box::new(1)); //~ ERROR borrowed value does not live long enough
// but it is ok if we use a temporary
tmp = box 2;
}
fn copy_after_move() {
- let a = box A { x: box 0, y: 1 };
+ let a: Box<_> = box A { x: box 0, y: 1 };
let _x = a.x;
let _y = a.y; //~ ERROR use of moved
//~^^ NOTE `a` moved here (through moving `a.x`)
}
fn move_after_move() {
- let a = box B { x: box 0, y: box 1 };
+ let a: Box<_> = box B { x: box 0, y: box 1 };
let _x = a.x;
let _y = a.y; //~ ERROR use of moved
//~^^ NOTE `a` moved here (through moving `a.x`)
}
fn borrow_after_move() {
- let a = box A { x: box 0, y: 1 };
+ let a: Box<_> = box A { x: box 0, y: 1 };
let _x = a.x;
let _y = &a.y; //~ ERROR use of moved
//~^^ NOTE `a` moved here (through moving `a.x`)
}
fn move_after_borrow() {
- let a = box B { x: box 0, y: box 1 };
+ let a: Box<_> = box B { x: box 0, y: box 1 };
let _x = &a.x;
let _y = a.y; //~ ERROR cannot move
}
fn copy_after_mut_borrow() {
- let mut a = box A { x: box 0, y: 1 };
+ let mut a: Box<_> = box A { x: box 0, y: 1 };
let _x = &mut a.x;
let _y = a.y; //~ ERROR cannot use
}
fn move_after_mut_borrow() {
- let mut a = box B { x: box 0, y: box 1 };
+ let mut a: Box<_> = box B { x: box 0, y: box 1 };
let _x = &mut a.x;
let _y = a.y; //~ ERROR cannot move
}
fn borrow_after_mut_borrow() {
- let mut a = box A { x: box 0, y: 1 };
+ let mut a: Box<_> = box A { x: box 0, y: 1 };
let _x = &mut a.x;
let _y = &a.y; //~ ERROR cannot borrow
}
fn mut_borrow_after_borrow() {
- let mut a = box A { x: box 0, y: 1 };
+ let mut a: Box<_> = box A { x: box 0, y: 1 };
let _x = &a.x;
let _y = &mut a.y; //~ ERROR cannot borrow
}
fn copy_after_move_nested() {
- let a = box C { x: box A { x: box 0, y: 1 }, y: 2 };
+ let a: Box<_> = box C { x: box A { x: box 0, y: 1 }, y: 2 };
let _x = a.x.x;
let _y = a.y; //~ ERROR use of collaterally moved
}
fn move_after_move_nested() {
- let a = box D { x: box A { x: box 0, y: 1 }, y: box 2 };
+ let a: Box<_> = box D { x: box A { x: box 0, y: 1 }, y: box 2 };
let _x = a.x.x;
let _y = a.y; //~ ERROR use of collaterally moved
}
fn borrow_after_move_nested() {
- let a = box C { x: box A { x: box 0, y: 1 }, y: 2 };
+ let a: Box<_> = box C { x: box A { x: box 0, y: 1 }, y: 2 };
let _x = a.x.x;
let _y = &a.y; //~ ERROR use of collaterally moved
}
fn move_after_borrow_nested() {
- let a = box D { x: box A { x: box 0, y: 1 }, y: box 2 };
+ let a: Box<_> = box D { x: box A { x: box 0, y: 1 }, y: box 2 };
let _x = &a.x.x;
let _y = a.y; //~ ERROR cannot move
}
fn copy_after_mut_borrow_nested() {
- let mut a = box C { x: box A { x: box 0, y: 1 }, y: 2 };
+ let mut a: Box<_> = box C { x: box A { x: box 0, y: 1 }, y: 2 };
let _x = &mut a.x.x;
let _y = a.y; //~ ERROR cannot use
}
fn move_after_mut_borrow_nested() {
- let mut a = box D { x: box A { x: box 0, y: 1 }, y: box 2 };
+ let mut a: Box<_> = box D { x: box A { x: box 0, y: 1 }, y: box 2 };
let _x = &mut a.x.x;
let _y = a.y; //~ ERROR cannot move
}
fn borrow_after_mut_borrow_nested() {
- let mut a = box C { x: box A { x: box 0, y: 1 }, y: 2 };
+ let mut a: Box<_> = box C { x: box A { x: box 0, y: 1 }, y: 2 };
let _x = &mut a.x.x;
let _y = &a.y; //~ ERROR cannot borrow
}
fn mut_borrow_after_borrow_nested() {
- let mut a = box C { x: box A { x: box 0, y: 1 }, y: 2 };
+ let mut a: Box<_> = box C { x: box A { x: box 0, y: 1 }, y: 2 };
let _x = &a.x.x;
let _y = &mut a.y; //~ ERROR cannot borrow
}
// Ensure that invoking a closure counts as a unique immutable borrow
#![feature(unboxed_closures)]
-#![feature(box_syntax)]
type Fn<'a> = Box<FnMut() + 'a>;
f: Box<FnMut() + 'a>
}
+// FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
fn call<F>(mut f: F) where F: FnMut(Fn) {
- f(box || {
+ f(Box::new(|| {
//~^ ERROR: cannot borrow `f` as mutable more than once
- f(box || {})
- });
+ f((Box::new(|| {})))
+ }));
}
fn test1() {
fn test7() {
fn foo<F>(_: F) where F: FnMut(Box<FnMut(isize)>, isize) {}
let mut f = |g: Box<FnMut(isize)>, b: isize| {};
- f(box |a| {
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ f(Box::new(|a| {
foo(f);
//~^ ERROR cannot move `f` into closure because it is borrowed
//~| ERROR cannot move out of captured outer variable in an `FnMut` closure
- }, 3);
+ }), 3);
}
fn main() {}
}
fn f() {
- let mut x = box 3;
+ let mut x: Box<_> = box 3;
let c1 = || get(&*x);
*x = 5; //~ ERROR cannot assign
}
f: Box<isize>
}
- let mut x = box Foo { f: box 3 };
+ let mut x: Box<_> = box Foo { f: box 3 };
let c1 = || get(&*x.f);
*x.f = 5; //~ ERROR cannot assign to `*x.f`
}
f: Box<isize>
}
- let mut x = box Foo { f: box 3 };
+ let mut x: Box<_> = box Foo { f: box 3 };
let c1 = || get(&*x.f);
let c2 = || *x.f = 5; //~ ERROR cannot borrow `x` as mutable
}
f: Box<isize>
}
- let mut x = box Foo { f: box 3 };
+ let mut x: Box<_> = box Foo { f: box 3 };
let c1 = to_fn_mut(|| set(&mut *x.f));
let c2 = to_fn_mut(|| set(&mut *x.f));
//~^ ERROR cannot borrow `x` as mutable more than once
}
fn main() {
- let mut ptr = box Foo { x: 0 };
+ let mut ptr: Box<_> = box Foo { x: 0 };
let mut test = |foo: &Foo| {
ptr = box Foo { x: ptr.x + 1 };
};
for &a in &f.a { //~ ERROR cannot move out
}
- let x = Some(box 1);
+ let x: Option<Box<_>> = Some(box 1);
for &a in x.iter() { //~ ERROR cannot move out
}
}
fn borrow_in_var_from_var() {
let mut x: isize = 1;
- let y = box &mut x;
+ let y: Box<_> = box &mut x;
let p = &y;
let q = &***p;
**y = 2; //~ ERROR cannot assign to `**y` because it is borrowed
fn borrow_in_var_from_field() {
let mut x = A { a: 1 };
- let y = box &mut x.a;
+ let y: Box<_> = box &mut x.a;
let p = &y;
let q = &***p;
**y = 2; //~ ERROR cannot assign to `**y` because it is borrowed
#![feature(box_syntax)]
fn main() {
- let x = Some(box 1);
+ let x: Option<Box<_>> = Some(box 1);
match x {
Some(ref _y) => {
let _a = x; //~ ERROR cannot move
#![feature(box_syntax)]
fn main() {
- let x = Some(box 1);
+ let x: Option<Box<_>> = Some(box 1);
match x {
Some(ref y) => {
let _b = *y; //~ ERROR cannot move out
// In this instance, the freeze is conditional and starts before
// the mut borrow.
- let mut v = box 3;
+ let mut v: Box<_> = box 3;
let _w;
if cond() {
_w = &v;
// In this instance, the freeze and mut borrow are on separate sides
// of the if.
- let mut v = box 3;
+ let mut v: Box<_> = box 3;
let _w;
if cond() {
_w = &v;
fn loop_overarching_alias_mut() {
// In this instance, the borrow encompasses the entire loop.
- let mut v = box 3;
+ let mut v: Box<_> = box 3;
let mut x = &mut v;
**x += 1;
loop {
fn block_overarching_alias_mut() {
// In this instance, the borrow encompasses the entire closure call.
- let mut v = box 3;
+ let mut v: Box<_> = box 3;
let mut x = &mut v;
for _ in 0..3 {
borrow(&*v); //~ ERROR cannot borrow
fn loop_aliased_mut() {
// In this instance, the borrow is carried through the loop.
- let mut v = box 3;
- let mut w = box 4;
+ let mut v: Box<_> = box 3;
+ let mut w: Box<_> = box 4;
let mut _x = &w;
loop {
borrow_mut(&mut *v); //~ ERROR cannot borrow
fn while_aliased_mut() {
// In this instance, the borrow is carried through the loop.
- let mut v = box 3;
- let mut w = box 4;
+ let mut v: Box<_> = box 3;
+ let mut w: Box<_> = box 4;
let mut _x = &w;
while cond() {
borrow_mut(&mut *v); //~ ERROR cannot borrow
fn loop_aliased_mut_break() {
// In this instance, the borrow is carried through the loop.
- let mut v = box 3;
- let mut w = box 4;
+ let mut v: Box<_> = box 3;
+ let mut w: Box<_> = box 4;
let mut _x = &w;
loop {
borrow_mut(&mut *v);
fn while_aliased_mut_break() {
// In this instance, the borrow is carried through the loop.
- let mut v = box 3;
- let mut w = box 4;
+ let mut v: Box<_> = box 3;
+ let mut w: Box<_> = box 4;
let mut _x = &w;
while cond() {
borrow_mut(&mut *v);
}
fn while_aliased_mut_cond(cond: bool, cond2: bool) {
- let mut v = box 3;
- let mut w = box 4;
+ let mut v: Box<_> = box 3;
+ let mut w: Box<_> = box 4;
let mut x = &mut w;
while cond {
**x += 1;
fn pre_freeze() {
// In this instance, the freeze starts before the mut borrow.
- let mut v = box 3;
+ let mut v: Box<_> = box 3;
let _w = &v;
borrow_mut(&mut *v); //~ ERROR cannot borrow
}
fn post_freeze() {
// In this instance, the const alias starts after the borrow.
- let mut v = box 3;
+ let mut v: Box<_> = box 3;
borrow_mut(&mut *v);
let _w = &v;
}
}
fn box_imm() {
- let v = box 3;
+ let v: Box<_> = box 3;
let _w = &v;
thread::spawn(move|| {
println!("v={}", *v);
}
fn box_imm_explicit() {
- let v = box 3;
+ let v: Box<_> = box 3;
let _w = &v;
thread::spawn(move|| {
println!("v={}", *v);
}
fn box_imm() {
- let mut v = box 3;
+ let mut v: Box<_> = box 3;
borrow(&*v,
|w| { //~ ERROR cannot borrow `v` as mutable
v = box 4;
fn to_fn_once<A,F:FnOnce<A>>(f: F) -> F { f }
pub fn main() {
- let bar = box 3;
+ let bar: Box<_> = box 3;
let _g = to_fn_mut(|| {
let _h = to_fn_once(move || -> isize { *bar }); //~ ERROR cannot move out of
});
}
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
#![feature(box_syntax)]
fn main() {
- let a = box box 2;
+ let a: Box<Box<_>> = box box 2;
let b = &a;
let z = *a; //~ ERROR: cannot move out of `*a` because it is borrowed
}
fn main() {
- let t = box 3;
+ let t: Box<_> = box 3;
call_f(move|| { *t + 1 });
call_f(move|| { *t + 1 }); //~ ERROR capture of moved value
fn borrow<T>(_: &T) { }
fn different_vars_after_borrows() {
- let x1 = box 1;
+ let x1: Box<_> = box 1;
let p1 = &x1;
- let x2 = box 2;
+ let x2: Box<_> = box 2;
let p2 = &x2;
thread::spawn(move|| {
drop(x1); //~ ERROR cannot move `x1` into closure because it is borrowed
}
fn different_vars_after_moves() {
- let x1 = box 1;
+ let x1: Box<_> = box 1;
drop(x1);
- let x2 = box 2;
+ let x2: Box<_> = box 2;
drop(x2);
thread::spawn(move|| {
drop(x1); //~ ERROR capture of moved value: `x1`
}
fn same_var_after_borrow() {
- let x = box 1;
+ let x: Box<_> = box 1;
let p = &x;
thread::spawn(move|| {
drop(x); //~ ERROR cannot move `x` into closure because it is borrowed
}
fn same_var_after_move() {
- let x = box 1;
+ let x: Box<_> = box 1;
drop(x);
thread::spawn(move|| {
drop(x); //~ ERROR capture of moved value: `x`
empty
}
fn main() {
- let mut x = box cycle::node(node_ {a: box cycle::empty});
+ let mut x: Box<_> = box cycle::node(node_ {a: box cycle::empty});
// Create a cycle!
match *x {
cycle::node(ref mut y) => {
}
fn main() {
- let v = MyVec { data: vec!(box 1, box 2, box 3) };
+ let v = MyVec::<Box<_>> { data: vec!(box 1, box 2, box 3) };
let good = &v[0]; // Shouldn't fail here
let bad = v[0];
//~^ ERROR cannot move out of indexed content
#![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
}
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
}
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
};
fn borrow(_v: &isize) {}
fn local() {
- let mut v = box 3;
+ let mut v: Box<_> = box 3;
borrow(&*v);
}
}
fn aliased_imm() {
- let mut v = box 3;
+ let mut v: Box<_> = box 3;
let _w = &v;
borrow(&*v);
}
fn aliased_mut() {
- let mut v = box 3;
+ let mut v: Box<_> = box 3;
let _w = &mut v;
borrow(&*v); //~ ERROR cannot borrow `*v`
}
fn aliased_other() {
- let mut v = box 3;
- let mut w = box 4;
+ let mut v: Box<_> = box 3;
+ let mut w: Box<_> = box 4;
let _x = &mut w;
borrow(&*v);
}
fn aliased_other_reassign() {
- let mut v = box 3;
- let mut w = box 4;
+ let mut v: Box<_> = box 3;
+ let mut w: Box<_> = box 4;
let mut _x = &mut w;
_x = &mut v;
borrow(&*v); //~ ERROR cannot borrow `*v`
--- /dev/null
+// 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! foo {
+ () => {
+ #[cfg_attr(all(), unknown)] //~ ERROR `unknown` is currently unknown
+ fn foo() {}
+ }
+}
+
+foo!();
+
+fn main() {}
}
fn main() {
- let nyan = cat(0_usize);
+ let nyan = cat(0);
}
fn sleep(&self) { loop{} }
fn meow(&self) {
println!("Meow");
- meows += 1_usize; //~ ERROR unresolved name
+ meows += 1; //~ ERROR unresolved name
sleep(); //~ ERROR unresolved name
}
// 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
}
+++ /dev/null
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![feature(optin_builtin_traits)]
-
-use std::marker::Send;
-
-enum TestE {
- A
-}
-
-struct MyType;
-
-struct NotSync;
-impl !Sync for NotSync {}
-
-unsafe impl Send for TestE {}
-unsafe impl Send for MyType {}
-unsafe impl Send for (MyType, MyType) {}
-//~^ ERROR builtin traits can only be implemented on structs or enums
-
-unsafe impl Send for &'static NotSync {}
-//~^ ERROR builtin traits can only be implemented on structs or enums
-
-unsafe impl Send for [MyType] {}
-//~^ ERROR builtin traits can only be implemented on structs or enums
-
-unsafe impl Send for &'static [NotSync] {}
-//~^ ERROR builtin traits can only be implemented on structs or enums
-//~^^ ERROR conflicting implementations for trait `core::marker::Send`
-
-fn is_send<T: Send>() {}
-
-fn main() {
- is_send::<(MyType, TestE)>();
-}
--- /dev/null
+// 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() {
+}
--- /dev/null
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(optin_builtin_traits)]
+
+use std::marker::Copy;
+
+enum TestE {
+ A
+}
+
+struct MyType;
+
+struct NotSync;
+impl !Sync for NotSync {}
+
+unsafe impl Send for TestE {}
+unsafe impl Send for MyType {}
+unsafe impl Send for (MyType, MyType) {}
+//~^ ERROR E0321
+
+unsafe impl Send for &'static NotSync {}
+//~^ ERROR E0321
+
+unsafe impl Send for [MyType] {}
+//~^ ERROR E0321
+
+unsafe impl Send for &'static [NotSync] {}
+//~^ ERROR E0321
+//~| ERROR conflicting implementations
+
+fn main() {
+}
--- /dev/null
+// 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() {
+}
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() { }
// 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 };
}
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() {
--- /dev/null
+// Copyright 2012-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.
+
+// Check that an constant-evaluation underflow highlights the correct
+// spot (where the underflow occurred), while also providing the
+// overall context for what caused the evaluation.
+
+const ONE: usize = 1;
+const TWO: usize = 2;
+const LEN: usize = ONE - TWO;
+//~^ ERROR array length constant evaluation error: attempted to sub with overflow [E0250]
+
+fn main() {
+ let a: [i8; LEN] = unimplemented!();
+ //~^ NOTE for array length here
+}
--- /dev/null
+// Copyright 2012-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.
+
+// Check that an constant-evaluation underflow highlights the correct
+// spot (where the underflow occurred).
+
+const ONE: usize = 1;
+const TWO: usize = 2;
+
+fn main() {
+ let a: [i8; ONE - TWO] = unimplemented!();
+ //~^ ERROR array length constant evaluation error: attempted to sub with overflow [E0250]
+}
// Test that cross-borrowing (implicitly converting from `Box<T>` to `&T`) is
// forbidden when `T` is a trait.
-#![feature(box_syntax)]
-
struct Foo;
trait Trait { fn foo(&self) {} }
impl Trait for Foo {}
pub fn main() {
- let x: Box<Trait> = box Foo;
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let x: Box<Trait> = Box::new(Foo);
let _y: &Trait = x; //~ ERROR mismatched types
//~| expected `&Trait`
//~| found `Box<Trait>`
struct A<T>
where T : Trait,
T : Add<T::Item>
- //~^ ERROR illegal recursive type
+ //~^ ERROR unsupported cyclic reference between types/traits detected
{
data: T
}
--- /dev/null
+// 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() { }
// 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
// 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;
// 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() {}
// 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() {}
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 { }
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);
}
// Forbid assignment into a dynamically sized type.
-#![feature(box_syntax)]
-
struct Fat<T: ?Sized> {
f1: isize,
f2: &'static str,
pub fn main() {
// Assignment.
let f5: &mut Fat<ToBar> = &mut Fat { f1: 5, f2: "some str", ptr: Bar1 {f :42} };
- let z: Box<ToBar> = box Bar1 {f: 36};
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let z: Box<ToBar> = Box::new(Bar1 {f: 36});
f5.ptr = *z;
//~^ ERROR the trait `core::marker::Sized` is not implemented
}
// Forbid assignment into a dynamically sized type.
-#![feature(box_syntax)]
-
struct Fat<T: ?Sized> {
f1: isize,
f2: &'static str,
pub fn main() {
// Assignment.
let f5: &mut Fat<ToBar> = &mut Fat { f1: 5, f2: "some str", ptr: Bar1 {f :42} };
- let z: Box<ToBar> = box Bar1 {f: 36};
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let z: Box<ToBar> = Box::new(Bar1 {f: 36});
f5.ptr = Bar1 {f: 36};
//~^ ERROR mismatched types
//~| expected `ToBar`
+++ /dev/null
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <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.
-
-trait Foo {}
-
-fn foo<T: Foo + Foo>() {} //~ ERROR `Foo` already appears in the list of bounds
-
-fn main() {}
// 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() {}
// except according to those terms.
enum test {
- div_zero = 1/0, //~ERROR expected constant: attempted to divide by zero
- rem_zero = 1%0 //~ERROR expected constant: attempted remainder with a divisor of zero
+ div_zero = 1/0, //~ERROR constant evaluation error: attempted to divide by zero
+ rem_zero = 1%0 //~ERROR constant evaluation error: attempted remainder with a divisor of zero
}
fn main() {}
--- /dev/null
+// 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() {}
--- /dev/null
+// 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() {}
+++ /dev/null
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <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.
-
-#[lang="foo"] //~ ERROR language items are subject to change
-trait Foo {}
-
-extern "rust-intrinsic" { //~ ERROR intrinsics are subject to change
- fn bar();
-}
-
-extern "rust-intrinsic" fn baz() { //~ ERROR intrinsics are subject to change
-}
-
-fn main() {
-}
-
--- /dev/null
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <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 "rust-intrinsic" { //~ ERROR intrinsics are subject to change
+ fn bar();
+}
+
+extern "rust-intrinsic" fn baz() { //~ ERROR intrinsics are subject to change
+}
+
+fn main() {
+}
--- /dev/null
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <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.
+
+#[lang="foo"] //~ ERROR language items are subject to change
+trait Foo {}
+
+fn main() {
+}
--- /dev/null
+// 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.
+
+#[static_assert] //~ ERROR `#[static_assert]` is an experimental feature
+static X: bool = true;
+
+fn main() {}
// 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();
--- /dev/null
+// 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() { }
--- /dev/null
+// 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(){
+}
// 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() {}
--- /dev/null
+// 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);
+ });
+}
--- /dev/null
+// 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() { }
// except according to those terms.
// error-pattern: too big for the current
+#![allow(exceeding_bitshifts)]
fn main() {
let fat : [u8; (1<<61)+(1<<31)] = [0; (1u64<<61) as usize +(1u64<<31) as usize];
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 {
// 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
}
}
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);
}
// 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(); }
--- /dev/null
+// 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);
+}
--- /dev/null
+// 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
--- /dev/null
+// 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
+}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(box_syntax)]
-
fn test<'x>(x: &'x isize) {
- drop::<Box<for<'z> FnMut(&'z isize) -> &'z isize>>(box |z| {
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ drop::<Box<for<'z> FnMut(&'z isize) -> &'z isize>>(Box::new(|z| {
x
//~^ ERROR cannot infer an appropriate lifetime
- });
+ }));
}
fn main() {}
#![feature(box_syntax)]
fn main() {
- let x = box 1;
+ let x: Box<_> = box 1;
let f = move|| {
let _a = x;
drop(x);
}
fn main() {
- let mut ptr = box Foo { x: 0 };
+ let mut ptr: Box<_> = box Foo { x: 0 };
let mut test = |foo: &Foo| {
println!("access {}", foo.x);
ptr = box Foo { x: ptr.x + 1 };
}
fn main() {
- let closure: Box<Fn()+'static> = box || ();
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let closure: Box<Fn()+'static> = Box::new(|| ());
let test = box Test { func: closure }; //~ ERROR mismatched types
}
// except according to those terms.
fn blah() -> i32 { //~ ERROR not all control paths return a value
- 1i32
+ 1
; //~ HELP consider removing this semicolon:
}
fn main() {
let r = {
- let x = box 42;
+ let x: Box<_> = box 42;
let f = to_fn_once(move|| &x); //~ ERROR: `x` does not live long enough
f()
};
fn do_it(x: &isize) { }
fn main() {
- let x = box 22;
+ let x: Box<_> = box 22;
let f = to_fn_once(move|| do_it(&*x));
to_fn_once(move|| {
f();
{
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}
}
fn main() {
- check((3_usize, 5_usize));
+ check((3, 5));
//~^ ERROR mismatched types
//~| expected `&_`
-//~| found `(usize, usize)`
+//~| found `(_, _)`
//~| expected &-ptr
//~| found tuple
}
// 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`
//~| 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
}
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
struct Foo { a: isize, b: isize }
fn main() {
- let mut x = box Foo { a: 1, b: 2 };
+ let mut x: Box<_> = box Foo { a: 1, b: 2 };
let (a, b) = (&mut x.a, &mut x.b);
//~^ ERROR cannot borrow `x` (here through borrowing `x.b`) as mutable more than once at a time
//~^^ NOTE previous borrow of `x` occurs here (through borrowing `x.a`)
- let mut foo = box Foo { a: 1, b: 2 };
+ let mut foo: Box<_> = box Foo { a: 1, b: 2 };
let (c, d) = (&mut foo.a, &foo.b);
//~^ ERROR cannot borrow `foo` (here through borrowing `foo.b`) as immutable
//~^^ NOTE previous borrow of `foo` occurs here (through borrowing `foo.a`)
}
fn main() {
- let x = 1_usize;
+ let x = 1;
let y: Foo;
// `x { ... }` should not be interpreted as a struct literal here
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(box_syntax)]
-
fn main() {
let _foo = &[1_usize, 2] as [usize];
//~^ ERROR cast to unsized type: `&[usize; 2]` as `[usize]`
//~^^ HELP consider using an implicit coercion to `&[usize]` instead
- let _bar = box 1_usize as std::fmt::Debug;
+
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let _bar = Box::new(1_usize) as std::fmt::Debug;
//~^ ERROR cast to unsized type: `Box<usize>` as `core::fmt::Debug`
//~^^ HELP did you mean `Box<core::fmt::Debug>`?
+
let _baz = 1_usize as std::fmt::Debug;
//~^ ERROR cast to unsized type: `usize` as `core::fmt::Debug`
//~^^ HELP consider using a box or reference as appropriate
+
let _quux = [1_usize, 2] as [usize];
//~^ ERROR cast to unsized type: `[usize; 2]` as `[usize]`
//~^^ HELP consider using a box or reference as appropriate
// Test that moves of unsized values within closures are caught
// and rejected.
-#![feature(box_syntax)]
-
fn main() {
- (|| box *[0_usize].as_slice())();
- //~^ ERROR cannot move out of borrowed content
- //~^^ ERROR cannot move a value of type [usize]
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ (|| Box::new(*[0].as_slice()))();
+ //~^ ERROR the trait `core::marker::Sized` is not implemented for the type `[_]`
}
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 => {}
#[cfg(target_pointer_width = "64")]
fn main() {
let n = 0_usize;
- let a = box [&n; 0xF000000000000000_usize];
+ let a: Box<_> = box [&n; 0xF000000000000000_usize];
println!("{}", a[0xFFFFFF_usize]);
}
#[cfg(target_pointer_width = "32")]
fn main() {
let n = 0_usize;
- let a = box [&n; 0xFFFFFFFF_usize];
+ let a: Box<_> = box [&n; 0xFFFFFFFF_usize];
println!("{}", a[0xFFFFFF_usize]);
}
// 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
_ => { },
AbstractRenderer
//~^ ERROR: the trait `core::marker::Sized` is not implemented
{
- match 0_usize {
+ match 0 {
_ => unimplemented!()
}
}
}
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
}
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
> {
type P;
}
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
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(box_syntax)]
-
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 || y = 0);
- c.push(box || y = 0);
+ c.push(Box::new(|| y = 0));
+ c.push(Box::new(|| y = 0));
//~^ ERROR cannot borrow `y` as mutable more than once at a time
}
fn ufcs() {
- let mut y = 1_usize;
+ let mut y = 1;
let c = RefCell::new(vec![]);
- Push::push(&c, box || y = 0);
- Push::push(&c, box || y = 0);
+ Push::push(&c, Box::new(|| y = 0));
+ Push::push(&c, Box::new(|| y = 0));
//~^ ERROR cannot borrow `y` as mutable more than once at a time
}
#[inline(never)]
fn foo(b: &Bar) {
- b.foo(&0usize)
+ b.foo(&0)
//~^ ERROR the trait `Foo` is not implemented for the type `Bar`
}
fn main() {
let a: [isize; TUP.1];
- //~^ ERROR expected constant expr for array length: tuple index out of bounds
+ //~^ ERROR array length constant evaluation error: tuple index out of bounds
+ //~| ERROR attempted out-of-bounds tuple index
+ //~| ERROR attempted out-of-bounds tuple index
}
fn main() {
let a: [isize; STRUCT.nonexistent_field];
- //~^ ERROR expected constant expr for array length: nonexistent struct field
+ //~^ ERROR array length constant evaluation error: nonexistent struct field
+ //~| ERROR attempted access of field `nonexistent_field`
+ //~| ERROR attempted access of field `nonexistent_field`
}
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
};
}
}
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() {
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;
}
--- /dev/null
+// 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.
+
+pub struct PublicType;
+struct PrivateType;
+
+pub trait PublicTrait {
+ type Item;
+}
+
+trait PrivateTrait {
+ type Item;
+}
+
+impl PublicTrait for PublicType {
+ type Item = PrivateType; //~ ERROR private type in exported type signature
+}
+
+// OK
+impl PublicTrait for PrivateType {
+ type Item = PrivateType;
+}
+
+// OK
+impl PrivateTrait for PublicType {
+ type Item = PrivateType;
+}
+
+// OK
+impl PrivateTrait for PrivateType {
+ type Item = PrivateType;
+}
+
+fn main() {}
--- /dev/null
+// 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(());
+}
--- /dev/null
+// 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(());
+}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(box_syntax)]
-
mod my_mod {
pub struct MyStruct {
priv_field: isize
let my_struct = my_mod::MyStruct();
let _woohoo = (&my_struct).priv_field;
//~^ ERROR field `priv_field` of struct `my_mod::MyStruct` is private
- let _woohoo = (box my_struct).priv_field;
+
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let _woohoo = (Box::new(my_struct)).priv_field;
//~^ ERROR field `priv_field` of struct `my_mod::MyStruct` is private
+
(&my_struct).happyfun(); //~ ERROR method `happyfun` is private
- (box my_struct).happyfun(); //~ ERROR method `happyfun` is private
+
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ (Box::new(my_struct)).happyfun(); //~ ERROR method `happyfun` is private
let nope = my_struct.priv_field;
//~^ ERROR field `priv_field` of struct `my_mod::MyStruct` is private
}
+++ /dev/null
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// 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");
- }
-}
// except according to those terms.
#![feature(unboxed_closures)]
-#![feature(box_syntax)]
fn id<T>(t: T) -> T { t }
fn f<'r, T>(v: &'r T) -> Box<FnMut() -> T + 'r> {
- id(box || *v) //~ ERROR cannot infer
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ id(Box::new(|| *v))
+ //~^ ERROR `v` does not live long enough
+ //~| ERROR cannot move out of borrowed content
}
fn main() {
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`
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(box_syntax)]
-
trait Foo { fn foo(&self) {} }
impl Foo for u8 {}
fn main() {
- let r: Box<Foo> = box 5;
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let r: Box<Foo> = Box::new(5);
let _m: Box<Foo> = r as Box<Foo>;
//~^ ERROR `core::marker::Sized` is not implemented for the type `Foo`
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
+#![feature(rustc_attrs)]
#![allow(dead_code)]
// Matching against NaN should result in a warning
use std::f64::NAN;
-fn main() {
+#[rustc_error]
+fn main() { //~ ERROR compilation successful
let x = NAN;
match x {
NAN => {},
};
//~^^^ WARNING unmatchable NaN in pattern, use the is_nan method in a guard instead
}
-
-// At least one error is needed so that compilation fails
-#[static_assert]
-static B: bool = false; //~ ERROR static assertion failed
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
}
}
_ => ()
}
- 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`
fn take_param<T:Foo>(foo: &T) { }
fn main() {
- let x = box 3;
+ let x: Box<_> = box 3;
take_param(&x);
//~^ ERROR the trait `core::marker::Copy` is not implemented
}
fn take_param<T:Foo>(foo: &T) { }
fn a() {
- let x = box 3;
+ let x: Box<_> = box 3;
take_param(&x); //~ ERROR `core::marker::Copy` is not implemented
}
fn b() {
- let x = box 3;
+ let x: Box<_> = box 3;
let y = &x;
let z = &x as &Foo; //~ ERROR `core::marker::Copy` is not implemented
}
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
}
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}
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
}
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 };
}
//
// 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
#![feature(box_syntax)]
fn main() {
- let x = box 5;
+ let x: Box<_> = box 5;
let y = x;
println!("{}", *x); //~ ERROR use of moved value: `*x`
y.clone();
extern crate macro_non_reexport_2;
fn main() {
- assert_eq!(reexported!(), 3_usize); //~ ERROR macro undefined
+ assert_eq!(reexported!(), 3); //~ ERROR macro undefined
}
extern crate macro_reexport_1;
fn main() {
- assert_eq!(reexported!(), 3_usize); //~ ERROR macro undefined
+ assert_eq!(reexported!(), 3); //~ ERROR macro undefined
}
--- /dev/null
+// 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;
// option. This file may not be copied, modified, or distributed
// except according to those terms.
+#![feature(plugin)]
#![plugin] //~ ERROR malformed plugin attribute
fn main() {}
// 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() {}
// 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() {}
fn main() {
let x: Box<HashMap<isize, isize>> = box HashMap::new();
let x: Box<Map<isize, isize>> = x;
- let y: Box<Map<usize, isize>> = box x;
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let y: Box<Map<usize, isize>> = Box::new(x);
//~^ ERROR the trait `Map<usize, isize>` is not implemented
}
//~| 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
}
#![feature(box_syntax)]
pub fn main() {
- let x = box 1;
+ let x: Box<_> = box 1;
let v = (1, 2);
#![feature(box_syntax)]
pub fn main() {
- let x = box 1;
+ let x: Box<_> = box 1;
let v = (1, 2);
struct Foo(Box<isize>);
fn main() {
- let x = (box 1,);
+ let x: (Box<_>,) = (box 1,);
let y = x.0;
let z = x.0; //~ ERROR use of moved value: `x.0`
// bound must be noncopyable. For details see
// http://smallcultfollowing.com/babysteps/blog/2013/04/30/the-case-of-the-recurring-closure/
-#![feature(box_syntax)]
#![feature(unboxed_closures)]
struct R<'a> {
}
fn conspirator<F>(mut f: F) where F: FnMut(&mut R, bool) {
- let mut r = R {c: box f};
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let mut r = R {c: Box::new(f)};
f(&mut r, false) //~ ERROR use of moved value
}
fn f(_: &mut isize) {}
fn main() {
- let mut x = box 3;
+ let mut x: Box<_> = box 3;
f(x) //~ ERROR mismatched types
}
// 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;
}
fn main() {
- let nyan : cat = cat(52_usize, 99);
+ let nyan : cat = cat(52, 99);
nyan.eat();
}
}
fn main() {
- let nyan : cat = cat(52_usize, 99);
+ let nyan : cat = cat(52, 99);
nyan.how_hungry = 0; //~ ERROR cannot assign
}
fn main() {
fn bar(n: isize) {
let _x: [isize; n];
- //~^ ERROR expected constant expr for array length: non-constant path in constant expr
+ //~^ ERROR no type for local variable
+ //~| ERROR array length constant evaluation error: non-constant path in constant expr
}
}
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]) } => ()
}
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
+#![feature(static_assert)]
#![allow(dead_code)]
#[static_assert]
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) => { } } }
--- /dev/null
+// 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() {}
// 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;
// except according to those terms.
// aux-build:privacy-tuple-struct.rs
-// ignore-fast
extern crate "privacy-tuple-struct" as other;
}
fn main() {
- let nyan : kitties::cat = kitties::cat(52_usize, 99);
+ let nyan : kitties::cat = kitties::cat(52, 99);
nyan.nap();
}
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
}
//~^ 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
}
// Test that attempts to implicitly coerce a value into an
// object respect the lifetime bound on the object type.
-#![feature(box_syntax)]
-
trait Foo : ::std::marker::MarkerTrait {}
impl<'a> Foo for &'a [u8] {}
+// FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+
fn a(v: &[u8]) -> Box<Foo + 'static> {
- let x: Box<Foo + 'static> = box v; //~ ERROR does not fulfill the required lifetime
+ let x: Box<Foo + 'static> = Box::new(v);
+ //~^ ERROR cannot infer an appropriate lifetime due to conflicting
x
}
fn b(v: &[u8]) -> Box<Foo + 'static> {
- box v //~ ERROR does not fulfill the required lifetime
+ Box::new(v)
+ //~^ ERROR cannot infer an appropriate lifetime due to conflicting
}
fn c(v: &[u8]) -> Box<Foo> {
// same as previous case due to RFC 599
- box v //~ ERROR does not fulfill the required lifetime
+ Box::new(v)
+ //~^ ERROR cannot infer an appropriate lifetime due to conflicting
}
fn d<'a,'b>(v: &'a [u8]) -> Box<Foo+'b> {
- box v //~ ERROR does not fulfill the required lifetime
+ Box::new(v)
+ //~^ ERROR cannot infer an appropriate lifetime due to conflicting
}
fn e<'a:'b,'b>(v: &'a [u8]) -> Box<Foo+'b> {
- box v // OK, thanks to 'a:'b
+ Box::new(v) // OK, thanks to 'a:'b
}
fn main() { }
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
}
}
pub fn chase_cat(&mut self) {
let _f = || {
let p: &'static mut usize = &mut self.food; //~ ERROR cannot infer
- *p = 3_usize;
+ *p = 3;
};
}
}
#![feature(box_syntax)]
+// FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+
use std::marker::MarkerTrait;
trait X : MarkerTrait {}
fn bad1<T: Iter>(v: T) -> Box<X+'static>
{
let item = v.into_item();
- box item //~ ERROR associated type `<T as Iter>::Item` may not live long enough
+ Box::new(item) //~ ERROR associated type `<T as Iter>::Item` may not live long enough
}
fn bad2<T: Iter>(v: T) -> Box<X+'static>
where Box<T::Item> : X
{
- let item = box v.into_item();
- box item //~ ERROR associated type `<T as Iter>::Item` may not live long enough
+ let item: Box<_> = box v.into_item();
+ Box::new(item) //~ ERROR associated type `<T as Iter>::Item` may not live long enough
}
fn bad3<'a, T: Iter>(v: T) -> Box<X+'a>
{
let item = v.into_item();
- box item //~ ERROR associated type `<T as Iter>::Item` may not live long enough
+ Box::new(item) //~ ERROR associated type `<T as Iter>::Item` may not live long enough
}
fn bad4<'a, T: Iter>(v: T) -> Box<X+'a>
where Box<T::Item> : X
{
- let item = box v.into_item();
- box item //~ ERROR associated type `<T as Iter>::Item` may not live long enough
+ let item: Box<_> = box v.into_item();
+ Box::new(item) //~ ERROR associated type `<T as Iter>::Item` may not live long enough
}
fn ok1<'a, T: Iter>(v: T) -> Box<X+'a>
where T::Item : 'a
{
let item = v.into_item();
- box item // OK, T::Item : 'a is declared
+ Box::new(item) // OK, T::Item : 'a is declared
}
fn ok2<'a, T: Iter>(v: &T, w: &'a T::Item) -> Box<X+'a>
where T::Item : Clone
{
let item = Clone::clone(w);
- box item // OK, T::Item : 'a is implied
+ Box::new(item) // OK, T::Item : 'a is implied
}
fn ok3<'a, T: Iter>(v: &'a T) -> Box<X+'a>
where T::Item : Clone + 'a
{
let item = Clone::clone(v.as_item());
- box item // OK, T::Item : 'a was declared
+ Box::new(item) // OK, T::Item : 'a was declared
}
fn meh1<'a, T: Iter>(v: &'a T) -> Box<X+'a>
// T::Item`. But we're not that smart at present.
let item = Clone::clone(v.as_item());
- box item //~ ERROR associated type `<T as Iter>::Item` may not live
+ Box::new(item) //~ ERROR associated type `<T as Iter>::Item` may not live
}
fn main() {}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(box_syntax)]
+// FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
trait X { fn foo(&self) {} }
fn p1<T>(v: T) -> Box<X+'static>
where T : X
{
- box v //~ ERROR parameter type `T` may not live long enough
+ Box::new(v) //~ ERROR parameter type `T` may not live long enough
}
fn p2<T>(v: Box<T>) -> Box<X+'static>
where Box<T> : X
{
- box v //~ ERROR parameter type `T` may not live long enough
+ Box::new(v) //~ ERROR parameter type `T` may not live long enough
}
fn p3<'a,T>(v: T) -> Box<X+'a>
where T : X
{
- box v //~ ERROR parameter type `T` may not live long enough
+ Box::new(v) //~ ERROR parameter type `T` may not live long enough
}
fn p4<'a,T>(v: Box<T>) -> Box<X+'a>
where Box<T> : X
{
- box v //~ ERROR parameter type `T` may not live long enough
+ Box::new(v) //~ ERROR parameter type `T` may not live long enough
}
fn main() {}
}
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);
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(box_syntax)]
+// FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
fn ignore<T>(t: T) {}
let y = 3;
let mut ay = &y;
- ignore::<Box<for<'z> FnMut(&'z isize)>>(box |z| {
+ ignore::<Box<for<'z> FnMut(&'z isize)>>(Box::new(|z| {
ay = x; //~ ERROR cannot infer
ay = &y;
ay = z;
- });
+ }));
- ignore::< Box<for<'z> FnMut(&'z isize) -> &'z isize>>(box |z| {
+ ignore::< Box<for<'z> FnMut(&'z isize) -> &'z isize>>(Box::new(|z| {
if false { return x; } //~ ERROR cannot infer an appropriate lifetime for automatic
if false { return ay; }
return z;
- });
+ }));
}
fn main() {}
// 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,) => {
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(box_syntax)]
+// FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
fn borrowed_proc<'a>(x: &'a isize) -> Box<FnMut()->(isize) + 'a> {
// This is legal, because the region bound on `proc`
// states that it captures `x`.
- box move|| { *x }
+ Box::new(move|| { *x })
}
fn static_proc(x: &isize) -> Box<FnMut()->(isize) + 'static> {
// This is illegal, because the region bound on `proc` is 'static.
- box move|| { *x } //~ ERROR cannot infer
+ Box::new(move|| { *x }) //~ ERROR captured variable `x` does not outlive the enclosing closure
}
fn main() { }
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();
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(box_syntax)]
#![feature(unboxed_closures)]
struct closure_box<'a> {
}
fn main() {
- let cl_box = {
+ let mut cl_box = {
let mut i = 3;
- box_it(box || i += 1) //~ ERROR cannot infer
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ box_it(Box::new(|| i += 1)) //~ ERROR `i` does not live long enough
};
cl_box.cl.call_mut(());
}
}
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);
}
--- /dev/null
+// 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!();
+}
fn main() {
let bad = {
let x = 1;
- let y = &x;
+ let y = &x; //~ ERROR `x` does not live long enough
- thread::scoped(|| { //~ ERROR cannot infer an appropriate lifetime
+ thread::scoped(|| {
+ //~^ ERROR `y` does not live long enough
let _z = y;
})
};
--- /dev/null
+// 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() {}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
+#![feature(static_assert)]
#![allow(dead_code)]
#[static_assert]
// option. This file may not be copied, modified, or distributed
// except according to those terms.
+#![feature(static_assert)]
#![allow(dead_code)]
#[static_assert]
fn f<T:'static>(_: T) {}
fn main() {
- let x = box 3;
+ let x: Box<_> = box 3;
f(x);
let x = &3; //~ ERROR borrowed value does not live long enough
f(x);
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,
};
}
fn f() -> isize { return g(); }
-fn g() -> usize { return 0_usize; }
+fn g() -> usize { return 0; }
fn main() { let y = f(); }
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(box_syntax)]
-
struct Struct {
person: &'static str
}
}
fn main() {
- let s: Box<Trait<isize>> = box Struct { person: "Fred" };
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let s: Box<Trait<isize>> = Box::new(Struct { person: "Fred" });
//~^ ERROR the trait `Trait<isize>` is not implemented for the type `Struct`
s.f(1);
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(box_syntax)]
-
struct Struct {
person: &'static str
}
fn main() {
let person = "Fred".to_string();
let person: &str = &person; //~ ERROR `person` does not live long enough
- let s: Box<Trait<&'static str>> = box Struct { person: person };
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let s: Box<Trait<&'static str>> = Box::new(Struct { person: person });
}
--- /dev/null
+// 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() {
+}
--- /dev/null
+// 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() { }
}
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() {}
--- /dev/null
+// 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
+}
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 `(_, _)`
}
// 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`
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);
}
--- /dev/null
+// 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() { }
#![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() {}
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);
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);
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(box_syntax)]
#![feature(unboxed_closures)]
// Tests that we can't move out of an unboxed closure environment
fn to_fn_mut<A,F:FnMut<A>>(f: F) -> F { f }
fn to_fn_once<A,F:FnOnce<A>>(f: F) -> F { f }
+// FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+
fn main() {
// By-ref cases
{
- let x = box 0_usize;
+ let x = Box::new(0);
let f = to_fn(|| drop(x)); //~ ERROR cannot move
}
{
- let x = box 0_usize;
+ let x = Box::new(0);
let f = to_fn_mut(|| drop(x)); //~ ERROR cannot move
}
{
- let x = box 0_usize;
+ let x = Box::new(0);
let f = to_fn_once(|| drop(x)); // OK -- FnOnce
}
// By-value cases
{
- let x = box 0_usize;
+ let x = Box::new(0);
let f = to_fn(move || drop(x)); //~ ERROR cannot move
}
{
- let x = box 0_usize;
+ let x = Box::new(0);
let f = to_fn_mut(move || drop(x)); //~ ERROR cannot move
}
{
- let x = box 0_usize;
+ let x = Box::new(0);
let f = to_fn_once(move || drop(x)); // this one is ok
}
}
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
// reference cannot escape the region of that variable.
fn main() {
let _f = {
- let x = 0_usize;
- || x //~ ERROR cannot infer an appropriate lifetime due to conflicting requirements
+ let x = 0;
+ || x //~ ERROR `x` does not live long enough
};
}
// 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
}
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
}
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
});
}
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
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(box_syntax)]
-
#[derive(Debug)]
struct r {
b: bool,
}
fn main() {
- let i = box r { b: true };
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let i = Box::new(r { b: true });
let _j = i.clone(); //~ ERROR not implement
println!("{:?}", i);
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(box_syntax)]
-
use std::rc::Rc;
fn f<T:Send>(__isize: T) {
}
fn main() {
- let i = box Rc::new(100);
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let i = Box::new(Rc::new(100));
f(i);
//~^ ERROR `core::marker::Send` is not implemented
}
#![feature(unsafe_destructor)]
-#![feature(box_syntax)]
-
use std::cell::Cell;
#[derive(Debug)]
fn main() {
let i1 = &Cell::new(0);
let i2 = &Cell::new(1);
- let r1 = vec!(box r { i: i1 });
- let r2 = vec!(box r { i: i2 });
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let r1 = vec!(Box::new(r { i: i1 }));
+ let r2 = vec!(Box::new(r { i: i2 }));
f(clone(&r1), clone(&r2));
//~^ ERROR the trait `core::clone::Clone` is not implemented for the type
//~^^ ERROR the trait `core::clone::Clone` is not implemented for the type
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) => { } } }
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;
}
+++ /dev/null
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <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 bounds are sized-compatible.
-
-trait T : Sized {}
-fn f<Y: ?Sized + T>() {
-//~^ERROR incompatible bounds on `Y`, bound `T` does not allow unsized type
-}
-
-pub fn main() {
-}
}
fn main() {
- let n = box Number { n: 42 };
- let mut l = box List { list: Vec::new() };
+ let n: Box<_> = box Number { n: 42 };
+ let mut l: Box<_> = box List { list: Vec::new() };
l.push(n);
let x = n.to_string();
//~^ ERROR: use of moved value: `n`
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);
}
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
}
}
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() { () }
let stack_val_interior_ref_2: &f64 = &stack_val.y;
let ref_to_unnamed: &SomeStruct = &SomeStruct { x: 11, y: 24.5 };
- let unique_val = box SomeStruct { x: 13, y: 26.5 };
+ let unique_val: Box<_> = box SomeStruct { x: 13, y: 26.5 };
let unique_val_ref: &SomeStruct = &*unique_val;
let unique_val_interior_ref_1: &int = &unique_val.x;
let unique_val_interior_ref_2: &f64 = &unique_val.y;
fn main() {
- let unique = box StructWithSomePadding { x: 99, y: 999, z: 9999, w: 99999 };
+ let unique: Box<_> = box StructWithSomePadding { x: 99, y: 999, z: 9999, w: 99999 };
- let unique_dtor = box StructWithDestructor { x: 77, y: 777, z: 7777, w: 77777 };
+ let unique_dtor: Box<_> = box StructWithDestructor { x: 77, y: 777, z: 7777, w: 77777 };
zzz(); // #break
}
fn main() {
some_generic_fun(0.5f64, 10);
- some_generic_fun(&29, box 110);
+ some_generic_fun(&29, Box::new(110));
}
fn zzz() { () }
--- /dev/null
+// 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;
+}
--- /dev/null
+// 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);
+
+}
--- /dev/null
+// 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() {()}
let _ = stack.self_by_ref(-1, 2_u16);
let _ = stack.self_by_val(-3, -4_i16);
- let owned = box Struct { x: 1234.5f64 };
+ let owned: Box<_> = box Struct { x: 1234.5f64 };
let _ = owned.self_by_ref(-5, -6_i32);
let _ = owned.self_by_val(-7, -8_i64);
let _ = owned.self_owned(-9, -10.5_f32);
let _ = stack.self_by_ref(-1, -2);
let _ = stack.self_by_val(-3, -4);
- let owned = box Enum::Variant1{ x: 1799, y: 1799 };
+ let owned: Box<_> = box Enum::Variant1{ x: 1799, y: 1799 };
let _ = owned.self_by_ref(-5, -6);
let _ = owned.self_by_val(-7, -8);
let _ = owned.self_owned(-9, -10);
let _ = stack.self_by_ref(-1, -2);
let _ = stack.self_by_val(-3, -4);
- let owned = box Struct { x: 1234.5f64 };
+ let owned: Box<_> = box Struct { x: 1234.5f64 };
let _ = owned.self_by_ref(-5, -6);
let _ = owned.self_by_val(-7, -8);
let _ = owned.self_owned(-9, -10);
let _ = stack.self_by_ref(-1, -2);
let _ = stack.self_by_val(-3, -4);
- let owned = box Struct { x: 200 };
+ let owned: Box<_> = box Struct { x: 200 };
let _ = owned.self_by_ref(-5, -6);
let _ = owned.self_by_val(-7, -8);
let _ = owned.self_owned(-9, -10);
let _ = stack.self_by_ref(-1, -2);
let _ = stack.self_by_val(-3, -4);
- let owned = box Struct { x: 200 };
+ let owned: Box<_> = box Struct { x: 200 };
let _ = owned.self_by_ref(-5, -6);
let _ = owned.self_by_val(-7, -8);
let _ = owned.self_owned(-9, -10);
let _ = stack.self_by_ref(-1, -2);
let _ = stack.self_by_val(-3, -4);
- let owned = box TupleStruct(200, -200.5);
+ let owned: Box<_> = box TupleStruct(200, -200.5);
let _ = owned.self_by_ref(-5, -6);
let _ = owned.self_by_val(-7, -8);
let _ = owned.self_owned(-9, -10);
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 {
let _ = stack.self_by_ref(-1, -2);
let _ = stack.self_by_val(-3, -4);
- let owned = box Struct { x: 200 };
+ let owned: Box<_> = box Struct { x: 200 };
let _ = owned.self_by_ref(-5, -6);
let _ = owned.self_by_val(-7, -8);
let _ = owned.self_owned(-9, -10);
let _ = stack.self_by_ref(-1, 2_u16);
let _ = stack.self_by_val(-3, -4_i16);
- let owned = box Struct { x: 879 };
+ let owned: Box<_> = box Struct { x: 879 };
let _ = owned.self_by_ref(-5, -6_i32);
let _ = owned.self_by_val(-7, -8_i64);
let _ = owned.self_owned(-9, -10.5_f32);
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);
// 0b01111100011111000111110001111100 = 2088533116
// 0b0111110001111100 = 31868
// 0b01111100 = 124
- let the_a = box ABC::TheA { x: 0, y: 8970181431921507452 };
+ let the_a: Box<_> = box ABC::TheA { x: 0, y: 8970181431921507452 };
// 0b0001000100010001000100010001000100010001000100010001000100010001 = 1229782938247303441
// 0b00010001000100010001000100010001 = 286331153
// 0b0001000100010001 = 4369
// 0b00010001 = 17
- let the_b = box ABC::TheB (0, 286331153, 286331153);
+ let the_b: Box<_> = box ABC::TheB (0, 286331153, 286331153);
- let univariant = box Univariant::TheOnlyCase(123234);
+ let univariant: Box<_> = box Univariant::TheOnlyCase(123234);
zzz(); // #break
}
};
let struct_ref = &a_struct;
- let owned = box 6;
+ let owned: Box<_> = box 6;
let mut closure = || {
let closure_local = 8;
c: 4
};
- let owned = box 5;
+ let owned: Box<_> = box 5;
let closure = move || {
zzz(); // #break
};
let struct_ref = &a_struct;
- let owned = box 6;
+ let owned: Box<_> = box 6;
{
let mut first_closure = || {
// 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() {
}
fn main() {
- let nyan = cat(0us);
+ let nyan = cat(0);
}
// 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
}
// 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
// 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
;
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
}
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
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);
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);
fn a() -> uint {
- 1usize
+ 1
}
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]);
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");
}
}
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)
}
}
}
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!();
});
// 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) {
}
}
-fn main() { foo(3_usize); }
+fn main() { foo(3); }
--- /dev/null
+// 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.
+
+// error-pattern:thread '<main>' panicked at 'arithmetic operation overflowed'
+// compile-flags: -C debug-assertions
+
+// (Work around constant-evaluation)
+fn value() -> u8 { 200 }
+
+fn main() {
+ let _x = value() + value() + value();
+}
--- /dev/null
+// 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.
+
+// error-pattern:thread '<main>' panicked at 'arithmetic operation overflowed'
+// compile-flags: -C debug-assertions
+
+// (Work around constant-evaluation)
+fn value() -> u8 { 200 }
+
+fn main() {
+ let x = value() * 4;
+}
--- /dev/null
+// 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.
+
+// error-pattern:thread '<main>' panicked at 'arithmetic operation overflowed'
+// compile-flags: -C debug-assertions
+
+// (Work around constant-evaluation)
+fn value() -> u8 { 42 }
+
+fn main() {
+ let _x = value() - (value() + 1);
+}
// error-pattern:panicked at 'Box<Any>'
-#![allow(unknown_features)]
-#![feature(box_syntax)]
-
fn main() {
- panic!(box 612_i64);
+ panic!(Box::new(612_i64));
}
// ignore-pretty: does not work well with `--test`
#[test]
-#[should_fail(expected = "foobar")]
+#[should_panic(expected = "foobar")]
fn test_foo() {
panic!("blah")
}
// error-pattern: panic
-#![allow(unknown_features)]
-#![feature(box_syntax)]
-
-fn main() { box panic!(); }
+fn main() { Box::new(panic!()); }
// error-pattern:fail
-#![allow(unknown_features)]
-#![feature(box_syntax)]
-
fn failfn() {
panic!();
}
fn main() {
- box 0;
+ Box::new(0);
failfn();
}
--- /dev/null
+-include ../tools.mk
+
+all:
+ $(rustc) -o foo foo.rs
--- /dev/null
+// 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() {
+}
--- /dev/null
+-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
--- /dev/null
+// 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);
+}
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;
// 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];
}
use rustc_driver::driver::{compile_input, CompileController};
use syntax::diagnostics::registry::Registry;
+use std::path::PathBuf;
+
fn main() {
let src = r#"
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();
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);
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();
// 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;
}
let x = 32.0f32;
let _ = (x + ((x * x) + 1.0).sqrt()).ln();
- let s: Box<SomeTrait> = box some_fields {field1: 43};
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let s: Box<SomeTrait> = Box::new(some_fields {field1: 43});
let s2: Box<some_fields> = box some_fields {field1: 43};
- let s3 = box nofields;
+ let s3: Box<_> = box nofields;
s.Method(43);
s3.Method(43);
}
fn main() { // foo
- let s = box some_fields {field1: 43};
+ let s: Box<_> = box some_fields {field1: 43};
hello((43, "a".to_string()), *s);
sub::sub2::hello();
sub2::sub3::hello();
pub fn dummy() {
// force the vtable to be created
- let _x = &1_usize as &Foo;
+ let _x = &1 as &Foo;
}
.arg(format!("{} {}",
rustc,
main_file.as_str()
- .unwrap()).as_slice())
+ .unwrap()))
.output().unwrap();
let err = String::from_utf8_lossy(result.error.as_slice());
use rustc_driver::{driver, CompilerCalls, Compilation};
use syntax::diagnostics;
+use std::path::PathBuf;
struct TestCalls {
count: u32
_: &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)
}
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");
}
--- /dev/null
+// 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);
+}
--- /dev/null
+// 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:lint_for_crate.rs
+// ignore-stage1
+// compile-flags: -D crate-not-okay
+
+#![feature(plugin, custom_attribute)]
+#![plugin(lint_for_crate)]
+#![crate_okay]
+
+pub fn main() { }
// aux-build:macro_crate_test.rs
// ignore-stage1
-#![feature(plugin)]
+#![feature(plugin, custom_attribute)]
#![plugin(macro_crate_test)]
#[macro_use] #[no_link]
--- /dev/null
+// 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);
+}
-// 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.
//
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,
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() {
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(box_syntax)]
-
static mut DROP_RAN: bool = false;
struct Foo;
pub fn main() {
{
- let _x: Box<Fat<Trait>> = box Fat { f: Foo };
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let _x: Box<Fat<Trait>> = Box::<Fat<Foo>>::new(Fat { f: Foo });
}
unsafe {
assert!(DROP_RAN);
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(box_syntax)]
-
static mut DROP_RAN: int = 0;
struct Foo;
pub fn main() {
{
- let _x: Box<Fat<[Foo]>> = box Fat { f: [Foo, Foo, Foo] };
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let _x: Box<Fat<[Foo]>> = Box::<Fat<[Foo; 3]>>::new(Fat { f: [Foo, Foo, Foo] });
}
unsafe {
assert!(DROP_RAN == 3);
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>); }
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![allow(unknown_features)]
-#![feature(box_syntax)]
-
#[derive(PartialEq, Debug)]
struct Point { x : int }
pub fn main() {
assert_eq!(14,14);
assert_eq!("abc".to_string(),"abc".to_string());
- assert_eq!(box Point{x:34},box Point{x:34});
+ assert_eq!(Box::new(Point{x:34}),Box::new(Point{x:34}));
assert_eq!(&Point{x:34},&Point{x:34});
}
}
#[derive(PartialEq)]
-struct Bar;
+pub struct Bar;
impl Foo for int {
type A = uint;
fn main() {
let x = get(22);
- assert_eq!(22_usize, x);
+ assert_eq!(22, x);
}
fn main() {
let v = vec!(1, 2, 3, 4, 5, 6);
- let r = pairwise_sub(box v.into_iter());
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let r = pairwise_sub(Box::new(v.into_iter()));
assert_eq!(r, 9);
}
fn boo(&self) -> <Self as Foo>::A;
}
-struct Bar;
+pub struct Bar;
impl Foo for char {
type A = Bar;
}
#[derive(PartialEq)]
-struct Bar;
+pub struct Bar;
impl Foo for int {
type A = uint;
pub fn main() {
let a = 42;
- assert!(foo2(a) == 42_usize);
+ assert!(foo2(a) == 42);
let a = Bar;
assert!(foo2(a) == 43);
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));
}
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));
}
}
pub fn main() {
- let z: uint = bar(2, 4_usize);
+ let z: uint = bar(2, 4);
}
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;
}
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 as Box<double>);
- assert_eq!(x.double(), 6_usize);
+ let x: Box<_> = box() (box 3 as Box<double>);
+ assert_eq!(x.double(), 6);
}
}
impl double for Box<uint> {
- fn double(self) -> uint { *self * 2_usize }
+ fn double(self) -> uint { *self * 2 }
}
pub fn main() {
- let x = box 3_usize;
- assert_eq!(x.double(), 6_usize);
+ let x: Box<_> = box 3;
+ assert_eq!(x.double(), 6);
}
}
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 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);
}
}
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<_>> = box box 3;
+ assert_eq!(x.double(), 6);
}
}
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 3_usize;
- assert_eq!(x.double(), 6_usize);
+ let x: Box<_> = box 3;
+ assert_eq!(x.double(), 6);
}
}
pub fn main() {
- let x = box 3_usize;
+ let x: Box<_> = box 3;
assert_eq!(x.foo(), "box 3".to_string());
}
}
#[inline(never)]
-fn inner(counter: &mut u32, main_pos: Pos, outer_pos: Pos) {
+fn inner(counter: &mut i32, main_pos: Pos, outer_pos: Pos) {
check!(counter; main_pos, outer_pos);
check!(counter; main_pos, outer_pos);
let inner_pos = pos!(); aux::callback(|aux_pos| {
}
#[inline(always)]
-fn inner_inlined(counter: &mut u32, main_pos: Pos, outer_pos: Pos) {
+fn inner_inlined(counter: &mut i32, main_pos: Pos, outer_pos: Pos) {
check!(counter; main_pos, outer_pos);
check!(counter; main_pos, outer_pos);
#[inline(always)]
- fn inner_further_inlined(counter: &mut u32, main_pos: Pos, outer_pos: Pos, inner_pos: Pos) {
+ fn inner_further_inlined(counter: &mut i32, main_pos: Pos, outer_pos: Pos, inner_pos: Pos) {
check!(counter; main_pos, outer_pos, inner_pos);
}
inner_further_inlined(counter, main_pos, outer_pos, pos!());
}
#[inline(never)]
-fn outer(mut counter: u32, main_pos: Pos) {
+fn outer(mut counter: i32, main_pos: Pos) {
inner(&mut counter, main_pos, pos!());
inner_inlined(&mut counter, main_pos, pos!());
}
"bad output: {}", s);
// Make sure the stack trace is *not* printed
- let p = template.clone().arg("fail").spawn().unwrap();
+ // (Remove RUST_BACKTRACE from our own environment, in case developer
+ // is running `make check` with it on.)
+ let p = template.clone().arg("fail").env_remove("RUST_BACKTRACE").spawn().unwrap();
let out = p.wait_with_output().unwrap();
assert!(!out.status.success());
let s = str::from_utf8(&out.error).unwrap();
// 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);
}
use std::collections::BitVec;
fn bitv_test() {
- let mut v1 = box BitVec::from_elem(31, false);
- let v2 = box BitVec::from_elem(31, true);
+ let mut v1: Box<_> = box BitVec::from_elem(31, false);
+ let v2: Box<_> = box BitVec::from_elem(31, true);
v1.union(&*v2);
}
}
pub fn main() {
- let x = asBlock(|| 22_usize);
- assert_eq!(x, 22_usize);
+ let x = asBlock(|| 22);
+ assert_eq!(x, 22);
}
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;
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| {
// 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;
}
fn b() -> i32 {
- let mut x = 3i32;
+ let mut x = 3;
x += 1;
let c1 = || get(&x);
let c2 = || get(&x);
}
fn c() -> i32 {
- let mut x = 3i32;
+ let mut x = 3;
x += 1;
let c1 = || x * 5;
let c2 = || get(&x);
#![feature(unboxed_closures)]
pub fn main() {
- let bar = box 3;
+ let bar: Box<_> = box 3;
let h = || -> int *bar;
assert_eq!(h(), 3);
}
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() {
- let mut ints = box Ints {sum: box 0, values: Vec::new()};
+ let mut ints: Box<_> = box Ints {sum: box 0, values: Vec::new()};
add_int(&mut *ints, 22);
add_int(&mut *ints, 44);
// 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;
}
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);
}
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);
}
use cci_borrow_lib::foo;
pub fn main() {
- let p = box 22_usize;
+ let p: Box<_> = box 22;
let r = foo(&*p);
println!("r={}", r);
- assert_eq!(r, 22_usize);
+ assert_eq!(r, 22);
}
//let bt0 = sys::frame_address();
//println!("%?", bt0);
- 3_usize.to(10_usize, |i| {
+ 3.to(10, |i| {
println!("{}", i);
//let bt1 = sys::frame_address();
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));
})
}
// 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();
}
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());
}
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;
}
}
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();
}
fn cat(done: extern fn(uint)) -> cat {
cat {
- meows: 0_usize,
+ meows: 0,
done: done
}
}
pub fn cat(in_name: String) -> cat {
cat {
name: in_name,
- meows: 0_usize
+ meows: 0
}
}
}
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();
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);
}
}
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 }
}
}
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);
}
}
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);
}
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;
}
}
}
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());
}
}
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 }
}
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);
}
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);
}
}
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();
}
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);
}
pub fn fails() {
let x = 2;
- let mut y = Vec::new();
+ let mut y: Vec<Box<_>> = Vec::new();
y.push(box Conzabble::Bickwick(do_it(&get_bar(x))));
}
}
pub fn main() {
- let z = box Pair { a : 10, b : 12};
+ let z: Box<_> = box Pair { a : 10, b : 12};
let _t = Thread::spawn(move|| {
assert_eq!(z.a, 10);
// rvalue expressions to be unsized. See #20169 for more information.
pub fn main() {
- let _: Box<[int]> = box { [1, 2, 3] };
- let _: Box<[int]> = box if true { [1, 2, 3] } else { [1, 3, 4] };
- let _: Box<[int]> = box match true { true => [1, 2, 3], false => [1, 3, 4] };
- let _: Box<Fn(int) -> _> = box { |x| (x as u8) };
- let _: Box<Debug> = box if true { false } else { true };
- let _: Box<Debug> = box match true { true => 'a', false => 'b' };
+ // FIXME #22405: We cannot infer the type `Box<[int; k]>` for
+ // the r-value expression from the context `Box<[int]>`, and
+ // therefore the `box EXPR` desugaring breaks down.
+ //
+ // One could reasonably claim that the `box EXPR` desugaring is
+ // effectively regressing half of Issue #20169. Hopefully we will
+ // eventually fix that, at which point the `Box::new` calls below
+ // should be replaced wth uses of `box`.
+
+ let _: Box<[int]> = Box::new({ [1, 2, 3] });
+ let _: Box<[int]> = Box::new(if true { [1, 2, 3] } else { [1, 3, 4] });
+ let _: Box<[int]> = Box::new(match true { true => [1, 2, 3], false => [1, 3, 4] });
+ let _: Box<Fn(int) -> _> = Box::new({ |x| (x as u8) });
+ let _: Box<Debug> = Box::new(if true { false } else { true });
+ let _: Box<Debug> = Box::new(match true { true => 'a', false => 'b' });
let _: &[int] = &{ [1, 2, 3] };
let _: &[int] = &if true { [1, 2, 3] } else { [1, 3, 4] };
let _: Vec<Box<Fn(int) -> _>> = vec![
Box::new(|x| (x as u8)),
- box |x| (x as i16 as u8),
+ Box::new(|x| (x as i16 as u8)),
];
}
#![feature(box_syntax)]
pub fn main() {
- let _: Box<[int]> = if true { box [1, 2, 3] } else { box [1] };
+ let _: Box<[int]> =
+ if true { let b: Box<_> = box [1, 2, 3]; b } else { let b: Box<_> = box [1]; b };
- let _: Box<[int]> = match true { true => box [1, 2, 3], false => box [1] };
+ let _: Box<[int]> = match true {
+ true => { let b: Box<_> = box [1, 2, 3]; b }
+ false => { let b: Box<_> = box [1]; b }
+ };
// Check we don't get over-keen at propagating coercions in the case of casts.
let x = if true { 42 } else { 42u8 } as u16;
}
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));
}
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
})
}
// 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]
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);
}
// Make sure const bounds work on things, and test that a few types
// are const.
-#![allow(unknown_features)]
-#![feature(box_syntax)]
-
fn foo<T: Sync>(x: T) -> T { x }
struct F { field: int }
foo("hi".to_string());
foo(~[1, 2, 3]);
foo(F{field: 42});
- foo((1, 2_usize));
+ foo((1, 2));
foo(@1);*/
- foo(box 1);
+ foo(Box::new(1));
}
pub fn main() {
use crate_method_reexport_grrrrrrr2::rust::add;
use crate_method_reexport_grrrrrrr2::rust::cx;
- let x = box() ();
+ let x: Box<_> = box () ();
x.cx();
let y = ();
y.add("hi".to_string());
--- /dev/null
+// 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() { }
use std::cell::Cell;
pub fn main() {
- let x = box Cell::new(5);
+ let x: Box<_> = box Cell::new(5);
x.set(1000);
println!("{}", x.get());
}
pub fn main() {
let a: A = Default::default();
- let b: Box<[_]> = box [];
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let b: Box<[_]> = Box::<[bool; 0]>::new([]);
assert_eq!(a.foo, b);
}
}
fn main() {
- let obj = A { foo: box [true, false] };
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let obj = A { foo: Box::new([true, false]) };
let s = json::encode(&obj).unwrap();
let obj2: A = json::decode(&s).unwrap();
assert!(obj.foo == obj2.foo);
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![allow(unknown_features)]
-#![feature(box_syntax)]
-
#[derive(PartialEq, PartialOrd, Eq, Ord)]
struct Foo(Box<[u8]>);
pub fn main() {
- let a = Foo(box [0, 1, 2]);
- let b = Foo(box [0, 1, 2]);
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let a = Foo(Box::new([0, 1, 2]));
+ let b = Foo(Box::new([0, 1, 2]));
assert!(a == b);
println!("{}", a != b);
println!("{}", a < b);
// 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() {
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);
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());
// Test that a custom deref with a fat pointer return type does not ICE
-#![allow(unknown_features)]
-#![feature(box_syntax)]
-
use std::ops::{Deref, DerefMut};
pub struct Arr {
}
fn main() {
- let mut a = Arr { ptr: box [1, 2, 3] };
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let mut a = Arr { ptr: Box::new([1, 2, 3]) };
foo(&mut a);
}
// Test that a custom deref with a fat pointer return type does not ICE
-#![allow(unknown_features)]
-#![feature(box_syntax)]
-
use std::ops::Deref;
pub struct Arr {
}
fn main() {
- let a = Arr { ptr: box [1, 2, 3] };
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let a = Arr { ptr: Box::new([1, 2, 3]) };
foo(&a);
}
foo3(f5);
// Box.
- let f1 = box [1, 2, 3];
+ let f1 = Box::new([1, 2, 3]);
assert!((*f1)[1] == 2);
let f2: Box<[int]> = f1;
assert!((*f2)[1] == 2);
foo(&*f1);
let f2 : Box<Fat<[int]>> = f1;
foo(&*f2);
- let f3 : Box<Fat<[int]>> = box Fat { f1: 5, f2: "some str", ptr: [1, 2, 3] };
+
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let f3 : Box<Fat<[int]>> =
+ Box::<Fat<[_; 3]>>::new(Fat { f1: 5, f2: "some str", ptr: [1, 2, 3] });
foo(&*f3);
}
assert!(f6.ptr.to_bar() == Bar);
// &*
- let f7: Box<ToBar> = box Bar1 {f :42};
+ //
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let f7: Box<ToBar> = Box::new(Bar1 {f :42});
bar(&*f7);
// Deep nesting
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![allow(unknown_features)]
-#![feature(box_syntax)]
+// FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
pub fn main() {
- assert!(Some(box() ()).is_some());
+ assert!(Some(Box::new(())).is_some());
- let xs: Box<[()]> = box [];
+ let xs: Box<[()]> = Box::<[(); 0]>::new([]);
assert!(Some(xs).is_some());
struct Foo;
- assert!(Some(box Foo).is_some());
+ assert!(Some(Box::new(Foo)).is_some());
- let ys: Box<[Foo]> = box [];
+ let ys: Box<[Foo]> = Box::<[Foo; 0]>::new([]);
assert!(Some(ys).is_some());
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![allow(unknown_features)]
-#![feature(box_syntax)]
-
pub fn main() {
- let x = *box() ();
+ let x = *Box::new(());
}
}
pub fn main() {
- let mut m = box linear_map::<(),()>();
+ let mut m: Box<_> = box linear_map::<(),()>();
assert_eq!(m.len(), 0);
}
impl Nus for thing { fn f(&self) {} }
pub fn main() {
- let y = box thing(A {a: 10});
+ let y: Box<_> = box thing(A {a: 10});
assert_eq!(y.clone().bar(), 10);
assert_eq!(y.quux(), 10);
#![allow(unknown_features)]
#![feature(box_syntax)]
-pub fn main() { let x = { box 100 }; assert!((*x == 100)); }
+pub fn main() { let x: Box<_> = { box 100 }; assert!((*x == 100)); }
// Tests for if as expressions returning boxed types
fn test_box() {
- let rs = if true { box 100 } else { box 101 };
+ let rs: Box<_> = if true { box 100 } else { box 101 };
assert_eq!(*rs, 100);
}
// Tests for match as expressions resulting in boxed types
fn test_box() {
- let res = match true { true => { box 100 }, _ => panic!() };
+ let res: Box<_> = match true { true => { box 100 }, _ => panic!() };
assert_eq!(*res, 100);
}
pub fn main() {
unsafe {
- assert_eq!(22_u8, rust_dbg_extern_identity_u8(22_u8));
+ assert_eq!(22, rust_dbg_extern_identity_u8(22));
}
}
pub fn main() {
unsafe {
- assert_eq!(22_u32, rust_dbg_extern_identity_u32(22_u32));
+ assert_eq!(22, rust_dbg_extern_identity_u32(22));
}
}
pub fn main() {
unsafe {
- assert_eq!(22_u64, rust_dbg_extern_identity_u64(22_u64));
+ assert_eq!(22, rust_dbg_extern_identity_u64(22));
}
}
+++ /dev/null
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// 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<_>>();
-}
+++ /dev/null
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-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<_>>();
-}
// 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;
pub fn main() {
let len = strlen("Rust".to_string());
- assert_eq!(len, 4_usize);
+ assert_eq!(len, 4);
}
// 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;
// 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;
}
pub fn main() {
- let obj = box 1;
+ let obj: Box<_> = box 1;
let objptr: *const uint = &*obj;
let f = Foo {x: obj, y: box 2};
let xptr = foo(f);
}
pub fn main() {
- let obj = box 1;
+ let obj: Box<_> = box 1;
let objptr: *const uint = &*obj;
let xptr = getaddr(obj);
assert_eq!(objptr, xptr);
fn id<T:Send>(t: T) -> T { return t; }
pub fn main() {
- let expected = box 100;
+ let expected: Box<_> = box 100;
let actual = id::<Box<int>>(expected.clone());
println!("{}", *actual);
assert_eq!(*expected, *actual);
use std::num::Int;
-extern "C" fn foo<T: Int>(a: T, b: T) -> T { a + b }
+extern "C" fn foo<T: WrappingOps>(a: T, b: T) -> T { a.wrapping_add(b) }
fn main() {
assert_eq!(99u8, foo(255u8, 100u8));
// except according to those terms.
#![allow(unknown_features)]
-#![feature(box_syntax)]
#![feature(unboxed_closures)]
/**
}
let ctrl_clone = ctrl.clone();
- ::map(input, box |a,b| emit(&mut intermediates, ctrl.clone(), a, b) );
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ ::map(input, Box::new(|a,b| emit(&mut intermediates, ctrl.clone(), a, b)));
ctrl_clone.send(ctrl_proto::mapper_done).unwrap();
}
// except according to those terms.
#![allow(unknown_features)]
-#![feature(box_syntax)]
#![feature(unboxed_closures)]
// Test that `Fn(int) -> int + 'static` parses as `(Fn(int) -> int) +
// cause a compilation error. Issue #18772.
fn adder(y: int) -> Box<Fn(int) -> int + 'static> {
- box move |x| y + x
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ Box::new(move |x| y + x)
}
fn main() {}
-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)); }
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);
}
// 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) {
}
}
-pub fn main() { foo(2_usize); }
+pub fn main() { foo(2); }
test_order();
// make sure that format! doesn't move out of local variables
- let a = box 3;
+ let a: Box<_> = box 3;
format!("{}", a);
format!("{}", a);
fn test_unique() {
let i = &Cell::new(0);
{
- let _a = box r(i);
+ let _a: Box<_> = box r(i);
}
assert_eq!(i.get(), 1);
}
fn test_unique_rec() {
let i = &Cell::new(0);
{
- let _a = box BoxR {
+ let _a: Box<_> = box BoxR {
x: r(i)
};
}
#[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);
}
}
#[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);
}
}
}
#[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);
}
}
}
#[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);
}
}
#[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);
}
}
}
#[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);
}
}
}
pub fn main() {
unsafe {
- let mut x = box 1;
+ let mut x: Box<_> = box 1;
assert_eq!(rusti::atomic_load(&*x), 1);
*x = 5;
pub fn main() {
unsafe {
- let x = box 1;
+ let x: Box<_> = box 1;
let mut y = rusti::init();
let mut z: *const uint = transmute(&x);
rusti::move_val_init(&mut y, x);
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);
}
}
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);
fn main() {
{
- let f = box DroppableStruct;
+ let f: Box<_> = box DroppableStruct;
let _a = Whatever::new(box f as Box<MyTrait>);
}
assert!(unsafe { DROPPED });
unsafe { DROPPED = false; }
{
- let f = box DroppableEnum::DroppableVariant1;
+ let f: Box<_> = box DroppableEnum::DroppableVariant1;
let _a = Whatever::new(box f as Box<MyTrait>);
}
assert!(unsafe { DROPPED });
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);
}
// except according to those terms.
#![allow(dead_code)]
-#![allow(unknown_features)]
-#![feature(box_syntax)]
+
+// FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
trait Foo { fn dummy(&self) { } }
impl Foo for int {}
let r = &1;
foog(x, &[r]);
- let x: [Box<Foo>; 2] = [box 1, box 2];
+ let x: [Box<Foo>; 2] = [Box::new(1), Box::new(2)];
bar(x);
- bar([box 1, box 2]);
+ bar([Box::new(1), Box::new(2)]);
- let x: &[Box<Foo>] = &[box 1, box 2];
+ let x: &[Box<Foo>] = &[Box::new(1), Box::new(2)];
bars(x);
- bars(&[box 1, box 2]);
+ bars(&[Box::new(1), Box::new(2)]);
- let x: &[Box<Foo>] = &[box 1, box 2];
- foog(x, &[box 1]);
+ let x: &[Box<Foo>] = &[Box::new(1), Box::new(2)];
+ foog(x, &[Box::new(1)]);
struct T<'a> {
t: [&'a (Foo+'a); 2]
t: &'a [Box<Foo+'static>]
}
let _n = M {
- t: &[box 1, box 2]
+ t: &[Box::new(1), Box::new(2)]
};
- let x: [Box<Foo>; 2] = [box 1, box 2];
+ let x: [Box<Foo>; 2] = [Box::new(1), Box::new(2)];
let _n = M {
t: &x
};
// except according to those terms.
#![allow(dead_code)]
-#![allow(unknown_features)]
-#![feature(box_syntax)]
// this code used to cause an ICE
}
fn main() {
- S {f: box F, g: box F};
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ S {f: Box::new(F), g: Box::new(F) };
}
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 {
use std::thunk::Thunk;
pub fn main() {
- let mut x = 1i32;
+ let mut x = 1;
let _thunk = Thunk::new(move|| { x = 2; });
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![allow(unknown_features)]
-#![feature(box_syntax)]
-
fn main() {
- fn test() -> Box<std::any::Any + 'static> { box 1 }
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ fn test() -> Box<std::any::Any + 'static> { Box::new(1) }
println!("{:?}", test())
}
}
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();
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![allow(unknown_features)]
-#![feature(box_syntax)]
-
struct Foo<'a> {
listener: Box<FnMut() + 'a>,
}
impl<'a> Foo<'a> {
fn new<F>(listener: F) -> Foo<'a> where F: FnMut() + 'a {
- Foo { listener: box listener }
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ Foo { listener: Box::new(listener) }
}
}
impl A for B1 {}
fn main() {
- let v = box B1;
+ let v: Box<_> = box B1;
let _c: Box<A> = v.clone();
}
// All 3 expressions should work in that the argument gets
// coerced to a trait object
-#![allow(unknown_features)]
-#![feature(box_syntax)]
+// FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
fn main() {
- send::<Box<Foo>>(box Output(0));
- Test::<Box<Foo>>::foo(box Output(0));
- Test::<Box<Foo>>::new().send(box Output(0));
+ send::<Box<Foo>>(Box::new(Output(0)));
+ Test::<Box<Foo>>::foo(Box::new(Output(0)));
+ Test::<Box<Foo>>::new().send(Box::new(Output(0)));
}
fn send<T>(_: T) {}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![allow(unknown_features)]
-#![feature(box_syntax)]
-
trait Matcher {
fn next_match(&mut self) -> Option<(uint, uint)>;
}
impl<'a, 'b, F> IntoMatcher<'a, CharPredMatcher<'a, 'b>> for F where F: FnMut(char) -> bool + 'b {
fn into_matcher(self, s: &'a str) -> CharPredMatcher<'a, 'b> {
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
CharPredMatcher {
str: s,
- pred: box self,
+ pred: Box::new(self),
}
}
}
#![feature(box_syntax)]
fn match_on_local() {
- let mut foo = Some(box 5);
+ let mut foo: Option<Box<_>> = Some(box 5);
match foo {
None => {},
Some(x) => {
}
fn match_on_binding() {
- match Some(box 7) {
+ match Some(Box::new(7)) {
mut foo => {
match foo {
None => {},
}
fn match_on_upvar() {
- let mut foo = Some(box 8i32);
+ let mut foo: Option<Box<_>> = Some(box 8);
let f = move|| {
match foo {
None => {},
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());
}
}
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];
// ignore-pretty
#![allow(unknown_features)]
-#![feature(box_syntax)]
#![feature(unboxed_closures)]
struct Parser<'a, I, O> {
impl<'a, I: 'a, O: 'a> Parser<'a, I, O> {
fn compose<K: 'a>(mut self, mut rhs: Parser<'a, O, K>) -> Parser<'a, I, K> {
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
Parser {
- parse: box move |x: I| {
+ parse: Box::new(move |x: I| {
match (self.parse)(x) {
Ok(r) => (rhs.parse)(r),
Err(e) => Err(e)
}
- }
+ })
}
}
}
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() {
// Test that generating drop glue for Box<str> doesn't ICE
-#![allow(unknown_features)]
-#![feature(box_syntax)]
-
fn f(s: Box<str>) -> Box<str> {
s
}
fn main() {
// There is currently no safe way to construct a `Box<str>`, so improvise
- let box_arr: Box<[u8]> = box ['h' as u8, 'e' as u8, 'l' as u8, 'l' as u8, 'o' as u8];
+ //
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let box_arr: Box<[u8]> = Box::new(['h' as u8, 'e' as u8, 'l' as u8, 'l' as u8, 'o' as u8]);
let box_str: Box<str> = unsafe { std::mem::transmute(box_arr) };
assert_eq!(&*box_str, "hello");
f(box_str);
// Check that trans doesn't ICE when translating an array repeat
// expression with a count of 1 and a non-Copy element type.
-#![allow(unknown_features)]
-#![feature(box_syntax)]
-
fn main() {
- let _ = [box 1_usize; 1];
+ let _ = [Box::new(1_usize); 1];
}
#[allow(unused_must_use)]
fn main() {
- (0_usize..10).map(uint_to_foo);
+ (0..10).map(uint_to_foo);
}
}
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);
}
}
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);
}
// Test that overloaded calls work with zero arity closures
-#![feature(box_syntax)]
-
fn main() {
- let functions: [Box<Fn() -> Option<()>>; 1] = [box || None];
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let functions: [Box<Fn() -> Option<()>>; 1] = [Box::new(|| None)];
let _: Option<Vec<()>> = functions.iter().map(|f| (*f)()).collect();
}
use std::fmt;
fn main() {
- let a: &fmt::Debug = &1_i32;
+ let a: &fmt::Debug = &1;
format!("{:?}", a);
}
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 => {},
_ => {},
}
}
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);
}
}
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);
}
}
pub fn main() {
- f(C(1_usize));
+ f(C(1));
}
}
pub fn main() {
- let z = box 22;
+ let z: Box<_> = box 22;
a_val(z.clone(), z.clone());
}
}
pub fn main() {
- let _f = box Font();
+ let _f: Box<_> = box Font();
}
//
// ignore-lexer-test FIXME #15883
-#![allow(unknown_features)]
-#![feature(box_syntax)]
#![feature(unsafe_destructor)]
pub type Task = int;
pub fn packet<T:Send>() -> *const packet<T> {
unsafe {
- let p: *const packet<T> = mem::transmute(box Stuff{
+ let p: *const packet<T> = mem::transmute(Box::new(Stuff{
state: empty,
blocked_task: None::<Task>,
payload: None::<T>
- });
+ }));
p
}
}
// let y = box ({a: 4});
// let z = box ({a: 4} as it);
// let z = box ({a: true} as it);
- let z = box() (box true as Box<it>);
+ let z: Box<_> = box () (box true as Box<it>);
// x.f();
// y.f();
// (*z).f();
// 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()
}
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]);
}
pub fn main() {
let fd: libc::c_int = 1 as libc::c_int;
- let _sock = box socket::socket_handle(fd);
+ let _sock: Box<_> = box socket::socket_handle(fd);
}
use std::collections::HashMap;
pub fn main() {
- let x;
+ let x: Box<_>;
let mut buggy_map: HashMap<uint, &uint> = HashMap::new();
x = box 1;
buggy_map.insert(42, &*x);
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![allow(unknown_features)]
-#![feature(box_syntax)]
-
type Connection = Box<FnMut(Vec<u8>) + 'static>;
fn f() -> Option<Connection> {
- let mock_connection: Connection = box |_| {};
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let mock_connection: Connection = Box::new(|_| {});
Some(mock_connection)
}
#![feature(box_syntax)]
pub fn main() {
- let mut x = box 3;
+ let mut x: Box<_> = box 3;
x = x;
assert_eq!(*x, 3);
}
// rustc --test ignores2.rs && ./ignores2
#![allow(unknown_features)]
-#![feature(box_syntax)]
#![feature(unboxed_closures)]
use std::old_path::{Path};
fn tester()
{
- let mut loader: rsrc_loader = box move|_path| {
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let mut loader: rsrc_loader = Box::new(move|_path| {
result::Result::Ok("more blah".to_string())
- };
+ });
let path = old_path::Path::new("blah");
assert!(loader(&path).is_ok());
// except according to those terms.
#![allow(unknown_features)]
-#![feature(box_syntax)]
use std::thread::Thread;
use std::sync::mpsc::Sender;
let _t = Thread::spawn(move|| {
let mut samples_chan = samples_chan;
- // `box() (...)` syntax is needed to make pretty printer converge in one try:
- let callback: SamplesFn = box() (move |buffer| {
- for i in 0_usize..buffer.len() {
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let callback: SamplesFn = Box::new(move |buffer| {
+ for i in 0..buffer.len() {
println!("{}: {}", i, buffer[i])
}
});
#![feature(box_syntax)]
pub fn main() {
- let y = box 1;
+ let y: Box<_> = box 1;
y;
}
// 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)]
// <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(); }
macro_rules! foo {
($tag: expr, $string: expr) => {
if $tag == $string {
- let element = box Element;
+ let element: Box<_> = box Element;
unsafe {
return std::mem::transmute::<_, uint>(element);
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![allow(unknown_features)]
-#![feature(box_syntax)]
-
enum Either<T, U> { Left(T), Right(U) }
pub fn main() {
- match Either::Left(box 17) {
+ match Either::Left(Box::new(17)) {
Either::Right(()) => {}
_ => {}
}
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);
}
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; }
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);
}
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);
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![allow(unknown_features)]
-#![feature(box_syntax)]
-
pub fn main() {
- match &[(box 5,box 7)] {
+ match &[(Box::new(5),Box::new(7))] {
ps => {
let (ref y, _) = ps[0];
assert!(**y == 5);
}
}
- match Some(&[(box 5,)]) {
+ match Some(&[(Box::new(5),)]) {
Some(ps) => {
let (ref y,) = ps[0];
assert!(**y == 5);
None => ()
}
- match Some(&[(box 5,box 7)]) {
+ match Some(&[(Box::new(5),Box::new(7))]) {
Some(ps) => {
let (ref y, ref z) = ps[0];
assert!(**y == 5);
struct X { pub x: uint }
impl Default for X {
fn default() -> X {
- X { x: 42_usize }
+ X { x: 42 }
}
}
extern crate issue2170lib;
pub fn main() {
- // let _ = issue2170lib::rsrc(2i32);
+ // let _ = issue2170lib::rsrc(2);
}
--- /dev/null
+// 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]));
+}
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() {
struct A { a: Box<isize> }
fn foo() -> Box<FnMut() -> isize + 'static> {
- let k = box 22;
+ 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;
- box result
+ // 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)
}
pub fn main() {
pub fn main() {
fn invoke<F>(f: F) where F: FnOnce() { f(); }
- let k = box 22;
+ let k: Box<_> = box 22;
let _u = A {a: k.clone()};
invoke(|| println!("{}", k.clone()) )
}
#![feature(box_syntax)]
fn f() {
- let a = box 1;
+ let a: Box<_> = box 1;
let b: &int = &*a;
println!("{}", b);
}
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-extern crate libc;
-
-extern {
- fn rust_get_test_int() -> libc::intptr_t;
-}
-
-trait A {
- fn foo(&self) {
- unsafe {
- rust_get_test_int();
- }
- }
-}
-
-pub fn main() {
-}
// 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]
// ignore-windows
// exec-env:RUST_LOG=debug
+// compile-flags:-C debug-assertions=y
#[macro_use]
extern crate log;
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)
}
}
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,
struct Pair { a: Box<int>, b: Box<int> }
pub fn main() {
- let mut x = box Pair {a: box 10, b: box 20};
+ let mut x: Box<_> = box Pair {a: box 10, b: box 20};
let x_internal = &mut *x;
match *x_internal {
Pair {a: ref mut a, b: ref mut _b} => {
None => return (),
Some(num) => num as u32
};
- assert_eq!(f, 1234u32);
+ assert_eq!(f, 1234);
println!("{}", f)
}
}
fn main() {
- let mut buf = [0_u8; 6];
+ let mut buf = [0; 6];
{
let mut writer: &mut [_] = &mut buf;
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);
}
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);
}
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); }
}
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); }
}
}
fn call_foo_other() -> int {
- let mut x = Vec::new();
+ let mut x: Vec<Box<_>> = Vec::new();
let y = x.foo();
x.push(box 0);
y
}
pub fn main() {
- let x = box Triple{x: 1, y: 2, z: 3};
+ let x: Box<_> = box Triple{x: 1, y: 2, z: 3};
assert_eq!(test(true, x.clone()), 2);
assert_eq!(test(true, x.clone()), 2);
assert_eq!(test(true, x.clone()), 2);
struct X { x: int, y: int, z: int }
pub fn main() {
- let x = box X{x: 1, y: 2, z: 3};
+ let x: Box<_> = box X{x: 1, y: 2, z: 3};
let y = x;
assert!((y.y == 2));
}
struct X { x: int, y: int, z: int }
-pub fn main() { let x = box X {x: 1, y: 2, z: 3}; let y = x; assert!((y.y == 2)); }
+pub fn main() { let x: Box<_> = box X {x: 1, y: 2, z: 3}; let y = x; assert!((y.y == 2)); }
}
pub fn main() {
- let x = box Triple{x: 1, y: 2, z: 3};
+ let x: Box<_> = box Triple{x: 1, y: 2, z: 3};
for _ in 0_usize..10000_usize {
assert_eq!(test(true, x.clone()), 2);
}
#![feature(box_syntax)]
fn main() {
- let x = box 1;
+ let x: Box<_> = box 1;
let v = (1, 2);
// Test that the lambda kind is inferred correctly as a return
// expression
-#![allow(unknown_features)]
-#![feature(box_syntax)]
-
-fn unique() -> Box<FnMut()+'static> { return box || (); }
+// FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+fn unique() -> Box<FnMut()+'static> { return Box::new(|| ()); }
pub fn main() {
}
// Test that the lambda kind is inferred correctly as a return
// expression
-#![allow(unknown_features)]
-#![feature(box_syntax)]
-
-fn unique() -> Box<FnMut()+'static> { box || () }
+// FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+fn unique() -> Box<FnMut()+'static> { Box::new(|| ()) }
pub fn main() {
}
// 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;
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);
// 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");
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() {
}
fn main() {
- let x = 22_i32;
+ let x = 22;
let x1: &SomeTrait<SomeType=i32> = &x;
let y = get_int(x1);
assert_eq!(x, y);
}
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);
}
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());
}
}
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);
}
}
pub fn main() {
- let box_5 = box 5_usize;
+ let box_5: Box<_> = box 5_usize;
assert_eq!(Rc::new(5_usize).to_uint(), Some(5));
- assert_eq!((box &box &Rc::new(box box &box_5)).to_uint(), Some(5));
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ assert_eq!((Box::new(&Box::new(&Rc::new(Box::new(Box::new(&box_5)))))).to_uint(), Some(5));
let point = Rc::new(Point {x: 2, y: 4});
assert_eq!(point.x, 2);
assert_eq!(point.y, 4);
fn main() {
// ICE trigger
- (G(PhantomData))(1_i32);
+ (G(PhantomData))(1);
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![allow(unknown_features)]
-#![feature(box_syntax)]
-
use std::cell::RefCell;
use std::rc::Rc;
use std::string::String;
pub fn main() {
assert_eq!(*Rc::new(5), 5);
- assert_eq!(***Rc::new(box box 5), 5);
+ assert_eq!(***Rc::new(Box::new(Box::new(5))), 5);
assert_eq!(*Rc::new(Point {x: 2, y: 4}), Point {x: 2, y: 4});
let i = Rc::new(RefCell::new(2));
}
fn main() {
- let mut f = box Foo {
+ let mut f: Box<_> = box Foo {
x: 1,
y: 2,
};
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![allow(unknown_features)]
-#![feature(box_syntax)]
-
fn f<T: 'static>(_x: T) {}
pub fn main() {
- f(box 5);
+ f(Box::new(5));
}
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});
}
pub fn bar(_offset: uint) { }
}
-pub fn main() { foo::bar(0_usize); }
+pub fn main() { foo::bar(0); }
}
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);
}
#![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 sum0 = box 0;
+ 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;
}
struct F<T> { f: T }
fn sums_to_using_uniq_rec(v: Vec<int> , sum: int) -> bool {
- let mut i = 0_usize;
- let mut sum0 = F {f: box 0};
+ 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;
}
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];
}
pub fn main() {
- let x = box 6;
+ let x: Box<_> = box 6;
let y = x.get();
println!("y={}", y);
assert_eq!(y, 6);
// 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);
}
// 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;
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);
// 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);
// 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);
// 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);
// 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);
#[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);
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 }
}
}
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 }
}
}
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 }
}
}
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);
}
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);
}
}
pub fn main() {
- let p = box 22_usize;
+ let p: Box<_> = box 22;
let r = foo(&*p);
println!("r={}", r);
- assert_eq!(r, 22_usize);
+ assert_eq!(r, 22);
}
}
pub fn main() {
- let p = box 3_usize;
+ let p: Box<_> = box 3;
let r = foo(&*p);
- assert_eq!(r, 3_usize);
+ assert_eq!(r, 3);
}
// except according to those terms.
#![allow(unknown_features)]
-#![feature(box_syntax)]
#![feature(unboxed_closures)]
struct closure_box<'a> {
}
pub fn main() {
- let mut i = 3i32;
+ let mut i = 3;
assert_eq!(i, 3);
{
let cl = || i += 1;
- let mut cl_box = box_it(box cl);
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let mut cl_box = box_it(Box::new(cl));
cl_box.cl.call_mut(());
}
assert_eq!(i, 4);
fn bar(x: &uint) -> uint { *x }
pub fn main() {
- let p = box 3_usize;
+ let p: Box<_> = box 3;
assert_eq!(bar(foo(&*p)), 3);
}
#![allow(dead_assignment)]
#![allow(unused_variable)]
#![allow(unknown_features)]
-#![feature(box_syntax)]
+
+// FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
// Should pass region checking.
fn ok(f: Box<FnMut(&uint)>) {
// f's type should be a subtype of g's type), because f can be
// used in any context that expects g's type. But this currently
// fails.
- let mut g: Box<for<'r> FnMut(&'r uint)> = box |x| { };
+ let mut g: Box<for<'r> FnMut(&'r uint)> = Box::new(|x| { });
g = f;
}
// This version is the same as above, except that here, g's type is
// inferred.
fn ok_inferred(f: Box<FnMut(&uint)>) {
- let mut g: Box<for<'r> FnMut(&'r uint)> = box |_| {};
+ let mut g: Box<for<'r> FnMut(&'r uint)> = Box::new(|_| {});
g = f;
}
fn borrow<T>(x: &T) -> &T {x}
pub fn main() {
- let x = box 3;
+ let x: Box<_> = box 3;
loop {
let y = borrow(&*x);
assert_eq!(*x, *y);
}
pub fn main() {
- let p = box Point {x: 3, y: 4};
+ let p: Box<_> = box Point {x: 3, y: 4};
let xc = x_coord(&*p);
assert_eq!(*xc, 3);
}
}
pub fn main() {
- let x = 3_usize;
- assert_eq!(parameterized(&x), 3_usize);
+ let x = 3;
+ assert_eq!(parameterized(&x), 3);
}
// 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[..]));
}
// ... 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()));
}
}
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[..]);
impl<'a,'tcx> Foo<'a,'tcx> {
fn bother(&mut self) -> int {
- self.elaborate_bounds(box |this| {
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ self.elaborate_bounds(Box::new(|this| {
// (*) Here: type of `this` is `&'f0 Foo<&'f1, '_2>`,
// where `'f0` and `'f1` are fresh, free regions that
// result from the bound regions on the closure, and `'2`
// `region_inference.rs` file (and the `givens` field, in
// particular) for more details.
this.foo()
- })
+ }))
}
fn foo(&mut self) -> int {
}
pub fn main() {
- let cl_box = box_it(box || println!("Hello, world!"));
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let cl_box = box_it(Box::new(|| println!("Hello, world!")));
call_static_closure(cl_box);
}
}
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);
}
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 _,
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); }
};
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
let new_x = x.change();
assert_eq!(new_x.a, 55);
- let x = box new_x;
+ let x: Box<_> = box new_x;
let new_x = x.change_again();
assert_eq!(new_x.a, 45);
}
use std::rc::Rc;
pub fn main() {
- let mut x = box 3;
+ let mut x: Box<_> = box 3;
x = x;
assert!(*x == 3);
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);
}
}
fn test05() {
- let three = box 3;
+ let three: Box<_> = box 3;
let fn_to_send = move|n:int| {
println!("{}", *three + n); // will copy x into the closure
assert_eq!(*three, 3);
}
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() {
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![allow(unknown_features)]
-#![feature(box_syntax)]
-
#[derive(Debug)]
struct Foo(Box<[u8]>);
pub fn main() {
- println!("{:?}", Foo(box [0, 1, 2]));
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ println!("{:?}", Foo(Box::new([0, 1, 2])));
}
--- /dev/null
+// 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(custom_derive)]
+
+#[derive_Clone]
+struct Test;
+
+pub fn main() {
+ Test.clone();
+}
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)");
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
+#![feature(static_assert)]
+
#[static_assert]
static b: bool = true;
impl Foo for uint {
fn foo() -> uint {
- 5_usize
+ 5
}
}
}
// 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;
}
}
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!");
}
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!");
}
--- /dev/null
+// 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);
+}
--- /dev/null
+// 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);
+}
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);
}
}
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);
}
}
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());
// 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> {
}
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));
}
// 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> {
}
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 {
}
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));
}
}
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());
// 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 {
}
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));
}
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');
}
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() {
pub fn main() {
let (tx, rx) = channel::<uint>();
- let x = box 1;
+ let x: Box<_> = box 1;
let x_in_parent = &(*x) as *const int as uint;
let _t = Thread::spawn(move || {
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) {
// 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) }
// 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")
}
}
fn check_names(arc: Arc<Vec<Box<Pet+Sync+Send>>>) {
for pet in &*arc {
- pet.name(box |name| {
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ pet.name(Box::new(|name| {
assert!(name.as_bytes()[0] == 'a' as u8 && name.as_bytes()[1] == 'l' as u8);
- })
+ }))
}
}
fn check_pedigree(arc: Arc<Vec<Box<Pet+Sync+Send>>>) {
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![allow(unknown_features)]
-#![feature(box_syntax)]
-
trait Trait<T> {
fn f(&self, x: T);
}
pub fn main() {
let a = Struct { x: 1, y: 2 };
- let b: Box<Trait<&'static str>> = box a;
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let b: Box<Trait<&'static str>> = Box::new(a);
b.f("Mary");
let c: &Trait<&'static str> = &a;
c.f("Joe");
a.write(b"Hello\n");
}
+// FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+
pub fn main() {
let a = Struct { x: 1, y: 2 };
- let b: Box<Trait> = box a;
+ let b: Box<Trait> = Box::new(a);
b.f();
let c: &Trait = &a;
c.f();
let out = old_io::stdout();
- foo(box out);
+ foo(Box::new(out));
}
}
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);
}
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);
}
}
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);
}
--- /dev/null
+// 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);
+}
assert_eq!(get_it(&1_u32), 1_u32);
assert_eq!(get_it(&1_u16), 1_u16);
assert_eq!(get_it(&Some(1_u16)), Some(1_u16));
- assert_eq!(get_it(&box 1), box 1);
+ assert_eq!(get_it(&Box::new(1)), Box::new(1));
}
--- /dev/null
+// 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() { }
--- /dev/null
+// 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);
+}
pub fn main() {
p_foo(r(10));
- p_foo(box r(10));
- p_foo(box 10);
+ p_foo::<Box<_>>(box r(10));
+ p_foo::<Box<_>>(box 10);
p_foo(10);
- s_foo(box 10);
+ s_foo::<Box<_>>(box 10);
s_foo(10);
- u_foo(box 10);
+ u_foo::<Box<_>>(box 10);
u_foo(10);
}
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();
})
}
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);
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);
}
// 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);
}
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;
}
}
fn main() {
- let foo = box Foo {
+ let foo: Box<_> = box Foo {
f: 1,
};
println!("{} {} {}", foo.foo(2), foo.bar(2), foo.baz(2));
- let bar = box Bar {
+ let bar: Box<_> = box Bar {
f: 1,
};
println!("{} {} {}", bar.foo(2), bar.bar(2), bar.baz(2));
}
fn main() {
- let a: &Foo = &22_i32;
+ let a: &Foo = &22;
assert_eq!(Foo::test(a), 22);
}
// Test that the call operator autoderefs when calling to an object type.
#![allow(unknown_features)]
-#![feature(box_syntax)]
#![feature(unboxed_closures)]
use std::ops::FnMut;
fn make_adder(x: int) -> Box<FnMut(int)->int + 'static> {
- box move |y| { x + y }
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ Box::new(move |y| { x + y })
}
pub fn main() {
// except according to those terms.
#![allow(unknown_features)]
-#![feature(box_syntax)]
#![feature(unboxed_closures)]
use std::ops::FnMut;
fn make_adder(x: int) -> Box<FnMut(int)->int + 'static> {
- box move |y| { x + y }
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ Box::new(move |y| { x + y })
}
pub fn main() {
fn main(){
fn bar<'a, T:Clone+'a> (t: T) -> Box<FnMut()->T + 'a> {
- box move || t.clone()
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ Box::new(move || t.clone())
}
let mut f = bar(42_u32);
#![feature(unboxed_closures)]
fn main() {
- let task: Box<Fn(int) -> int> = box |x| x;
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let task: Box<Fn(int) -> int> = Box::new(|x| x);
task.call((0, ));
- let mut task: Box<FnMut(int) -> int> = box |x| x;
+ let mut task: Box<FnMut(int) -> int> = Box::new(|x| x);
task(0);
call(|x| x, 22);
//
// 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.
//
}
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);
}
}
pub fn main() {
- let x = box X { a: 32 };
+ let x: Box<_> = box X { a: 32 };
let new_x = x.change();
assert_eq!(new_x.a, 55);
}
#![feature(box_syntax)]
pub fn main() {
- let mut i = box 1;
+ let mut i: Box<_> = box 1;
// Should be a copy
let mut j;
j = i.clone();
#![feature(box_syntax)]
pub fn main() {
- let i = box 1;
- let mut j = box 2;
+ let i: Box<_> = box 1;
+ let mut j: Box<_> = box 2;
// Should drop the previous value of j
j = i;
assert_eq!(*j, 1);
}
pub fn main() {
- let t = f(box 100);
+ let t = f::<Box<_>>(box 100);
assert_eq!(t, box 100);
}
#![feature(box_syntax)]
pub fn main() {
- let mut i;
+ let mut i: Box<_>;
i = box 1;
assert_eq!(*i, 1);
}
struct J { j: int }
pub fn main() {
- let i = box J {
+ let i: Box<_> = box J {
j: 100
};
assert_eq!(i.j, 100);
#![feature(box_syntax)]
pub fn main() {
- let i = box vec!(100);
+ let i: Box<_> = box vec!(100);
assert_eq!((*i)[0], 100);
}
#![feature(box_syntax)]
pub fn main() {
- let i = box 100;
+ let i: Box<_> = box 100;
assert!(i == box 100);
assert!(i < box 101);
assert!(i <= box 100);
pub fn main() {
enum t { t1(int), t2(int), }
- let _x = box t::t1(10);
+ let _x: Box<_> = box t::t1(10);
/*alt *x {
t1(a) {
#![feature(box_syntax)]
pub fn main() {
- box 100;
+ let _: Box<_> = box 100;
}
fn vec() {
#![feature(box_syntax)]
pub fn main() {
- let mut i = box 1;
+ let mut i: Box<_> = box 1;
// Should be a copy
let mut j = i.clone();
*i = 2;
#![feature(box_syntax)]
pub fn main() {
- let i = box 1;
+ let i: Box<_> = box 1;
let j = i;
assert_eq!(*j, 1);
}
#![feature(box_syntax)]
pub fn main() {
- let i = box 100;
+ let i: Box<_> = box 100;
let j = i;
assert_eq!(*j, 100);
}
#![feature(box_syntax)]
pub fn main() {
- let i = box 100;
+ let i: Box<_> = box 100;
assert_eq!(*i, 100);
}
#![feature(box_syntax)]
pub fn main() {
- let _x = box vec!(0,0,0,0,0);
+ let _x: Box<_> = box vec!(0,0,0,0,0);
}
#![feature(box_syntax)]
pub fn main() {
- let mut a = vec!(box 10);
+ let mut a: Vec<Box<_>> = vec!(box 10);
let b = a.clone();
assert_eq!(*a[0], 10);
#![feature(box_syntax)]
pub fn main() {
- let vect = vec!(box 100);
+ let vect : Vec<Box<_>> = vec!(box 100);
assert!(vect[0] == box 100);
}
#![feature(box_syntax)]
pub fn main() {
- let _i = box 100;
+ let _i: Box<_> = box 100;
}
assert!(i != j);
}
- let i = box 100;
- let j = box 100;
+ let i: Box<_> = box 100;
+ let j: Box<_> = box 100;
f(i, j);
- let i = box 100;
- let j = box 101;
+ let i: Box<_> = box 100;
+ let j: Box<_> = box 101;
g(i, j);
}
assert!(i != j);
}
- let i = box 100;
- let j = box 100;
+ let i: Box<_> = box 100;
+ let j: Box<_> = box 100;
f(i, j);
- let i = box 100;
- let j = box 101;
+ let i: Box<_> = box 100;
+ let j: Box<_> = box 101;
g(i, j);
}
assert!(i != j);
}
- let i = box 100;
- let j = box 100;
+ let i: Box<_> = box 100;
+ let j: Box<_> = box 100;
f(i, j);
- let i = box 100;
- let j = box 101;
+ let i: Box<_> = box 100;
+ let j: Box<_> = box 101;
g(i, j);
}
#![feature(box_syntax)]
pub fn main() {
- let i = box 100;
+ let i: Box<_> = box 100;
println!("{}", i);
}
// Issue #961
-#![allow(unknown_features)]
-#![feature(box_syntax)]
-
fn altsimple() {
- match box true {
+ match Box::new(true) {
_ => { }
}
}
#![feature(box_syntax)]
pub fn main() {
- let i = box 100;
- let j = box 200;
+ let i: Box<_> = box 100;
+ let j: Box<_> = box 200;
let j = i;
assert_eq!(*j, 100);
}
#![feature(box_syntax)]
pub fn main() {
- let mut i;
+ let mut i: Box<_>;
i = box 100;
assert_eq!(*i, 100);
}
#![feature(box_syntax)]
pub fn main() {
- let i = box 100;
+ let i: Box<_> = box 100;
let mut j;
j = i;
assert_eq!(*j, 100);
#![feature(box_syntax)]
pub fn main() {
- let mut i = box 0;
+ let mut i: Box<_> = box 0;
*i = 1;
assert_eq!(*i, 1);
}
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);
struct X { x: int }
pub fn main() {
- let x = box X {x: 1};
+ let x: Box<_> = box X {x: 1};
let bar = x;
assert_eq!(bar.x, 1);
}
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|| {
})
}).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;
}
use std::sync::mpsc::channel;
pub fn main() {
- let (tx, rx) = channel();
+ let (tx, rx) = channel::<Box<_>>();
tx.send(box 100).unwrap();
let v = rx.recv().unwrap();
assert_eq!(v, box 100);
use std::mem::swap;
pub fn main() {
- let mut i = box 100;
- let mut j = box 200;
+ let mut i: Box<_> = box 100;
+ let mut j: Box<_> = box 200;
swap(&mut i, &mut j);
assert_eq!(i, box 200);
assert_eq!(j, box 100);
// <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.
// <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)]
f: [T; 3]
}
- let data = 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,
f2: [u8; 5],
}
- let data = box Baz_{ f1: 42, f2: ['a' as u8, 'b' as u8, 'c' as u8, 'd' as u8, 'e' as u8] };
+ let data: Box<_> = box Baz_ {
+ f1: 42, f2: ['a' as u8, 'b' as u8, 'c' as u8, 'd' as u8, 'e' as u8] };
let x: &Baz = mem::transmute( raw::Slice { len: 5, data: &*data } );
assert!(x.f1 == 42);
let chs: Vec<char> = x.f2.chars().collect();
let obj: Box<St> = box St { f: 42 };
let obj: &Tr = &*obj;
let obj: raw::TraitObject = mem::transmute(&*obj);
- let data = box Qux_{ f: St { f: 234 } };
+ let data: Box<_> = box Qux_{ f: St { f: 234 } };
let x: &Qux = mem::transmute(raw::TraitObject { vtable: obj.vtable,
data: mem::transmute(&*data) });
assert!(x.f.foo() == 234);
#![feature(box_syntax)]
pub fn main() {
- let _x = box 1;
+ let _x: Box<_> = box 1;
let lam_move = || {};
lam_move();
}
pub fn main()
{
- let y = box 1;
+ let y: Box<_> = box 1;
y;
}
use std::thread;
fn f() {
- let _a = box 0;
+ let _a: Box<_> = box 0;
panic!();
}
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();
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);
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()));
}
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;
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));
//}
}
}
pub fn main() {
- assert!(MAX_LEN <= std::usize::BITS);
+ assert!(MAX_LEN <= std::usize::BITS as usize);
// len can't go above 64.
for len in 2..MAX_LEN {
for _ in 0..REPEATS {
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() {
}
fn main() {
- let x = 42u32;
+ let x = 42;
foo1(&x);
foo2(&x);
unsafe {
#[cfg(windows)]
pub fn main() {
unsafe {
- let expected = 1234_usize;
+ let expected = 1234;
kernel32::SetLastError(expected);
let actual = kernel32::GetLastError();
println!("actual = {}", actual);
#[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))]