Merge remote-tracking branch 'upstream/master' into asm-compile-tests

This commit is contained in:
Denys Zariaiev 2019-03-13 21:00:45 +01:00
commit eeb5f171da
3937 changed files with 27996 additions and 23185 deletions

View file

@ -161,6 +161,7 @@ Michael Woerister <michaelwoerister@posteo> <michaelwoerister@gmail>
Mickaël Raybaud-Roig <raybaudroigm@gmail.com> m-r-r <raybaudroigm@gmail.com>
Ms2ger <ms2ger@gmail.com> <Ms2ger@gmail.com>
Mukilan Thiagarajan <mukilanthiagarajan@gmail.com>
Nathan West <Lucretiel@gmail.com> <lucretiel@gmail.com>
Nathan Wilson <wilnathan@gmail.com>
Nathaniel Herman <nherman@post.harvard.edu> Nathaniel Herman <nherman@college.harvard.edu>
Neil Pankey <npankey@gmail.com> <neil@wire.im>

View file

@ -230,7 +230,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "cargo"
version = "0.35.0"
version = "0.36.0"
dependencies = [
"atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"bufstream 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
@ -238,7 +238,7 @@ dependencies = [
"bytesize 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
"core-foundation 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
"crates-io 0.23.0",
"crates-io 0.24.0",
"crossbeam-utils 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"crypto-hash 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"curl 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)",
@ -374,7 +374,7 @@ dependencies = [
"clippy-mini-macro-test 0.2.0",
"clippy_dev 0.0.1",
"clippy_lints 0.0.212",
"compiletest_rs 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)",
"compiletest_rs 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
"derive-new 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -493,7 +493,7 @@ dependencies = [
[[package]]
name = "compiletest_rs"
version = "0.3.18"
version = "0.3.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
@ -508,6 +508,7 @@ dependencies = [
"serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)",
"tempfile 3.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"tester 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -539,7 +540,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "crates-io"
version = "0.23.0"
version = "0.24.0"
dependencies = [
"curl 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)",
"failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
@ -744,7 +745,7 @@ dependencies = [
[[package]]
name = "dlmalloc"
version = "0.1.2"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"compiler_builtins 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1339,7 +1340,7 @@ dependencies = [
[[package]]
name = "lsp-codec"
version = "0.1.1"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1399,7 +1400,7 @@ dependencies = [
"serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)",
"string_cache 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
"string_cache_codegen 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"string_cache_codegen 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"tendril 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -1590,7 +1591,7 @@ dependencies = [
"byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
"cargo_metadata 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"colored 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"compiletest_rs 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)",
"compiletest_rs 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
"directories 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1936,14 +1937,6 @@ dependencies = [
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "proc-macro2"
version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "proc-macro2"
version = "0.4.24"
@ -2015,14 +2008,6 @@ name = "quote"
version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "quote"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "quote"
version = "0.6.10"
@ -2247,7 +2232,7 @@ dependencies = [
name = "rls"
version = "1.34.0"
dependencies = [
"cargo 0.35.0",
"cargo 0.36.0",
"cargo_metadata 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"clippy_lints 0.0.212",
"crossbeam-channel 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2261,7 +2246,7 @@ dependencies = [
"jsonrpc-core 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"lsp-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"lsp-codec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"lsp-types 0.55.4 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ordslice 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2272,7 +2257,7 @@ dependencies = [
"rls-analysis 0.16.12 (registry+https://github.com/rust-lang/crates.io-index)",
"rls-blacklist 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"rls-data 0.18.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rls-rustc 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rls-rustc 0.6.0",
"rls-span 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rls-vfs 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2325,8 +2310,7 @@ dependencies = [
[[package]]
name = "rls-rustc"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
version = "0.6.0"
[[package]]
name = "rls-span"
@ -2374,14 +2358,15 @@ dependencies = [
"num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"polonius-engine 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-rayon 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-rayon-core 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-rayon 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-rayon-core 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc_apfloat 0.0.0",
"rustc_data_structures 0.0.0",
"rustc_errors 0.0.0",
"rustc_fs_util 0.0.0",
"rustc_macros 0.1.0",
"rustc_target 0.0.0",
"scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"scoped-tls 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serialize 0.0.0",
"smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
"syntax 0.0.0",
@ -2425,8 +2410,8 @@ dependencies = [
"rustc-ap-rustc_cratesio_shim 373.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-ap-serialize 373.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-rayon 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-rayon-core 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-rayon 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-rayon-core 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
"stable_deref_trait 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -2524,23 +2509,23 @@ dependencies = [
[[package]]
name = "rustc-rayon"
version = "0.1.1"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-rayon-core 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-rayon-core 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rustc-rayon-core"
version = "0.1.1"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -2640,6 +2625,7 @@ dependencies = [
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc 0.0.0",
"rustc-demangle 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc_allocator 0.0.0",
@ -2688,11 +2674,13 @@ dependencies = [
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"ena 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"graphviz 0.0.0",
"jobserver 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-rayon 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-rayon-core 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-rayon 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-rayon-core 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc_cratesio_shim 0.0.0",
"serialize 0.0.0",
"smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2708,13 +2696,14 @@ dependencies = [
"graphviz 0.0.0",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc 0.0.0",
"rustc-rayon 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-rayon 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc_allocator 0.0.0",
"rustc_borrowck 0.0.0",
"rustc_codegen_utils 0.0.0",
"rustc_data_structures 0.0.0",
"rustc_errors 0.0.0",
"rustc_incremental 0.0.0",
"rustc_interface 0.0.0",
"rustc_lint 0.0.0",
"rustc_metadata 0.0.0",
"rustc_mir 0.0.0",
@ -2726,7 +2715,7 @@ dependencies = [
"rustc_target 0.0.0",
"rustc_traits 0.0.0",
"rustc_typeck 0.0.0",
"scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"scoped-tls 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serialize 0.0.0",
"smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
"syntax 0.0.0",
@ -2758,7 +2747,7 @@ version = "0.0.0"
dependencies = [
"graphviz 0.0.0",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc 0.0.0",
"rustc_data_structures 0.0.0",
"rustc_fs_util 0.0.0",
@ -2767,6 +2756,36 @@ dependencies = [
"syntax_pos 0.0.0",
]
[[package]]
name = "rustc_interface"
version = "0.0.0"
dependencies = [
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc 0.0.0",
"rustc-rayon 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc_allocator 0.0.0",
"rustc_borrowck 0.0.0",
"rustc_codegen_utils 0.0.0",
"rustc_data_structures 0.0.0",
"rustc_errors 0.0.0",
"rustc_incremental 0.0.0",
"rustc_lint 0.0.0",
"rustc_metadata 0.0.0",
"rustc_mir 0.0.0",
"rustc_passes 0.0.0",
"rustc_plugin 0.0.0",
"rustc_privacy 0.0.0",
"rustc_resolve 0.0.0",
"rustc_traits 0.0.0",
"rustc_typeck 0.0.0",
"scoped-tls 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serialize 0.0.0",
"smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
"syntax 0.0.0",
"syntax_ext 0.0.0",
"syntax_pos 0.0.0",
]
[[package]]
name = "rustc_lint"
version = "0.0.0"
@ -2798,6 +2817,16 @@ dependencies = [
"core 0.0.0",
]
[[package]]
name = "rustc_macros"
version = "0.1.0"
dependencies = [
"proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.15.22 (registry+https://github.com/rust-lang/crates.io-index)",
"synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rustc_metadata"
version = "0.0.0"
@ -3090,6 +3119,11 @@ name = "scoped-tls"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "scoped-tls"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "scoped_threadpool"
version = "0.1.9"
@ -3230,7 +3264,7 @@ dependencies = [
"cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)",
"compiler_builtins 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"core 0.0.0",
"dlmalloc 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"dlmalloc 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"fortanix-sgx-abi 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
"panic_abort 0.0.0",
@ -3255,19 +3289,19 @@ dependencies = [
"phf_shared 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)",
"precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.82 (registry+https://github.com/rust-lang/crates.io-index)",
"string_cache_codegen 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"string_cache_codegen 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "string_cache_codegen"
version = "0.4.1"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"phf_generator 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)",
"phf_shared 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
"string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -3345,7 +3379,7 @@ dependencies = [
"rustc_data_structures 0.0.0",
"rustc_errors 0.0.0",
"rustc_target 0.0.0",
"scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"scoped-tls 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serialize 0.0.0",
"smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
"syntax_pos 0.0.0",
@ -3372,7 +3406,7 @@ dependencies = [
"arena 0.0.0",
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc_data_structures 0.0.0",
"scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"scoped-tls 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serialize 0.0.0",
"unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -3415,6 +3449,15 @@ dependencies = [
name = "term"
version = "0.0.0"
[[package]]
name = "term"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "term"
version = "0.5.1"
@ -3451,6 +3494,16 @@ dependencies = [
"term 0.0.0",
]
[[package]]
name = "tester"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"getopts 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
"term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "textwrap"
version = "0.10.0"
@ -3976,7 +4029,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum commoncrypto 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d056a8586ba25a1e4d61cb090900e495952c7886786fc55f909ab2f819b69007"
"checksum commoncrypto-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1fed34f46747aa73dfaa578069fd8279d2818ade2b55f38f22a9401c7f4083e2"
"checksum compiler_builtins 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6711d51cb46744dd8305293cc3fbc392aaff7a8f5095a7c4fae1e5113ef07c96"
"checksum compiletest_rs 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)" = "0d76d4322a40f6b0db7259d4f2c8a65ed8b0d84fce0bbc61b98cf47f8ec6eec3"
"checksum compiletest_rs 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)" = "56c799b1f7142badf3b047b4c1f2074cc96b6b784fb2432f2ed9c87da0a03749"
"checksum constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8ff012e225ce166d4422e0e78419d901719760f62ae2b7969ca6b564d1b54a9e"
"checksum core-foundation 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4e2640d6d0bf22e82bed1b73c6aef8d5dd31e5abe6666c57e6d45e2649f4f887"
"checksum core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e7ca8a5221364ef15ce201e8ed2f609fc312682a8f4e0e3d4aa5879764e0fa3b"
@ -4000,7 +4053,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum digest 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "03b072242a8cbaf9c145665af9d250c59af3b958f83ed6824e13533cf76d5b90"
"checksum directories 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "72d337a64190607d4fcca2cb78982c5dd57f4916e19696b48a575fa746b6cb0f"
"checksum dirs 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "88972de891f6118092b643d85a0b28e0678e0f948d7f879aa32f2d5aafe97d2a"
"checksum dlmalloc 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d56ad71b31043818d0ee10a7fb9664882f8e45849c81647585e6a3124f185517"
"checksum dlmalloc 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f283302e035e61c23f2b86b3093e8c6273a4c3125742d6087e96ade001ca5e63"
"checksum either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3be565ca5c557d7f59e7cfcf1844f9e3033650c929c6566f511e8005f205c1d0"
"checksum elasticlunr-rs 2.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a99a310cd1f9770e7bf8e48810c7bcbb0e078c8fb23a8c7bcf0da4c2bf61a455"
"checksum ena 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f56c93cc076508c549d9bb747f79aa9b4eb098be7b8cad8830c3137ef52d1e00"
@ -4064,7 +4117,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum lock_api 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "949826a5ccf18c1b3a7c3d57692778d21768b79e46eb9dd07bfc4c2160036c54"
"checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6"
"checksum log_settings 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "19af41f0565d7c19b2058153ad0b42d4d5ce89ec4dbf06ed6741114a8b63e7cd"
"checksum lsp-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f3570f641b984e3e4613a1ca34db2ea72549bbc3c0316d33f5af91ab514dcbff"
"checksum lsp-codec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "169d737ad89cf8ddd82d1804d9122f54568c49377665157277cc90d747b1d31a"
"checksum lsp-types 0.55.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6392b5843615b8a2adeebe87b83fdd29567c0870baba3407a67e6dbfee4712f8"
"checksum lzma-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "d1eaa027402541975218bb0eec67d6b0412f6233af96e0d096d31dbdfd22e614"
"checksum mac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4"
@ -4124,7 +4177,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
"checksum pretty_assertions 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3a029430f0d744bc3d15dd474d591bed2402b645d024583082b9f63bb936dac6"
"checksum pretty_env_logger 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "df8b3f4e0475def7d9c2e5de8e5a1306949849761e107b360d03e98eafaffd61"
"checksum proc-macro2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "1b06e2f335f48d24442b35a19df506a835fb3547bc3c06ef27340da9acf5cae7"
"checksum proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)" = "77619697826f31a02ae974457af0b29b723e5619e113e9397b8b82c6bd253f09"
"checksum proptest 0.8.7 (registry+https://github.com/rust-lang/crates.io-index)" = "926d0604475349f463fe44130aae73f2294b5309ab2ca0310b998bd334ef191f"
"checksum pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d6fdf85cda6cadfae5428a54661d431330b312bc767ddbc57adbedc24da66e32"
@ -4132,7 +4184,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0"
"checksum quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "07589615d719a60c8dd8a4622e7946465dfef20d1a428f969e3443e7386d5f45"
"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"
"checksum quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9949cfe66888ffe1d53e6ec9d9f3b70714083854be20fd5e271b232a017401e8"
"checksum quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "53fa22a1994bd0f9372d7a816207d8a2677ad0325b073f5c5332760f0fb62b5c"
"checksum racer 2.1.19 (registry+https://github.com/rust-lang/crates.io-index)" = "d634483bed41bb116122b84ffe0ef8740345c2ceb2784ce86c33499700eb13a7"
"checksum rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8356f47b32624fef5b3301c1be97e5944ecdd595409cc5da11d05f211db6cfbd"
@ -4158,7 +4209,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum rls-analysis 0.16.12 (registry+https://github.com/rust-lang/crates.io-index)" = "ae18d8ad01dec3b2014f4d7ae3c607d7adbcff79e5d3b48ea42ea71c10d43a71"
"checksum rls-blacklist 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b8ce1fdac03e138c4617ff87b194e1ff57a39bb985a044ccbd8673d30701e411"
"checksum rls-data 0.18.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5f80b84551b32e26affaf7f12374913b5061730c0dcd185d9e8fa5a15e36e65c"
"checksum rls-rustc 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9dba7390427aefa953608429701e3665192ca810ba8ae09301e001b7c7bed0"
"checksum rls-span 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "33d66f1d6c6ccd5c98029f162544131698f6ebb61d8c697681cac409dcd08805"
"checksum rls-vfs 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "72d56425bd5aa86d9d4372b76f0381d3b4bda9c0220e71956c9fcc929f45c1f1"
"checksum rustc-ap-arena 373.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8be999235b541fc8eb54901b66e899a06076709ac5f53d6b2c5c59d29ad54780"
@ -4172,8 +4222,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum rustc-ap-syntax_pos 373.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8e4f88a1213562373cee9de5a1d77bbf16dd706030304af041c9733492fcc952"
"checksum rustc-demangle 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "82ae957aa1b3055d8e086486723c0ccd3d7b8fa190ae8fa2e35543b6171c810e"
"checksum rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7540fc8b0c49f096ee9c961cda096467dce8084bec6bdca2fc83895fd9b28cb8"
"checksum rustc-rayon 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c6d5a683c6ba4ed37959097e88d71c9e8e26659a3cb5be8b389078e7ad45306"
"checksum rustc-rayon-core 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "40f06724db71e18d68b3b946fdf890ca8c921d9edccc1404fdfdb537b0d12649"
"checksum rustc-rayon 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8d98c51d9cbbe810c8b6693236d3412d8cd60513ff27a3e1b6af483dca0af544"
"checksum rustc-rayon-core 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "526e7b6d2707a5b9bec3927d424ad70fa3cfc68e0ac1b75e46cdbbc95adc5108"
"checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"
"checksum rustc_tools_util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3c5a95edfa0c893236ae4778bb7c4752760e4c0d245e19b5eff33c5aa5eb9dc"
"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
@ -4183,6 +4233,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum same-file 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8f20c4be53a8a1ff4c1f1b2bd14570d2f634628709752f0702ecdd2b3f9a5267"
"checksum schannel 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "0e1a231dc10abf6749cfa5d7767f25888d484201accbd919b66ab5413c502d56"
"checksum scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "332ffa32bf586782a3efaeb58f127980944bbc8c4d6913a86107ac2a5ab24b28"
"checksum scoped-tls 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2"
"checksum scoped_threadpool 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8"
"checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27"
"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
@ -4201,7 +4252,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum socket2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "c4d11a52082057d87cb5caa31ad812f4504b97ab44732cd8359df2e9ff9f48e7"
"checksum stable_deref_trait 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ffbc596e092fe5f598b12ef46cc03754085ac2f4d8c739ad61c4ae266cc3b3fa"
"checksum string_cache 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "25d70109977172b127fe834e5449e5ab1740b9ba49fa18a2020f509174f25423"
"checksum string_cache_codegen 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "35293b05cf1494e8ddd042a7df6756bf18d07f42d234f32e71dce8a7aabb0191"
"checksum string_cache_codegen 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1eea1eee654ef80933142157fdad9dd8bc43cf7c74e999e369263496f04ff4da"
"checksum string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b1884d1bc09741d466d9b14e6d37ac89d6909cbcac41dd9ae982d4d063bbedfc"
"checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550"
"checksum strum 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f6c3a2071519ab6a48f465808c4c1ffdd00dfc8e93111d02b4fc5abab177676e"
@ -4213,9 +4264,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum tar 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)" = "a303ba60a099fcd2aaa646b14d2724591a96a75283e4b7ed3d1a1658909d9ae2"
"checksum tempfile 3.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "7e91405c14320e5c79b3d148e1c86f40749a36e490642202a31689cb1a3452b2"
"checksum tendril 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9de21546595a0873061940d994bbbc5c35f024ae4fd61ec5c5b159115684f508"
"checksum term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "fa63644f74ce96fbeb9b794f66aff2a52d601cbd5e80f4b97123e3899f4570f1"
"checksum term 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5e6b677dd1e8214ea1ef4297f85dbcbed8e8cdddb561040cc998ca2551c37561"
"checksum termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4096add70612622289f2fdcdbd5086dc81c1e2675e6ae58d6c4f62a16c6d7f2f"
"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096"
"checksum tester 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5e812cb26c597f86a49b26dbb58b878bd2a2b4b93fc069dc39499228fe556ff6"
"checksum textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "307686869c93e71f94da64286f9a9524c0f308a9e1c87a583de8e9c9039ad3f6"
"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b"
"checksum time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "d825be0eb33fda1a7e68012d51e9c7f451dc1a69391e7fdc197060bb8c56667b"

View file

@ -4,10 +4,10 @@ Version 1.33.0 (2019-02-28)
Language
--------
- [You can now use the `cfg(target_vendor)` attribute.][57465] E.g.
`#[cfg(target_vendor="linux")] fn main() { println!("Hello Linux!"); }`
`#[cfg(target_vendor="apple")] fn main() { println!("Hello Apple!"); }`
- [Integer patterns such as in a match expression can now be exhaustive.][56362]
E.g. You can have match statement on a `u8` that covers `0..=255` and
you would no longer be required to have a `_ => unreachable!()` case.
you would no longer be required to have a `_ => unreachable!()` case.
- [You can now have multiple patterns in `if let` and `while let`
expressions.][57532] You can do this with the same syntax as a `match`
expression. E.g.
@ -51,8 +51,7 @@ Language
// Allowed as there is only one `Read` in the module.
pub trait Read {}
```
- [`extern` functions will now abort by default when panicking.][55982]
This was previously undefined behaviour.
- [You may now use `Rc`, `Arc`, and `Pin` as method receivers][56805].
Compiler
--------
@ -109,27 +108,30 @@ Compatibility Notes
are now deprecated in the standard library, and their usage will now produce a warning.
Please use the `str::{trim_start, trim_end, trim_start_matches, trim_end_matches}`
methods instead.
- The `Error::cause` method has been deprecated in favor of `Error::source` which supports
downcasting.
[57615]: https://github.com/rust-lang/rust/pull/57615/
[57465]: https://github.com/rust-lang/rust/pull/57465/
[57532]: https://github.com/rust-lang/rust/pull/57532/
[57535]: https://github.com/rust-lang/rust/pull/57535/
[57566]: https://github.com/rust-lang/rust/pull/57566/
[55982]: https://github.com/rust-lang/rust/pull/55982/
[56303]: https://github.com/rust-lang/rust/pull/56303/
[56351]: https://github.com/rust-lang/rust/pull/56351/
[56362]: https://github.com/rust-lang/rust/pull/56362
[56642]: https://github.com/rust-lang/rust/pull/56642/
[56769]: https://github.com/rust-lang/rust/pull/56769/
[56805]: https://github.com/rust-lang/rust/pull/56805
[56947]: https://github.com/rust-lang/rust/pull/56947/
[57049]: https://github.com/rust-lang/rust/pull/57049/
[57067]: https://github.com/rust-lang/rust/pull/57067/
[57105]: https://github.com/rust-lang/rust/pull/57105
[57130]: https://github.com/rust-lang/rust/pull/57130/
[57167]: https://github.com/rust-lang/rust/pull/57167/
[57175]: https://github.com/rust-lang/rust/pull/57175/
[57234]: https://github.com/rust-lang/rust/pull/57234/
[57332]: https://github.com/rust-lang/rust/pull/57332/
[56947]: https://github.com/rust-lang/rust/pull/56947/
[57049]: https://github.com/rust-lang/rust/pull/57049/
[57067]: https://github.com/rust-lang/rust/pull/57067/
[56769]: https://github.com/rust-lang/rust/pull/56769/
[56642]: https://github.com/rust-lang/rust/pull/56642/
[56303]: https://github.com/rust-lang/rust/pull/56303/
[56351]: https://github.com/rust-lang/rust/pull/56351/
[55982]: https://github.com/rust-lang/rust/pull/55982/
[56362]: https://github.com/rust-lang/rust/pull/56362
[57105]: https://github.com/rust-lang/rust/pull/57105
[57465]: https://github.com/rust-lang/rust/pull/57465/
[57532]: https://github.com/rust-lang/rust/pull/57532/
[57535]: https://github.com/rust-lang/rust/pull/57535/
[57566]: https://github.com/rust-lang/rust/pull/57566/
[57615]: https://github.com/rust-lang/rust/pull/57615/
[cargo/6484]: https://github.com/rust-lang/cargo/pull/6484/
[`unix::FileExt::read_exact_at`]: https://doc.rust-lang.org/std/os/unix/fs/trait.FileExt.html#method.read_exact_at
[`unix::FileExt::write_all_at`]: https://doc.rust-lang.org/std/os/unix/fs/trait.FileExt.html#method.write_all_at
@ -170,7 +172,7 @@ Language
- [You can now match against literals in macros with the `literal`
specifier.][56072] This will match against a literal of any type.
E.g. `1`, `'A'`, `"Hello World"`
- [Self can now be used as a constructor and pattern for unit and tuple structs.][56365] E.g.
- [Self can now be used as a constructor and pattern for unit and tuple structs.][56365] E.g.
```rust
struct Point(i32, i32);
@ -460,7 +462,7 @@ Version 1.31.0 (2018-12-06)
Language
--------
- 🎉 [This version marks the release of the 2018 edition of Rust.][54057] 🎉
- 🎉 [This version marks the release of the 2018 edition of Rust.][54057] 🎉
- [New lifetime elision rules now allow for eliding lifetimes in functions and
impl headers.][54778] E.g. `impl<'a> Reader for BufReader<'a> {}` can now be
`impl Reader for BufReader<'_> {}`. Lifetimes are still required to be defined

View file

@ -5,11 +5,6 @@ environment:
# server goes down presumably. See #43333 for more info
CARGO_HTTP_CHECK_REVOKE: false
# Execute the builds on GCE instead of Hyper-V. Those builders have a 3-4
# minute startup overhead, but AppVeyor support recommended this as a
# possible solution for #58160 (spurious 259 exit codes)
appveyor_build_worker_cloud: gce
matrix:
# 32/64 bit MSVC tests
- MSYS_BITS: 64

View file

@ -61,7 +61,7 @@
# support. You'll need to write a target specification at least, and most
# likely, teach rustc about the C ABI of the target. Get in touch with the
# Rust team and file an issue if you need assistance in porting!
#targets = "X86;ARM;AArch64;Mips;PowerPC;SystemZ;JSBackend;MSP430;Sparc;NVPTX;Hexagon"
#targets = "X86;ARM;AArch64;Mips;PowerPC;SystemZ;MSP430;Sparc;NVPTX;Hexagon"
# LLVM experimental targets to build support for. These targets are specified in
# the same format as above, but since these targets are experimental, they are
@ -104,6 +104,8 @@
# The value specified here will be passed as `-DLLVM_USE_LINKER` to CMake.
#use-linker = "lld"
# Whether or not to specify `-DLLVM_TEMPORARILY_ALLOW_OLD_TOOLCHAIN=YES`
#allow-old-toolchain = false
# =============================================================================
# General build configuration options
@ -162,6 +164,9 @@
# Python interpreter to use for various tasks throughout the build, notably
# rustdoc tests, the lldb python interpreter, and some dist bits and pieces.
# Note that Python 2 is currently required.
#
# Defaults to python2.7, then python2. If neither executable can be found, then
# it defaults to the Python interpreter used to execute x.py.
#python = "python2.7"
# Force Cargo to check that Cargo.lock describes the precise dependency

View file

@ -107,6 +107,14 @@ fn main() {
// actually downloaded, so we just always pass the `--sysroot` option.
cmd.arg("--sysroot").arg(&sysroot);
cmd.arg("-Zexternal-macro-backtrace");
// Link crates to the proc macro crate for the target, but use a host proc macro crate
// to actually run the macros
if env::var_os("RUST_DUAL_PROC_MACROS").is_some() {
cmd.arg("-Zdual-proc-macros");
}
// When we build Rust dylibs they're all intended for intermediate
// usage, so make sure we pass the -Cprefer-dynamic flag instead of
// linking all deps statically into the dylib.
@ -256,13 +264,6 @@ fn main() {
}
}
// Force all crates compiled by this compiler to (a) be unstable and (b)
// allow the `rustc_private` feature to link to other unstable crates
// also in the sysroot.
if env::var_os("RUSTC_FORCE_UNSTABLE").is_some() {
cmd.arg("-Z").arg("force-unstable-if-unmarked");
}
if let Ok(map) = env::var("RUSTC_DEBUGINFO_MAP") {
cmd.arg("--remap-path-prefix").arg(&map);
}
@ -282,6 +283,14 @@ fn main() {
}
}
// Force all crates compiled by this compiler to (a) be unstable and (b)
// allow the `rustc_private` feature to link to other unstable crates
// also in the sysroot. We also do this for host crates, since those
// may be proc macros, in which case we might ship them.
if env::var_os("RUSTC_FORCE_UNSTABLE").is_some() && (stage != "0" || target.is_some()) {
cmd.arg("-Z").arg("force-unstable-if-unmarked");
}
if env::var_os("RUSTC_PARALLEL_COMPILER").is_some() {
cmd.arg("--cfg").arg("parallel_compiler");
}

View file

@ -262,6 +262,10 @@ def default_build_triple():
cputype = 'arm'
if ostype == 'linux-android':
ostype = 'linux-androideabi'
elif ostype == 'unknown-freebsd':
cputype = subprocess.check_output(
['uname', '-p']).strip().decode(default_encoding)
ostype = 'unknown-freebsd'
elif cputype == 'armv6l':
cputype = 'arm'
if ostype == 'linux-android':
@ -830,7 +834,7 @@ def main():
# x.py help <cmd> ...
if len(sys.argv) > 1 and sys.argv[1] == 'help':
sys.argv = sys.argv[:1] + [sys.argv[2], '-h'] + sys.argv[3:]
sys.argv = [sys.argv[0], '-h'] + sys.argv[2:]
help_triggered = (
'-h' in sys.argv) or ('--help' in sys.argv) or (len(sys.argv) == 1)

View file

@ -405,7 +405,8 @@ impl<'a> Builder<'a> {
test::Miri,
test::Clippy,
test::CompiletestTest,
test::RustdocJS,
test::RustdocJSStd,
test::RustdocJSNotStd,
test::RustdocTheme,
// Run bootstrap close to the end as it's unlikely to fail
test::Bootstrap,
@ -813,6 +814,17 @@ impl<'a> Builder<'a> {
cargo.env("RUST_CHECK", "1");
}
match mode {
Mode::Std | Mode::Test | Mode::ToolBootstrap | Mode::ToolStd | Mode::ToolTest=> {},
Mode::Rustc | Mode::Codegen | Mode::ToolRustc => {
// Build proc macros both for the host and the target
if target != compiler.host && cmd != "check" {
cargo.arg("-Zdual-proc-macros");
cargo.env("RUST_DUAL_PROC_MACROS", "1");
}
},
}
cargo.arg("-j").arg(self.jobs().to_string());
// Remove make-related flags to ensure Cargo can correctly set things up
cargo.env_remove("MAKEFLAGS");

View file

@ -14,7 +14,7 @@ use crate::Build;
use crate::config::Config;
// The version number
pub const CFG_RELEASE_NUM: &str = "1.34.0";
pub const CFG_RELEASE_NUM: &str = "1.35.0";
pub struct GitInfo {
inner: Option<Info>,

View file

@ -42,7 +42,8 @@ impl Step for Std {
true);
let libdir = builder.sysroot_libdir(compiler, target);
add_to_sysroot(&builder, &libdir, &libstd_stamp(builder, compiler, target));
let hostdir = builder.sysroot_libdir(compiler, compiler.host);
add_to_sysroot(&builder, &libdir, &hostdir, &libstd_stamp(builder, compiler, target));
}
}
@ -88,7 +89,8 @@ impl Step for Rustc {
true);
let libdir = builder.sysroot_libdir(compiler, target);
add_to_sysroot(&builder, &libdir, &librustc_stamp(builder, compiler, target));
let hostdir = builder.sysroot_libdir(compiler, compiler.host);
add_to_sysroot(&builder, &libdir, &hostdir, &librustc_stamp(builder, compiler, target));
}
}
@ -175,7 +177,8 @@ impl Step for Test {
true);
let libdir = builder.sysroot_libdir(compiler, target);
add_to_sysroot(builder, &libdir, &libtest_stamp(builder, compiler, target));
let hostdir = builder.sysroot_libdir(compiler, compiler.host);
add_to_sysroot(builder, &libdir, &hostdir, &libtest_stamp(builder, compiler, target));
}
}
@ -222,7 +225,8 @@ impl Step for Rustdoc {
true);
let libdir = builder.sysroot_libdir(compiler, target);
add_to_sysroot(&builder, &libdir, &rustdoc_stamp(builder, compiler, target));
let hostdir = builder.sysroot_libdir(compiler, compiler.host);
add_to_sysroot(&builder, &libdir, &hostdir, &rustdoc_stamp(builder, compiler, target));
builder.cargo(compiler, Mode::ToolRustc, target, "clean");
}
}

View file

@ -224,7 +224,8 @@ impl Step for StdLink {
target_compiler.host,
target));
let libdir = builder.sysroot_libdir(target_compiler, target);
add_to_sysroot(builder, &libdir, &libstd_stamp(builder, compiler, target));
let hostdir = builder.sysroot_libdir(target_compiler, compiler.host);
add_to_sysroot(builder, &libdir, &hostdir, &libstd_stamp(builder, compiler, target));
if builder.config.sanitizers && compiler.stage != 0 && target == "x86_64-apple-darwin" {
// The sanitizers are only built in stage1 or above, so the dylibs will
@ -431,8 +432,12 @@ impl Step for TestLink {
&compiler.host,
target_compiler.host,
target));
add_to_sysroot(builder, &builder.sysroot_libdir(target_compiler, target),
&libtest_stamp(builder, compiler, target));
add_to_sysroot(
builder,
&builder.sysroot_libdir(target_compiler, target),
&builder.sysroot_libdir(target_compiler, compiler.host),
&libtest_stamp(builder, compiler, target)
);
builder.cargo(target_compiler, Mode::ToolTest, target, "clean");
}
@ -496,8 +501,8 @@ impl Step for Rustc {
return;
}
// Ensure that build scripts have a std to link against.
builder.ensure(Std {
// Ensure that build scripts and proc macros have a std / libproc_macro to link against.
builder.ensure(Test {
compiler: builder.compiler(self.compiler.stage, builder.config.build),
target: builder.config.build,
});
@ -592,8 +597,12 @@ impl Step for RustcLink {
&compiler.host,
target_compiler.host,
target));
add_to_sysroot(builder, &builder.sysroot_libdir(target_compiler, target),
&librustc_stamp(builder, compiler, target));
add_to_sysroot(
builder,
&builder.sysroot_libdir(target_compiler, target),
&builder.sysroot_libdir(target_compiler, compiler.host),
&librustc_stamp(builder, compiler, target)
);
builder.cargo(target_compiler, Mode::ToolRustc, target, "clean");
}
}
@ -1015,10 +1024,20 @@ impl Step for Assemble {
///
/// For a particular stage this will link the file listed in `stamp` into the
/// `sysroot_dst` provided.
pub fn add_to_sysroot(builder: &Builder<'_>, sysroot_dst: &Path, stamp: &Path) {
pub fn add_to_sysroot(
builder: &Builder<'_>,
sysroot_dst: &Path,
sysroot_host_dst: &Path,
stamp: &Path
) {
t!(fs::create_dir_all(&sysroot_dst));
for path in builder.read_stamp_file(stamp) {
builder.copy(&path, &sysroot_dst.join(path.file_name().unwrap()));
t!(fs::create_dir_all(&sysroot_host_dst));
for (path, host) in builder.read_stamp_file(stamp) {
if host {
builder.copy(&path, &sysroot_host_dst.join(path.file_name().unwrap()));
} else {
builder.copy(&path, &sysroot_dst.join(path.file_name().unwrap()));
}
}
}
@ -1047,8 +1066,14 @@ pub fn run_cargo(builder: &Builder<'_>,
let mut deps = Vec::new();
let mut toplevel = Vec::new();
let ok = stream_cargo(builder, cargo, &mut |msg| {
let filenames = match msg {
CargoMessage::CompilerArtifact { filenames, .. } => filenames,
let (filenames, crate_types) = match msg {
CargoMessage::CompilerArtifact {
filenames,
target: CargoTarget {
crate_types,
},
..
} => (filenames, crate_types),
_ => return,
};
for filename in filenames {
@ -1063,15 +1088,19 @@ pub fn run_cargo(builder: &Builder<'_>,
let filename = Path::new(&*filename);
// If this was an output file in the "host dir" we don't actually
// worry about it, it's not relevant for us.
// worry about it, it's not relevant for us
if filename.starts_with(&host_root_dir) {
// Unless it's a proc macro used in the compiler
if crate_types.iter().any(|t| t == "proc-macro") {
deps.push((filename.to_path_buf(), true));
}
continue;
}
// If this was output in the `deps` dir then this is a precise file
// name (hash included) so we start tracking it.
if filename.starts_with(&target_deps_dir) {
deps.push(filename.to_path_buf());
deps.push((filename.to_path_buf(), false));
continue;
}
@ -1124,10 +1153,10 @@ pub fn run_cargo(builder: &Builder<'_>,
let candidate = format!("{}.lib", path_to_add);
let candidate = PathBuf::from(candidate);
if candidate.exists() {
deps.push(candidate);
deps.push((candidate, false));
}
}
deps.push(path_to_add.into());
deps.push((path_to_add.into(), false));
}
// Now we want to update the contents of the stamp file, if necessary. First
@ -1140,12 +1169,13 @@ pub fn run_cargo(builder: &Builder<'_>,
let mut new_contents = Vec::new();
let mut max = None;
let mut max_path = None;
for dep in deps.iter() {
for (dep, proc_macro) in deps.iter() {
let mtime = mtime(dep);
if Some(mtime) > max {
max = Some(mtime);
max_path = Some(dep.clone());
}
new_contents.extend(if *proc_macro { b"h" } else { b"t" });
new_contents.extend(dep.to_str().unwrap().as_bytes());
new_contents.extend(b"\0");
}
@ -1157,7 +1187,7 @@ pub fn run_cargo(builder: &Builder<'_>,
if contents_equal && max <= stamp_mtime {
builder.verbose(&format!("not updating {:?}; contents equal and {:?} <= {:?}",
stamp, max, stamp_mtime));
return deps
return deps.into_iter().map(|(d, _)| d).collect()
}
if max > stamp_mtime {
builder.verbose(&format!("updating {:?} as {:?} changed", stamp, max_path));
@ -1165,7 +1195,7 @@ pub fn run_cargo(builder: &Builder<'_>,
builder.verbose(&format!("updating {:?} as deps changed", stamp));
}
t!(fs::write(&stamp, &new_contents));
deps
deps.into_iter().map(|(d, _)| d).collect()
}
pub fn stream_cargo(
@ -1211,6 +1241,11 @@ pub fn stream_cargo(
status.success()
}
#[derive(Deserialize)]
pub struct CargoTarget<'a> {
crate_types: Vec<Cow<'a, str>>,
}
#[derive(Deserialize)]
#[serde(tag = "reason", rename_all = "kebab-case")]
pub enum CargoMessage<'a> {
@ -1218,6 +1253,7 @@ pub enum CargoMessage<'a> {
package_id: Cow<'a, str>,
features: Vec<Cow<'a, str>>,
filenames: Vec<Cow<'a, str>>,
target: CargoTarget<'a>,
},
BuildScriptExecuted {
package_id: Cow<'a, str>,

View file

@ -78,6 +78,7 @@ pub struct Config {
pub llvm_link_jobs: Option<u32>,
pub llvm_version_suffix: Option<String>,
pub llvm_use_linker: Option<String>,
pub llvm_allow_old_toolchain: Option<bool>,
pub lld_enabled: bool,
pub lldb_enabled: bool,
@ -263,6 +264,7 @@ struct Llvm {
ldflags: Option<String>,
use_libcxx: Option<bool>,
use_linker: Option<String>,
allow_old_toolchain: Option<bool>,
}
#[derive(Deserialize, Default, Clone)]
@ -530,6 +532,7 @@ impl Config {
config.llvm_ldflags = llvm.ldflags.clone();
set(&mut config.llvm_use_libcxx, llvm.use_libcxx);
config.llvm_use_linker = llvm.use_linker.clone();
config.llvm_allow_old_toolchain = llvm.allow_old_toolchain.clone();
}
if let Some(ref rust) = toml.rust {

View file

@ -904,6 +904,8 @@ impl Step for Src {
"src/stdsimd",
"src/libproc_macro",
"src/tools/rustc-std-workspace-core",
"src/librustc",
"src/libsyntax",
];
copy_src_dirs(builder, &std_src_dirs[..], &[], &dst_src);

View file

@ -60,7 +60,7 @@ macro_rules! book {
// NOTE: When adding a book here, make sure to ALSO build the book by
// adding a build step in `src/bootstrap/builder.rs`!
book!(
EditionGuide, "src/doc/edition-guide", "edition-guide", RustbookVersion::MdBook1;
EditionGuide, "src/doc/edition-guide", "edition-guide", RustbookVersion::MdBook2;
EmbeddedBook, "src/doc/embedded-book", "embedded-book", RustbookVersion::MdBook2;
Nomicon, "src/doc/nomicon", "nomicon", RustbookVersion::MdBook1;
Reference, "src/doc/reference", "reference", RustbookVersion::MdBook1;

View file

@ -1129,7 +1129,7 @@ impl Build {
ret
}
fn read_stamp_file(&self, stamp: &Path) -> Vec<PathBuf> {
fn read_stamp_file(&self, stamp: &Path) -> Vec<(PathBuf, bool)> {
if self.config.dry_run {
return Vec::new();
}
@ -1142,8 +1142,9 @@ impl Build {
if part.is_empty() {
continue
}
let path = PathBuf::from(t!(str::from_utf8(part)));
paths.push(path);
let host = part[0] as char == 'h';
let path = PathBuf::from(t!(str::from_utf8(&part[1..])));
paths.push((path, host));
}
paths
}

View file

@ -238,6 +238,10 @@ impl Step for Llvm {
cfg.define("LLVM_USE_LINKER", linker);
}
if let Some(true) = builder.config.llvm_allow_old_toolchain {
cfg.define("LLVM_TEMPORARILY_ALLOW_OLD_TOOLCHAIN", "YES");
}
if let Some(ref python) = builder.config.python {
cfg.define("PYTHON_EXECUTABLE", python);
}

View file

@ -34,15 +34,17 @@ impl Finder {
fn maybe_have<S: AsRef<OsStr>>(&mut self, cmd: S) -> Option<PathBuf> {
let cmd: OsString = cmd.as_ref().into();
let path = self.path.clone();
let path = &self.path;
self.cache.entry(cmd.clone()).or_insert_with(|| {
for path in env::split_paths(&path) {
for path in env::split_paths(path) {
let target = path.join(&cmd);
let mut cmd_alt = cmd.clone();
cmd_alt.push(".exe");
if target.is_file() || // some/path/git
target.with_extension("exe").exists() || // some/path/git.exe
target.join(&cmd_alt).exists() { // some/path/git/git.exe
let mut cmd_exe = cmd.clone();
cmd_exe.push(".exe");
if target.is_file() // some/path/git
|| path.join(&cmd_exe).exists() // some/path/git.exe
|| target.join(&cmd_exe).exists() // some/path/git/git.exe
{
return Some(target);
}
}
@ -107,9 +109,9 @@ pub fn check(build: &mut Build) {
}
build.config.python = build.config.python.take().map(|p| cmd_finder.must_have(p))
.or_else(|| env::var_os("BOOTSTRAP_PYTHON").map(PathBuf::from)) // set by bootstrap.py
.or_else(|| cmd_finder.maybe_have("python2.7"))
.or_else(|| cmd_finder.maybe_have("python2"))
.or_else(|| env::var_os("BOOTSTRAP_PYTHON").map(PathBuf::from)) // set by bootstrap.py
.or_else(|| Some(cmd_finder.must_have("python")));
build.config.nodejs = build.config.nodejs.take().map(|p| cmd_finder.must_have(p))

View file

@ -574,12 +574,52 @@ impl Step for RustdocTheme {
}
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub struct RustdocJS {
pub struct RustdocJSStd {
pub host: Interned<String>,
pub target: Interned<String>,
}
impl Step for RustdocJS {
impl Step for RustdocJSStd {
type Output = ();
const DEFAULT: bool = true;
const ONLY_HOSTS: bool = true;
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
run.path("src/test/rustdoc-js-std")
}
fn make_run(run: RunConfig<'_>) {
run.builder.ensure(RustdocJSStd {
host: run.host,
target: run.target,
});
}
fn run(self, builder: &Builder<'_>) {
if let Some(ref nodejs) = builder.config.nodejs {
let mut command = Command::new(nodejs);
command.args(&["src/tools/rustdoc-js-std/tester.js", &*self.host]);
builder.ensure(crate::doc::Std {
target: self.target,
stage: builder.top_stage,
});
builder.run(&mut command);
} else {
builder.info(
"No nodejs found, skipping \"src/test/rustdoc-js-std\" tests"
);
}
}
}
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub struct RustdocJSNotStd {
pub host: Interned<String>,
pub target: Interned<String>,
pub compiler: Compiler,
}
impl Step for RustdocJSNotStd {
type Output = ();
const DEFAULT: bool = true;
const ONLY_HOSTS: bool = true;
@ -589,21 +629,24 @@ impl Step for RustdocJS {
}
fn make_run(run: RunConfig<'_>) {
run.builder.ensure(RustdocJS {
let compiler = run.builder.compiler(run.builder.top_stage, run.host);
run.builder.ensure(RustdocJSNotStd {
host: run.host,
target: run.target,
compiler,
});
}
fn run(self, builder: &Builder<'_>) {
if let Some(ref nodejs) = builder.config.nodejs {
let mut command = Command::new(nodejs);
command.args(&["src/tools/rustdoc-js/tester.js", &*self.host]);
builder.ensure(crate::doc::Std {
if builder.config.nodejs.is_some() {
builder.ensure(Compiletest {
compiler: self.compiler,
target: self.target,
stage: builder.top_stage,
mode: "js-doc-test",
suite: "rustdoc-js",
path: None,
compare_mode: None,
});
builder.run(&mut command);
} else {
builder.info(
"No nodejs found, skipping \"src/test/rustdoc-js\" tests"
@ -996,12 +1039,13 @@ impl Step for Compiletest {
.arg(builder.sysroot_libdir(compiler, target));
cmd.arg("--rustc-path").arg(builder.rustc(compiler));
let is_rustdoc_ui = suite.ends_with("rustdoc-ui");
let is_rustdoc = suite.ends_with("rustdoc-ui") || suite.ends_with("rustdoc-js");
// Avoid depending on rustdoc when we don't need it.
if mode == "rustdoc"
|| (mode == "run-make" && suite.ends_with("fulldeps"))
|| (mode == "ui" && is_rustdoc_ui)
|| (mode == "ui" && is_rustdoc)
|| mode == "js-doc-test"
{
cmd.arg("--rustdoc-path")
.arg(builder.rustdoc(compiler.host));
@ -1035,12 +1079,12 @@ impl Step for Compiletest {
cmd.arg("--nodejs").arg(nodejs);
}
let mut flags = if is_rustdoc_ui {
let mut flags = if is_rustdoc {
Vec::new()
} else {
vec!["-Crpath".to_string()]
};
if !is_rustdoc_ui {
if !is_rustdoc {
if builder.config.rust_optimize_tests {
flags.push("-O".to_string());
}

View file

@ -91,7 +91,8 @@ impl Step for ToolBuild {
compile::CargoMessage::CompilerArtifact {
package_id,
features,
filenames
filenames,
target: _,
} => {
(package_id, features, filenames)
}

View file

@ -3,23 +3,8 @@ FROM ubuntu:16.04
COPY scripts/cross-apt-packages.sh /scripts/
RUN sh /scripts/cross-apt-packages.sh
# Ubuntu 16.04 (this container) ships with make 4, but something in the
# toolchains we build below chokes on that, so go back to make 3
COPY scripts/make3.sh /scripts/
RUN sh /scripts/make3.sh
COPY scripts/crosstool-ng.sh /scripts/
RUN sh /scripts/crosstool-ng.sh
COPY scripts/rustbuild-setup.sh /scripts/
RUN sh /scripts/rustbuild-setup.sh
USER rustbuild
WORKDIR /tmp
COPY dist-x86_64-netbsd/build-netbsd-toolchain.sh /tmp/
RUN ./build-netbsd-toolchain.sh
USER root
RUN /tmp/build-netbsd-toolchain.sh
COPY scripts/sccache.sh /scripts/
RUN sh /scripts/sccache.sh

View file

@ -28,15 +28,15 @@ mkdir -p /x-tools/x86_64-unknown-netbsd/sysroot
URL=https://s3-us-west-1.amazonaws.com/rust-lang-ci2/rust-ci-mirror
# Originally from ftp://ftp.netbsd.org/pub/NetBSD/NetBSD-$BSD/source/sets/*.tgz
curl $URL/2017-03-17-netbsd-src.tgz | tar xzf -
curl $URL/2017-03-17-netbsd-gnusrc.tgz | tar xzf -
curl $URL/2017-03-17-netbsd-sharesrc.tgz | tar xzf -
curl $URL/2017-03-17-netbsd-syssrc.tgz | tar xzf -
curl $URL/2018-03-01-netbsd-src.tgz | tar xzf -
curl $URL/2018-03-01-netbsd-gnusrc.tgz | tar xzf -
curl $URL/2018-03-01-netbsd-sharesrc.tgz | tar xzf -
curl $URL/2018-03-01-netbsd-syssrc.tgz | tar xzf -
# Originally from ftp://ftp.netbsd.org/pub/NetBSD/NetBSD-$BSD/amd64/binary/sets/*.tgz
curl $URL/2017-03-17-netbsd-base.tgz | \
curl $URL/2018-03-01-netbsd-base.tgz | \
tar xzf - -C /x-tools/x86_64-unknown-netbsd/sysroot ./usr/include ./usr/lib ./lib
curl $URL/2017-03-17-netbsd-comp.tgz | \
curl $URL/2018-03-01-netbsd-comp.tgz | \
tar xzf - -C /x-tools/x86_64-unknown-netbsd/sysroot ./usr/include ./usr/lib
cd usr/src

View file

@ -18,4 +18,10 @@ COPY scripts/sccache.sh /scripts/
RUN sh /scripts/sccache.sh
ENV RUST_CONFIGURE_ARGS --build=i686-unknown-linux-gnu
ENV SCRIPT python2.7 ../x.py test
# Exclude some tests that are unlikely to be platform specific, to speed up
# this slow job.
ENV SCRIPT python2.7 ../x.py test \
--exclude src/bootstrap \
--exclude src/test/rustdoc-js \
--exclude src/tools/error_index_generator \
--exclude src/tools/linkchecker

@ -1 +1 @@
Subproject commit 0e9061cbaf95adfb9f3ed36c6cef4c046f282e86
Subproject commit 9cffbeabec3bcec42d09432bfe7705125c848889

@ -1 +1 @@
Subproject commit 419edb885ec1a98c0747b3907003d79e3e6b93a9
Subproject commit aa0022c875907886cae8f3ef8e9ebf6e2a5e728d

@ -1 +1 @@
Subproject commit bd2778f304989ee52be8201504d6ec621dd60ca9
Subproject commit 9e656ead82bfe869493dec82653a52e27fa6a05c

@ -1 +1 @@
Subproject commit b7eb4a087207af2405c0669fa577f8545b894c66
Subproject commit f1ff93b66844493a7b03101c7df66ac958c62418

@ -1 +1 @@
Subproject commit 1c775a1dc5e29bc44b36604b510d6196d98077fa
Subproject commit 41493ffce5d0e17d54eaf5ec9a995054e2b9aece

View file

@ -53,7 +53,7 @@ For example, in the following code:
```rust
/// Does the thing.
pub fn do_the_thing(_: SomeType) {
println!("Let's do the thing!");
println!("Let's do the thing!");
}
/// Token you use to [`do_the_thing`].
@ -66,15 +66,15 @@ target out also works:
```rust
pub mod some_module {
/// Token you use to do the thing.
pub struct SomeStruct;
/// Token you use to do the thing.
pub struct SomeStruct;
}
/// Does the thing. Requires one [`SomeStruct`] for the thing to work.
///
/// [`SomeStruct`]: some_module::SomeStruct
pub fn do_the_thing(_: some_module::SomeStruct) {
println!("Let's do the thing!");
println!("Let's do the thing!");
}
```
@ -428,3 +428,30 @@ $ rustdoc src/lib.rs --test -Z unstable-options --persist-doctests target/rustdo
This flag allows you to keep doctest executables around after they're compiled or run.
Usually, rustdoc will immediately discard a compiled doctest after it's been tested, but
with this option, you can keep those binaries around for farther testing.
### `--show-coverage`: calculate the percentage of items with documentation
Using this flag looks like this:
```bash
$ rustdoc src/lib.rs -Z unstable-options --show-coverage
```
If you want to determine how many items in your crate are documented, pass this flag to rustdoc.
When it receives this flag, it will count the public items in your crate that have documentation,
and print out the counts and a percentage instead of generating docs.
Some methodology notes about what rustdoc counts in this metric:
* Rustdoc will only count items from your crate (i.e. items re-exported from other crates don't
count).
* Docs written directly onto inherent impl blocks are not counted, even though their doc comments
are displayed, because the common pattern in Rust code is to write all inherent methods into the
same impl block.
* Items in a trait implementation are not counted, as those impls will inherit any docs from the
trait itself.
* By default, only public items are counted. To count private items as well, pass
`--document-private-items` at the same time.
Public items that are not documented can be seen with the built-in `missing_docs` lint. Private
items that are not documented can be seen with Clippy's `missing_docs_in_private_items` lint.

View file

@ -0,0 +1,24 @@
# `c_variadic`
The tracking issue for this feature is: [#44930]
[#44930]: https://github.com/rust-lang/rust/issues/44930
------------------------
The `c_variadic` language feature enables C-variadic functions to be
defined in Rust. The may be called both from within Rust and via FFI.
## Examples
```rust
#![feature(c_variadic)]
pub unsafe extern "C" fn add(n: usize, mut args: ...) -> usize {
let mut sum = 0;
for _ in 0..n {
sum += args.arg::<usize>();
}
sum
}
```

View file

@ -0,0 +1,26 @@
# `c_variadic`
The tracking issue for this feature is: [#44930]
[#44930]: https://github.com/rust-lang/rust/issues/44930
------------------------
The `c_variadic` library feature exposes the `VaList` structure,
Rust's analogue of C's `va_list` type.
## Examples
```rust
#![feature(c_variadic)]
use std::ffi::VaList;
pub unsafe extern "C" fn vadd(n: usize, mut args: VaList) -> usize {
let mut sum = 0;
for _ in 0..n {
sum += args.arg::<usize>();
}
sum
}
```

View file

@ -290,6 +290,8 @@ def print_array_of_values(array_name, data_ptr_val, length, internal_dict):
def read_utf8_string(ptr_val, byte_count):
if byte_count == 0:
return '""'
error = lldb.SBError()
process = ptr_val.get_wrapped_value().GetProcess()
data = process.ReadMemory(ptr_val.as_integer(), byte_count, error)

View file

@ -489,7 +489,7 @@ impl<T: ?Sized> From<Box<T>> for Pin<Box<T>> {
}
#[stable(feature = "box_from_slice", since = "1.17.0")]
impl<'a, T: Copy> From<&'a [T]> for Box<[T]> {
impl<T: Copy> From<&[T]> for Box<[T]> {
/// Converts a `&[T]` into a `Box<[T]>`
///
/// This conversion allocates on the heap
@ -503,7 +503,7 @@ impl<'a, T: Copy> From<&'a [T]> for Box<[T]> {
///
/// println!("{:?}", boxed_slice);
/// ```
fn from(slice: &'a [T]) -> Box<[T]> {
fn from(slice: &[T]) -> Box<[T]> {
let mut boxed = unsafe { RawVec::with_capacity(slice.len()).into_box() };
boxed.copy_from_slice(slice);
boxed
@ -511,7 +511,7 @@ impl<'a, T: Copy> From<&'a [T]> for Box<[T]> {
}
#[stable(feature = "box_from_slice", since = "1.17.0")]
impl<'a> From<&'a str> for Box<str> {
impl From<&str> for Box<str> {
/// Converts a `&str` into a `Box<str>`
///
/// This conversion allocates on the heap
@ -523,7 +523,7 @@ impl<'a> From<&'a str> for Box<str> {
/// println!("{}", boxed);
/// ```
#[inline]
fn from(s: &'a str) -> Box<str> {
fn from(s: &str) -> Box<str> {
unsafe { from_boxed_utf8_unchecked(Box::from(s.as_bytes())) }
}
}

View file

@ -34,8 +34,7 @@
#[cfg(not(test))]
#[macro_export]
#[stable(feature = "rust1", since = "1.0.0")]
#[cfg_attr(not(stage0), allow_internal_unstable(box_syntax))]
#[cfg_attr(stage0, allow_internal_unstable)]
#[allow_internal_unstable(box_syntax)]
macro_rules! vec {
($elem:expr; $n:expr) => (
$crate::vec::from_elem($elem, $n)

View file

@ -1145,7 +1145,7 @@ impl<T> From<T> for Rc<T> {
}
#[stable(feature = "shared_from_slice", since = "1.21.0")]
impl<'a, T: Clone> From<&'a [T]> for Rc<[T]> {
impl<T: Clone> From<&[T]> for Rc<[T]> {
#[inline]
fn from(v: &[T]) -> Rc<[T]> {
<Self as RcFromSlice<T>>::from_slice(v)
@ -1153,7 +1153,7 @@ impl<'a, T: Clone> From<&'a [T]> for Rc<[T]> {
}
#[stable(feature = "shared_from_slice", since = "1.21.0")]
impl<'a> From<&'a str> for Rc<str> {
impl From<&str> for Rc<str> {
#[inline]
fn from(v: &str) -> Rc<str> {
let rc = Rc::<[u8]>::from(v.as_bytes());

View file

@ -486,7 +486,7 @@ impl String {
/// [`str::from_utf8`]: ../../std/str/fn.from_utf8.html
/// [`as_bytes`]: struct.String.html#method.as_bytes
/// [`FromUtf8Error`]: struct.FromUtf8Error.html
/// [`Err`]: ../../stdresult/enum.Result.html#variant.Err
/// [`Err`]: ../../std/result/enum.Result.html#variant.Err
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn from_utf8(vec: Vec<u8>) -> Result<String, FromUtf8Error> {
@ -2073,48 +2073,17 @@ impl ops::DerefMut for String {
/// [`String`]: struct.String.html
/// [`from_str`]: ../../std/str/trait.FromStr.html#tymethod.from_str
#[stable(feature = "str_parse_error", since = "1.5.0")]
#[derive(Copy)]
pub enum ParseError {}
pub type ParseError = core::convert::Infallible;
#[stable(feature = "rust1", since = "1.0.0")]
impl FromStr for String {
type Err = ParseError;
type Err = core::convert::Infallible;
#[inline]
fn from_str(s: &str) -> Result<String, ParseError> {
Ok(String::from(s))
}
}
#[stable(feature = "str_parse_error", since = "1.5.0")]
impl Clone for ParseError {
fn clone(&self) -> ParseError {
match *self {}
}
}
#[stable(feature = "str_parse_error", since = "1.5.0")]
impl fmt::Debug for ParseError {
fn fmt(&self, _: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {}
}
}
#[stable(feature = "str_parse_error2", since = "1.8.0")]
impl fmt::Display for ParseError {
fn fmt(&self, _: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {}
}
}
#[stable(feature = "str_parse_error", since = "1.5.0")]
impl PartialEq for ParseError {
fn eq(&self, _: &ParseError) -> bool {
match *self {}
}
}
#[stable(feature = "str_parse_error", since = "1.5.0")]
impl Eq for ParseError {}
/// A trait for converting a value to a `String`.
///
@ -2203,9 +2172,9 @@ impl AsRef<[u8]> for String {
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> From<&'a str> for String {
impl From<&str> for String {
#[inline]
fn from(s: &'a str) -> String {
fn from(s: &str) -> String {
s.to_owned()
}
}

View file

@ -1260,7 +1260,7 @@ impl<T> Vec<T> {
/// This method uses a closure to create new values on every push. If
/// you'd rather [`Clone`] a given value, use [`resize`]. If you want
/// to use the [`Default`] trait to generate values, you can pass
/// [`Default::default()`] as the second argument..
/// [`Default::default()`] as the second argument.
///
/// # Examples
///
@ -2182,25 +2182,25 @@ impl<T> AsMut<[T]> for Vec<T> {
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T: Clone> From<&'a [T]> for Vec<T> {
impl<T: Clone> From<&[T]> for Vec<T> {
#[cfg(not(test))]
fn from(s: &'a [T]) -> Vec<T> {
fn from(s: &[T]) -> Vec<T> {
s.to_vec()
}
#[cfg(test)]
fn from(s: &'a [T]) -> Vec<T> {
fn from(s: &[T]) -> Vec<T> {
crate::slice::to_vec(s)
}
}
#[stable(feature = "vec_from_mut", since = "1.19.0")]
impl<'a, T: Clone> From<&'a mut [T]> for Vec<T> {
impl<T: Clone> From<&mut [T]> for Vec<T> {
#[cfg(not(test))]
fn from(s: &'a mut [T]) -> Vec<T> {
fn from(s: &mut [T]) -> Vec<T> {
s.to_vec()
}
#[cfg(test)]
fn from(s: &'a mut [T]) -> Vec<T> {
fn from(s: &mut [T]) -> Vec<T> {
crate::slice::to_vec(s)
}
}
@ -2231,8 +2231,8 @@ impl<T> From<Vec<T>> for Box<[T]> {
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> From<&'a str> for Vec<u8> {
fn from(s: &'a str) -> Vec<u8> {
impl From<&str> for Vec<u8> {
fn from(s: &str) -> Vec<u8> {
From::from(s.as_bytes())
}
}
@ -2468,6 +2468,25 @@ impl<T: fmt::Debug> fmt::Debug for Drain<'_, T> {
}
}
impl<'a, T> Drain<'a, T> {
/// Returns the remaining items of this iterator as a slice.
///
/// # Examples
///
/// ```
/// # #![feature(vec_drain_as_slice)]
/// let mut vec = vec!['a', 'b', 'c'];
/// let mut drain = vec.drain(..);
/// assert_eq!(drain.as_slice(), &['a', 'b', 'c']);
/// let _ = drain.next().unwrap();
/// assert_eq!(drain.as_slice(), &['b', 'c']);
/// ```
#[unstable(feature = "vec_drain_as_slice", reason = "recently added", issue = "58957")]
pub fn as_slice(&self) -> &[T] {
self.iter.as_slice()
}
}
#[stable(feature = "drain", since = "1.6.0")]
unsafe impl<T: Sync> Sync for Drain<'_, T> {}
#[stable(feature = "drain", since = "1.6.0")]

View file

@ -49,7 +49,7 @@ unsafe impl<T, A: Unsize<[T]>> FixedSizeArray<T> for A {
}
/// The error type returned when a conversion from a slice to an array fails.
#[unstable(feature = "try_from", issue = "33417")]
#[stable(feature = "try_from", since = "1.34.0")]
#[derive(Debug, Copy, Clone)]
pub struct TryFromSliceError(());
@ -138,8 +138,8 @@ macro_rules! array_impls {
}
}
#[unstable(feature = "try_from", issue = "33417")]
impl<'a, T> TryFrom<&'a [T]> for [T; $N] where T: Copy {
#[stable(feature = "try_from", since = "1.34.0")]
impl<T> TryFrom<&[T]> for [T; $N] where T: Copy {
type Error = TryFromSliceError;
fn try_from(slice: &[T]) -> Result<[T; $N], TryFromSliceError> {
@ -147,7 +147,7 @@ macro_rules! array_impls {
}
}
#[unstable(feature = "try_from", issue = "33417")]
#[stable(feature = "try_from", since = "1.34.0")]
impl<'a, T> TryFrom<&'a [T]> for &'a [T; $N] {
type Error = TryFromSliceError;
@ -161,7 +161,7 @@ macro_rules! array_impls {
}
}
#[unstable(feature = "try_from", issue = "33417")]
#[stable(feature = "try_from", since = "1.34.0")]
impl<'a, T> TryFrom<&'a mut [T]> for &'a mut [T; $N] {
type Error = TryFromSliceError;

View file

@ -35,7 +35,7 @@ fn scatter(x: i32) -> i32 { (x * 31) % 127 }
fn bench_max_by_key(b: &mut Bencher) {
b.iter(|| {
let it = 0..100;
it.max_by_key(|&x| scatter(x))
it.map(black_box).max_by_key(|&x| scatter(x))
})
}
@ -56,7 +56,7 @@ fn bench_max_by_key2(b: &mut Bencher) {
fn bench_max(b: &mut Bencher) {
b.iter(|| {
let it = 0..100;
it.map(scatter).max()
it.map(black_box).map(scatter).max()
})
}
@ -185,13 +185,13 @@ bench_sums! {
bench_sums! {
bench_filter_sum,
bench_filter_ref_sum,
(0i64..1000000).filter(|x| x % 2 == 0)
(0i64..1000000).filter(|x| x % 3 == 0)
}
bench_sums! {
bench_filter_chain_sum,
bench_filter_chain_ref_sum,
(0i64..1000000).chain(0..1000000).filter(|x| x % 2 == 0)
(0i64..1000000).chain(0..1000000).filter(|x| x % 3 == 0)
}
bench_sums! {
@ -306,3 +306,31 @@ fn bench_skip_then_zip(b: &mut Bencher) {
assert_eq!(s, 2009900);
});
}
#[bench]
fn bench_filter_count(b: &mut Bencher) {
b.iter(|| {
(0i64..1000000).map(black_box).filter(|x| x % 3 == 0).count()
})
}
#[bench]
fn bench_filter_ref_count(b: &mut Bencher) {
b.iter(|| {
(0i64..1000000).map(black_box).by_ref().filter(|x| x % 3 == 0).count()
})
}
#[bench]
fn bench_filter_chain_count(b: &mut Bencher) {
b.iter(|| {
(0i64..1000000).chain(0..1000000).map(black_box).filter(|x| x % 3 == 0).count()
})
}
#[bench]
fn bench_filter_chain_ref_count(b: &mut Bencher) {
b.iter(|| {
(0i64..1000000).chain(0..1000000).map(black_box).by_ref().filter(|x| x % 3 == 0).count()
})
}

View file

@ -218,7 +218,7 @@ impl FromStr for char {
}
#[unstable(feature = "try_from", issue = "33417")]
#[stable(feature = "try_from", since = "1.34.0")]
impl TryFrom<u32> for char {
type Error = CharTryFromError;
@ -233,11 +233,11 @@ impl TryFrom<u32> for char {
}
/// The error type returned when a conversion from u32 to char fails.
#[unstable(feature = "try_from", issue = "33417")]
#[stable(feature = "try_from", since = "1.34.0")]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct CharTryFromError(());
#[unstable(feature = "try_from", issue = "33417")]
#[stable(feature = "try_from", since = "1.34.0")]
impl fmt::Display for CharTryFromError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
"converted integer out of range for `char`".fmt(f)

View file

@ -30,7 +30,7 @@ pub use self::convert::{from_u32, from_digit};
pub use self::convert::from_u32_unchecked;
#[stable(feature = "char_from_str", since = "1.20.0")]
pub use self::convert::ParseCharError;
#[unstable(feature = "try_from", issue = "33417")]
#[stable(feature = "try_from", since = "1.34.0")]
pub use self::convert::CharTryFromError;
#[stable(feature = "decode_utf16", since = "1.9.0")]
pub use self::decode::{decode_utf16, DecodeUtf16, DecodeUtf16Error};

View file

@ -1004,26 +1004,26 @@ mod impls {
// & pointers
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, 'b, A: ?Sized, B: ?Sized> PartialEq<&'b B> for &'a A where A: PartialEq<B> {
impl<A: ?Sized, B: ?Sized> PartialEq<&B> for &A where A: PartialEq<B> {
#[inline]
fn eq(&self, other: & &'b B) -> bool { PartialEq::eq(*self, *other) }
fn eq(&self, other: & &B) -> bool { PartialEq::eq(*self, *other) }
#[inline]
fn ne(&self, other: & &'b B) -> bool { PartialEq::ne(*self, *other) }
fn ne(&self, other: & &B) -> bool { PartialEq::ne(*self, *other) }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, 'b, A: ?Sized, B: ?Sized> PartialOrd<&'b B> for &'a A where A: PartialOrd<B> {
impl<A: ?Sized, B: ?Sized> PartialOrd<&B> for &A where A: PartialOrd<B> {
#[inline]
fn partial_cmp(&self, other: &&'b B) -> Option<Ordering> {
fn partial_cmp(&self, other: &&B) -> Option<Ordering> {
PartialOrd::partial_cmp(*self, *other)
}
#[inline]
fn lt(&self, other: & &'b B) -> bool { PartialOrd::lt(*self, *other) }
fn lt(&self, other: & &B) -> bool { PartialOrd::lt(*self, *other) }
#[inline]
fn le(&self, other: & &'b B) -> bool { PartialOrd::le(*self, *other) }
fn le(&self, other: & &B) -> bool { PartialOrd::le(*self, *other) }
#[inline]
fn ge(&self, other: & &'b B) -> bool { PartialOrd::ge(*self, *other) }
fn ge(&self, other: & &B) -> bool { PartialOrd::ge(*self, *other) }
#[inline]
fn gt(&self, other: & &'b B) -> bool { PartialOrd::gt(*self, *other) }
fn gt(&self, other: & &B) -> bool { PartialOrd::gt(*self, *other) }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<A: ?Sized> Ord for &A where A: Ord {
@ -1036,26 +1036,26 @@ mod impls {
// &mut pointers
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, 'b, A: ?Sized, B: ?Sized> PartialEq<&'b mut B> for &'a mut A where A: PartialEq<B> {
impl<A: ?Sized, B: ?Sized> PartialEq<&mut B> for &mut A where A: PartialEq<B> {
#[inline]
fn eq(&self, other: &&'b mut B) -> bool { PartialEq::eq(*self, *other) }
fn eq(&self, other: &&mut B) -> bool { PartialEq::eq(*self, *other) }
#[inline]
fn ne(&self, other: &&'b mut B) -> bool { PartialEq::ne(*self, *other) }
fn ne(&self, other: &&mut B) -> bool { PartialEq::ne(*self, *other) }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, 'b, A: ?Sized, B: ?Sized> PartialOrd<&'b mut B> for &'a mut A where A: PartialOrd<B> {
impl<A: ?Sized, B: ?Sized> PartialOrd<&mut B> for &mut A where A: PartialOrd<B> {
#[inline]
fn partial_cmp(&self, other: &&'b mut B) -> Option<Ordering> {
fn partial_cmp(&self, other: &&mut B) -> Option<Ordering> {
PartialOrd::partial_cmp(*self, *other)
}
#[inline]
fn lt(&self, other: &&'b mut B) -> bool { PartialOrd::lt(*self, *other) }
fn lt(&self, other: &&mut B) -> bool { PartialOrd::lt(*self, *other) }
#[inline]
fn le(&self, other: &&'b mut B) -> bool { PartialOrd::le(*self, *other) }
fn le(&self, other: &&mut B) -> bool { PartialOrd::le(*self, *other) }
#[inline]
fn ge(&self, other: &&'b mut B) -> bool { PartialOrd::ge(*self, *other) }
fn ge(&self, other: &&mut B) -> bool { PartialOrd::ge(*self, *other) }
#[inline]
fn gt(&self, other: &&'b mut B) -> bool { PartialOrd::gt(*self, *other) }
fn gt(&self, other: &&mut B) -> bool { PartialOrd::gt(*self, *other) }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<A: ?Sized> Ord for &mut A where A: Ord {
@ -1066,18 +1066,18 @@ mod impls {
impl<A: ?Sized> Eq for &mut A where A: Eq {}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, 'b, A: ?Sized, B: ?Sized> PartialEq<&'b mut B> for &'a A where A: PartialEq<B> {
impl<A: ?Sized, B: ?Sized> PartialEq<&mut B> for &A where A: PartialEq<B> {
#[inline]
fn eq(&self, other: &&'b mut B) -> bool { PartialEq::eq(*self, *other) }
fn eq(&self, other: &&mut B) -> bool { PartialEq::eq(*self, *other) }
#[inline]
fn ne(&self, other: &&'b mut B) -> bool { PartialEq::ne(*self, *other) }
fn ne(&self, other: &&mut B) -> bool { PartialEq::ne(*self, *other) }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, 'b, A: ?Sized, B: ?Sized> PartialEq<&'b B> for &'a mut A where A: PartialEq<B> {
impl<A: ?Sized, B: ?Sized> PartialEq<&B> for &mut A where A: PartialEq<B> {
#[inline]
fn eq(&self, other: &&'b B) -> bool { PartialEq::eq(*self, *other) }
fn eq(&self, other: &&B) -> bool { PartialEq::eq(*self, *other) }
#[inline]
fn ne(&self, other: &&'b B) -> bool { PartialEq::ne(*self, *other) }
fn ne(&self, other: &&B) -> bool { PartialEq::ne(*self, *other) }
}
}

View file

@ -41,6 +41,8 @@
#![stable(feature = "rust1", since = "1.0.0")]
use fmt;
/// An identity function.
///
/// Two things are important to note about this function:
@ -359,30 +361,88 @@ pub trait From<T>: Sized {
/// An attempted conversion that consumes `self`, which may or may not be
/// expensive.
///
/// Library authors should not directly implement this trait, but should prefer
/// implementing the [`TryFrom`] trait, which offers greater flexibility and
/// provides an equivalent `TryInto` implementation for free, thanks to a
/// blanket implementation in the standard library. For more information on this,
/// see the documentation for [`Into`].
/// Library authors should usually not directly implement this trait,
/// but should prefer implementing the [`TryFrom`] trait, which offers
/// greater flexibility and provides an equivalent `TryInto`
/// implementation for free, thanks to a blanket implementation in the
/// standard library. For more information on this, see the
/// documentation for [`Into`].
///
/// # Implementing `TryInto`
///
/// This suffers the same restrictions and reasoning as implementing
/// [`Into`], see there for details.
///
/// [`TryFrom`]: trait.TryFrom.html
/// [`Into`]: trait.Into.html
#[unstable(feature = "try_from", issue = "33417")]
#[stable(feature = "try_from", since = "1.34.0")]
pub trait TryInto<T>: Sized {
/// The type returned in the event of a conversion error.
#[stable(feature = "try_from", since = "1.34.0")]
type Error;
/// Performs the conversion.
#[stable(feature = "try_from", since = "1.34.0")]
fn try_into(self) -> Result<T, Self::Error>;
}
/// Attempt to construct `Self` via a conversion.
#[unstable(feature = "try_from", issue = "33417")]
/// Simple and safe type conversions that may fail in a controlled
/// way under some circumstances. It is the reciprocal of [`TryInto`].
///
/// This is useful when you are doing a type conversion that may
/// trivially succeed but may also need special handling.
/// For example, there is no way to convert an `i64` into an `i32`
/// using the [`From`] trait, because an `i64` may contain a value
/// that an `i32` cannot represent and so the conversion would lose data.
/// This might be handled by truncating the `i64` to an `i32` (essentially
/// giving the `i64`'s value modulo `i32::MAX`) or by simply returning
/// `i32::MAX`, or by some other method. The `From` trait is intended
/// for perfect conversions, so the `TryFrom` trait informs the
/// programmer when a type conversion could go bad and lets them
/// decide how to handle it.
///
/// # Generic Implementations
///
/// - `TryFrom<T> for U` implies [`TryInto<U>`]` for T`
/// - [`try_from`] is reflexive, which means that `TryFrom<T> for T`
/// is implemented and cannot fail -- the associated `Error` type for
/// calling `T::try_from()` on a value of type `T` is `Infallible`.
/// When the `!` type is stablized `Infallible` and `!` will be
/// equivalent.
///
/// # Examples
///
/// As described, [`i32`] implements `TryFrom<i64>`:
///
/// ```
/// use std::convert::TryFrom;
///
/// let big_number = 1_000_000_000_000i64;
/// // Silently truncates `big_number`, requires detecting
/// // and handling the truncation after the fact.
/// let smaller_number = big_number as i32;
/// assert_eq!(smaller_number, -727379968);
///
/// // Returns an error because `big_number` is too big to
/// // fit in an `i32`.
/// let try_smaller_number = i32::try_from(big_number);
/// assert!(try_smaller_number.is_err());
///
/// // Returns `Ok(3)`.
/// let try_successful_smaller_number = i32::try_from(3);
/// assert!(try_successful_smaller_number.is_ok());
/// ```
///
/// [`try_from`]: trait.TryFrom.html#tymethod.try_from
/// [`TryInto`]: trait.TryInto.html
#[stable(feature = "try_from", since = "1.34.0")]
pub trait TryFrom<T>: Sized {
/// The type returned in the event of a conversion error.
#[stable(feature = "try_from", since = "1.34.0")]
type Error;
/// Performs the conversion.
#[stable(feature = "try_from", since = "1.34.0")]
fn try_from(value: T) -> Result<Self, Self::Error>;
}
@ -450,7 +510,7 @@ impl<T> From<T> for T {
// TryFrom implies TryInto
#[unstable(feature = "try_from", issue = "33417")]
#[stable(feature = "try_from", since = "1.34.0")]
impl<T, U> TryInto<U> for T where U: TryFrom<T>
{
type Error = U::Error;
@ -462,9 +522,9 @@ impl<T, U> TryInto<U> for T where U: TryFrom<T>
// Infallible conversions are semantically equivalent to fallible conversions
// with an uninhabited error type.
#[unstable(feature = "try_from", issue = "33417")]
#[stable(feature = "try_from", since = "1.34.0")]
impl<T, U> TryFrom<U> for T where U: Into<T> {
type Error = !;
type Error = Infallible;
fn try_from(value: U) -> Result<Self, Self::Error> {
Ok(U::into(value))
@ -496,3 +556,115 @@ impl AsRef<str> for str {
self
}
}
////////////////////////////////////////////////////////////////////////////////
// THE NO-ERROR ERROR TYPE
////////////////////////////////////////////////////////////////////////////////
/// The error type for errors that can never happen.
///
/// Since this enum has no variant, a value of this type can never actually exist.
/// This can be useful for generic APIs that use [`Result`] and parameterize the error type,
/// to indicate that the result is always [`Ok`].
///
/// For example, the [`TryFrom`] trait (conversion that returns a [`Result`])
/// has a blanket implementation for all types where a reverse [`Into`] implementation exists.
///
/// ```ignore (illustrates std code, duplicating the impl in a doctest would be an error)
/// impl<T, U> TryFrom<U> for T where U: Into<T> {
/// type Error = Infallible;
///
/// fn try_from(value: U) -> Result<Self, Infallible> {
/// Ok(U::into(value)) // Never returns `Err`
/// }
/// }
/// ```
///
/// # Future compatibility
///
/// This enum has the same role as [the `!` “never” type][never],
/// which is unstable in this version of Rust.
/// When `!` is stabilized, we plan to make `Infallible` a type alias to it:
///
/// ```ignore (illustrates future std change)
/// pub type Infallible = !;
/// ```
///
/// … and eventually deprecate `Infallible`.
///
///
/// However there is one case where `!` syntax can be used
/// before `!` is stabilized as a full-fleged type: in the position of a functions return type.
/// Specifically, it is possible implementations for two different function pointer types:
///
/// ```
/// trait MyTrait {}
/// impl MyTrait for fn() -> ! {}
/// impl MyTrait for fn() -> std::convert::Infallible {}
/// ```
///
/// With `Infallible` being an enum, this code is valid.
/// However when `Infallible` becomes an alias for the never type,
/// the two `impl`s will start to overlap
/// and therefore will be disallowed by the languages trait coherence rules.
///
/// [`Ok`]: ../result/enum.Result.html#variant.Ok
/// [`Result`]: ../result/enum.Result.html
/// [`TryFrom`]: trait.TryFrom.html
/// [`Into`]: trait.Into.html
/// [never]: ../../std/primitive.never.html
#[stable(feature = "convert_infallible", since = "1.34.0")]
#[derive(Copy)]
pub enum Infallible {}
#[stable(feature = "convert_infallible", since = "1.34.0")]
impl Clone for Infallible {
fn clone(&self) -> Infallible {
match *self {}
}
}
#[stable(feature = "convert_infallible", since = "1.34.0")]
impl fmt::Debug for Infallible {
fn fmt(&self, _: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {}
}
}
#[stable(feature = "convert_infallible", since = "1.34.0")]
impl fmt::Display for Infallible {
fn fmt(&self, _: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {}
}
}
#[stable(feature = "convert_infallible", since = "1.34.0")]
impl PartialEq for Infallible {
fn eq(&self, _: &Infallible) -> bool {
match *self {}
}
}
#[stable(feature = "convert_infallible", since = "1.34.0")]
impl Eq for Infallible {}
#[stable(feature = "convert_infallible", since = "1.34.0")]
impl PartialOrd for Infallible {
fn partial_cmp(&self, _other: &Self) -> Option<crate::cmp::Ordering> {
match *self {}
}
}
#[stable(feature = "convert_infallible", since = "1.34.0")]
impl Ord for Infallible {
fn cmp(&self, _other: &Self) -> crate::cmp::Ordering {
match *self {}
}
}
#[stable(feature = "convert_infallible", since = "1.34.0")]
impl From<!> for Infallible {
fn from(x: !) -> Self {
x
}
}

View file

@ -15,6 +15,7 @@ fn float_to_decimal_common_exact<T>(fmt: &mut Formatter, num: &T,
// FIXME(#53491): Technically, this is calling `get_mut` on an uninitialized
// `MaybeUninit` (here and elsewhere in this file). Revisit this once
// we decided whether that is valid or not.
// Using `freeze` is *not enough*; `flt2dec::Part` is an enum!
let formatted = flt2dec::to_exact_fixed_str(flt2dec::strategy::grisu::format_exact,
*num, sign, precision,
false, buf.get_mut(), parts.get_mut());
@ -33,6 +34,7 @@ fn float_to_decimal_common_shortest<T>(fmt: &mut Formatter, num: &T,
// enough for f32 and f64
let mut buf = MaybeUninit::<[u8; flt2dec::MAX_SIG_DIGITS]>::uninitialized();
let mut parts = MaybeUninit::<[flt2dec::Part; 4]>::uninitialized();
// FIXME(#53491)
let formatted = flt2dec::to_shortest_str(flt2dec::strategy::grisu::format_shortest, *num,
sign, precision, false, buf.get_mut(),
parts.get_mut());
@ -71,6 +73,7 @@ fn float_to_exponential_common_exact<T>(fmt: &mut Formatter, num: &T,
unsafe {
let mut buf = MaybeUninit::<[u8; 1024]>::uninitialized(); // enough for f32 and f64
let mut parts = MaybeUninit::<[flt2dec::Part; 6]>::uninitialized();
// FIXME(#53491)
let formatted = flt2dec::to_exact_exp_str(flt2dec::strategy::grisu::format_exact,
*num, sign, precision,
upper, buf.get_mut(), parts.get_mut());
@ -90,6 +93,7 @@ fn float_to_exponential_common_shortest<T>(fmt: &mut Formatter,
// enough for f32 and f64
let mut buf = MaybeUninit::<[u8; flt2dec::MAX_SIG_DIGITS]>::uninitialized();
let mut parts = MaybeUninit::<[flt2dec::Part; 6]>::uninitialized();
// FIXME(#53491)
let formatted = flt2dec::to_shortest_exp_str(flt2dec::strategy::grisu::format_shortest,
*num, sign, (0, 0), upper,
buf.get_mut(), parts.get_mut());

View file

@ -37,21 +37,21 @@ macro_rules! forward_ref_binop {
}
#[$attr]
impl<'a> $imp<&'a $u> for $t {
impl $imp<&$u> for $t {
type Output = <$t as $imp<$u>>::Output;
#[inline]
fn $method(self, other: &'a $u) -> <$t as $imp<$u>>::Output {
fn $method(self, other: &$u) -> <$t as $imp<$u>>::Output {
$imp::$method(self, *other)
}
}
#[$attr]
impl<'a, 'b> $imp<&'a $u> for &'b $t {
impl $imp<&$u> for &$t {
type Output = <$t as $imp<$u>>::Output;
#[inline]
fn $method(self, other: &'a $u) -> <$t as $imp<$u>>::Output {
fn $method(self, other: &$u) -> <$t as $imp<$u>>::Output {
$imp::$method(*self, *other)
}
}
@ -67,9 +67,9 @@ macro_rules! forward_ref_op_assign {
};
(impl $imp:ident, $method:ident for $t:ty, $u:ty, #[$attr:meta]) => {
#[$attr]
impl<'a> $imp<&'a $u> for $t {
impl $imp<&$u> for $t {
#[inline]
fn $method(&mut self, other: &'a $u) {
fn $method(&mut self, other: &$u) {
$imp::$method(self, *other);
}
}

View file

@ -1282,13 +1282,11 @@ extern "rust-intrinsic" {
/// The stabilized versions of this intrinsic are available on the integer
/// primitives via the `saturating_add` method. For example,
/// [`std::u32::saturating_add`](../../std/primitive.u32.html#method.saturating_add)
#[cfg(not(stage0))]
pub fn saturating_add<T>(a: T, b: T) -> T;
/// Computes `a - b`, while saturating at numeric bounds.
/// The stabilized versions of this intrinsic are available on the integer
/// primitives via the `saturating_sub` method. For example,
/// [`std::u32::saturating_sub`](../../std/primitive.u32.html#method.saturating_sub)
#[cfg(not(stage0))]
pub fn saturating_sub<T>(a: T, b: T) -> T;
/// Returns the value of the discriminant for the variant in 'v',

View file

@ -681,12 +681,7 @@ impl<I: Iterator, P> Iterator for Filter<I, P> where P: FnMut(&I::Item) -> bool
#[inline]
fn next(&mut self) -> Option<I::Item> {
for x in &mut self.iter {
if (self.predicate)(&x) {
return Some(x);
}
}
None
self.try_for_each(Err).err()
}
#[inline]
@ -707,12 +702,9 @@ impl<I: Iterator, P> Iterator for Filter<I, P> where P: FnMut(&I::Item) -> bool
// Using the branchless version will also simplify the LLVM byte code, thus
// leaving more budget for LLVM optimizations.
#[inline]
fn count(mut self) -> usize {
let mut count = 0;
for x in &mut self.iter {
count += (self.predicate)(&x) as usize;
}
count
fn count(self) -> usize {
let mut predicate = self.predicate;
self.iter.map(|x| predicate(&x) as usize).sum()
}
#[inline]
@ -746,12 +738,7 @@ impl<I: DoubleEndedIterator, P> DoubleEndedIterator for Filter<I, P>
{
#[inline]
fn next_back(&mut self) -> Option<I::Item> {
for x in self.iter.by_ref().rev() {
if (self.predicate)(&x) {
return Some(x);
}
}
None
self.try_rfold((), |_, x| Err(x)).err()
}
#[inline]
@ -820,12 +807,7 @@ impl<B, I: Iterator, F> Iterator for FilterMap<I, F>
#[inline]
fn next(&mut self) -> Option<B> {
for x in self.iter.by_ref() {
if let Some(y) = (self.f)(x) {
return Some(y);
}
}
None
self.try_for_each(Err).err()
}
#[inline]
@ -863,12 +845,7 @@ impl<B, I: DoubleEndedIterator, F> DoubleEndedIterator for FilterMap<I, F>
{
#[inline]
fn next_back(&mut self) -> Option<B> {
for x in self.iter.by_ref().rev() {
if let Some(y) = (self.f)(x) {
return Some(y);
}
}
None
self.try_rfold((), |_, x| Err(x)).err()
}
#[inline]

View file

@ -2008,12 +2008,7 @@ pub trait Iterator {
#[stable(feature = "rust1", since = "1.0.0")]
fn max(self) -> Option<Self::Item> where Self: Sized, Self::Item: Ord
{
select_fold1(self,
|_| (),
// switch to y even if it is only equal, to preserve
// stability.
|_, x, _, y| *x <= *y)
.map(|(_, x)| x)
self.max_by(Ord::cmp)
}
/// Returns the minimum element of an iterator.
@ -2038,12 +2033,7 @@ pub trait Iterator {
#[stable(feature = "rust1", since = "1.0.0")]
fn min(self) -> Option<Self::Item> where Self: Sized, Self::Item: Ord
{
select_fold1(self,
|_| (),
// only switch to y if it is strictly smaller, to
// preserve stability.
|_, x, _, y| *x > *y)
.map(|(_, x)| x)
self.min_by(Ord::cmp)
}
/// Returns the element that gives the maximum value from the
@ -2062,15 +2052,11 @@ pub trait Iterator {
/// ```
#[inline]
#[stable(feature = "iter_cmp_by_key", since = "1.6.0")]
fn max_by_key<B: Ord, F>(self, f: F) -> Option<Self::Item>
fn max_by_key<B: Ord, F>(self, mut f: F) -> Option<Self::Item>
where Self: Sized, F: FnMut(&Self::Item) -> B,
{
select_fold1(self,
f,
// switch to y even if it is only equal, to preserve
// stability.
|x_p, _, y_p, _| x_p <= y_p)
.map(|(_, x)| x)
// switch to y even if it is only equal, to preserve stability.
select_fold1(self.map(|x| (f(&x), x)), |(x_p, _), (y_p, _)| x_p <= y_p).map(|(_, x)| x)
}
/// Returns the element that gives the maximum value with respect to the
@ -2092,12 +2078,8 @@ pub trait Iterator {
fn max_by<F>(self, mut compare: F) -> Option<Self::Item>
where Self: Sized, F: FnMut(&Self::Item, &Self::Item) -> Ordering,
{
select_fold1(self,
|_| (),
// switch to y even if it is only equal, to preserve
// stability.
|_, x, _, y| Ordering::Greater != compare(x, y))
.map(|(_, x)| x)
// switch to y even if it is only equal, to preserve stability.
select_fold1(self, |x, y| compare(x, y) != Ordering::Greater)
}
/// Returns the element that gives the minimum value from the
@ -2115,15 +2097,11 @@ pub trait Iterator {
/// assert_eq!(*a.iter().min_by_key(|x| x.abs()).unwrap(), 0);
/// ```
#[stable(feature = "iter_cmp_by_key", since = "1.6.0")]
fn min_by_key<B: Ord, F>(self, f: F) -> Option<Self::Item>
fn min_by_key<B: Ord, F>(self, mut f: F) -> Option<Self::Item>
where Self: Sized, F: FnMut(&Self::Item) -> B,
{
select_fold1(self,
f,
// only switch to y if it is strictly smaller, to
// preserve stability.
|x_p, _, y_p, _| x_p > y_p)
.map(|(_, x)| x)
// only switch to y if it is strictly smaller, to preserve stability.
select_fold1(self.map(|x| (f(&x), x)), |(x_p, _), (y_p, _)| x_p > y_p).map(|(_, x)| x)
}
/// Returns the element that gives the minimum value with respect to the
@ -2145,12 +2123,8 @@ pub trait Iterator {
fn min_by<F>(self, mut compare: F) -> Option<Self::Item>
where Self: Sized, F: FnMut(&Self::Item, &Self::Item) -> Ordering,
{
select_fold1(self,
|_| (),
// switch to y even if it is strictly smaller, to
// preserve stability.
|_, x, _, y| Ordering::Greater == compare(x, y))
.map(|(_, x)| x)
// only switch to y if it is strictly smaller, to preserve stability.
select_fold1(self, |x, y| compare(x, y) == Ordering::Greater)
}
@ -2693,34 +2667,23 @@ pub trait Iterator {
}
}
/// Select an element from an iterator based on the given "projection"
/// and "comparison" function.
/// Select an element from an iterator based on the given "comparison"
/// function.
///
/// This is an idiosyncratic helper to try to factor out the
/// commonalities of {max,min}{,_by}. In particular, this avoids
/// having to implement optimizations several times.
#[inline]
fn select_fold1<I, B, FProj, FCmp>(mut it: I,
mut f_proj: FProj,
mut f_cmp: FCmp) -> Option<(B, I::Item)>
where I: Iterator,
FProj: FnMut(&I::Item) -> B,
FCmp: FnMut(&B, &I::Item, &B, &I::Item) -> bool
fn select_fold1<I, F>(mut it: I, mut f: F) -> Option<I::Item>
where
I: Iterator,
F: FnMut(&I::Item, &I::Item) -> bool,
{
// start with the first element as our selection. This avoids
// having to use `Option`s inside the loop, translating to a
// sizeable performance gain (6x in one case).
it.next().map(|first| {
let first_p = f_proj(&first);
it.fold((first_p, first), |(sel_p, sel), x| {
let x_p = f_proj(&x);
if f_cmp(&sel_p, &sel, &x_p, &x) {
(x_p, x)
} else {
(sel_p, sel)
}
})
it.fold(first, |sel, x| if f(&sel, &x) { x } else { sel })
})
}

View file

@ -123,7 +123,6 @@
#![feature(abi_unadjusted)]
#![feature(adx_target_feature)]
#![feature(maybe_uninit, maybe_uninit_slice, maybe_uninit_array)]
#![feature(unrestricted_attribute_tokens)]
#![feature(external_doc)]
#[prelude_import]

View file

@ -1,7 +1,6 @@
/// Entry point of thread panic. For details, see `std::macros`.
#[macro_export]
#[cfg_attr(not(stage0), allow_internal_unstable(core_panic, __rust_unstable_column))]
#[cfg_attr(stage0, allow_internal_unstable)]
#[allow_internal_unstable(core_panic, __rust_unstable_column)]
#[stable(feature = "core", since = "1.6.0")]
macro_rules! panic {
() => (
@ -422,8 +421,7 @@ macro_rules! write {
/// ```
#[macro_export]
#[stable(feature = "rust1", since = "1.0.0")]
#[cfg_attr(stage0, allow_internal_unstable)]
#[cfg_attr(not(stage0), allow_internal_unstable(format_args_nl))]
#[allow_internal_unstable(format_args_nl)]
macro_rules! writeln {
($dst:expr) => (
write!($dst, "\n")

View file

@ -636,7 +636,7 @@ unsafe impl<T: ?Sized> Freeze for &mut T {}
/// [`Pin<P>`]: ../pin/struct.Pin.html
/// [`pin module`]: ../../std/pin/index.html
#[stable(feature = "pin", since = "1.33.0")]
#[cfg_attr(not(stage0), lang = "unpin")]
#[lang = "unpin"]
pub auto trait Unpin {}
/// A marker type which does not implement `Unpin`.

View file

@ -900,10 +900,16 @@ pub fn discriminant<T>(v: &T) -> Discriminant<T> {
}
}
// FIXME: Reference `MaybeUninit` from these docs, once that is stable.
/// A wrapper to inhibit compiler from automatically calling `T`s destructor.
///
/// This wrapper is 0-cost.
///
/// `ManuallyDrop<T>` is subject to the same layout optimizations as `T`.
/// As a consequence, it has *no effect* on the assumptions that the compiler makes
/// about all values being initialized at their type. In particular, initializing
/// a `ManuallyDrop<&mut T>` with [`mem::zeroed`] is undefined behavior.
///
/// # Examples
///
/// This wrapper helps with explicitly documenting the drop order dependencies between fields of
@ -935,6 +941,8 @@ pub fn discriminant<T>(v: &T) -> Discriminant<T> {
/// }
/// }
/// ```
///
/// [`mem::zeroed`]: fn.zeroed.html
#[stable(feature = "manually_drop", since = "1.20.0")]
#[lang = "manually_drop"]
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
@ -1035,7 +1043,7 @@ impl<T: ?Sized> DerefMut for ManuallyDrop<T> {
}
}
/// A newtype to construct uninitialized instances of `T`.
/// A wrapper to construct uninitialized instances of `T`.
///
/// The compiler, in general, assumes that variables are properly initialized
/// at their respective type. For example, a variable of reference type must
@ -1049,33 +1057,43 @@ impl<T: ?Sized> DerefMut for ManuallyDrop<T> {
/// use std::mem::{self, MaybeUninit};
///
/// let x: &i32 = unsafe { mem::zeroed() }; // undefined behavior!
/// // equivalent code with `MaybeUninit`
/// // The equivalent code with `MaybeUninit<&i32>`:
/// let x: &i32 = unsafe { MaybeUninit::zeroed().into_initialized() }; // undefined behavior!
/// ```
///
/// This is exploited by the compiler for various optimizations, such as eliding
/// run-time checks and optimizing `enum` layout.
///
/// Not initializing memory at all (instead of zero-initializing it) causes the same
/// issue: after all, the initial value of the variable might just happen to be
/// one that violates the invariant. Moreover, uninitialized memory is special
/// in that the compiler knows that it does not have a fixed value. This makes
/// it undefined behavior to have uninitialized data in a variable even if that
/// variable has otherwise no restrictions about which values are valid:
/// Similarly, entirely uninitialized memory may have any content, while a `bool` must
/// always be `true` or `false`. Hence, creating an uninitialized `bool` is undefined behavior:
///
/// ```rust,no_run
/// #![feature(maybe_uninit)]
/// use std::mem::{self, MaybeUninit};
///
/// let b: bool = unsafe { mem::uninitialized() }; // undefined behavior!
/// // The equivalent code with `MaybeUninit<bool>`:
/// let b: bool = unsafe { MaybeUninit::uninitialized().into_initialized() }; // undefined behavior!
/// ```
///
/// Moreover, uninitialized memory is special in that the compiler knows that
/// it does not have a fixed value. This makes it undefined behavior to have
/// uninitialized data in a variable even if that variable has an integer type,
/// which otherwise can hold any bit pattern:
///
/// ```rust,no_run
/// #![feature(maybe_uninit)]
/// use std::mem::{self, MaybeUninit};
///
/// let x: i32 = unsafe { mem::uninitialized() }; // undefined behavior!
/// // equivalent code with `MaybeUninit`
/// // The equivalent code with `MaybeUninit<i32>`:
/// let x: i32 = unsafe { MaybeUninit::uninitialized().into_initialized() }; // undefined behavior!
/// ```
/// (Notice that the rules around uninitialized integers are not finalized yet, but
/// until they are, it is advisable to avoid them.)
///
/// `MaybeUninit` serves to enable unsafe code to deal with uninitialized data:
/// it is a signal to the compiler indicating that the data here might *not*
/// `MaybeUninit<T>` serves to enable unsafe code to deal with uninitialized data.
/// It is a signal to the compiler indicating that the data here might *not*
/// be initialized:
///
/// ```rust
@ -1083,7 +1101,7 @@ impl<T: ?Sized> DerefMut for ManuallyDrop<T> {
/// use std::mem::MaybeUninit;
///
/// // Create an explicitly uninitialized reference. The compiler knows that data inside
/// // a `MaybeUninit` may be invalid, and hence this is not UB:
/// // a `MaybeUninit<T>` may be invalid, and hence this is not UB:
/// let mut x = MaybeUninit::<&i32>::uninitialized();
/// // Set it to a valid value.
/// x.set(&0);
@ -1092,20 +1110,30 @@ impl<T: ?Sized> DerefMut for ManuallyDrop<T> {
/// let x = unsafe { x.into_initialized() };
/// ```
///
/// The compiler then knows to not optimize this code.
/// The compiler then knows to not make any incorrect assumptions or optimizations on this code.
// FIXME before stabilizing, explain how to initialize a struct field-by-field.
#[allow(missing_debug_implementations)]
#[unstable(feature = "maybe_uninit", issue = "53491")]
// NOTE after stabilizing `MaybeUninit` proceed to deprecate `mem::{uninitialized,zeroed}`
#[derive(Copy)]
// NOTE after stabilizing `MaybeUninit` proceed to deprecate `mem::uninitialized`.
pub union MaybeUninit<T> {
uninit: (),
value: ManuallyDrop<T>,
}
#[unstable(feature = "maybe_uninit", issue = "53491")]
impl<T: Copy> Clone for MaybeUninit<T> {
#[inline(always)]
fn clone(&self) -> Self {
// Not calling T::clone(), we cannot know if we are initialized enough for that.
*self
}
}
impl<T> MaybeUninit<T> {
/// Create a new `MaybeUninit` initialized with the given value.
/// Create a new `MaybeUninit<T>` initialized with the given value.
///
/// Note that dropping a `MaybeUninit` will never call `T`'s drop code.
/// Note that dropping a `MaybeUninit<T>` will never call `T`'s drop code.
/// It is your responsibility to make sure `T` gets dropped if it got initialized.
#[unstable(feature = "maybe_uninit", issue = "53491")]
#[inline(always)]
@ -1113,9 +1141,9 @@ impl<T> MaybeUninit<T> {
MaybeUninit { value: ManuallyDrop::new(val) }
}
/// Creates a new `MaybeUninit` in an uninitialized state.
/// Creates a new `MaybeUninit<T>` in an uninitialized state.
///
/// Note that dropping a `MaybeUninit` will never call `T`'s drop code.
/// Note that dropping a `MaybeUninit<T>` will never call `T`'s drop code.
/// It is your responsibility to make sure `T` gets dropped if it got initialized.
#[unstable(feature = "maybe_uninit", issue = "53491")]
#[inline(always)]
@ -1123,14 +1151,43 @@ impl<T> MaybeUninit<T> {
MaybeUninit { uninit: () }
}
/// Creates a new `MaybeUninit` in an uninitialized state, with the memory being
/// Creates a new `MaybeUninit<T>` in an uninitialized state, with the memory being
/// filled with `0` bytes. It depends on `T` whether that already makes for
/// proper initialization. For example, `MaybeUninit<usize>::zeroed()` is initialized,
/// but `MaybeUninit<&'static i32>::zeroed()` is not because references must not
/// be null.
///
/// Note that dropping a `MaybeUninit` will never call `T`'s drop code.
/// Note that dropping a `MaybeUninit<T>` will never call `T`'s drop code.
/// It is your responsibility to make sure `T` gets dropped if it got initialized.
///
/// # Example
///
/// Correct usage of this function: initializing a struct with zero, where all
/// fields of the struct can hold the bit-pattern 0 as a valid value.
///
/// ```rust
/// #![feature(maybe_uninit)]
/// use std::mem::MaybeUninit;
///
/// let x = MaybeUninit::<(u8, bool)>::zeroed();
/// let x = unsafe { x.into_initialized() };
/// assert_eq!(x, (0, false));
/// ```
///
/// *Incorrect* usage of this function: initializing a struct with zero, where some fields
/// cannot hold 0 as a valid value.
///
/// ```rust,no_run
/// #![feature(maybe_uninit)]
/// use std::mem::MaybeUninit;
///
/// enum NotZero { One = 1, Two = 2 };
///
/// let x = MaybeUninit::<(u8, NotZero)>::zeroed();
/// let x = unsafe { x.into_initialized() };
/// // Inside a pair, we create a `NotZero` that does not have a valid discriminant.
/// // This is undefined behavior.
/// ```
#[unstable(feature = "maybe_uninit", issue = "53491")]
#[inline]
pub fn zeroed() -> MaybeUninit<T> {
@ -1141,9 +1198,10 @@ impl<T> MaybeUninit<T> {
u
}
/// Sets the value of the `MaybeUninit`. This overwrites any previous value without dropping it.
/// For your convenience, this also returns a mutable reference to the (now safely initialized)
/// contents of `self`.
/// Sets the value of the `MaybeUninit<T>`. This overwrites any previous value
/// without dropping it, so be careful not to use this twice unless you want to
/// skip running the destructor. For your convenience, this also returns a mutable
/// reference to the (now safely initialized) contents of `self`.
#[unstable(feature = "maybe_uninit", issue = "53491")]
#[inline(always)]
pub fn set(&mut self, val: T) -> &mut T {
@ -1154,7 +1212,35 @@ impl<T> MaybeUninit<T> {
}
/// Gets a pointer to the contained value. Reading from this pointer or turning it
/// into a reference will be undefined behavior unless the `MaybeUninit` is initialized.
/// into a reference is undefined behavior unless the `MaybeUninit<T>` is initialized.
///
/// # Examples
///
/// Correct usage of this method:
///
/// ```rust
/// #![feature(maybe_uninit)]
/// use std::mem::MaybeUninit;
///
/// let mut x = MaybeUninit::<Vec<u32>>::uninitialized();
/// unsafe { x.as_mut_ptr().write(vec![0,1,2]); }
/// // Create a reference into the `MaybeUninit<T>`. This is okay because we initialized it.
/// let x_vec = unsafe { &*x.as_ptr() };
/// assert_eq!(x_vec.len(), 3);
/// ```
///
/// *Incorrect* usage of this method:
///
/// ```rust,no_run
/// #![feature(maybe_uninit)]
/// use std::mem::MaybeUninit;
///
/// let x = MaybeUninit::<Vec<u32>>::uninitialized();
/// let x_vec = unsafe { &*x.as_ptr() };
/// // We have created a reference to an uninitialized vector! This is undefined behavior.
/// ```
/// (Notice that the rules around references to uninitialized data are not finalized yet, but
/// until they are, it is advisable to avoid them.)
#[unstable(feature = "maybe_uninit", issue = "53491")]
#[inline(always)]
pub fn as_ptr(&self) -> *const T {
@ -1162,22 +1248,77 @@ impl<T> MaybeUninit<T> {
}
/// Gets a mutable pointer to the contained value. Reading from this pointer or turning it
/// into a reference will be undefined behavior unless the `MaybeUninit` is initialized.
/// into a reference is undefined behavior unless the `MaybeUninit<T>` is initialized.
///
/// # Examples
///
/// Correct usage of this method:
///
/// ```rust
/// #![feature(maybe_uninit)]
/// use std::mem::MaybeUninit;
///
/// let mut x = MaybeUninit::<Vec<u32>>::uninitialized();
/// unsafe { x.as_mut_ptr().write(vec![0,1,2]); }
/// // Create a reference into the `MaybeUninit<Vec<u32>>`.
/// // This is okay because we initialized it.
/// let x_vec = unsafe { &mut *x.as_mut_ptr() };
/// x_vec.push(3);
/// assert_eq!(x_vec.len(), 4);
/// ```
///
/// *Incorrect* usage of this method:
///
/// ```rust,no_run
/// #![feature(maybe_uninit)]
/// use std::mem::MaybeUninit;
///
/// let mut x = MaybeUninit::<Vec<u32>>::uninitialized();
/// let x_vec = unsafe { &mut *x.as_mut_ptr() };
/// // We have created a reference to an uninitialized vector! This is undefined behavior.
/// ```
/// (Notice that the rules around references to uninitialized data are not finalized yet, but
/// until they are, it is advisable to avoid them.)
#[unstable(feature = "maybe_uninit", issue = "53491")]
#[inline(always)]
pub fn as_mut_ptr(&mut self) -> *mut T {
unsafe { &mut *self.value as *mut T }
}
/// Extracts the value from the `MaybeUninit` container. This is a great way
/// Extracts the value from the `MaybeUninit<T>` container. This is a great way
/// to ensure that the data will get dropped, because the resulting `T` is
/// subject to the usual drop handling.
///
/// # Safety
///
/// It is up to the caller to guarantee that the `MaybeUninit` really is in an initialized
/// It is up to the caller to guarantee that the `MaybeUninit<T>` really is in an initialized
/// state. Calling this when the content is not yet fully initialized causes undefined
/// behavior.
///
/// # Examples
///
/// Correct usage of this method:
///
/// ```rust
/// #![feature(maybe_uninit)]
/// use std::mem::MaybeUninit;
///
/// let mut x = MaybeUninit::<bool>::uninitialized();
/// unsafe { x.as_mut_ptr().write(true); }
/// let x_init = unsafe { x.into_initialized() };
/// assert_eq!(x_init, true);
/// ```
///
/// *Incorrect* usage of this method:
///
/// ```rust,no_run
/// #![feature(maybe_uninit)]
/// use std::mem::MaybeUninit;
///
/// let x = MaybeUninit::<Vec<u32>>::uninitialized();
/// let x_init = unsafe { x.into_initialized() };
/// // `x` had not been initialized yet, so this last line caused undefined behavior.
/// ```
#[unstable(feature = "maybe_uninit", issue = "53491")]
#[inline(always)]
pub unsafe fn into_initialized(self) -> T {
@ -1185,11 +1326,73 @@ impl<T> MaybeUninit<T> {
ManuallyDrop::into_inner(self.value)
}
/// Reads the value from the `MaybeUninit<T>` container. The resulting `T` is subject
/// to the usual drop handling.
///
/// Whenever possible, it is preferrable to use [`into_initialized`] instead, which
/// prevents duplicating the content of the `MaybeUninit<T>`.
///
/// # Safety
///
/// It is up to the caller to guarantee that the `MaybeUninit<T>` really is in an initialized
/// state. Calling this when the content is not yet fully initialized causes undefined
/// behavior.
///
/// Moreover, this leaves a copy of the same data behind in the `MaybeUninit<T>`. When using
/// multiple copies of the data (by calling `read_initialized` multiple times, or first
/// calling `read_initialized` and then [`into_initialized`]), it is your responsibility
/// to ensure that that data may indeed be duplicated.
///
/// [`into_initialized`]: #method.into_initialized
///
/// # Examples
///
/// Correct usage of this method:
///
/// ```rust
/// #![feature(maybe_uninit)]
/// use std::mem::MaybeUninit;
///
/// let mut x = MaybeUninit::<u32>::uninitialized();
/// x.set(13);
/// let x1 = unsafe { x.read_initialized() };
/// // `u32` is `Copy`, so we may read multiple times.
/// let x2 = unsafe { x.read_initialized() };
/// assert_eq!(x1, x2);
///
/// let mut x = MaybeUninit::<Option<Vec<u32>>>::uninitialized();
/// x.set(None);
/// let x1 = unsafe { x.read_initialized() };
/// // Duplicating a `None` value is okay, so we may read multiple times.
/// let x2 = unsafe { x.read_initialized() };
/// assert_eq!(x1, x2);
/// ```
///
/// *Incorrect* usage of this method:
///
/// ```rust,no_run
/// #![feature(maybe_uninit)]
/// use std::mem::MaybeUninit;
///
/// let mut x = MaybeUninit::<Option<Vec<u32>>>::uninitialized();
/// x.set(Some(vec![0,1,2]));
/// let x1 = unsafe { x.read_initialized() };
/// let x2 = unsafe { x.read_initialized() };
/// // We now created two copies of the same vector, leading to a double-free when
/// // they both get dropped!
/// ```
#[unstable(feature = "maybe_uninit", issue = "53491")]
#[inline(always)]
pub unsafe fn read_initialized(&self) -> T {
intrinsics::panic_if_uninhabited::<T>();
self.as_ptr().read()
}
/// Gets a reference to the contained value.
///
/// # Safety
///
/// It is up to the caller to guarantee that the `MaybeUninit` really is in an initialized
/// It is up to the caller to guarantee that the `MaybeUninit<T>` really is in an initialized
/// state. Calling this when the content is not yet fully initialized causes undefined
/// behavior.
#[unstable(feature = "maybe_uninit_ref", issue = "53491")]
@ -1202,7 +1405,7 @@ impl<T> MaybeUninit<T> {
///
/// # Safety
///
/// It is up to the caller to guarantee that the `MaybeUninit` really is in an initialized
/// It is up to the caller to guarantee that the `MaybeUninit<T>` really is in an initialized
/// state. Calling this when the content is not yet fully initialized causes undefined
/// behavior.
// FIXME(#53491): We currently rely on the above being incorrect, i.e., we have references

View file

@ -2,7 +2,7 @@
#![stable(feature = "rust1", since = "1.0.0")]
use convert::TryFrom;
use convert::{TryFrom, Infallible};
use fmt;
use intrinsics;
use mem;
@ -346,7 +346,7 @@ $EndFeature, "
concat!("Shifts the bits to the left by a specified amount, `n`,
wrapping the truncated bits to the end of the resulting integer.
Please note this isn't the same operation as `<<`!
Please note this isn't the same operation as the `<<` shifting operator!
# Examples
@ -370,7 +370,7 @@ assert_eq!(n.rotate_left(", $rot, "), m);
wrapping the truncated bits to the beginning of the resulting
integer.
Please note this isn't the same operation as `>>`!
Please note this isn't the same operation as the `>>` shifting operator!
# Examples
@ -874,33 +874,6 @@ bounds instead of overflowing.
Basic usage:
```
", $Feature, "assert_eq!(100", stringify!($SelfT), ".saturating_add(1), 101);
assert_eq!(", stringify!($SelfT), "::max_value().saturating_add(100), ", stringify!($SelfT),
"::max_value());",
$EndFeature, "
```"),
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
#[cfg(stage0)]
pub fn saturating_add(self, rhs: Self) -> Self {
match self.checked_add(rhs) {
Some(x) => x,
None if rhs >= 0 => Self::max_value(),
None => Self::min_value(),
}
}
}
doc_comment! {
concat!("Saturating integer addition. Computes `self + rhs`, saturating at the numeric
bounds instead of overflowing.
# Examples
Basic usage:
```
", $Feature, "assert_eq!(100", stringify!($SelfT), ".saturating_add(1), 101);
assert_eq!(", stringify!($SelfT), "::max_value().saturating_add(100), ", stringify!($SelfT),
@ -911,37 +884,11 @@ $EndFeature, "
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_saturating_int_methods")]
#[inline]
#[cfg(not(stage0))]
pub const fn saturating_add(self, rhs: Self) -> Self {
intrinsics::saturating_add(self, rhs)
}
}
doc_comment! {
concat!("Saturating integer subtraction. Computes `self - rhs`, saturating at the
numeric bounds instead of overflowing.
# Examples
Basic usage:
```
", $Feature, "assert_eq!(100", stringify!($SelfT), ".saturating_sub(127), -27);
assert_eq!(", stringify!($SelfT), "::min_value().saturating_sub(100), ", stringify!($SelfT),
"::min_value());",
$EndFeature, "
```"),
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
#[cfg(stage0)]
pub fn saturating_sub(self, rhs: Self) -> Self {
match self.checked_sub(rhs) {
Some(x) => x,
None if rhs >= 0 => Self::min_value(),
None => Self::max_value(),
}
}
}
doc_comment! {
concat!("Saturating integer subtraction. Computes `self - rhs`, saturating at the
@ -960,7 +907,6 @@ $EndFeature, "
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_saturating_int_methods")]
#[inline]
#[cfg(not(stage0))]
pub const fn saturating_sub(self, rhs: Self) -> Self {
intrinsics::saturating_sub(self, rhs)
}
@ -2000,7 +1946,6 @@ assert_eq!(value, ", $swap_op, ");
When starting from a slice rather than an array, fallible conversion APIs can be used:
```
#![feature(try_from)]
use std::convert::TryInto;
fn read_be_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT), " {
@ -2032,13 +1977,12 @@ assert_eq!(value, ", $swap_op, ");
When starting from a slice rather than an array, fallible conversion APIs can be used:
```
#![feature(try_from)]
use std::convert::TryInto;
fn read_be_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT), " {
fn read_le_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT), " {
let (int_bytes, rest) = input.split_at(std::mem::size_of::<", stringify!($SelfT), ">());
*input = rest;
", stringify!($SelfT), "::from_be_bytes(int_bytes.try_into().unwrap())
", stringify!($SelfT), "::from_le_bytes(int_bytes.try_into().unwrap())
}
```"),
#[stable(feature = "int_to_from_bytes", since = "1.32.0")]
@ -2074,13 +2018,12 @@ assert_eq!(value, ", $swap_op, ");
When starting from a slice rather than an array, fallible conversion APIs can be used:
```
#![feature(try_from)]
use std::convert::TryInto;
fn read_be_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT), " {
fn read_ne_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT), " {
let (int_bytes, rest) = input.split_at(std::mem::size_of::<", stringify!($SelfT), ">());
*input = rest;
", stringify!($SelfT), "::from_be_bytes(int_bytes.try_into().unwrap())
", stringify!($SelfT), "::from_ne_bytes(int_bytes.try_into().unwrap())
}
```"),
#[stable(feature = "int_to_from_bytes", since = "1.32.0")]
@ -2303,7 +2246,7 @@ assert_eq!(n.trailing_zeros(), 3);", $EndFeature, "
concat!("Shifts the bits to the left by a specified amount, `n`,
wrapping the truncated bits to the end of the resulting integer.
Please note this isn't the same operation as `<<`!
Please note this isn't the same operation as the `<<` shifting operator!
# Examples
@ -2327,7 +2270,7 @@ assert_eq!(n.rotate_left(", $rot, "), m);
wrapping the truncated bits to the beginning of the resulting
integer.
Please note this isn't the same operation as `>>`!
Please note this isn't the same operation as the `>>` shifting operator!
# Examples
@ -2783,29 +2726,6 @@ the numeric bounds instead of overflowing.
Basic usage:
```
", $Feature, "assert_eq!(100", stringify!($SelfT), ".saturating_add(1), 101);
assert_eq!(200u8.saturating_add(127), 255);", $EndFeature, "
```"),
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
#[cfg(stage0)]
pub fn saturating_add(self, rhs: Self) -> Self {
match self.checked_add(rhs) {
Some(x) => x,
None => Self::max_value(),
}
}
}
doc_comment! {
concat!("Saturating integer addition. Computes `self + rhs`, saturating at
the numeric bounds instead of overflowing.
# Examples
Basic usage:
```
", $Feature, "assert_eq!(100", stringify!($SelfT), ".saturating_add(1), 101);
assert_eq!(200u8.saturating_add(127), 255);", $EndFeature, "
@ -2814,7 +2734,6 @@ assert_eq!(200u8.saturating_add(127), 255);", $EndFeature, "
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_saturating_int_methods")]
#[inline]
#[cfg(not(stage0))]
pub const fn saturating_add(self, rhs: Self) -> Self {
intrinsics::saturating_add(self, rhs)
}
@ -2828,29 +2747,6 @@ at the numeric bounds instead of overflowing.
Basic usage:
```
", $Feature, "assert_eq!(100", stringify!($SelfT), ".saturating_sub(27), 73);
assert_eq!(13", stringify!($SelfT), ".saturating_sub(127), 0);", $EndFeature, "
```"),
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
#[cfg(stage0)]
pub fn saturating_sub(self, rhs: Self) -> Self {
match self.checked_sub(rhs) {
Some(x) => x,
None => Self::min_value(),
}
}
}
doc_comment! {
concat!("Saturating integer subtraction. Computes `self - rhs`, saturating
at the numeric bounds instead of overflowing.
# Examples
Basic usage:
```
", $Feature, "assert_eq!(100", stringify!($SelfT), ".saturating_sub(27), 73);
assert_eq!(13", stringify!($SelfT), ".saturating_sub(127), 0);", $EndFeature, "
@ -2858,7 +2754,6 @@ assert_eq!(13", stringify!($SelfT), ".saturating_sub(127), 0);", $EndFeature, "
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_saturating_int_methods")]
#[inline]
#[cfg(not(stage0))]
pub const fn saturating_sub(self, rhs: Self) -> Self {
intrinsics::saturating_sub(self, rhs)
}
@ -3767,7 +3662,6 @@ assert_eq!(value, ", $swap_op, ");
When starting from a slice rather than an array, fallible conversion APIs can be used:
```
#![feature(try_from)]
use std::convert::TryInto;
fn read_be_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT), " {
@ -3799,13 +3693,12 @@ assert_eq!(value, ", $swap_op, ");
When starting from a slice rather than an array, fallible conversion APIs can be used:
```
#![feature(try_from)]
use std::convert::TryInto;
fn read_be_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT), " {
fn read_le_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT), " {
let (int_bytes, rest) = input.split_at(std::mem::size_of::<", stringify!($SelfT), ">());
*input = rest;
", stringify!($SelfT), "::from_be_bytes(int_bytes.try_into().unwrap())
", stringify!($SelfT), "::from_le_bytes(int_bytes.try_into().unwrap())
}
```"),
#[stable(feature = "int_to_from_bytes", since = "1.32.0")]
@ -3841,13 +3734,12 @@ assert_eq!(value, ", $swap_op, ");
When starting from a slice rather than an array, fallible conversion APIs can be used:
```
#![feature(try_from)]
use std::convert::TryInto;
fn read_be_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT), " {
fn read_ne_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT), " {
let (int_bytes, rest) = input.split_at(std::mem::size_of::<", stringify!($SelfT), ">());
*input = rest;
", stringify!($SelfT), "::from_be_bytes(int_bytes.try_into().unwrap())
", stringify!($SelfT), "::from_ne_bytes(int_bytes.try_into().unwrap())
}
```"),
#[stable(feature = "int_to_from_bytes", since = "1.32.0")]
@ -4504,7 +4396,7 @@ macro_rules! from_str_radix_int_impl {
from_str_radix_int_impl! { isize i8 i16 i32 i64 i128 usize u8 u16 u32 u64 u128 }
/// The error type returned when a checked integral type conversion fails.
#[unstable(feature = "try_from", issue = "33417")]
#[stable(feature = "try_from", since = "1.34.0")]
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub struct TryFromIntError(());
@ -4519,27 +4411,40 @@ impl TryFromIntError {
}
}
#[unstable(feature = "try_from", issue = "33417")]
#[stable(feature = "try_from", since = "1.34.0")]
impl fmt::Display for TryFromIntError {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
self.__description().fmt(fmt)
}
}
#[unstable(feature = "try_from", issue = "33417")]
#[stable(feature = "try_from", since = "1.34.0")]
impl From<Infallible> for TryFromIntError {
fn from(x: Infallible) -> TryFromIntError {
match x {}
}
}
#[unstable(feature = "never_type", issue = "35121")]
impl From<!> for TryFromIntError {
fn from(never: !) -> TryFromIntError {
never
// Match rather than coerce to make sure that code like
// `From<Infallible> for TryFromIntError` above will keep working
// when `Infallible` becomes an alias to `!`.
match never {}
}
}
// no possible bounds violation
macro_rules! try_from_unbounded {
($source:ty, $($target:ty),*) => {$(
#[unstable(feature = "try_from", issue = "33417")]
#[stable(feature = "try_from", since = "1.34.0")]
impl TryFrom<$source> for $target {
type Error = TryFromIntError;
/// Try to create the target number type from a source
/// number type. This returns an error if the source value
/// is outside of the range of the target type.
#[inline]
fn try_from(value: $source) -> Result<Self, Self::Error> {
Ok(value as $target)
@ -4551,10 +4456,13 @@ macro_rules! try_from_unbounded {
// only negative bounds
macro_rules! try_from_lower_bounded {
($source:ty, $($target:ty),*) => {$(
#[unstable(feature = "try_from", issue = "33417")]
#[stable(feature = "try_from", since = "1.34.0")]
impl TryFrom<$source> for $target {
type Error = TryFromIntError;
/// Try to create the target number type from a source
/// number type. This returns an error if the source value
/// is outside of the range of the target type.
#[inline]
fn try_from(u: $source) -> Result<$target, TryFromIntError> {
if u >= 0 {
@ -4570,10 +4478,13 @@ macro_rules! try_from_lower_bounded {
// unsigned to signed (only positive bound)
macro_rules! try_from_upper_bounded {
($source:ty, $($target:ty),*) => {$(
#[unstable(feature = "try_from", issue = "33417")]
#[stable(feature = "try_from", since = "1.34.0")]
impl TryFrom<$source> for $target {
type Error = TryFromIntError;
/// Try to create the target number type from a source
/// number type. This returns an error if the source value
/// is outside of the range of the target type.
#[inline]
fn try_from(u: $source) -> Result<$target, TryFromIntError> {
if u > (<$target>::max_value() as $source) {
@ -4589,10 +4500,13 @@ macro_rules! try_from_upper_bounded {
// all other cases
macro_rules! try_from_both_bounded {
($source:ty, $($target:ty),*) => {$(
#[unstable(feature = "try_from", issue = "33417")]
#[stable(feature = "try_from", since = "1.34.0")]
impl TryFrom<$source> for $target {
type Error = TryFromIntError;
/// Try to create the target number type from a source
/// number type. This returns an error if the source value
/// is outside of the range of the target type.
#[inline]
fn try_from(u: $source) -> Result<$target, TryFromIntError> {
let min = <$target>::min_value() as $source;
@ -4613,7 +4527,7 @@ macro_rules! rev {
)*}
}
/// intra-sign conversions
// intra-sign conversions
try_from_upper_bounded!(u16, u8);
try_from_upper_bounded!(u32, u16, u8);
try_from_upper_bounded!(u64, u32, u16, u8);

View file

@ -429,7 +429,8 @@ assert_eq!(n.trailing_zeros(), 3);
/// wrapping the truncated bits to the end of the resulting
/// integer.
///
/// Please note this isn't the same operation as `>>`!
/// Please note this isn't the same operation as the `>>` shifting
/// operator!
///
/// # Examples
///
@ -454,7 +455,8 @@ assert_eq!(n.trailing_zeros(), 3);
/// wrapping the truncated bits to the beginning of the resulting
/// integer.
///
/// Please note this isn't the same operation as `<<`!
/// Please note this isn't the same operation as the `<<` shifting
/// operator!
///
/// # Examples
///

View file

@ -26,11 +26,13 @@ use hash::{Hash, Hasher};
/// Used as a [slicing index], `RangeFull` produces the full array as a slice.
///
/// ```
/// let arr = [0, 1, 2, 3];
/// assert_eq!(arr[ .. ], [0,1,2,3]); // RangeFull
/// assert_eq!(arr[ ..3], [0,1,2 ]);
/// assert_eq!(arr[1.. ], [ 1,2,3]);
/// assert_eq!(arr[1..3], [ 1,2 ]);
/// let arr = [0, 1, 2, 3, 4];
/// assert_eq!(arr[ .. ], [0,1,2,3,4]); // RangeFull
/// assert_eq!(arr[ .. 3], [0,1,2 ]);
/// assert_eq!(arr[ ..=3], [0,1,2,3 ]);
/// assert_eq!(arr[1.. ], [ 1,2,3,4]);
/// assert_eq!(arr[1.. 3], [ 1,2 ]);
/// assert_eq!(arr[1..=3], [ 1,2,3 ]);
/// ```
///
/// [`IntoIterator`]: ../iter/trait.Iterator.html
@ -60,11 +62,13 @@ impl fmt::Debug for RangeFull {
/// assert_eq!((3..5), std::ops::Range { start: 3, end: 5 });
/// assert_eq!(3 + 4 + 5, (3..6).sum());
///
/// let arr = ['a', 'b', 'c', 'd'];
/// assert_eq!(arr[ .. ], ['a', 'b', 'c', 'd']);
/// assert_eq!(arr[ ..3], ['a', 'b', 'c', ]);
/// assert_eq!(arr[1.. ], [ 'b', 'c', 'd']);
/// assert_eq!(arr[1..3], [ 'b', 'c' ]); // Range
/// let arr = [0, 1, 2, 3, 4];
/// assert_eq!(arr[ .. ], [0,1,2,3,4]);
/// assert_eq!(arr[ .. 3], [0,1,2 ]);
/// assert_eq!(arr[ ..=3], [0,1,2,3 ]);
/// assert_eq!(arr[1.. ], [ 1,2,3,4]);
/// assert_eq!(arr[1.. 3], [ 1,2 ]); // Range
/// assert_eq!(arr[1..=3], [ 1,2,3 ]);
/// ```
#[doc(alias = "..")]
#[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186
@ -160,11 +164,13 @@ impl<Idx: PartialOrd<Idx>> Range<Idx> {
/// assert_eq!((2..), std::ops::RangeFrom { start: 2 });
/// assert_eq!(2 + 3 + 4, (2..).take(3).sum());
///
/// let arr = [0, 1, 2, 3];
/// assert_eq!(arr[ .. ], [0,1,2,3]);
/// assert_eq!(arr[ ..3], [0,1,2 ]);
/// assert_eq!(arr[1.. ], [ 1,2,3]); // RangeFrom
/// assert_eq!(arr[1..3], [ 1,2 ]);
/// let arr = [0, 1, 2, 3, 4];
/// assert_eq!(arr[ .. ], [0,1,2,3,4]);
/// assert_eq!(arr[ .. 3], [0,1,2 ]);
/// assert_eq!(arr[ ..=3], [0,1,2,3 ]);
/// assert_eq!(arr[1.. ], [ 1,2,3,4]); // RangeFrom
/// assert_eq!(arr[1.. 3], [ 1,2 ]);
/// assert_eq!(arr[1..=3], [ 1,2,3 ]);
/// ```
///
/// [`Iterator`]: ../iter/trait.IntoIterator.html
@ -240,11 +246,13 @@ impl<Idx: PartialOrd<Idx>> RangeFrom<Idx> {
/// elements before the index indicated by `end`.
///
/// ```
/// let arr = [0, 1, 2, 3];
/// assert_eq!(arr[ .. ], [0,1,2,3]);
/// assert_eq!(arr[ ..3], [0,1,2 ]); // RangeTo
/// assert_eq!(arr[1.. ], [ 1,2,3]);
/// assert_eq!(arr[1..3], [ 1,2 ]);
/// let arr = [0, 1, 2, 3, 4];
/// assert_eq!(arr[ .. ], [0,1,2,3,4]);
/// assert_eq!(arr[ .. 3], [0,1,2 ]); // RangeTo
/// assert_eq!(arr[ ..=3], [0,1,2,3 ]);
/// assert_eq!(arr[1.. ], [ 1,2,3,4]);
/// assert_eq!(arr[1.. 3], [ 1,2 ]);
/// assert_eq!(arr[1..=3], [ 1,2,3 ]);
/// ```
///
/// [`IntoIterator`]: ../iter/trait.Iterator.html
@ -312,9 +320,13 @@ impl<Idx: PartialOrd<Idx>> RangeTo<Idx> {
/// assert_eq!((3..=5), std::ops::RangeInclusive::new(3, 5));
/// assert_eq!(3 + 4 + 5, (3..=5).sum());
///
/// let arr = [0, 1, 2, 3];
/// assert_eq!(arr[ ..=2], [0,1,2 ]);
/// assert_eq!(arr[1..=2], [ 1,2 ]); // RangeInclusive
/// let arr = [0, 1, 2, 3, 4];
/// assert_eq!(arr[ .. ], [0,1,2,3,4]);
/// assert_eq!(arr[ .. 3], [0,1,2 ]);
/// assert_eq!(arr[ ..=3], [0,1,2,3 ]);
/// assert_eq!(arr[1.. ], [ 1,2,3,4]);
/// assert_eq!(arr[1.. 3], [ 1,2 ]);
/// assert_eq!(arr[1..=3], [ 1,2,3 ]); // RangeInclusive
/// ```
#[doc(alias = "..=")]
#[derive(Clone)] // not Copy -- see #27186
@ -569,9 +581,13 @@ impl<Idx: PartialOrd<Idx>> RangeInclusive<Idx> {
/// array elements up to and including the index indicated by `end`.
///
/// ```
/// let arr = [0, 1, 2, 3];
/// assert_eq!(arr[ ..=2], [0,1,2 ]); // RangeToInclusive
/// assert_eq!(arr[1..=2], [ 1,2 ]);
/// let arr = [0, 1, 2, 3, 4];
/// assert_eq!(arr[ .. ], [0,1,2,3,4]);
/// assert_eq!(arr[ .. 3], [0,1,2 ]);
/// assert_eq!(arr[ ..=3], [0,1,2,3 ]); // RangeToInclusive
/// assert_eq!(arr[1.. ], [ 1,2,3,4]);
/// assert_eq!(arr[1.. 3], [ 1,2 ]);
/// assert_eq!(arr[1..=3], [ 1,2,3 ]);
/// ```
///
/// [`IntoIterator`]: ../iter/trait.Iterator.html
@ -676,7 +692,7 @@ pub enum Bound<T> {
#[stable(feature = "collections_range", since = "1.28.0")]
/// `RangeBounds` is implemented by Rust's built-in range types, produced
/// by range syntax like `..`, `a..`, `..b` or `c..d`.
/// by range syntax like `..`, `a..`, `..b`, `..=c`, `d..e`, or `f..=g`.
pub trait RangeBounds<T: ?Sized> {
/// Start index bound.
///

View file

@ -1286,7 +1286,7 @@ impl<A, V: FromIterator<A>> FromIterator<Option<A>> for Option<V> {
/// # Examples
///
/// Here is an example which increments every integer in a vector.
/// `We use the checked variant of `add` that returns `None` when the
/// We use the checked variant of `add` that returns `None` when the
/// calculation would result in an overflow.
///
/// ```

View file

@ -215,7 +215,7 @@
//! had a method `fn get_pin_mut(self: Pin<&mut Self>) -> Pin<&mut T>`.
//! Then we could do the following:
//! ```compile_fail
//! fn exploit_ref_cell<T>(rc: Pin<&mut RefCell<T>) {
//! fn exploit_ref_cell<T>(rc: Pin<&mut RefCell<T>>) {
//! { let p = rc.as_mut().get_pin_mut(); } // Here we get pinned access to the `T`.
//! let rc_shr: &RefCell<T> = rc.into_ref().get_ref();
//! let b = rc_shr.borrow_mut();
@ -279,7 +279,7 @@ use ops::{Deref, DerefMut, Receiver, CoerceUnsized, DispatchFromDyn};
// implementations, are allowed because they all only use `&P`, so they cannot move
// the value behind `pointer`.
#[stable(feature = "pin", since = "1.33.0")]
#[cfg_attr(not(stage0), lang = "pin")]
#[lang = "pin"]
#[fundamental]
#[repr(transparent)]
#[derive(Copy, Clone, Hash, Eq, Ord)]

View file

@ -301,7 +301,7 @@ pub unsafe fn swap<T>(x: *mut T, y: *mut T) {
// Perform the swap
copy_nonoverlapping(x, tmp.as_mut_ptr(), 1);
copy(y, x, 1); // `x` and `y` may overlap
copy_nonoverlapping(tmp.get_ref(), y, 1);
copy_nonoverlapping(tmp.as_ptr(), y, 1);
}
/// Swaps `count * size_of::<T>()` bytes between the two regions of memory
@ -2790,7 +2790,7 @@ impl<T: ?Sized> Unique<T> {
}
/// Acquires the underlying `*mut` pointer.
pub fn as_ptr(self) -> *mut T {
pub const fn as_ptr(self) -> *mut T {
self.pointer as *mut T
}
@ -2837,15 +2837,15 @@ impl<T: ?Sized> fmt::Pointer for Unique<T> {
}
#[unstable(feature = "ptr_internals", issue = "0")]
impl<'a, T: ?Sized> From<&'a mut T> for Unique<T> {
fn from(reference: &'a mut T) -> Self {
impl<T: ?Sized> From<&mut T> for Unique<T> {
fn from(reference: &mut T) -> Self {
unsafe { Unique { pointer: reference as *mut T, _marker: PhantomData } }
}
}
#[unstable(feature = "ptr_internals", issue = "0")]
impl<'a, T: ?Sized> From<&'a T> for Unique<T> {
fn from(reference: &'a T) -> Self {
impl<T: ?Sized> From<&T> for Unique<T> {
fn from(reference: &T) -> Self {
unsafe { Unique { pointer: reference as *const T, _marker: PhantomData } }
}
}
@ -2874,6 +2874,16 @@ impl<'a, T: ?Sized> From<NonNull<T>> for Unique<T> {
/// Usually this won't be necessary; covariance is correct for most safe abstractions,
/// such as Box, Rc, Arc, Vec, and LinkedList. This is the case because they
/// provide a public API that follows the normal shared XOR mutable rules of Rust.
///
/// Notice that `NonNull<T>` has a `From` instance for `&T`. However, this does
/// not change the fact that mutating through a (pointer derived from a) shared
/// reference is undefined behavior unless the mutation happens inside an
/// [`UnsafeCell<T>`]. The same goes for creating a mutable reference from a shared
/// reference. When using this `From` instance without an `UnsafeCell<T>`,
/// it is your responsibility to ensure that `as_mut` is never called, and `as_ptr`
/// is never used for mutation.
///
/// [`UnsafeCell<T>`]: ../cell/struct.UnsafeCell.html
#[stable(feature = "nonnull", since = "1.25.0")]
#[repr(transparent)]
#[rustc_layout_scalar_valid_range_start(1)]
@ -2903,7 +2913,8 @@ impl<T: Sized> NonNull<T> {
/// some other means.
#[stable(feature = "nonnull", since = "1.25.0")]
#[inline]
pub fn dangling() -> Self {
#[cfg_attr(not(stage0), rustc_const_unstable(feature = "const_ptr_nonnull"))]
pub const fn dangling() -> Self {
unsafe {
let ptr = mem::align_of::<T>() as *mut T;
NonNull::new_unchecked(ptr)
@ -2966,7 +2977,8 @@ impl<T: ?Sized> NonNull<T> {
/// Cast to a pointer of another type
#[stable(feature = "nonnull_cast", since = "1.27.0")]
#[inline]
pub fn cast<U>(self) -> NonNull<U> {
#[cfg_attr(not(stage0), rustc_const_unstable(feature = "const_ptr_nonnull"))]
pub const fn cast<U>(self) -> NonNull<U> {
unsafe {
NonNull::new_unchecked(self.as_ptr() as *mut U)
}
@ -3047,17 +3059,17 @@ impl<T: ?Sized> From<Unique<T>> for NonNull<T> {
}
#[stable(feature = "nonnull", since = "1.25.0")]
impl<'a, T: ?Sized> From<&'a mut T> for NonNull<T> {
impl<T: ?Sized> From<&mut T> for NonNull<T> {
#[inline]
fn from(reference: &'a mut T) -> Self {
fn from(reference: &mut T) -> Self {
unsafe { NonNull { pointer: reference as *mut T } }
}
}
#[stable(feature = "nonnull", since = "1.25.0")]
impl<'a, T: ?Sized> From<&'a T> for NonNull<T> {
impl<T: ?Sized> From<&T> for NonNull<T> {
#[inline]
fn from(reference: &'a T) -> Self {
fn from(reference: &T) -> Self {
unsafe { NonNull { pointer: reference as *const T } }
}
}

View file

@ -1200,7 +1200,7 @@ impl<A, E, V: FromIterator<A>> FromIterator<Result<A, E>> for Result<V, E> {
/// let res: Result<Vec<u32>, &'static str> = v.iter().map(|x: &u32|
/// x.checked_add(1).ok_or("Overflow!")
/// ).collect();
/// assert!(res == Ok(vec![2, 3]));
/// assert_eq!(res, Ok(vec![2, 3]));
/// ```
#[inline]
fn from_iter<I: IntoIterator<Item=Result<A, E>>>(iter: I) -> Result<V, E> {

View file

@ -3288,6 +3288,34 @@ impl<'a, T> IterMut<'a, T> {
pub fn into_slice(self) -> &'a mut [T] {
unsafe { from_raw_parts_mut(self.ptr, len!(self)) }
}
/// Views the underlying data as a subslice of the original data.
///
/// To avoid creating `&mut [T]` references that alias, the returned slice
/// borrows its lifetime from the iterator the method is applied on.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// # #![feature(slice_iter_mut_as_slice)]
/// let mut slice: &mut [usize] = &mut [1, 2, 3];
///
/// // First, we get the iterator:
/// let mut iter = slice.iter_mut();
/// // So if we check what the `as_slice` method returns here, we have "[1, 2, 3]":
/// assert_eq!(iter.as_slice(), &[1, 2, 3]);
///
/// // Next, we move to the second element of the slice:
/// iter.next();
/// // Now `as_slice` returns "[2, 3]":
/// assert_eq!(iter.as_slice(), &[2, 3]);
/// ```
#[unstable(feature = "slice_iter_mut_as_slice", reason = "recently added", issue = "58957")]
pub fn as_slice(&self) -> &[T] {
self.make_slice()
}
}
iterator!{struct IterMut -> *mut T, &'a mut T, mut, {mut}, {}}

View file

@ -3965,7 +3965,7 @@ impl str {
me.make_ascii_lowercase()
}
/// Return an iterator that escapes each char in `s` with [`char::escape_debug`].
/// Return an iterator that escapes each char in `self` with [`char::escape_debug`].
///
/// Note: only extended grapheme codepoints that begin the string will be
/// escaped.
@ -4013,7 +4013,7 @@ impl str {
}
}
/// Return an iterator that escapes each char in `s` with [`char::escape_default`].
/// Return an iterator that escapes each char in `self` with [`char::escape_default`].
///
/// [`char::escape_default`]: ../std/primitive.char.html#method.escape_default
///
@ -4051,7 +4051,7 @@ impl str {
EscapeDefault { inner: self.chars().flat_map(CharEscapeDefault) }
}
/// Return an iterator that escapes each char in `s` with [`char::escape_unicode`].
/// Return an iterator that escapes each char in `self` with [`char::escape_unicode`].
///
/// [`char::escape_unicode`]: ../std/primitive.char.html#method.escape_unicode
///

View file

@ -290,15 +290,11 @@ pub enum Ordering {
/// [`AtomicBool`]: struct.AtomicBool.html
#[cfg(target_has_atomic = "8")]
#[stable(feature = "rust1", since = "1.0.0")]
#[cfg_attr(not(stage0), rustc_deprecated(
#[rustc_deprecated(
since = "1.34.0",
reason = "the `new` function is now preferred",
suggestion = "AtomicBool::new(false)",
))]
#[cfg_attr(stage0, rustc_deprecated(
since = "1.34.0",
reason = "the `new` function is now preferred",
))]
)]
pub const ATOMIC_BOOL_INIT: AtomicBool = AtomicBool::new(false);
#[cfg(target_has_atomic = "8")]
@ -1158,15 +1154,11 @@ macro_rules! atomic_int {
/// An atomic integer initialized to `0`.
#[$stable_init_const]
#[cfg_attr(stage0, rustc_deprecated(
since = "1.34.0",
reason = "the `new` function is now preferred",
))]
#[cfg_attr(not(stage0), rustc_deprecated(
#[rustc_deprecated(
since = "1.34.0",
reason = "the `new` function is now preferred",
suggestion = $atomic_new,
))]
)]
pub const $atomic_init: $atomic_type = $atomic_type::new(0);
#[$stable]

View file

@ -3,146 +3,146 @@ fn test_format_int() {
// Formatting integers should select the right implementation based off
// the type of the argument. Also, hex/octal/binary should be defined
// for integers, but they shouldn't emit the negative sign.
assert!(format!("{}", 1isize) == "1");
assert!(format!("{}", 1i8) == "1");
assert!(format!("{}", 1i16) == "1");
assert!(format!("{}", 1i32) == "1");
assert!(format!("{}", 1i64) == "1");
assert!(format!("{}", -1isize) == "-1");
assert!(format!("{}", -1i8) == "-1");
assert!(format!("{}", -1i16) == "-1");
assert!(format!("{}", -1i32) == "-1");
assert!(format!("{}", -1i64) == "-1");
assert!(format!("{:?}", 1isize) == "1");
assert!(format!("{:?}", 1i8) == "1");
assert!(format!("{:?}", 1i16) == "1");
assert!(format!("{:?}", 1i32) == "1");
assert!(format!("{:?}", 1i64) == "1");
assert!(format!("{:b}", 1isize) == "1");
assert!(format!("{:b}", 1i8) == "1");
assert!(format!("{:b}", 1i16) == "1");
assert!(format!("{:b}", 1i32) == "1");
assert!(format!("{:b}", 1i64) == "1");
assert!(format!("{:x}", 1isize) == "1");
assert!(format!("{:x}", 1i8) == "1");
assert!(format!("{:x}", 1i16) == "1");
assert!(format!("{:x}", 1i32) == "1");
assert!(format!("{:x}", 1i64) == "1");
assert!(format!("{:X}", 1isize) == "1");
assert!(format!("{:X}", 1i8) == "1");
assert!(format!("{:X}", 1i16) == "1");
assert!(format!("{:X}", 1i32) == "1");
assert!(format!("{:X}", 1i64) == "1");
assert!(format!("{:o}", 1isize) == "1");
assert!(format!("{:o}", 1i8) == "1");
assert!(format!("{:o}", 1i16) == "1");
assert!(format!("{:o}", 1i32) == "1");
assert!(format!("{:o}", 1i64) == "1");
assert_eq!(format!("{}", 1isize), "1");
assert_eq!(format!("{}", 1i8), "1");
assert_eq!(format!("{}", 1i16), "1");
assert_eq!(format!("{}", 1i32), "1");
assert_eq!(format!("{}", 1i64), "1");
assert_eq!(format!("{}", -1isize), "-1");
assert_eq!(format!("{}", -1i8), "-1");
assert_eq!(format!("{}", -1i16), "-1");
assert_eq!(format!("{}", -1i32), "-1");
assert_eq!(format!("{}", -1i64), "-1");
assert_eq!(format!("{:?}", 1isize), "1");
assert_eq!(format!("{:?}", 1i8), "1");
assert_eq!(format!("{:?}", 1i16), "1");
assert_eq!(format!("{:?}", 1i32), "1");
assert_eq!(format!("{:?}", 1i64), "1");
assert_eq!(format!("{:b}", 1isize), "1");
assert_eq!(format!("{:b}", 1i8), "1");
assert_eq!(format!("{:b}", 1i16), "1");
assert_eq!(format!("{:b}", 1i32), "1");
assert_eq!(format!("{:b}", 1i64), "1");
assert_eq!(format!("{:x}", 1isize), "1");
assert_eq!(format!("{:x}", 1i8), "1");
assert_eq!(format!("{:x}", 1i16), "1");
assert_eq!(format!("{:x}", 1i32), "1");
assert_eq!(format!("{:x}", 1i64), "1");
assert_eq!(format!("{:X}", 1isize), "1");
assert_eq!(format!("{:X}", 1i8), "1");
assert_eq!(format!("{:X}", 1i16), "1");
assert_eq!(format!("{:X}", 1i32), "1");
assert_eq!(format!("{:X}", 1i64), "1");
assert_eq!(format!("{:o}", 1isize), "1");
assert_eq!(format!("{:o}", 1i8), "1");
assert_eq!(format!("{:o}", 1i16), "1");
assert_eq!(format!("{:o}", 1i32), "1");
assert_eq!(format!("{:o}", 1i64), "1");
assert!(format!("{}", 1usize) == "1");
assert!(format!("{}", 1u8) == "1");
assert!(format!("{}", 1u16) == "1");
assert!(format!("{}", 1u32) == "1");
assert!(format!("{}", 1u64) == "1");
assert!(format!("{:?}", 1usize) == "1");
assert!(format!("{:?}", 1u8) == "1");
assert!(format!("{:?}", 1u16) == "1");
assert!(format!("{:?}", 1u32) == "1");
assert!(format!("{:?}", 1u64) == "1");
assert!(format!("{:b}", 1usize) == "1");
assert!(format!("{:b}", 1u8) == "1");
assert!(format!("{:b}", 1u16) == "1");
assert!(format!("{:b}", 1u32) == "1");
assert!(format!("{:b}", 1u64) == "1");
assert!(format!("{:x}", 1usize) == "1");
assert!(format!("{:x}", 1u8) == "1");
assert!(format!("{:x}", 1u16) == "1");
assert!(format!("{:x}", 1u32) == "1");
assert!(format!("{:x}", 1u64) == "1");
assert!(format!("{:X}", 1usize) == "1");
assert!(format!("{:X}", 1u8) == "1");
assert!(format!("{:X}", 1u16) == "1");
assert!(format!("{:X}", 1u32) == "1");
assert!(format!("{:X}", 1u64) == "1");
assert!(format!("{:o}", 1usize) == "1");
assert!(format!("{:o}", 1u8) == "1");
assert!(format!("{:o}", 1u16) == "1");
assert!(format!("{:o}", 1u32) == "1");
assert!(format!("{:o}", 1u64) == "1");
assert_eq!(format!("{}", 1usize), "1");
assert_eq!(format!("{}", 1u8), "1");
assert_eq!(format!("{}", 1u16), "1");
assert_eq!(format!("{}", 1u32), "1");
assert_eq!(format!("{}", 1u64), "1");
assert_eq!(format!("{:?}", 1usize), "1");
assert_eq!(format!("{:?}", 1u8), "1");
assert_eq!(format!("{:?}", 1u16), "1");
assert_eq!(format!("{:?}", 1u32), "1");
assert_eq!(format!("{:?}", 1u64), "1");
assert_eq!(format!("{:b}", 1usize), "1");
assert_eq!(format!("{:b}", 1u8), "1");
assert_eq!(format!("{:b}", 1u16), "1");
assert_eq!(format!("{:b}", 1u32), "1");
assert_eq!(format!("{:b}", 1u64), "1");
assert_eq!(format!("{:x}", 1usize), "1");
assert_eq!(format!("{:x}", 1u8), "1");
assert_eq!(format!("{:x}", 1u16), "1");
assert_eq!(format!("{:x}", 1u32), "1");
assert_eq!(format!("{:x}", 1u64), "1");
assert_eq!(format!("{:X}", 1usize), "1");
assert_eq!(format!("{:X}", 1u8), "1");
assert_eq!(format!("{:X}", 1u16), "1");
assert_eq!(format!("{:X}", 1u32), "1");
assert_eq!(format!("{:X}", 1u64), "1");
assert_eq!(format!("{:o}", 1usize), "1");
assert_eq!(format!("{:o}", 1u8), "1");
assert_eq!(format!("{:o}", 1u16), "1");
assert_eq!(format!("{:o}", 1u32), "1");
assert_eq!(format!("{:o}", 1u64), "1");
// Test a larger number
assert!(format!("{:b}", 55) == "110111");
assert!(format!("{:o}", 55) == "67");
assert!(format!("{}", 55) == "55");
assert!(format!("{:x}", 55) == "37");
assert!(format!("{:X}", 55) == "37");
assert_eq!(format!("{:b}", 55), "110111");
assert_eq!(format!("{:o}", 55), "67");
assert_eq!(format!("{}", 55), "55");
assert_eq!(format!("{:x}", 55), "37");
assert_eq!(format!("{:X}", 55), "37");
}
#[test]
fn test_format_int_zero() {
assert!(format!("{}", 0) == "0");
assert!(format!("{:?}", 0) == "0");
assert!(format!("{:b}", 0) == "0");
assert!(format!("{:o}", 0) == "0");
assert!(format!("{:x}", 0) == "0");
assert!(format!("{:X}", 0) == "0");
assert_eq!(format!("{}", 0), "0");
assert_eq!(format!("{:?}", 0), "0");
assert_eq!(format!("{:b}", 0), "0");
assert_eq!(format!("{:o}", 0), "0");
assert_eq!(format!("{:x}", 0), "0");
assert_eq!(format!("{:X}", 0), "0");
assert!(format!("{}", 0u32) == "0");
assert!(format!("{:?}", 0u32) == "0");
assert!(format!("{:b}", 0u32) == "0");
assert!(format!("{:o}", 0u32) == "0");
assert!(format!("{:x}", 0u32) == "0");
assert!(format!("{:X}", 0u32) == "0");
assert_eq!(format!("{}", 0u32), "0");
assert_eq!(format!("{:?}", 0u32), "0");
assert_eq!(format!("{:b}", 0u32), "0");
assert_eq!(format!("{:o}", 0u32), "0");
assert_eq!(format!("{:x}", 0u32), "0");
assert_eq!(format!("{:X}", 0u32), "0");
}
#[test]
fn test_format_int_flags() {
assert!(format!("{:3}", 1) == " 1");
assert!(format!("{:>3}", 1) == " 1");
assert!(format!("{:>+3}", 1) == " +1");
assert!(format!("{:<3}", 1) == "1 ");
assert!(format!("{:#}", 1) == "1");
assert!(format!("{:#x}", 10) == "0xa");
assert!(format!("{:#X}", 10) == "0xA");
assert!(format!("{:#5x}", 10) == " 0xa");
assert!(format!("{:#o}", 10) == "0o12");
assert!(format!("{:08x}", 10) == "0000000a");
assert!(format!("{:8x}", 10) == " a");
assert!(format!("{:<8x}", 10) == "a ");
assert!(format!("{:>8x}", 10) == " a");
assert!(format!("{:#08x}", 10) == "0x00000a");
assert!(format!("{:08}", -10) == "-0000010");
assert!(format!("{:x}", !0u8) == "ff");
assert!(format!("{:X}", !0u8) == "FF");
assert!(format!("{:b}", !0u8) == "11111111");
assert!(format!("{:o}", !0u8) == "377");
assert!(format!("{:#x}", !0u8) == "0xff");
assert!(format!("{:#X}", !0u8) == "0xFF");
assert!(format!("{:#b}", !0u8) == "0b11111111");
assert!(format!("{:#o}", !0u8) == "0o377");
assert_eq!(format!("{:3}", 1), " 1");
assert_eq!(format!("{:>3}", 1), " 1");
assert_eq!(format!("{:>+3}", 1), " +1");
assert_eq!(format!("{:<3}", 1), "1 ");
assert_eq!(format!("{:#}", 1), "1");
assert_eq!(format!("{:#x}", 10), "0xa");
assert_eq!(format!("{:#X}", 10), "0xA");
assert_eq!(format!("{:#5x}", 10), " 0xa");
assert_eq!(format!("{:#o}", 10), "0o12");
assert_eq!(format!("{:08x}", 10), "0000000a");
assert_eq!(format!("{:8x}", 10), " a");
assert_eq!(format!("{:<8x}", 10), "a ");
assert_eq!(format!("{:>8x}", 10), " a");
assert_eq!(format!("{:#08x}", 10), "0x00000a");
assert_eq!(format!("{:08}", -10), "-0000010");
assert_eq!(format!("{:x}", !0u8), "ff");
assert_eq!(format!("{:X}", !0u8), "FF");
assert_eq!(format!("{:b}", !0u8), "11111111");
assert_eq!(format!("{:o}", !0u8), "377");
assert_eq!(format!("{:#x}", !0u8), "0xff");
assert_eq!(format!("{:#X}", !0u8), "0xFF");
assert_eq!(format!("{:#b}", !0u8), "0b11111111");
assert_eq!(format!("{:#o}", !0u8), "0o377");
}
#[test]
fn test_format_int_sign_padding() {
assert!(format!("{:+5}", 1) == " +1");
assert!(format!("{:+5}", -1) == " -1");
assert!(format!("{:05}", 1) == "00001");
assert!(format!("{:05}", -1) == "-0001");
assert!(format!("{:+05}", 1) == "+0001");
assert!(format!("{:+05}", -1) == "-0001");
assert_eq!(format!("{:+5}", 1), " +1");
assert_eq!(format!("{:+5}", -1), " -1");
assert_eq!(format!("{:05}", 1), "00001");
assert_eq!(format!("{:05}", -1), "-0001");
assert_eq!(format!("{:+05}", 1), "+0001");
assert_eq!(format!("{:+05}", -1), "-0001");
}
#[test]
fn test_format_int_twos_complement() {
use core::{i8, i16, i32, i64};
assert!(format!("{}", i8::MIN) == "-128");
assert!(format!("{}", i16::MIN) == "-32768");
assert!(format!("{}", i32::MIN) == "-2147483648");
assert!(format!("{}", i64::MIN) == "-9223372036854775808");
use core::{i16, i32, i64, i8};
assert_eq!(format!("{}", i8::MIN), "-128");
assert_eq!(format!("{}", i16::MIN), "-32768");
assert_eq!(format!("{}", i32::MIN), "-2147483648");
assert_eq!(format!("{}", i64::MIN), "-9223372036854775808");
}
#[test]
fn test_format_debug_hex() {
assert!(format!("{:02x?}", b"Foo\0") == "[46, 6f, 6f, 00]");
assert!(format!("{:02X?}", b"Foo\0") == "[46, 6F, 6F, 00]");
assert_eq!(format!("{:02x?}", b"Foo\0"), "[46, 6f, 6f, 00]");
assert_eq!(format!("{:02X?}", b"Foo\0"), "[46, 6F, 6F, 00]");
}

View file

@ -1082,12 +1082,39 @@ fn test_iterator_product_result() {
assert_eq!(v.iter().cloned().product::<Result<i32, _>>(), Err(()));
}
/// A wrapper struct that implements `Eq` and `Ord` based on the wrapped
/// integer modulo 3. Used to test that `Iterator::max` and `Iterator::min`
/// return the correct element if some of them are equal.
#[derive(Debug)]
struct Mod3(i32);
impl PartialEq for Mod3 {
fn eq(&self, other: &Self) -> bool {
self.0 % 3 == other.0 % 3
}
}
impl Eq for Mod3 {}
impl PartialOrd for Mod3 {
fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
Some(self.cmp(other))
}
}
impl Ord for Mod3 {
fn cmp(&self, other: &Self) -> core::cmp::Ordering {
(self.0 % 3).cmp(&(other.0 % 3))
}
}
#[test]
fn test_iterator_max() {
let v: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
assert_eq!(v[..4].iter().cloned().max(), Some(3));
assert_eq!(v.iter().cloned().max(), Some(10));
assert_eq!(v[..0].iter().cloned().max(), None);
assert_eq!(v.iter().cloned().map(Mod3).max().map(|x| x.0), Some(8));
}
#[test]
@ -1096,6 +1123,7 @@ fn test_iterator_min() {
assert_eq!(v[..4].iter().cloned().min(), Some(0));
assert_eq!(v.iter().cloned().min(), Some(0));
assert_eq!(v[..0].iter().cloned().min(), None);
assert_eq!(v.iter().cloned().map(Mod3).min().map(|x| x.0), Some(0));
}
#[test]

View file

@ -26,7 +26,6 @@
#![feature(str_internals)]
#![feature(test)]
#![feature(trusted_len)]
#![feature(try_from)]
#![feature(try_trait)]
#![feature(align_offset)]
#![feature(reverse_bits)]

View file

@ -17,13 +17,14 @@ graphviz = { path = "../libgraphviz" }
jobserver = "0.1"
lazy_static = "1.0.0"
num_cpus = "1.0"
scoped-tls = { version = "0.1.1", features = ["nightly"] }
scoped-tls = "1.0"
log = { version = "0.4", features = ["release_max_level_info", "std"] }
polonius-engine = "0.6.2"
rustc-rayon = "0.1.1"
rustc-rayon-core = "0.1.1"
rustc-rayon = "0.1.2"
rustc-rayon-core = "0.1.2"
rustc_apfloat = { path = "../librustc_apfloat" }
rustc_target = { path = "../librustc_target" }
rustc_macros = { path = "../librustc_macros" }
rustc_data_structures = { path = "../librustc_data_structures" }
errors = { path = "../librustc_errors", package = "rustc_errors" }
serialize = { path = "../libserialize" }

View file

@ -398,7 +398,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
args: I) -> CFGIndex {
let func_or_rcvr_exit = self.expr(func_or_rcvr, pred);
let ret = self.straightline(call_expr, func_or_rcvr_exit, args);
let m = self.tcx.hir().get_module_parent(call_expr.id);
let m = self.tcx.hir().get_module_parent_by_hir_id(call_expr.hir_id);
if self.tcx.is_ty_uninhabited_from(m, self.tables.expr_ty(call_expr)) {
self.add_unreachable_node()
} else {
@ -571,9 +571,9 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
match destination.target_id {
Ok(loop_id) => {
for b in &self.breakable_block_scopes {
if b.block_expr_id == self.tcx.hir().node_to_hir_id(loop_id).local_id {
if b.block_expr_id == loop_id.local_id {
let scope = region::Scope {
id: self.tcx.hir().node_to_hir_id(loop_id).local_id,
id: loop_id.local_id,
data: region::ScopeData::Node
};
return (scope, match scope_cf_kind {
@ -583,9 +583,9 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
}
}
for l in &self.loop_scopes {
if l.loop_id == self.tcx.hir().node_to_hir_id(loop_id).local_id {
if l.loop_id == loop_id.local_id {
let scope = region::Scope {
id: self.tcx.hir().node_to_hir_id(loop_id).local_id,
id: loop_id.local_id,
data: region::ScopeData::Node
};
return (scope, match scope_cf_kind {

View file

@ -67,7 +67,7 @@ use crate::traits::query::{
};
use crate::ty::{TyCtxt, FnSig, Instance, InstanceDef,
ParamEnv, ParamEnvAnd, Predicate, PolyFnSig, PolyTraitRef, Ty};
use crate::ty::subst::Substs;
use crate::ty::subst::SubstsRef;
// erase!() just makes tokens go away. It's used to specify which macro argument
// is repeated (i.e., which sub-expression of the macro we are in) but don't need
@ -456,6 +456,8 @@ define_dep_nodes!( <'tcx>
[eval_always] CoherenceInherentImplOverlapCheck,
[] CoherenceCheckTrait(DefId),
[eval_always] PrivacyAccessLevels(CrateNum),
[eval_always] CheckPrivateInPublic(CrateNum),
[eval_always] Analysis(CrateNum),
// Represents the MIR for a fn; also used as the task node for
// things read/modify that MIR.
@ -661,7 +663,7 @@ define_dep_nodes!( <'tcx>
[] TypeOpNormalizePolyFnSig(CanonicalTypeOpNormalizeGoal<'tcx, PolyFnSig<'tcx>>),
[] TypeOpNormalizeFnSig(CanonicalTypeOpNormalizeGoal<'tcx, FnSig<'tcx>>),
[] SubstituteNormalizeAndTestPredicates { key: (DefId, &'tcx Substs<'tcx>) },
[] SubstituteNormalizeAndTestPredicates { key: (DefId, SubstsRef<'tcx>) },
[] MethodAutoderefSteps(CanonicalTyGoal<'tcx>),
[input] TargetFeaturesWhitelist,

View file

@ -94,7 +94,7 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> {
/// Checks any attribute.
fn check_attributes(&self, item: &hir::Item, target: Target) {
if target == Target::Fn || target == Target::Const {
self.tcx.codegen_fn_attrs(self.tcx.hir().local_def_id(item.id));
self.tcx.codegen_fn_attrs(self.tcx.hir().local_def_id_from_hir_id(item.hir_id));
} else if let Some(a) = item.attrs.iter().find(|a| a.check_name("target_feature")) {
self.tcx.sess.struct_span_err(a.span, "attribute should be applied to a function")
.span_label(item.span, "not a function")
@ -344,12 +344,6 @@ impl<'a, 'tcx> Visitor<'tcx> for CheckAttrVisitor<'a, 'tcx> {
}
}
pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
for &module in tcx.hir().krate().modules.keys() {
tcx.ensure().check_mod_attrs(tcx.hir().local_def_id(module));
}
}
fn is_c_like_enum(item: &hir::Item) -> bool {
if let hir::ItemKind::Enum(ref def, _) = item.node {
for variant in &def.variants {

View file

@ -3,12 +3,13 @@ use crate::util::nodemap::{NodeMap, DefIdMap};
use syntax::ast;
use syntax::ext::base::MacroKind;
use syntax_pos::Span;
use rustc_macros::HashStable;
use crate::hir;
use crate::ty;
use self::Namespace::*;
#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, HashStable)]
pub enum CtorKind {
/// Constructor function automatically created by a tuple struct/variant.
Fn,
@ -18,7 +19,7 @@ pub enum CtorKind {
Fictive,
}
#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, HashStable)]
pub enum NonMacroAttrKind {
/// Single-segment attribute defined by the language (`#[inline]`)
Builtin,
@ -32,7 +33,7 @@ pub enum NonMacroAttrKind {
Custom,
}
#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, HashStable)]
pub enum Def {
// Type namespace
Mod(DefId),
@ -209,7 +210,7 @@ pub type ExportMap = DefIdMap<Vec<Export>>;
/// namespace.
pub type ImportMap = NodeMap<PerNS<Option<PathResolution>>>;
#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable)]
#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
pub struct Export {
/// The name of the target.
pub ident: ast::Ident,

View file

@ -34,7 +34,6 @@
use syntax::ast::{Ident, Name, Attribute};
use syntax_pos::Span;
use crate::hir::*;
use crate::hir::def::Def;
use crate::hir::map::Map;
use super::itemlikevisit::DeepVisitor;
@ -228,9 +227,6 @@ pub trait Visitor<'v> : Sized {
fn visit_id(&mut self, _hir_id: HirId) {
// Nothing to do.
}
fn visit_def_mention(&mut self, _def: Def) {
// Nothing to do.
}
fn visit_name(&mut self, _span: Span, _name: Name) {
// Nothing to do.
}
@ -494,13 +490,10 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
visitor.visit_ty(typ);
visitor.visit_generics(type_parameters)
}
ItemKind::Existential(ExistTy {ref generics, ref bounds, impl_trait_fn}) => {
ItemKind::Existential(ExistTy { ref generics, ref bounds, impl_trait_fn: _ }) => {
visitor.visit_id(item.hir_id);
walk_generics(visitor, generics);
walk_list!(visitor, visit_param_bound, bounds);
if let Some(impl_trait_fn) = impl_trait_fn {
visitor.visit_def_mention(Def::Fn(impl_trait_fn))
}
}
ItemKind::Enum(ref enum_definition, ref type_parameters) => {
visitor.visit_generics(type_parameters);
@ -617,6 +610,9 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) {
TyKind::Typeof(ref expression) => {
visitor.visit_anon_const(expression)
}
TyKind::CVarArgs(ref lt) => {
visitor.visit_lifetime(lt)
}
TyKind::Infer | TyKind::Err => {}
}
}
@ -637,7 +633,6 @@ pub fn walk_qpath<'v, V: Visitor<'v>>(visitor: &mut V, qpath: &'v QPath, id: Hir
}
pub fn walk_path<'v, V: Visitor<'v>>(visitor: &mut V, path: &'v Path) {
visitor.visit_def_mention(path.def);
for segment in &path.segments {
visitor.visit_path_segment(path.span, segment);
}
@ -694,8 +689,7 @@ pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat) {
PatKind::Ref(ref subpattern, _) => {
visitor.visit_pat(subpattern)
}
PatKind::Binding(_, canonical_id, _hir_id, ident, ref optional_subpattern) => {
visitor.visit_def_mention(Def::Local(canonical_id));
PatKind::Binding(_, _hir_id, ident, ref optional_subpattern) => {
visitor.visit_ident(ident);
walk_list!(visitor, visit_pat, optional_subpattern);
}
@ -875,7 +869,6 @@ pub fn walk_trait_item_ref<'v, V: Visitor<'v>>(visitor: &mut V, trait_item_ref:
pub fn walk_impl_item<'v, V: Visitor<'v>>(visitor: &mut V, impl_item: &'v ImplItem) {
// N.B., deliberately force a compilation error if/when new fields are added.
let ImplItem {
id: _,
hir_id: _,
ident,
ref vis,
@ -1062,18 +1055,12 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
ExprKind::Break(ref destination, ref opt_expr) => {
if let Some(ref label) = destination.label {
visitor.visit_label(label);
if let Ok(node_id) = destination.target_id {
visitor.visit_def_mention(Def::Label(node_id))
}
}
walk_list!(visitor, visit_expr, opt_expr);
}
ExprKind::Continue(ref destination) => {
if let Some(ref label) = destination.label {
visitor.visit_label(label);
if let Ok(node_id) = destination.target_id {
visitor.visit_def_mention(Def::Label(node_id))
}
}
}
ExprKind::Ret(ref optional_expression) => {
@ -1103,7 +1090,7 @@ pub fn walk_arm<'v, V: Visitor<'v>>(visitor: &mut V, arm: &'v Arm) {
}
pub fn walk_vis<'v, V: Visitor<'v>>(visitor: &mut V, vis: &'v Visibility) {
if let VisibilityKind::Restricted { ref path, id: _, hir_id } = vis.node {
if let VisibilityKind::Restricted { ref path, hir_id } = vis.node {
visitor.visit_id(hir_id);
visitor.visit_path(path, hir_id)
}

File diff suppressed because it is too large Load diff

View file

@ -75,10 +75,10 @@ pub enum Code<'a> {
}
impl<'a> Code<'a> {
pub fn id(&self) -> NodeId {
pub fn id(&self) -> ast::HirId {
match *self {
Code::FnLike(node) => node.id(),
Code::Expr(block) => block.id,
Code::Expr(block) => block.hir_id,
}
}
@ -104,7 +104,7 @@ struct ItemFnParts<'a> {
vis: &'a ast::Visibility,
generics: &'a ast::Generics,
body: ast::BodyId,
id: NodeId,
id: ast::HirId,
span: Span,
attrs: &'a [Attribute],
}
@ -114,13 +114,13 @@ struct ItemFnParts<'a> {
struct ClosureParts<'a> {
decl: &'a FnDecl,
body: ast::BodyId,
id: NodeId,
id: ast::HirId,
span: Span,
attrs: &'a [Attribute],
}
impl<'a> ClosureParts<'a> {
fn new(d: &'a FnDecl, b: ast::BodyId, id: NodeId, s: Span, attrs: &'a [Attribute]) -> Self {
fn new(d: &'a FnDecl, b: ast::BodyId, id: ast::HirId, s: Span, attrs: &'a [Attribute]) -> Self {
ClosureParts {
decl: d,
body: b,
@ -168,7 +168,7 @@ impl<'a> FnLikeNode<'a> {
|c: ClosureParts<'_>| c.span)
}
pub fn id(self) -> NodeId {
pub fn id(self) -> ast::HirId {
self.handle(|i: ItemFnParts<'_>| i.id,
|id, _, _: &'a ast::MethodSig, _, _, _, _| id,
|c: ClosureParts<'_>| c.id)
@ -213,7 +213,7 @@ impl<'a> FnLikeNode<'a> {
fn handle<A, I, M, C>(self, item_fn: I, method: M, closure: C) -> A where
I: FnOnce(ItemFnParts<'a>) -> A,
M: FnOnce(NodeId,
M: FnOnce(ast::HirId,
Ident,
&'a ast::MethodSig,
Option<&'a ast::Visibility>,
@ -227,7 +227,7 @@ impl<'a> FnLikeNode<'a> {
map::Node::Item(i) => match i.node {
ast::ItemKind::Fn(ref decl, header, ref generics, block) =>
item_fn(ItemFnParts {
id: i.id,
id: i.hir_id,
ident: i.ident,
decl: &decl,
body: block,
@ -241,21 +241,21 @@ impl<'a> FnLikeNode<'a> {
},
map::Node::TraitItem(ti) => match ti.node {
ast::TraitItemKind::Method(ref sig, ast::TraitMethod::Provided(body)) => {
method(ti.id, ti.ident, sig, None, body, ti.span, &ti.attrs)
method(ti.hir_id, ti.ident, sig, None, body, ti.span, &ti.attrs)
}
_ => bug!("trait method FnLikeNode that is not fn-like"),
},
map::Node::ImplItem(ii) => {
match ii.node {
ast::ImplItemKind::Method(ref sig, body) => {
method(ii.id, ii.ident, sig, Some(&ii.vis), body, ii.span, &ii.attrs)
method(ii.hir_id, ii.ident, sig, Some(&ii.vis), body, ii.span, &ii.attrs)
}
_ => bug!("impl method FnLikeNode that is not fn-like")
}
},
map::Node::Expr(e) => match e.node {
ast::ExprKind::Closure(_, ref decl, block, _fn_decl_span, _gen) =>
closure(ClosureParts::new(&decl, block, e.id, e.span, &e.attrs)),
closure(ClosureParts::new(&decl, block, e.hir_id, e.span, &e.attrs)),
_ => bug!("expr FnLikeNode that is not fn-like"),
},
_ => bug!("other FnLikeNode that is not fn-like"),

View file

@ -356,7 +356,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
fn visit_item(&mut self, i: &'hir Item) {
debug!("visit_item: {:?}", i);
debug_assert_eq!(i.hir_id.owner,
self.definitions.opt_def_index(i.id).unwrap());
self.definitions.opt_def_index(self.hir_to_node_id[&i.hir_id]).unwrap());
self.with_dep_node_owner(i.hir_id.owner, i, |this| {
this.insert(i.span, i.hir_id, Node::Item(i));
this.with_parent(i.hir_id, |this| {
@ -386,7 +386,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
fn visit_trait_item(&mut self, ti: &'hir TraitItem) {
debug_assert_eq!(ti.hir_id.owner,
self.definitions.opt_def_index(ti.id).unwrap());
self.definitions.opt_def_index(self.hir_to_node_id[&ti.hir_id]).unwrap());
self.with_dep_node_owner(ti.hir_id.owner, ti, |this| {
this.insert(ti.span, ti.hir_id, Node::TraitItem(ti));
@ -398,7 +398,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
fn visit_impl_item(&mut self, ii: &'hir ImplItem) {
debug_assert_eq!(ii.hir_id.owner,
self.definitions.opt_def_index(ii.id).unwrap());
self.definitions.opt_def_index(self.hir_to_node_id[&ii.hir_id]).unwrap());
self.with_dep_node_owner(ii.hir_id.owner, ii, |this| {
this.insert(ii.span, ii.hir_id, Node::ImplItem(ii));
@ -507,7 +507,8 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
}
fn visit_macro_def(&mut self, macro_def: &'hir MacroDef) {
let def_index = self.definitions.opt_def_index(macro_def.id).unwrap();
let node_id = self.hir_to_node_id[&macro_def.hir_id];
let def_index = self.definitions.opt_def_index(node_id).unwrap();
self.with_dep_node_owner(def_index, macro_def, |this| {
this.insert(macro_def.span, macro_def.hir_id, Node::MacroDef(macro_def));

View file

@ -73,7 +73,7 @@ impl<'a> DefCollector<'a> {
decl: &'a FnDecl,
body: &'a Block,
) {
let (closure_id, return_impl_trait_id) = match header.asyncness {
let (closure_id, return_impl_trait_id) = match header.asyncness.node {
IsAsync::Async {
closure_id,
return_impl_trait_id,
@ -129,10 +129,10 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
}
ItemKind::Fn(
ref decl,
ref header @ FnHeader { asyncness: IsAsync::Async { .. }, .. },
ref header,
ref generics,
ref body,
) => {
) if header.asyncness.node.is_async() => {
return self.visit_async_fn(
i.id,
i.ident.name,
@ -242,9 +242,9 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
fn visit_impl_item(&mut self, ii: &'a ImplItem) {
let def_data = match ii.node {
ImplItemKind::Method(MethodSig {
header: ref header @ FnHeader { asyncness: IsAsync::Async { .. }, .. },
ref header,
ref decl,
}, ref body) => {
}, ref body) if header.asyncness.node.is_async() => {
return self.visit_async_fn(
ii.id,
ii.ident.name,

View file

@ -319,7 +319,7 @@ impl<'hir> Map<'hir> {
match node {
Node::Item(item) => {
let def_id = || self.local_def_id(item.id);
let def_id = || self.local_def_id_from_hir_id(item.hir_id);
match item.node {
ItemKind::Static(_, m, _) => Some(Def::Static(def_id(), m == MutMutable)),
@ -341,7 +341,7 @@ impl<'hir> Map<'hir> {
}
}
Node::ForeignItem(item) => {
let def_id = self.local_def_id(item.id);
let def_id = self.local_def_id_from_hir_id(item.hir_id);
match item.node {
ForeignItemKind::Fn(..) => Some(Def::Fn(def_id)),
ForeignItemKind::Static(_, m) => Some(Def::Static(def_id, m)),
@ -349,7 +349,7 @@ impl<'hir> Map<'hir> {
}
}
Node::TraitItem(item) => {
let def_id = self.local_def_id(item.id);
let def_id = self.local_def_id_from_hir_id(item.hir_id);
match item.node {
TraitItemKind::Const(..) => Some(Def::AssociatedConst(def_id)),
TraitItemKind::Method(..) => Some(Def::Method(def_id)),
@ -357,7 +357,7 @@ impl<'hir> Map<'hir> {
}
}
Node::ImplItem(item) => {
let def_id = self.local_def_id(item.id);
let def_id = self.local_def_id_from_hir_id(item.hir_id);
match item.node {
ImplItemKind::Const(..) => Some(Def::AssociatedConst(def_id)),
ImplItemKind::Method(..) => Some(Def::Method(def_id)),
@ -366,11 +366,11 @@ impl<'hir> Map<'hir> {
}
}
Node::Variant(variant) => {
let def_id = self.local_def_id(variant.node.data.id());
let def_id = self.local_def_id_from_hir_id(variant.node.data.hir_id());
Some(Def::Variant(def_id))
}
Node::StructCtor(variant) => {
let def_id = self.local_def_id(variant.id());
let def_id = self.local_def_id_from_hir_id(variant.hir_id());
Some(Def::StructCtor(def_id, def::CtorKind::from_hir(variant)))
}
Node::AnonConst(_) |
@ -387,17 +387,22 @@ impl<'hir> Map<'hir> {
Node::Block(_) |
Node::Crate => None,
Node::Local(local) => {
Some(Def::Local(local.id))
Some(Def::Local(self.hir_to_node_id(local.hir_id)))
}
Node::MacroDef(macro_def) => {
Some(Def::Macro(self.local_def_id(macro_def.id),
Some(Def::Macro(self.local_def_id_from_hir_id(macro_def.hir_id),
MacroKind::Bang))
}
Node::GenericParam(param) => {
Some(match param.kind {
GenericParamKind::Lifetime { .. } => Def::Local(param.id),
GenericParamKind::Type { .. } => Def::TyParam(self.local_def_id(param.id)),
GenericParamKind::Const { .. } => Def::ConstParam(self.local_def_id(param.id)),
GenericParamKind::Lifetime { .. } => {
let node_id = self.hir_to_node_id(param.hir_id);
Def::Local(node_id)
},
GenericParamKind::Type { .. } => Def::TyParam(
self.local_def_id_from_hir_id(param.hir_id)),
GenericParamKind::Const { .. } => Def::ConstParam(
self.local_def_id_from_hir_id(param.hir_id)),
})
}
}
@ -422,7 +427,7 @@ impl<'hir> Map<'hir> {
}
pub fn trait_item(&self, id: TraitItemId) -> &'hir TraitItem {
self.read(id.node_id);
self.read_by_hir_id(id.hir_id);
// N.B., intentionally bypass `self.forest.krate()` so that we
// do not trigger a read of the whole krate here
@ -430,7 +435,7 @@ impl<'hir> Map<'hir> {
}
pub fn impl_item(&self, id: ImplItemId) -> &'hir ImplItem {
self.read(id.node_id);
self.read_by_hir_id(id.hir_id);
// N.B., intentionally bypass `self.forest.krate()` so that we
// do not trigger a read of the whole krate here
@ -496,10 +501,10 @@ impl<'hir> Map<'hir> {
}
/// Given a body owner's id, returns the `BodyId` associated with it.
pub fn body_owned_by(&self, id: NodeId) -> BodyId {
self.maybe_body_owned_by(id).unwrap_or_else(|| {
span_bug!(self.span(id), "body_owned_by: {} has no associated body",
self.node_to_string(id));
pub fn body_owned_by(&self, id: HirId) -> BodyId {
self.maybe_body_owned_by_by_hir_id(id).unwrap_or_else(|| {
span_bug!(self.span_by_hir_id(id), "body_owned_by: {} has no associated body",
self.hir_to_string(id));
})
}
@ -534,19 +539,19 @@ impl<'hir> Map<'hir> {
self.body_owner_kind(node_id)
}
pub fn ty_param_owner(&self, id: NodeId) -> NodeId {
match self.get(id) {
pub fn ty_param_owner(&self, id: HirId) -> HirId {
match self.get_by_hir_id(id) {
Node::Item(&Item { node: ItemKind::Trait(..), .. }) => id,
Node::GenericParam(_) => self.get_parent_node(id),
_ => bug!("ty_param_owner: {} not a type parameter", self.node_to_string(id))
Node::GenericParam(_) => self.get_parent_node_by_hir_id(id),
_ => bug!("ty_param_owner: {} not a type parameter", self.hir_to_string(id))
}
}
pub fn ty_param_name(&self, id: NodeId) -> Name {
match self.get(id) {
pub fn ty_param_name(&self, id: HirId) -> Name {
match self.get_by_hir_id(id) {
Node::Item(&Item { node: ItemKind::Trait(..), .. }) => keywords::SelfUpper.name(),
Node::GenericParam(param) => param.name.ident().name,
_ => bug!("ty_param_name: {} not a type parameter", self.node_to_string(id)),
_ => bug!("ty_param_name: {} not a type parameter", self.hir_to_string(id)),
}
}
@ -613,11 +618,11 @@ impl<'hir> Map<'hir> {
}
for id in &module.trait_items {
visitor.visit_trait_item(self.expect_trait_item(id.node_id));
visitor.visit_trait_item(self.expect_trait_item(id.hir_id));
}
for id in &module.impl_items {
visitor.visit_impl_item(self.expect_impl_item(id.node_id));
visitor.visit_impl_item(self.expect_impl_item(id.hir_id));
}
}
@ -794,7 +799,7 @@ impl<'hir> Map<'hir> {
/// false
/// }
/// ```
pub fn get_return_block(&self, id: NodeId) -> Option<NodeId> {
pub fn get_return_block(&self, id: HirId) -> Option<HirId> {
let match_fn = |node: &Node<'_>| {
match *node {
Node::Item(_) |
@ -817,7 +822,10 @@ impl<'hir> Map<'hir> {
}
};
self.walk_parent_nodes(id, match_fn, match_non_returning_block).ok()
let node_id = self.hir_to_node_id(id);
self.walk_parent_nodes(node_id, match_fn, match_non_returning_block)
.ok()
.map(|return_node_id| self.node_to_hir_id(return_node_id))
}
/// Retrieves the `NodeId` for `id`'s parent item, or `id` itself if no
@ -921,66 +929,52 @@ impl<'hir> Map<'hir> {
// FIXME(@ljedrz): replace the NodeId variant
pub fn expect_item_by_hir_id(&self, id: HirId) -> &'hir Item {
let node_id = self.hir_to_node_id(id);
self.expect_item(node_id)
}
pub fn expect_impl_item(&self, id: NodeId) -> &'hir ImplItem {
match self.find(id) {
Some(Node::ImplItem(item)) => item,
_ => bug!("expected impl item, found {}", self.node_to_string(id))
match self.find_by_hir_id(id) { // read recorded by `find`
Some(Node::Item(item)) => item,
_ => bug!("expected item, found {}", self.hir_to_string(id))
}
}
// FIXME(@ljedrz): replace the NodeId variant
pub fn expect_impl_item_by_hir_id(&self, id: HirId) -> &'hir ImplItem {
let node_id = self.hir_to_node_id(id);
self.expect_impl_item(node_id)
pub fn expect_impl_item(&self, id: HirId) -> &'hir ImplItem {
match self.find_by_hir_id(id) {
Some(Node::ImplItem(item)) => item,
_ => bug!("expected impl item, found {}", self.hir_to_string(id))
}
}
// FIXME(@ljedrz): replace the NodeId variant
pub fn expect_trait_item_by_hir_id(&self, id: HirId) -> &'hir TraitItem {
let node_id = self.hir_to_node_id(id);
self.expect_trait_item(node_id)
}
pub fn expect_trait_item(&self, id: NodeId) -> &'hir TraitItem {
match self.find(id) {
pub fn expect_trait_item(&self, id: HirId) -> &'hir TraitItem {
match self.find_by_hir_id(id) {
Some(Node::TraitItem(item)) => item,
_ => bug!("expected trait item, found {}", self.node_to_string(id))
_ => bug!("expected trait item, found {}", self.hir_to_string(id))
}
}
pub fn expect_variant_data(&self, id: HirId) -> &'hir VariantData {
let id = self.hir_to_node_id(id); // FIXME(@ljedrz): remove when possible
match self.find(id) {
match self.find_by_hir_id(id) {
Some(Node::Item(i)) => {
match i.node {
ItemKind::Struct(ref struct_def, _) |
ItemKind::Union(ref struct_def, _) => struct_def,
_ => bug!("struct ID bound to non-struct {}", self.node_to_string(id))
_ => bug!("struct ID bound to non-struct {}", self.hir_to_string(id))
}
}
Some(Node::StructCtor(data)) => data,
Some(Node::Variant(variant)) => &variant.node.data,
_ => bug!("expected struct or variant, found {}", self.node_to_string(id))
_ => bug!("expected struct or variant, found {}", self.hir_to_string(id))
}
}
pub fn expect_variant(&self, id: HirId) -> &'hir Variant {
let id = self.hir_to_node_id(id); // FIXME(@ljedrz): remove when possible
match self.find(id) {
match self.find_by_hir_id(id) {
Some(Node::Variant(variant)) => variant,
_ => bug!("expected variant, found {}", self.node_to_string(id)),
_ => bug!("expected variant, found {}", self.hir_to_string(id)),
}
}
pub fn expect_foreign_item(&self, id: NodeId) -> &'hir ForeignItem {
match self.find(id) {
pub fn expect_foreign_item(&self, id: HirId) -> &'hir ForeignItem {
match self.find_by_hir_id(id) {
Some(Node::ForeignItem(item)) => item,
_ => bug!("expected foreign item, found {}", self.node_to_string(id))
_ => bug!("expected foreign item, found {}", self.hir_to_string(id))
}
}
@ -1008,7 +1002,7 @@ impl<'hir> Map<'hir> {
Node::Field(f) => f.ident.name,
Node::Lifetime(lt) => lt.name.ident().name,
Node::GenericParam(param) => param.name.ident().name,
Node::Binding(&Pat { node: PatKind::Binding(_, _, _, l, _), .. }) => l.name,
Node::Binding(&Pat { node: PatKind::Binding(_, _, l, _), .. }) => l.name,
Node::StructCtor(_) => self.name(self.get_parent(id)),
_ => bug!("no name for {}", self.node_to_string(id))
}

File diff suppressed because it is too large Load diff

View file

@ -70,7 +70,7 @@ impl hir::Pat {
where F: FnMut(hir::BindingAnnotation, HirId, Span, ast::Ident),
{
self.walk(|p| {
if let PatKind::Binding(binding_mode, _, _, ident, _) = p.node {
if let PatKind::Binding(binding_mode, _, ident, _) = p.node {
f(binding_mode, p.hir_id, p.span, ident);
}
true
@ -110,8 +110,8 @@ impl hir::Pat {
pub fn simple_ident(&self) -> Option<ast::Ident> {
match self.node {
PatKind::Binding(hir::BindingAnnotation::Unannotated, _, _, ident, None) |
PatKind::Binding(hir::BindingAnnotation::Mutable, _, _, ident, None) => Some(ident),
PatKind::Binding(hir::BindingAnnotation::Unannotated, _, ident, None) |
PatKind::Binding(hir::BindingAnnotation::Mutable, _, ident, None) => Some(ident),
_ => None,
}
}

View file

@ -25,7 +25,7 @@ pub enum AnnNode<'a> {
Name(&'a ast::Name),
Block(&'a hir::Block),
Item(&'a hir::Item),
SubItem(ast::NodeId),
SubItem(hir::HirId),
Expr(&'a hir::Expr),
Pat(&'a hir::Pat),
}
@ -434,6 +434,9 @@ impl<'a> State<'a> {
self.s.word("/*ERROR*/")?;
self.pclose()?;
}
hir::TyKind::CVarArgs(_) => {
self.s.word("...")?;
}
}
self.end()
}
@ -924,7 +927,7 @@ impl<'a> State<'a> {
}
pub fn print_trait_item(&mut self, ti: &hir::TraitItem) -> io::Result<()> {
self.ann.pre(self, AnnNode::SubItem(ti.id))?;
self.ann.pre(self, AnnNode::SubItem(ti.hir_id))?;
self.hardbreak_if_not_bol()?;
self.maybe_print_comment(ti.span.lo())?;
self.print_outer_attributes(&ti.attrs)?;
@ -956,11 +959,11 @@ impl<'a> State<'a> {
default.as_ref().map(|ty| &**ty))?;
}
}
self.ann.post(self, AnnNode::SubItem(ti.id))
self.ann.post(self, AnnNode::SubItem(ti.hir_id))
}
pub fn print_impl_item(&mut self, ii: &hir::ImplItem) -> io::Result<()> {
self.ann.pre(self, AnnNode::SubItem(ii.id))?;
self.ann.pre(self, AnnNode::SubItem(ii.hir_id))?;
self.hardbreak_if_not_bol()?;
self.maybe_print_comment(ii.span.lo())?;
self.print_outer_attributes(&ii.attrs)?;
@ -986,7 +989,7 @@ impl<'a> State<'a> {
self.print_associated_type(ii.ident, Some(bounds), None)?;
}
}
self.ann.post(self, AnnNode::SubItem(ii.id))
self.ann.post(self, AnnNode::SubItem(ii.hir_id))
}
pub fn print_stmt(&mut self, st: &hir::Stmt) -> io::Result<()> {
@ -1762,7 +1765,7 @@ impl<'a> State<'a> {
// is that it doesn't matter
match pat.node {
PatKind::Wild => self.s.word("_")?,
PatKind::Binding(binding_mode, _, _, ident, ref sub) => {
PatKind::Binding(binding_mode, _, ident, ref sub) => {
match binding_mode {
hir::BindingAnnotation::Ref => {
self.word_nbsp("ref")?;
@ -2004,7 +2007,7 @@ impl<'a> State<'a> {
s.print_type(ty)?;
s.end()
})?;
if decl.variadic {
if decl.c_variadic {
self.s.word(", ...")?;
}
self.pclose()?;
@ -2248,7 +2251,6 @@ impl<'a> State<'a> {
let generics = hir::Generics {
params: hir::HirVec::new(),
where_clause: hir::WhereClause {
id: ast::DUMMY_NODE_ID,
hir_id: hir::DUMMY_HIR_ID,
predicates: hir::HirVec::new(),
},

View file

@ -1,53 +0,0 @@
//! This module contains `HashStable` implementations for various data types
//! from rustc::middle::cstore in no particular order.
impl_stable_hash_for!(enum crate::middle::cstore::DepKind {
UnexportedMacrosOnly,
MacrosOnly,
Implicit,
Explicit
});
impl_stable_hash_for!(enum crate::middle::cstore::NativeLibraryKind {
NativeStatic,
NativeStaticNobundle,
NativeFramework,
NativeUnknown
});
impl_stable_hash_for!(struct crate::middle::cstore::NativeLibrary {
kind,
name,
cfg,
foreign_module,
wasm_import_module
});
impl_stable_hash_for!(struct crate::middle::cstore::ForeignModule {
foreign_items,
def_id
});
impl_stable_hash_for!(enum crate::middle::cstore::LinkagePreference {
RequireDynamic,
RequireStatic
});
impl_stable_hash_for!(struct crate::middle::cstore::ExternCrate {
src,
span,
path_len,
direct
});
impl_stable_hash_for!(enum crate::middle::cstore::ExternCrateSource {
Extern(def_id),
Use,
Path,
});
impl_stable_hash_for!(struct crate::middle::cstore::CrateSource {
dylib,
rlib,
rmeta
});

View file

@ -69,15 +69,6 @@ impl<'a> ToStableHashKey<StableHashingContext<'a>> for CrateNum {
}
}
impl<'a> HashStable<StableHashingContext<'a>> for hir::ItemLocalId {
#[inline]
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
self.as_u32().hash_stable(hcx, hasher);
}
}
impl<'a> ToStableHashKey<StableHashingContext<'a>>
for hir::ItemLocalId {
type KeyType = hir::ItemLocalId;
@ -116,11 +107,11 @@ impl<'a> HashStable<StableHashingContext<'a>> for hir::TraitItemId {
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
let hir::TraitItemId {
node_id
hir_id
} = * self;
hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
node_id.hash_stable(hcx, hasher);
hir_id.hash_stable(hcx, hasher);
})
}
}
@ -130,195 +121,26 @@ impl<'a> HashStable<StableHashingContext<'a>> for hir::ImplItemId {
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
let hir::ImplItemId {
node_id
hir_id
} = * self;
hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
node_id.hash_stable(hcx, hasher);
hir_id.hash_stable(hcx, hasher);
})
}
}
impl_stable_hash_for!(enum hir::ParamName {
Plain(name),
Fresh(index),
Error,
});
impl_stable_hash_for!(enum hir::LifetimeName {
Param(param_name),
Implicit,
Underscore,
Static,
Error,
});
impl_stable_hash_for!(struct ast::Label {
ident
});
impl_stable_hash_for!(struct hir::Lifetime {
id,
hir_id,
span,
name
});
impl_stable_hash_for!(struct hir::Path {
span,
def,
segments
});
impl_stable_hash_for!(struct hir::PathSegment {
ident -> (ident.name),
id,
hir_id,
def,
infer_types,
args
});
impl_stable_hash_for!(struct hir::ConstArg {
value,
span,
});
impl_stable_hash_for!(enum hir::GenericArg {
Lifetime(lt),
Type(ty),
Const(ct),
});
impl_stable_hash_for!(struct hir::GenericArgs {
args,
bindings,
parenthesized
});
impl_stable_hash_for!(enum hir::GenericBound {
Trait(poly_trait_ref, trait_bound_modifier),
Outlives(lifetime)
});
impl_stable_hash_for!(enum hir::TraitBoundModifier {
None,
Maybe
});
impl_stable_hash_for!(struct hir::GenericParam {
id,
hir_id,
name,
pure_wrt_drop,
attrs,
bounds,
span,
kind
});
impl_stable_hash_for!(enum hir::LifetimeParamKind {
Explicit,
InBand,
Elided,
Error,
});
impl<'a> HashStable<StableHashingContext<'a>> for hir::GenericParamKind {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
mem::discriminant(self).hash_stable(hcx, hasher);
match self {
hir::GenericParamKind::Lifetime { kind } => {
kind.hash_stable(hcx, hasher);
}
hir::GenericParamKind::Type { ref default, synthetic } => {
default.hash_stable(hcx, hasher);
synthetic.hash_stable(hcx, hasher);
}
hir::GenericParamKind::Const { ref ty } => {
ty.hash_stable(hcx, hasher);
}
}
}
}
impl_stable_hash_for!(struct hir::Generics {
params,
where_clause,
span
});
impl_stable_hash_for!(enum hir::SyntheticTyParamKind {
ImplTrait
});
impl_stable_hash_for!(struct hir::WhereClause {
id,
hir_id,
predicates
});
impl_stable_hash_for!(enum hir::WherePredicate {
BoundPredicate(pred),
RegionPredicate(pred),
EqPredicate(pred)
});
impl_stable_hash_for!(struct hir::WhereBoundPredicate {
span,
bound_generic_params,
bounded_ty,
bounds
});
impl_stable_hash_for!(struct hir::WhereRegionPredicate {
span,
lifetime,
bounds
});
impl_stable_hash_for!(struct hir::WhereEqPredicate {
id,
hir_id,
span,
lhs_ty,
rhs_ty
});
impl_stable_hash_for!(struct hir::MutTy {
ty,
mutbl
});
impl_stable_hash_for!(struct hir::MethodSig {
header,
decl
});
impl_stable_hash_for!(struct hir::TypeBinding {
id,
hir_id,
ident -> (ident.name),
ty,
span
});
impl_stable_hash_for!(struct hir::FnHeader {
unsafety,
constness,
asyncness,
abi
});
impl<'a> HashStable<StableHashingContext<'a>> for hir::Ty {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
hcx.while_hashing_hir_bodies(true, |hcx| {
let hir::Ty {
id: _,
hir_id: _,
ref node,
ref span,
@ -330,243 +152,25 @@ impl<'a> HashStable<StableHashingContext<'a>> for hir::Ty {
}
}
impl_stable_hash_for!(enum hir::PrimTy {
Int(int_ty),
Uint(uint_ty),
Float(float_ty),
Str,
Bool,
Char
});
impl_stable_hash_for!(struct hir::BareFnTy {
unsafety,
abi,
generic_params,
decl,
arg_names
});
impl_stable_hash_for!(struct hir::ExistTy {
generics,
impl_trait_fn,
bounds
});
impl_stable_hash_for!(enum hir::TyKind {
Slice(t),
Array(t, body_id),
Ptr(t),
Rptr(lifetime, t),
BareFn(t),
Never,
Tup(ts),
Path(qpath),
Def(it, lt),
TraitObject(trait_refs, lifetime),
Typeof(body_id),
Err,
Infer
});
impl_stable_hash_for!(struct hir::FnDecl {
inputs,
output,
variadic,
implicit_self
});
impl_stable_hash_for!(enum hir::FunctionRetTy {
DefaultReturn(span),
Return(t)
});
impl_stable_hash_for!(enum hir::ImplicitSelfKind {
Imm,
Mut,
ImmRef,
MutRef,
None
});
impl_stable_hash_for!(struct hir::TraitRef {
// Don't hash the ref_id. It is tracked via the thing it is used to access
ref_id -> _,
hir_ref_id -> _,
path,
});
impl_stable_hash_for!(struct hir::PolyTraitRef {
bound_generic_params,
trait_ref,
span
});
impl_stable_hash_for!(enum hir::QPath {
Resolved(t, path),
TypeRelative(t, path_segment)
});
impl_stable_hash_for!(struct hir::MacroDef {
name,
vis,
attrs,
id,
hir_id,
span,
legacy,
body
});
impl_stable_hash_for!(struct hir::Block {
stmts,
expr,
id -> _,
hir_id -> _,
rules,
span,
targeted_by_break,
});
impl_stable_hash_for!(struct hir::Pat {
id -> _,
hir_id -> _,
node,
span,
});
impl_stable_hash_for_spanned!(hir::FieldPat);
impl_stable_hash_for!(struct hir::FieldPat {
id -> _,
hir_id -> _,
ident -> (ident.name),
pat,
is_shorthand,
});
impl_stable_hash_for!(enum hir::BindingAnnotation {
Unannotated,
Mutable,
Ref,
RefMut
});
impl_stable_hash_for!(enum hir::RangeEnd {
Included,
Excluded
});
impl_stable_hash_for!(enum hir::PatKind {
Wild,
Binding(binding_mode, var, hir_id, name, sub),
Struct(path, field_pats, dotdot),
TupleStruct(path, field_pats, dotdot),
Path(path),
Tuple(field_pats, dotdot),
Box(sub),
Ref(sub, mutability),
Lit(expr),
Range(start, end, end_kind),
Slice(one, two, three)
});
impl_stable_hash_for!(enum hir::BinOpKind {
Add,
Sub,
Mul,
Div,
Rem,
And,
Or,
BitXor,
BitAnd,
BitOr,
Shl,
Shr,
Eq,
Lt,
Le,
Ne,
Ge,
Gt
});
impl_stable_hash_for_spanned!(hir::BinOpKind);
impl_stable_hash_for!(enum hir::UnOp {
UnDeref,
UnNot,
UnNeg
});
impl_stable_hash_for!(struct hir::Stmt {
id,
hir_id,
node,
span,
});
impl_stable_hash_for!(struct hir::Local {
pat,
ty,
init,
id,
hir_id,
span,
attrs,
source
});
impl_stable_hash_for!(struct hir::Arm {
attrs,
pats,
guard,
body
});
impl_stable_hash_for!(enum hir::Guard {
If(expr),
});
impl_stable_hash_for!(struct hir::Field {
id -> _,
hir_id -> _,
ident,
expr,
span,
is_shorthand,
});
impl_stable_hash_for_spanned!(ast::Name);
impl_stable_hash_for!(enum hir::BlockCheckMode {
DefaultBlock,
UnsafeBlock(src),
PushUnsafeBlock(src),
PopUnsafeBlock(src)
});
impl_stable_hash_for!(enum hir::UnsafeSource {
CompilerGenerated,
UserProvided
});
impl_stable_hash_for!(struct hir::AnonConst {
id,
hir_id,
body
});
impl<'a> HashStable<StableHashingContext<'a>> for hir::Expr {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
hcx.while_hashing_hir_bodies(true, |hcx| {
let hir::Expr {
id: _,
hir_id: _,
ref span,
ref node,
@ -580,96 +184,10 @@ impl<'a> HashStable<StableHashingContext<'a>> for hir::Expr {
}
}
impl_stable_hash_for!(enum hir::ExprKind {
Box(sub),
Array(subs),
Call(callee, args),
MethodCall(segment, span, args),
Tup(fields),
Binary(op, lhs, rhs),
Unary(op, operand),
Lit(value),
Cast(expr, t),
Type(expr, t),
If(cond, then, els),
While(cond, body, label),
Loop(body, label, loop_src),
Match(matchee, arms, match_src),
Closure(capture_clause, decl, body_id, span, gen),
Block(blk, label),
Assign(lhs, rhs),
AssignOp(op, lhs, rhs),
Field(owner, ident),
Index(lhs, rhs),
Path(path),
AddrOf(mutability, sub),
Break(destination, sub),
Continue(destination),
Ret(val),
InlineAsm(asm, inputs, outputs),
Struct(path, fields, base),
Repeat(val, times),
Yield(val),
Err
});
impl_stable_hash_for!(enum hir::LocalSource {
Normal,
ForLoopDesugar
});
impl_stable_hash_for!(enum hir::LoopSource {
Loop,
WhileLet,
ForLoop
});
impl<'a> HashStable<StableHashingContext<'a>> for hir::MatchSource {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
use crate::hir::MatchSource;
mem::discriminant(self).hash_stable(hcx, hasher);
match *self {
MatchSource::Normal |
MatchSource::WhileLetDesugar |
MatchSource::ForLoopDesugar |
MatchSource::TryDesugar => {
// No fields to hash.
}
MatchSource::IfLetDesugar { contains_else_clause } => {
contains_else_clause.hash_stable(hcx, hasher);
}
}
}
}
impl_stable_hash_for!(enum hir::GeneratorMovability {
Static,
Movable
});
impl_stable_hash_for!(enum hir::CaptureClause {
CaptureByValue,
CaptureByRef
});
impl_stable_hash_for_spanned!(usize);
impl_stable_hash_for!(struct hir::Destination {
label,
target_id
});
impl_stable_hash_for_spanned!(ast::Ident);
impl_stable_hash_for!(enum hir::LoopIdError {
OutsideLoopScope,
UnlabeledCfInWhileCondition,
UnresolvedLabel
});
impl_stable_hash_for!(struct ast::Ident {
name,
span,
@ -680,7 +198,6 @@ impl<'a> HashStable<StableHashingContext<'a>> for hir::TraitItem {
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
let hir::TraitItem {
id: _,
hir_id: _,
ident,
ref attrs,
@ -699,23 +216,12 @@ impl<'a> HashStable<StableHashingContext<'a>> for hir::TraitItem {
}
}
impl_stable_hash_for!(enum hir::TraitMethod {
Required(name),
Provided(body)
});
impl_stable_hash_for!(enum hir::TraitItemKind {
Const(t, body),
Method(sig, method),
Type(bounds, rhs)
});
impl<'a> HashStable<StableHashingContext<'a>> for hir::ImplItem {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
let hir::ImplItem {
id: _,
hir_id: _,
ident,
ref vis,
@ -738,13 +244,6 @@ impl<'a> HashStable<StableHashingContext<'a>> for hir::ImplItem {
}
}
impl_stable_hash_for!(enum hir::ImplItemKind {
Const(t, body),
Method(sig, body),
Existential(bounds),
Type(t)
});
impl_stable_hash_for!(enum ::syntax::ast::CrateSugar {
JustCrate,
PubCrate,
@ -763,9 +262,8 @@ impl<'a> HashStable<StableHashingContext<'a>> for hir::VisibilityKind {
hir::VisibilityKind::Crate(sugar) => {
sugar.hash_stable(hcx, hasher);
}
hir::VisibilityKind::Restricted { ref path, id, hir_id } => {
hir::VisibilityKind::Restricted { ref path, hir_id } => {
hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
id.hash_stable(hcx, hasher);
hir_id.hash_stable(hcx, hasher);
});
path.hash_stable(hcx, hasher);
@ -776,27 +274,6 @@ impl<'a> HashStable<StableHashingContext<'a>> for hir::VisibilityKind {
impl_stable_hash_for_spanned!(hir::VisibilityKind);
impl<'a> HashStable<StableHashingContext<'a>> for hir::Defaultness {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
mem::discriminant(self).hash_stable(hcx, hasher);
match *self {
hir::Defaultness::Final => {
// No fields to hash.
}
hir::Defaultness::Default { has_value } => {
has_value.hash_stable(hcx, hasher);
}
}
}
}
impl_stable_hash_for!(enum hir::ImplPolarity {
Positive,
Negative
});
impl<'a> HashStable<StableHashingContext<'a>> for hir::Mod {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
@ -826,45 +303,8 @@ impl<'a> HashStable<StableHashingContext<'a>> for hir::Mod {
}
}
impl_stable_hash_for!(struct hir::ForeignMod {
abi,
items
});
impl_stable_hash_for!(struct hir::EnumDef {
variants
});
impl_stable_hash_for!(struct hir::VariantKind {
ident -> (ident.name),
attrs,
data,
disr_expr
});
impl_stable_hash_for_spanned!(hir::VariantKind);
impl_stable_hash_for!(enum hir::UseKind {
Single,
Glob,
ListStem
});
impl_stable_hash_for!(struct hir::StructField {
span,
ident -> (ident.name),
vis,
id,
hir_id,
ty,
attrs
});
impl_stable_hash_for!(enum hir::VariantData {
Struct(fields, id, hir_id),
Tuple(fields, id, hir_id),
Unit(id, hir_id)
});
impl<'a> HashStable<StableHashingContext<'a>> for hir::Item {
fn hash_stable<W: StableHasherResult>(&self,
@ -873,7 +313,6 @@ impl<'a> HashStable<StableHashingContext<'a>> for hir::Item {
let hir::Item {
ident,
ref attrs,
id: _,
hir_id: _,
ref node,
ref vis,
@ -890,89 +329,6 @@ impl<'a> HashStable<StableHashingContext<'a>> for hir::Item {
}
}
impl_stable_hash_for!(enum hir::ItemKind {
ExternCrate(orig_name),
Use(path, use_kind),
Static(ty, mutability, body_id),
Const(ty, body_id),
Fn(fn_decl, header, generics, body_id),
Mod(module),
ForeignMod(foreign_mod),
GlobalAsm(global_asm),
Ty(ty, generics),
Existential(exist),
Enum(enum_def, generics),
Struct(variant_data, generics),
Union(variant_data, generics),
Trait(is_auto, unsafety, generics, bounds, item_refs),
TraitAlias(generics, bounds),
Impl(unsafety, impl_polarity, impl_defaultness, generics, trait_ref, ty, impl_item_refs)
});
impl_stable_hash_for!(struct hir::TraitItemRef {
id,
ident -> (ident.name),
kind,
span,
defaultness
});
impl_stable_hash_for!(struct hir::ImplItemRef {
id,
ident -> (ident.name),
kind,
span,
vis,
defaultness
});
impl<'a> HashStable<StableHashingContext<'a>> for hir::AssociatedItemKind {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
mem::discriminant(self).hash_stable(hcx, hasher);
match *self {
hir::AssociatedItemKind::Const |
hir::AssociatedItemKind::Existential |
hir::AssociatedItemKind::Type => {
// No fields to hash.
}
hir::AssociatedItemKind::Method { has_self } => {
has_self.hash_stable(hcx, hasher);
}
}
}
}
impl_stable_hash_for!(struct hir::ForeignItem {
ident -> (ident.name),
attrs,
node,
id,
hir_id,
span,
vis
});
impl_stable_hash_for!(enum hir::ForeignItemKind {
Fn(fn_decl, arg_names, generics),
Static(ty, is_mutbl),
Type
});
impl_stable_hash_for!(enum hir::StmtKind {
Local(local),
Item(item_id),
Expr(expr),
Semi(expr)
});
impl_stable_hash_for!(struct hir::Arg {
pat,
id,
hir_id
});
impl<'a> HashStable<StableHashingContext<'a>> for hir::Body {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
@ -1003,103 +359,6 @@ impl<'a> ToStableHashKey<StableHashingContext<'a>> for hir::BodyId {
}
}
impl_stable_hash_for!(struct hir::InlineAsmOutput {
constraint,
is_rw,
is_indirect,
span
});
impl_stable_hash_for!(struct hir::GlobalAsm {
asm,
ctxt -> _, // This is used for error reporting
});
impl_stable_hash_for!(struct hir::InlineAsm {
asm,
asm_str_style,
outputs,
inputs,
clobbers,
volatile,
alignstack,
dialect,
ctxt -> _, // This is used for error reporting
});
impl_stable_hash_for!(enum hir::def::CtorKind {
Fn,
Const,
Fictive
});
impl_stable_hash_for!(enum hir::def::NonMacroAttrKind {
Builtin,
Tool,
DeriveHelper,
LegacyPluginHelper,
Custom,
});
impl_stable_hash_for!(enum hir::def::Def {
Mod(def_id),
Struct(def_id),
Union(def_id),
Enum(def_id),
Existential(def_id),
Variant(def_id),
Trait(def_id),
TyAlias(def_id),
TraitAlias(def_id),
AssociatedTy(def_id),
AssociatedExistential(def_id),
PrimTy(prim_ty),
TyParam(def_id),
ConstParam(def_id),
SelfTy(trait_def_id, impl_def_id),
ForeignTy(def_id),
Fn(def_id),
Const(def_id),
Static(def_id, is_mutbl),
StructCtor(def_id, ctor_kind),
SelfCtor(impl_def_id),
VariantCtor(def_id, ctor_kind),
Method(def_id),
AssociatedConst(def_id),
Local(def_id),
Upvar(def_id, index, expr_id),
Label(node_id),
Macro(def_id, macro_kind),
ToolMod,
NonMacroAttr(attr_kind),
Err
});
impl_stable_hash_for!(enum hir::Mutability {
MutMutable,
MutImmutable
});
impl_stable_hash_for!(enum hir::IsAuto {
Yes,
No
});
impl_stable_hash_for!(enum hir::Unsafety {
Unsafe,
Normal
});
impl_stable_hash_for!(enum hir::IsAsync {
Async,
NotAsync
});
impl_stable_hash_for!(enum hir::Constness {
Const,
NotConst
});
impl<'a> HashStable<StableHashingContext<'a>> for hir::def_id::DefIndex {
fn hash_stable<W: StableHasherResult>(&self,
@ -1119,18 +378,6 @@ for hir::def_id::DefIndex {
}
}
impl_stable_hash_for!(struct hir::def::Export {
ident,
def,
vis,
span
});
impl_stable_hash_for!(struct crate::middle::lib_features::LibFeatures {
stable,
unstable
});
impl<'a> HashStable<StableHashingContext<'a>> for crate::middle::lang_items::LangItem {
fn hash_stable<W: StableHasherResult>(&self,
_: &mut StableHashingContext<'a>,
@ -1139,11 +386,6 @@ impl<'a> HashStable<StableHashingContext<'a>> for crate::middle::lang_items::Lan
}
}
impl_stable_hash_for!(struct crate::middle::lang_items::LanguageItems {
items,
missing
});
impl<'a> HashStable<StableHashingContext<'a>> for hir::TraitCandidate {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
@ -1178,26 +420,6 @@ impl<'a> ToStableHashKey<StableHashingContext<'a>> for hir::TraitCandidate {
}
}
impl_stable_hash_for!(struct hir::CodegenFnAttrs {
flags,
inline,
optimize,
export_name,
link_name,
target_features,
linkage,
link_section,
});
impl<'hir> HashStable<StableHashingContext<'hir>> for hir::CodegenFnAttrFlags
{
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'hir>,
hasher: &mut StableHasher<W>) {
self.bits().hash_stable(hcx, hasher);
}
}
impl<'hir> HashStable<StableHashingContext<'hir>> for attr::InlineAttr {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'hir>,
@ -1214,7 +436,3 @@ impl<'hir> HashStable<StableHashingContext<'hir>> for attr::OptimizeAttr {
}
}
impl_stable_hash_for!(struct hir::Freevar {
def,
span
});

View file

@ -1,503 +0,0 @@
//! This module contains `HashStable` implementations for various MIR data
//! types in no particular order.
use crate::ich::StableHashingContext;
use crate::mir;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher,
StableHasherResult};
use std::mem;
impl_stable_hash_for!(struct mir::GeneratorLayout<'tcx> { fields });
impl_stable_hash_for!(struct mir::SourceInfo { span, scope });
impl_stable_hash_for!(enum mir::Mutability { Mut, Not });
impl_stable_hash_for!(enum mir::LocalKind { Var, Temp, Arg, ReturnPointer });
impl_stable_hash_for!(struct mir::LocalDecl<'tcx> {
mutability,
ty,
user_ty,
name,
source_info,
visibility_scope,
internal,
is_block_tail,
is_user_variable
});
impl_stable_hash_for!(struct mir::UpvarDecl { debug_name, var_hir_id, by_ref, mutability });
impl_stable_hash_for!(struct mir::BasicBlockData<'tcx> { statements, terminator, is_cleanup });
impl_stable_hash_for!(struct mir::UnsafetyViolation { source_info, description, details, kind });
impl_stable_hash_for!(struct mir::UnsafetyCheckResult { violations, unsafe_blocks });
impl_stable_hash_for!(enum mir::BorrowKind {
Shared,
Shallow,
Unique,
Mut { allow_two_phase_borrow },
});
impl_stable_hash_for!(enum mir::UnsafetyViolationKind {
General,
GeneralAndConstFn,
ExternStatic(lint_node_id),
BorrowPacked(lint_node_id),
});
impl_stable_hash_for!(struct mir::Terminator<'tcx> {
kind,
source_info
});
impl_stable_hash_for!(
impl<T> for enum mir::ClearCrossCrate<T> [ mir::ClearCrossCrate ] {
Clear,
Set(value),
}
);
impl<'a> HashStable<StableHashingContext<'a>> for mir::Local {
#[inline]
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
self.index().hash_stable(hcx, hasher);
}
}
impl<'a> HashStable<StableHashingContext<'a>> for mir::BasicBlock {
#[inline]
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
self.index().hash_stable(hcx, hasher);
}
}
impl<'a> HashStable<StableHashingContext<'a>> for mir::Field {
#[inline]
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
self.index().hash_stable(hcx, hasher);
}
}
impl<'a> HashStable<StableHashingContext<'a>>
for mir::SourceScope {
#[inline]
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
self.index().hash_stable(hcx, hasher);
}
}
impl<'a> HashStable<StableHashingContext<'a>> for mir::Promoted {
#[inline]
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
self.index().hash_stable(hcx, hasher);
}
}
impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
for mir::TerminatorKind<'gcx> {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
mem::discriminant(self).hash_stable(hcx, hasher);
match *self {
mir::TerminatorKind::Goto { ref target } => {
target.hash_stable(hcx, hasher);
}
mir::TerminatorKind::SwitchInt { ref discr,
switch_ty,
ref values,
ref targets } => {
discr.hash_stable(hcx, hasher);
switch_ty.hash_stable(hcx, hasher);
values.hash_stable(hcx, hasher);
targets.hash_stable(hcx, hasher);
}
mir::TerminatorKind::Resume |
mir::TerminatorKind::Abort |
mir::TerminatorKind::Return |
mir::TerminatorKind::GeneratorDrop |
mir::TerminatorKind::Unreachable => {}
mir::TerminatorKind::Drop { ref location, target, unwind } => {
location.hash_stable(hcx, hasher);
target.hash_stable(hcx, hasher);
unwind.hash_stable(hcx, hasher);
}
mir::TerminatorKind::DropAndReplace { ref location,
ref value,
target,
unwind, } => {
location.hash_stable(hcx, hasher);
value.hash_stable(hcx, hasher);
target.hash_stable(hcx, hasher);
unwind.hash_stable(hcx, hasher);
}
mir::TerminatorKind::Yield { ref value,
resume,
drop } => {
value.hash_stable(hcx, hasher);
resume.hash_stable(hcx, hasher);
drop.hash_stable(hcx, hasher);
}
mir::TerminatorKind::Call { ref func,
ref args,
ref destination,
cleanup,
from_hir_call, } => {
func.hash_stable(hcx, hasher);
args.hash_stable(hcx, hasher);
destination.hash_stable(hcx, hasher);
cleanup.hash_stable(hcx, hasher);
from_hir_call.hash_stable(hcx, hasher);
}
mir::TerminatorKind::Assert { ref cond,
expected,
ref msg,
target,
cleanup } => {
cond.hash_stable(hcx, hasher);
expected.hash_stable(hcx, hasher);
msg.hash_stable(hcx, hasher);
target.hash_stable(hcx, hasher);
cleanup.hash_stable(hcx, hasher);
}
mir::TerminatorKind::FalseEdges { ref real_target, ref imaginary_targets } => {
real_target.hash_stable(hcx, hasher);
for target in imaginary_targets {
target.hash_stable(hcx, hasher);
}
}
mir::TerminatorKind::FalseUnwind { ref real_target, ref unwind } => {
real_target.hash_stable(hcx, hasher);
unwind.hash_stable(hcx, hasher);
}
}
}
}
impl_stable_hash_for!(struct mir::Statement<'tcx> { source_info, kind });
impl_stable_hash_for!(impl<'gcx> for enum mir::StatementKind<'gcx> [ mir::StatementKind ] {
Assign(place, rvalue),
FakeRead(cause, place),
SetDiscriminant { place, variant_index },
StorageLive(place),
StorageDead(place),
Retag(retag_kind, place),
AscribeUserType(place, variance, c_ty),
Nop,
InlineAsm { asm, outputs, inputs },
});
impl_stable_hash_for!(enum mir::RetagKind { FnEntry, TwoPhase, Raw, Default });
impl_stable_hash_for!(enum mir::FakeReadCause {
ForMatchGuard,
ForMatchedPlace,
ForGuardBinding,
ForLet
});
impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for mir::Place<'gcx> {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
mem::discriminant(self).hash_stable(hcx, hasher);
match *self {
mir::Place::Local(ref local) => {
local.hash_stable(hcx, hasher);
}
mir::Place::Static(ref statik) => {
statik.hash_stable(hcx, hasher);
}
mir::Place::Promoted(ref promoted) => {
promoted.hash_stable(hcx, hasher);
}
mir::Place::Projection(ref place_projection) => {
place_projection.hash_stable(hcx, hasher);
}
}
}
}
impl<'a, 'gcx, B, V, T> HashStable<StableHashingContext<'a>>
for mir::Projection<'gcx, B, V, T>
where B: HashStable<StableHashingContext<'a>>,
V: HashStable<StableHashingContext<'a>>,
T: HashStable<StableHashingContext<'a>>
{
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
let mir::Projection {
ref base,
ref elem,
} = *self;
base.hash_stable(hcx, hasher);
elem.hash_stable(hcx, hasher);
}
}
impl<'a, 'gcx, V, T> HashStable<StableHashingContext<'a>>
for mir::ProjectionElem<'gcx, V, T>
where V: HashStable<StableHashingContext<'a>>,
T: HashStable<StableHashingContext<'a>>
{
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
mem::discriminant(self).hash_stable(hcx, hasher);
match *self {
mir::ProjectionElem::Deref => {}
mir::ProjectionElem::Field(field, ref ty) => {
field.hash_stable(hcx, hasher);
ty.hash_stable(hcx, hasher);
}
mir::ProjectionElem::Index(ref value) => {
value.hash_stable(hcx, hasher);
}
mir::ProjectionElem::ConstantIndex { offset, min_length, from_end } => {
offset.hash_stable(hcx, hasher);
min_length.hash_stable(hcx, hasher);
from_end.hash_stable(hcx, hasher);
}
mir::ProjectionElem::Subslice { from, to } => {
from.hash_stable(hcx, hasher);
to.hash_stable(hcx, hasher);
}
mir::ProjectionElem::Downcast(adt_def, variant) => {
adt_def.hash_stable(hcx, hasher);
variant.hash_stable(hcx, hasher);
}
}
}
}
impl_stable_hash_for!(struct mir::SourceScopeData { span, parent_scope });
impl_stable_hash_for!(struct mir::SourceScopeLocalData {
lint_root, safety
});
impl<'a> HashStable<StableHashingContext<'a>> for mir::Safety {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
mem::discriminant(self).hash_stable(hcx, hasher);
match *self {
mir::Safety::Safe |
mir::Safety::BuiltinUnsafe |
mir::Safety::FnUnsafe => {}
mir::Safety::ExplicitUnsafe(node_id) => {
node_id.hash_stable(hcx, hasher);
}
}
}
}
impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for mir::Operand<'gcx> {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
mem::discriminant(self).hash_stable(hcx, hasher);
match *self {
mir::Operand::Copy(ref place) => {
place.hash_stable(hcx, hasher);
}
mir::Operand::Move(ref place) => {
place.hash_stable(hcx, hasher);
}
mir::Operand::Constant(ref constant) => {
constant.hash_stable(hcx, hasher);
}
}
}
}
impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for mir::Rvalue<'gcx> {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
mem::discriminant(self).hash_stable(hcx, hasher);
match *self {
mir::Rvalue::Use(ref operand) => {
operand.hash_stable(hcx, hasher);
}
mir::Rvalue::Repeat(ref operand, ref val) => {
operand.hash_stable(hcx, hasher);
val.hash_stable(hcx, hasher);
}
mir::Rvalue::Ref(region, borrow_kind, ref place) => {
region.hash_stable(hcx, hasher);
borrow_kind.hash_stable(hcx, hasher);
place.hash_stable(hcx, hasher);
}
mir::Rvalue::Len(ref place) => {
place.hash_stable(hcx, hasher);
}
mir::Rvalue::Cast(cast_kind, ref operand, ty) => {
cast_kind.hash_stable(hcx, hasher);
operand.hash_stable(hcx, hasher);
ty.hash_stable(hcx, hasher);
}
mir::Rvalue::BinaryOp(op, ref operand1, ref operand2) |
mir::Rvalue::CheckedBinaryOp(op, ref operand1, ref operand2) => {
op.hash_stable(hcx, hasher);
operand1.hash_stable(hcx, hasher);
operand2.hash_stable(hcx, hasher);
}
mir::Rvalue::UnaryOp(op, ref operand) => {
op.hash_stable(hcx, hasher);
operand.hash_stable(hcx, hasher);
}
mir::Rvalue::Discriminant(ref place) => {
place.hash_stable(hcx, hasher);
}
mir::Rvalue::NullaryOp(op, ty) => {
op.hash_stable(hcx, hasher);
ty.hash_stable(hcx, hasher);
}
mir::Rvalue::Aggregate(ref kind, ref operands) => {
kind.hash_stable(hcx, hasher);
operands.hash_stable(hcx, hasher);
}
}
}
}
impl_stable_hash_for!(enum mir::CastKind {
Misc,
ReifyFnPointer,
ClosureFnPointer,
UnsafeFnPointer,
Unsize
});
impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
for mir::AggregateKind<'gcx> {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
mem::discriminant(self).hash_stable(hcx, hasher);
match *self {
mir::AggregateKind::Tuple => {}
mir::AggregateKind::Array(t) => {
t.hash_stable(hcx, hasher);
}
mir::AggregateKind::Adt(adt_def, idx, substs, user_substs, active_field) => {
adt_def.hash_stable(hcx, hasher);
idx.hash_stable(hcx, hasher);
substs.hash_stable(hcx, hasher);
user_substs.hash_stable(hcx, hasher);
active_field.hash_stable(hcx, hasher);
}
mir::AggregateKind::Closure(def_id, ref substs) => {
def_id.hash_stable(hcx, hasher);
substs.hash_stable(hcx, hasher);
}
mir::AggregateKind::Generator(def_id, ref substs, movability) => {
def_id.hash_stable(hcx, hasher);
substs.hash_stable(hcx, hasher);
movability.hash_stable(hcx, hasher);
}
}
}
}
impl_stable_hash_for!(enum mir::BinOp {
Add,
Sub,
Mul,
Div,
Rem,
BitXor,
BitAnd,
BitOr,
Shl,
Shr,
Eq,
Lt,
Le,
Ne,
Ge,
Gt,
Offset
});
impl_stable_hash_for!(enum mir::UnOp {
Not,
Neg
});
impl_stable_hash_for!(enum mir::NullOp {
Box,
SizeOf
});
impl_stable_hash_for!(struct mir::Constant<'tcx> { span, ty, user_ty, literal });
impl_stable_hash_for!(struct mir::Location { block, statement_index });
impl_stable_hash_for!(struct mir::BorrowCheckResult<'tcx> {
closure_requirements,
used_mut_upvars
});
impl_stable_hash_for!(struct mir::ClosureRegionRequirements<'tcx> {
num_external_vids,
outlives_requirements
});
impl_stable_hash_for!(struct mir::ClosureOutlivesRequirement<'tcx> {
subject,
outlived_free_region,
blame_span,
category
});
impl_stable_hash_for!(enum mir::ConstraintCategory {
Return,
Yield,
UseAsConst,
UseAsStatic,
TypeAnnotation,
Cast,
ClosureBounds,
CallArgument,
CopyBound,
SizedBound,
Assignment,
OpaqueType,
Boring,
BoringNoLocation,
Internal,
});
impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for mir::ClosureOutlivesSubject<'gcx> {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
mem::discriminant(self).hash_stable(hcx, hasher);
match *self {
mir::ClosureOutlivesSubject::Ty(ref ty) => {
ty.hash_stable(hcx, hasher);
}
mir::ClosureOutlivesSubject::Region(ref region) => {
region.hash_stable(hcx, hasher);
}
}
}
}
impl_stable_hash_for!(struct mir::interpret::GlobalId<'tcx> { instance, promoted });
impl_stable_hash_for!(struct mir::UserTypeProjection<'tcx> { base, projs });
impl_stable_hash_for!(struct mir::UserTypeProjections<'tcx> { contents });

View file

@ -1,15 +1,6 @@
//! This module contains `HashStable` implementations for various data types
//! that don't fit into any of the other impls_xxx modules.
impl_stable_hash_for!(enum crate::session::search_paths::PathKind {
Native,
Crate,
Dependency,
Framework,
ExternFlag,
All
});
impl_stable_hash_for!(enum ::rustc_target::spec::PanicStrategy {
Abort,
Unwind

File diff suppressed because it is too large Load diff

View file

@ -7,9 +7,7 @@ pub use self::hcx::{StableHashingContextProvider, StableHashingContext, NodeIdHa
mod caching_source_map_view;
mod hcx;
mod impls_cstore;
mod impls_hir;
mod impls_mir;
mod impls_misc;
mod impls_ty;
mod impls_syntax;

View file

@ -24,6 +24,7 @@
use crate::infer::{InferCtxt, RegionVariableOrigin, TypeVariableOrigin};
use rustc_data_structures::indexed_vec::IndexVec;
use rustc_data_structures::sync::Lrc;
use rustc_macros::HashStable;
use serialize::UseSpecializedDecodable;
use smallvec::SmallVec;
use std::ops::Index;
@ -41,7 +42,7 @@ mod substitute;
/// A "canonicalized" type `V` is one where all free inference
/// variables have been rewritten to "canonical vars". These are
/// numbered starting from 0 in order of first appearance.
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcDecodable, RustcEncodable)]
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcDecodable, RustcEncodable, HashStable)]
pub struct Canonical<'gcx, V> {
pub max_universe: ty::UniverseIndex,
pub variables: CanonicalVarInfos<'gcx>,
@ -61,7 +62,7 @@ impl<'gcx> UseSpecializedDecodable for CanonicalVarInfos<'gcx> {}
/// vectors with the original values that were replaced by canonical
/// variables. You will need to supply it later to instantiate the
/// canonicalized query response.
#[derive(Clone, Debug, PartialEq, Eq, Hash, RustcDecodable, RustcEncodable)]
#[derive(Clone, Debug, PartialEq, Eq, Hash, RustcDecodable, RustcEncodable, HashStable)]
pub struct CanonicalVarValues<'tcx> {
pub var_values: IndexVec<BoundVar, Kind<'tcx>>,
}
@ -99,7 +100,7 @@ impl Default for OriginalQueryValues<'tcx> {
/// canonical value. This is sufficient information for code to create
/// a copy of the canonical value in some other inference context,
/// with fresh inference variables replacing the canonical values.
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcDecodable, RustcEncodable)]
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcDecodable, RustcEncodable, HashStable)]
pub struct CanonicalVarInfo {
pub kind: CanonicalVarKind,
}
@ -122,7 +123,7 @@ impl CanonicalVarInfo {
/// Describes the "kind" of the canonical variable. This is a "kind"
/// in the type-theory sense of the term -- i.e., a "meta" type system
/// that analyzes type-like values.
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcDecodable, RustcEncodable)]
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcDecodable, RustcEncodable, HashStable)]
pub enum CanonicalVarKind {
/// Some kind of type inference variable.
Ty(CanonicalTyVarKind),
@ -159,7 +160,7 @@ impl CanonicalVarKind {
/// 22.) can only be instantiated with integral/float types (e.g.,
/// usize or f32). In order to faithfully reproduce a type, we need to
/// know what set of types a given type variable can be unified with.
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcDecodable, RustcEncodable)]
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcDecodable, RustcEncodable, HashStable)]
pub enum CanonicalTyVarKind {
/// General type variable `?T` that can be unified with arbitrary types.
General(ty::UniverseIndex),
@ -174,7 +175,7 @@ pub enum CanonicalTyVarKind {
/// After we execute a query with a canonicalized key, we get back a
/// `Canonical<QueryResponse<..>>`. You can use
/// `instantiate_query_result` to access the data in this result.
#[derive(Clone, Debug)]
#[derive(Clone, Debug, HashStable)]
pub struct QueryResponse<'tcx, R> {
pub var_values: CanonicalVarValues<'tcx>,
pub region_constraints: Vec<QueryRegionConstraint<'tcx>>,
@ -189,7 +190,7 @@ pub type CanonicalizedQueryResponse<'gcx, T> =
/// Indicates whether or not we were able to prove the query to be
/// true.
#[derive(Copy, Clone, Debug)]
#[derive(Copy, Clone, Debug, HashStable)]
pub enum Certainty {
/// The query is known to be true, presuming that you apply the
/// given `var_values` and the region-constraints are satisfied.
@ -443,6 +444,9 @@ impl<'tcx> CanonicalVarValues<'tcx> {
UnpackedKind::Lifetime(..) => tcx.mk_region(
ty::ReLateBound(ty::INNERMOST, ty::BoundRegion::BrAnon(i))
).into(),
UnpackedKind::Const(..) => {
unimplemented!() // FIXME(const_generics)
}
})
.collect()
}

View file

@ -315,6 +315,10 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
obligations.extend(ok.into_obligations());
}
(UnpackedKind::Const(..), UnpackedKind::Const(..)) => {
unimplemented!() // FIXME(const_generics)
}
_ => {
bug!(
"kind mismatch, cannot unify {:?} and {:?}",
@ -473,6 +477,9 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
opt_values[br.assert_bound_var()] = Some(*original_value);
}
}
UnpackedKind::Const(..) => {
unimplemented!() // FIXME(const_generics)
}
}
}
@ -568,6 +575,11 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
ty::OutlivesPredicate(t1, r2)
)
),
UnpackedKind::Const(..) => {
// Consts cannot outlive one another, so we don't expect to
// ecounter this branch.
span_bug!(cause.span, "unexpected const outlives {:?}", constraint);
}
}
)
})
@ -602,6 +614,9 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
obligations
.extend(self.at(cause, param_env).eq(v1, v2)?.into_obligations());
}
(UnpackedKind::Const(..), UnpackedKind::Const(..)) => {
unimplemented!() // FIXME(const_generics)
}
_ => {
bug!("kind mismatch, cannot unify {:?} and {:?}", value1, value2,);
}

View file

@ -34,7 +34,7 @@ use crate::ty::{IntType, UintType};
use crate::ty::{self, Ty, TyCtxt};
use crate::ty::error::TypeError;
use crate::ty::relate::{self, Relate, RelateResult, TypeRelation};
use crate::ty::subst::Substs;
use crate::ty::subst::SubstsRef;
use crate::traits::{Obligation, PredicateObligations};
use syntax::ast;
@ -373,9 +373,9 @@ impl<'cx, 'gcx, 'tcx> TypeRelation<'cx, 'gcx, 'tcx> for Generalizer<'cx, 'gcx, '
fn relate_item_substs(&mut self,
item_def_id: DefId,
a_subst: &'tcx Substs<'tcx>,
b_subst: &'tcx Substs<'tcx>)
-> RelateResult<'tcx, &'tcx Substs<'tcx>>
a_subst: SubstsRef<'tcx>,
b_subst: SubstsRef<'tcx>)
-> RelateResult<'tcx, SubstsRef<'tcx>>
{
if self.ambient_variance == ty::Variance::Invariant {
// Avoid fetching the variance if we are in an invariant
@ -449,7 +449,7 @@ impl<'cx, 'gcx, 'tcx> TypeRelation<'cx, 'gcx, 'tcx> for Generalizer<'cx, 'gcx, '
let origin = *variables.var_origin(vid);
let new_var_id = variables.new_var(self.for_universe, false, origin);
let u = self.tcx().mk_var(new_var_id);
let u = self.tcx().mk_ty_var(new_var_id);
debug!("generalize: replacing original vid={:?} with new={:?}",
vid, u);
return Ok(u);

View file

@ -5,7 +5,7 @@ use crate::hir::def_id::DefId;
use crate::ty::{self, Ty, TyCtxt};
use crate::ty::TyVar;
use crate::ty::subst::Substs;
use crate::ty::subst::SubstsRef;
use crate::ty::relate::{self, Relate, RelateResult, TypeRelation};
/// Ensures `a` is made equal to `b`. Returns `a` on success.
@ -33,9 +33,9 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx>
fn relate_item_substs(&mut self,
_item_def_id: DefId,
a_subst: &'tcx Substs<'tcx>,
b_subst: &'tcx Substs<'tcx>)
-> RelateResult<'tcx, &'tcx Substs<'tcx>>
a_subst: SubstsRef<'tcx>,
b_subst: SubstsRef<'tcx>)
-> RelateResult<'tcx, SubstsRef<'tcx>>
{
// N.B., once we are equating types, we don't care about
// variance, so don't try to lookup the variance here. This

View file

@ -56,7 +56,7 @@ use crate::hir::Node;
use crate::middle::region;
use crate::traits::{ObligationCause, ObligationCauseCode};
use crate::ty::error::TypeError;
use crate::ty::{self, subst::Subst, Region, Ty, TyCtxt, TyKind, TypeFoldable};
use crate::ty::{self, subst::{Subst, SubstsRef}, Region, Ty, TyCtxt, TyKind, TypeFoldable};
use errors::{Applicability, DiagnosticBuilder, DiagnosticStyledString};
use std::{cmp, fmt};
use syntax_pos::{Pos, Span};
@ -570,7 +570,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
value: &mut DiagnosticStyledString,
other_value: &mut DiagnosticStyledString,
name: String,
sub: &ty::subst::Substs<'tcx>,
sub: ty::subst::SubstsRef<'tcx>,
pos: usize,
other_ty: &Ty<'tcx>,
) {
@ -648,7 +648,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
mut t1_out: &mut DiagnosticStyledString,
mut t2_out: &mut DiagnosticStyledString,
path: String,
sub: &ty::subst::Substs<'tcx>,
sub: ty::subst::SubstsRef<'tcx>,
other_path: String,
other_ty: &Ty<'tcx>,
) -> Option<()> {
@ -687,21 +687,15 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
fn strip_generic_default_params(
&self,
def_id: DefId,
substs: &ty::subst::Substs<'tcx>,
) -> &'tcx ty::subst::Substs<'tcx> {
substs: ty::subst::SubstsRef<'tcx>,
) -> SubstsRef<'tcx> {
let generics = self.tcx.generics_of(def_id);
let mut num_supplied_defaults = 0;
let mut type_params = generics
.params
.iter()
.rev()
.filter_map(|param| match param.kind {
ty::GenericParamDefKind::Lifetime => None,
ty::GenericParamDefKind::Type { has_default, .. } => {
Some((param.def_id, has_default))
}
})
.peekable();
let mut type_params = generics.params.iter().rev().filter_map(|param| match param.kind {
ty::GenericParamDefKind::Lifetime => None,
ty::GenericParamDefKind::Type { has_default, .. } => Some((param.def_id, has_default)),
ty::GenericParamDefKind::Const => None, // FIXME(const_generics:defaults)
}).peekable();
let has_default = {
let has_default = type_params.peek().map(|(_, has_default)| has_default);
*has_default.unwrap_or(&false)

View file

@ -101,7 +101,7 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> {
let (span_1, span_2, main_label, span_label) = match (sup_is_ret_type, sub_is_ret_type) {
(None, None) => {
let (main_label_1, span_label_1) = if ty_sup.id == ty_sub.id {
let (main_label_1, span_label_1) = if ty_sup.hir_id == ty_sub.hir_id {
(
"this type is declared with multiple lifetimes...".to_owned(),
"...but data with one lifetime flows into the other here".to_owned()

View file

@ -7,7 +7,7 @@ use crate::infer::{SubregionOrigin, TypeTrace};
use crate::traits::{ObligationCause, ObligationCauseCode};
use crate::ty;
use crate::ty::error::ExpectedFound;
use crate::ty::subst::Substs;
use crate::ty::subst::SubstsRef;
use crate::util::ppaux::RegionHighlightMode;
impl NiceRegionError<'me, 'gcx, 'tcx> {
@ -175,8 +175,8 @@ impl NiceRegionError<'me, 'gcx, 'tcx> {
sub_placeholder: Option<ty::Region<'tcx>>,
sup_placeholder: Option<ty::Region<'tcx>>,
trait_def_id: DefId,
expected_substs: &'tcx Substs<'tcx>,
actual_substs: &'tcx Substs<'tcx>,
expected_substs: SubstsRef<'tcx>,
actual_substs: SubstsRef<'tcx>,
) -> DiagnosticBuilder<'me> {
debug!(
"try_report_placeholders_trait(\

View file

@ -18,7 +18,7 @@ use crate::traits::{self, ObligationCause, PredicateObligations, TraitEngine};
use crate::ty::error::{ExpectedFound, TypeError, UnconstrainedNumeric};
use crate::ty::fold::TypeFoldable;
use crate::ty::relate::RelateResult;
use crate::ty::subst::{Kind, Substs};
use crate::ty::subst::{Kind, InternalSubsts, SubstsRef};
use crate::ty::{self, GenericParamDefKind, Ty, TyCtxt, CtxtInterners};
use crate::ty::{FloatVid, IntVid, TyVid};
use crate::util::nodemap::FxHashMap;
@ -656,7 +656,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
type_variables
.unsolved_variables()
.into_iter()
.map(|t| self.tcx.mk_var(t))
.map(|t| self.tcx.mk_ty_var(t))
.chain(
(0..int_unification_table.len())
.map(|i| ty::IntVid { index: i as u32 })
@ -981,7 +981,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
}
pub fn next_ty_var(&self, origin: TypeVariableOrigin) -> Ty<'tcx> {
self.tcx.mk_var(self.next_ty_var_id(false, origin))
self.tcx.mk_ty_var(self.next_ty_var_id(false, origin))
}
pub fn next_ty_var_in_universe(
@ -992,11 +992,11 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
let vid = self.type_variables
.borrow_mut()
.new_var(universe, false, origin);
self.tcx.mk_var(vid)
self.tcx.mk_ty_var(vid)
}
pub fn next_diverging_ty_var(&self, origin: TypeVariableOrigin) -> Ty<'tcx> {
self.tcx.mk_var(self.next_ty_var_id(true, origin))
self.tcx.mk_ty_var(self.next_ty_var_id(true, origin))
}
pub fn next_int_var_id(&self) -> IntVid {
@ -1081,15 +1081,18 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
TypeVariableOrigin::TypeParameterDefinition(span, param.name),
);
self.tcx.mk_var(ty_var_id).into()
self.tcx.mk_ty_var(ty_var_id).into()
}
GenericParamDefKind::Const { .. } => {
unimplemented!() // FIXME(const_generics)
}
}
}
/// Given a set of generics defined on a type or impl, returns a substitution mapping each
/// type/region parameter to a fresh inference variable.
pub fn fresh_substs_for_item(&self, span: Span, def_id: DefId) -> &'tcx Substs<'tcx> {
Substs::for_item(self.tcx, def_id, |param, _| self.var_for_def(span, param))
pub fn fresh_substs_for_item(&self, span: Span, def_id: DefId) -> SubstsRef<'tcx> {
InternalSubsts::for_item(self.tcx, def_id, |param, _| self.var_for_def(span, param))
}
/// Returns `true` if errors have been reported since this infcx was

View file

@ -310,7 +310,7 @@ where
ty::Projection(projection_ty)
if D::normalization() == NormalizationStrategy::Lazy =>
{
return Ok(self.relate_projection_ty(projection_ty, self.infcx.tcx.mk_var(vid)));
return Ok(self.relate_projection_ty(projection_ty, self.infcx.tcx.mk_ty_var(vid)));
}
_ => (),
@ -764,7 +764,7 @@ where
// the universe `_universe`.
let new_var_id = variables.new_var(self.universe, false, origin);
let u = self.tcx().mk_var(new_var_id);
let u = self.tcx().mk_ty_var(new_var_id);
debug!(
"generalize: replacing original vid={:?} with new={:?}",
vid,

View file

@ -4,12 +4,11 @@ use crate::hir::Node;
use crate::infer::{self, InferCtxt, InferOk, TypeVariableOrigin};
use crate::infer::outlives::free_region_map::FreeRegionRelations;
use rustc_data_structures::fx::FxHashMap;
use syntax::ast;
use crate::traits::{self, PredicateObligation};
use crate::ty::{self, Ty, TyCtxt, GenericParamDefKind};
use crate::ty::fold::{BottomUpFolder, TypeFoldable, TypeFolder};
use crate::ty::outlives::Component;
use crate::ty::subst::{Kind, Substs, UnpackedKind};
use crate::ty::subst::{Kind, InternalSubsts, SubstsRef, UnpackedKind};
use crate::util::nodemap::DefIdMap;
pub type OpaqueTypeMap<'tcx> = DefIdMap<OpaqueTypeDecl<'tcx>>;
@ -30,7 +29,7 @@ pub struct OpaqueTypeDecl<'tcx> {
/// fn foo<'a, 'b, T>() -> Foo<'a, T>
///
/// then `substs` would be `['a, T]`.
pub substs: &'tcx Substs<'tcx>,
pub substs: SubstsRef<'tcx>,
/// The type variable that represents the value of the abstract type
/// that we require. In other words, after we compile this function,
@ -381,10 +380,15 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
substs,
item_def_id: _,
}) => {
for r in substs.regions() {
bound_region(r);
for k in substs {
match k.unpack() {
UnpackedKind::Lifetime(lt) => bound_region(lt),
UnpackedKind::Type(ty) => types.push(ty),
UnpackedKind::Const(_) => {
// Const parameters don't impose constraints.
}
}
}
types.extend(substs.types());
}
Component::EscapingProjection(more_components) => {
@ -437,7 +441,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
// lifetimes with 'static and remapping only those used in the
// `impl Trait` return type, resulting in the parameters
// shifting.
let id_substs = Substs::identity_for_item(gcx, def_id);
let id_substs = InternalSubsts::identity_for_item(gcx, def_id);
let map: FxHashMap<Kind<'tcx>, Kind<'gcx>> = opaque_defn
.substs
.iter()
@ -681,13 +685,14 @@ impl<'a, 'gcx, 'tcx> Instantiator<'a, 'gcx, 'tcx> {
// let x = || foo(); // returns the Opaque assoc with `foo`
// }
// ```
if let Some(opaque_node_id) = tcx.hir().as_local_node_id(def_id) {
if let Some(opaque_hir_id) = tcx.hir().as_local_hir_id(def_id) {
let parent_def_id = self.parent_def_id;
let def_scope_default = || {
let opaque_parent_node_id = tcx.hir().get_parent(opaque_node_id);
parent_def_id == tcx.hir().local_def_id(opaque_parent_node_id)
let opaque_parent_hir_id = tcx.hir().get_parent_item(opaque_hir_id);
parent_def_id == tcx.hir()
.local_def_id_from_hir_id(opaque_parent_hir_id)
};
let in_definition_scope = match tcx.hir().find(opaque_node_id) {
let in_definition_scope = match tcx.hir().find_by_hir_id(opaque_hir_id) {
Some(Node::Item(item)) => match item.node {
// impl trait
hir::ItemKind::Existential(hir::ExistTy {
@ -701,7 +706,7 @@ impl<'a, 'gcx, 'tcx> Instantiator<'a, 'gcx, 'tcx> {
}) => may_define_existential_type(
tcx,
self.parent_def_id,
opaque_node_id,
opaque_hir_id,
),
_ => def_scope_default(),
},
@ -709,13 +714,13 @@ impl<'a, 'gcx, 'tcx> Instantiator<'a, 'gcx, 'tcx> {
hir::ImplItemKind::Existential(_) => may_define_existential_type(
tcx,
self.parent_def_id,
opaque_node_id,
opaque_hir_id,
),
_ => def_scope_default(),
},
_ => bug!(
"expected (impl) item, found {}",
tcx.hir().node_to_string(opaque_node_id),
tcx.hir().hir_to_string(opaque_hir_id),
),
};
if in_definition_scope {
@ -740,7 +745,7 @@ impl<'a, 'gcx, 'tcx> Instantiator<'a, 'gcx, 'tcx> {
&mut self,
ty: Ty<'tcx>,
def_id: DefId,
substs: &'tcx Substs<'tcx>,
substs: SubstsRef<'tcx>,
) -> Ty<'tcx> {
let infcx = self.infcx;
let tcx = infcx.tcx;
@ -834,20 +839,20 @@ impl<'a, 'gcx, 'tcx> Instantiator<'a, 'gcx, 'tcx> {
pub fn may_define_existential_type(
tcx: TyCtxt<'_, '_, '_>,
def_id: DefId,
opaque_node_id: ast::NodeId,
opaque_hir_id: hir::HirId,
) -> bool {
let mut node_id = tcx
let mut hir_id = tcx
.hir()
.as_local_node_id(def_id)
.as_local_hir_id(def_id)
.unwrap();
// named existential types can be defined by any siblings or
// children of siblings
let mod_id = tcx.hir().get_parent(opaque_node_id);
let mod_id = tcx.hir().get_parent_item(opaque_hir_id);
// so we walk up the node tree until we hit the root or the parent
// of the opaque type
while node_id != mod_id && node_id != ast::CRATE_NODE_ID {
node_id = tcx.hir().get_parent(node_id);
while hir_id != mod_id && hir_id != hir::CRATE_HIR_ID {
hir_id = tcx.hir().get_parent_item(hir_id);
}
// syntactically we are allowed to define the concrete type
node_id == mod_id
hir_id == mod_id
}

View file

@ -67,6 +67,7 @@ use crate::hir;
use crate::traits::ObligationCause;
use crate::ty::outlives::Component;
use crate::ty::{self, Region, Ty, TyCtxt, TypeFoldable};
use crate::ty::subst::UnpackedKind;
impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
/// Registers that the given region obligation must be resolved
@ -430,13 +431,18 @@ where
if approx_env_bounds.is_empty() && trait_bounds.is_empty() && needs_infer {
debug!("projection_must_outlive: no declared bounds");
for component_ty in projection_ty.substs.types() {
self.type_must_outlive(origin.clone(), component_ty, region);
}
for r in projection_ty.substs.regions() {
self.delegate
.push_sub_region_constraint(origin.clone(), region, r);
for k in projection_ty.substs {
match k.unpack() {
UnpackedKind::Lifetime(lt) => {
self.delegate.push_sub_region_constraint(origin.clone(), region, lt);
}
UnpackedKind::Type(ty) => {
self.type_must_outlive(origin.clone(), ty, region);
}
UnpackedKind::Const(_) => {
// Const parameters don't impose constraints.
}
}
}
return;

View file

@ -2,7 +2,7 @@ use crate::hir::def_id::DefId;
use crate::infer::outlives::env::RegionBoundPairs;
use crate::infer::{GenericKind, VerifyBound};
use crate::traits;
use crate::ty::subst::{Subst, Substs};
use crate::ty::subst::{Subst, InternalSubsts};
use crate::ty::{self, Ty, TyCtxt};
use crate::util::captures::Captures;
@ -292,7 +292,7 @@ impl<'cx, 'gcx, 'tcx> VerifyBoundCx<'cx, 'gcx, 'tcx> {
.iter()
.map(|(p, _)| *p)
.collect();
let identity_substs = Substs::identity_for_item(tcx, assoc_item_def_id);
let identity_substs = InternalSubsts::identity_for_item(tcx, assoc_item_def_id);
let identity_proj = tcx.mk_projection(assoc_item_def_id, identity_substs);
self.collect_outlives_from_predicate_list(
move |ty| ty == identity_proj,

View file

@ -141,14 +141,8 @@ pub mod util {
pub mod bug;
}
// A private module so that macro-expanded idents like
// `::rustc::lint::Lint` will also work in `rustc` itself.
//
// `libstd` uses the same trick.
#[doc(hidden)]
mod rustc {
pub use crate::lint;
}
// Allows macros to refer to this crate as `::rustc`
extern crate self as rustc;
// FIXME(#27438): right now the unit tests of librustc don't refer to any actual
// functions generated in librustc_data_structures (all

View file

@ -386,6 +386,12 @@ declare_lint! {
"ambiguous associated items"
}
declare_lint! {
pub NESTED_IMPL_TRAIT,
Warn,
"nested occurrence of `impl Trait` type"
}
/// Does nothing as a lint pass, but registers some `Lint`s
/// that are used by other parts of the compiler.
#[derive(Copy, Clone)]
@ -457,6 +463,7 @@ impl LintPass for HardwiredLints {
parser::ILL_FORMED_ATTRIBUTE_INPUT,
DEPRECATED_IN_FUTURE,
AMBIGUOUS_ASSOCIATED_ITEMS,
NESTED_IMPL_TRAIT,
)
}
}
@ -474,6 +481,7 @@ pub enum BuiltinLintDiagnostics {
ElidedLifetimesInPaths(usize, Span, bool, Span, String),
UnknownCrateTypes(Span, String, String),
UnusedImports(String, Vec<(Span, String)>),
NestedImplTrait { outer_impl_trait_span: Span, inner_impl_trait_span: Span },
}
impl BuiltinLintDiagnostics {
@ -564,6 +572,12 @@ impl BuiltinLintDiagnostics {
);
}
}
BuiltinLintDiagnostics::NestedImplTrait {
outer_impl_trait_span, inner_impl_trait_span
} => {
db.span_label(outer_impl_trait_span, "outer `impl Trait`");
db.span_label(inner_impl_trait_span, "nested `impl Trait` here");
}
}
}
}

View file

@ -729,8 +729,7 @@ impl<'a, 'tcx> LintContext<'tcx> for LateContext<'a, 'tcx> {
match span {
Some(s) => self.tcx.struct_span_lint_hir(lint, hir_id, s, msg),
None => {
let node_id = self.tcx.hir().hir_to_node_id(hir_id); // FIXME(@ljedrz): remove later
self.tcx.struct_lint_node(lint, node_id, msg)
self.tcx.struct_lint_node(lint, hir_id, msg)
},
}
}
@ -793,11 +792,11 @@ impl<'a, 'tcx> LateContext<'a, 'tcx> {
run_lints!(self, exit_lint_attrs, attrs);
}
fn with_param_env<F>(&mut self, id: ast::NodeId, f: F)
fn with_param_env<F>(&mut self, id: hir::HirId, f: F)
where F: FnOnce(&mut Self),
{
let old_param_env = self.param_env;
self.param_env = self.tcx.param_env(self.tcx.hir().local_def_id(id));
self.param_env = self.tcx.param_env(self.tcx.hir().local_def_id_from_hir_id(id));
f(self);
self.param_env = old_param_env;
}
@ -841,7 +840,7 @@ impl<'a, 'tcx> hir_visit::Visitor<'tcx> for LateContext<'a, 'tcx> {
let generics = self.generics.take();
self.generics = it.node.generics();
self.with_lint_attrs(it.hir_id, &it.attrs, |cx| {
cx.with_param_env(it.id, |cx| {
cx.with_param_env(it.hir_id, |cx| {
run_lints!(cx, check_item, it);
hir_visit::walk_item(cx, it);
run_lints!(cx, check_item_post, it);
@ -852,7 +851,7 @@ impl<'a, 'tcx> hir_visit::Visitor<'tcx> for LateContext<'a, 'tcx> {
fn visit_foreign_item(&mut self, it: &'tcx hir::ForeignItem) {
self.with_lint_attrs(it.hir_id, &it.attrs, |cx| {
cx.with_param_env(it.id, |cx| {
cx.with_param_env(it.hir_id, |cx| {
run_lints!(cx, check_foreign_item, it);
hir_visit::walk_foreign_item(cx, it);
run_lints!(cx, check_foreign_item_post, it);
@ -983,7 +982,7 @@ impl<'a, 'tcx> hir_visit::Visitor<'tcx> for LateContext<'a, 'tcx> {
let generics = self.generics.take();
self.generics = Some(&trait_item.generics);
self.with_lint_attrs(trait_item.hir_id, &trait_item.attrs, |cx| {
cx.with_param_env(trait_item.id, |cx| {
cx.with_param_env(trait_item.hir_id, |cx| {
run_lints!(cx, check_trait_item, trait_item);
hir_visit::walk_trait_item(cx, trait_item);
run_lints!(cx, check_trait_item_post, trait_item);
@ -996,7 +995,7 @@ impl<'a, 'tcx> hir_visit::Visitor<'tcx> for LateContext<'a, 'tcx> {
let generics = self.generics.take();
self.generics = Some(&impl_item.generics);
self.with_lint_attrs(impl_item.hir_id, &impl_item.attrs, |cx| {
cx.with_param_env(impl_item.id, |cx| {
cx.with_param_env(impl_item.hir_id, |cx| {
run_lints!(cx, check_impl_item, impl_item);
hir_visit::walk_impl_item(cx, impl_item);
run_lints!(cx, check_impl_item_post, impl_item);

View file

@ -132,14 +132,22 @@ macro_rules! declare_lint {
#[macro_export]
macro_rules! declare_tool_lint {
($vis: vis $tool: ident ::$NAME: ident, $Level: ident, $desc: expr) => (
declare_tool_lint!{$vis $tool::$NAME, $Level, $desc, false}
(
$(#[$attr:meta])* $vis:vis $tool:ident ::$NAME:ident, $Level: ident, $desc: expr
) => (
declare_tool_lint!{$(#[$attr])* $vis $tool::$NAME, $Level, $desc, false}
);
($vis: vis $tool: ident ::$NAME: ident, $Level: ident, $desc: expr,
report_in_external_macro: $rep: expr) => (
declare_tool_lint!{$vis $tool::$NAME, $Level, $desc, $rep}
(
$(#[$attr:meta])* $vis:vis $tool:ident ::$NAME:ident, $Level:ident, $desc:expr,
report_in_external_macro: $rep:expr
) => (
declare_tool_lint!{$(#[$attr])* $vis $tool::$NAME, $Level, $desc, $rep}
);
($vis: vis $tool: ident ::$NAME: ident, $Level: ident, $desc: expr, $external: expr) => (
(
$(#[$attr:meta])* $vis:vis $tool:ident ::$NAME:ident, $Level:ident, $desc:expr,
$external:expr
) => (
$(#[$attr])*
$vis static $NAME: &$crate::lint::Lint = &$crate::lint::Lint {
name: &concat!(stringify!($tool), "::", stringify!($NAME)),
default_level: $crate::lint::$Level,
@ -723,7 +731,7 @@ fn lint_levels<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, cnum: CrateNum)
};
let krate = tcx.hir().krate();
builder.with_lint_attrs(ast::CRATE_NODE_ID, &krate.attrs, |builder| {
builder.with_lint_attrs(hir::CRATE_HIR_ID, &krate.attrs, |builder| {
intravisit::walk_crate(builder, krate);
});
@ -737,13 +745,13 @@ struct LintLevelMapBuilder<'a, 'tcx: 'a> {
impl<'a, 'tcx> LintLevelMapBuilder<'a, 'tcx> {
fn with_lint_attrs<F>(&mut self,
id: ast::NodeId,
id: hir::HirId,
attrs: &[ast::Attribute],
f: F)
where F: FnOnce(&mut Self)
{
let push = self.levels.push(attrs);
self.levels.register_id(self.tcx.hir().definitions().node_to_hir_id(id));
self.levels.register_id(id);
f(self);
self.levels.pop(push);
}
@ -755,25 +763,25 @@ impl<'a, 'tcx> intravisit::Visitor<'tcx> for LintLevelMapBuilder<'a, 'tcx> {
}
fn visit_item(&mut self, it: &'tcx hir::Item) {
self.with_lint_attrs(it.id, &it.attrs, |builder| {
self.with_lint_attrs(it.hir_id, &it.attrs, |builder| {
intravisit::walk_item(builder, it);
});
}
fn visit_foreign_item(&mut self, it: &'tcx hir::ForeignItem) {
self.with_lint_attrs(it.id, &it.attrs, |builder| {
self.with_lint_attrs(it.hir_id, &it.attrs, |builder| {
intravisit::walk_foreign_item(builder, it);
})
}
fn visit_expr(&mut self, e: &'tcx hir::Expr) {
self.with_lint_attrs(e.id, &e.attrs, |builder| {
self.with_lint_attrs(e.hir_id, &e.attrs, |builder| {
intravisit::walk_expr(builder, e);
})
}
fn visit_struct_field(&mut self, s: &'tcx hir::StructField) {
self.with_lint_attrs(s.id, &s.attrs, |builder| {
self.with_lint_attrs(s.hir_id, &s.attrs, |builder| {
intravisit::walk_struct_field(builder, s);
})
}
@ -782,25 +790,25 @@ impl<'a, 'tcx> intravisit::Visitor<'tcx> for LintLevelMapBuilder<'a, 'tcx> {
v: &'tcx hir::Variant,
g: &'tcx hir::Generics,
item_id: hir::HirId) {
self.with_lint_attrs(v.node.data.id(), &v.node.attrs, |builder| {
self.with_lint_attrs(v.node.data.hir_id(), &v.node.attrs, |builder| {
intravisit::walk_variant(builder, v, g, item_id);
})
}
fn visit_local(&mut self, l: &'tcx hir::Local) {
self.with_lint_attrs(l.id, &l.attrs, |builder| {
self.with_lint_attrs(l.hir_id, &l.attrs, |builder| {
intravisit::walk_local(builder, l);
})
}
fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem) {
self.with_lint_attrs(trait_item.id, &trait_item.attrs, |builder| {
self.with_lint_attrs(trait_item.hir_id, &trait_item.attrs, |builder| {
intravisit::walk_trait_item(builder, trait_item);
});
}
fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem) {
self.with_lint_attrs(impl_item.id, &impl_item.attrs, |builder| {
self.with_lint_attrs(impl_item.hir_id, &impl_item.attrs, |builder| {
intravisit::walk_impl_item(builder, impl_item);
});
}

Some files were not shown because too many files have changed in this diff Show more