Merge remote-tracking branch 'upstream/master' into asm-compile-tests
This commit is contained in:
commit
eeb5f171da
3937 changed files with 27996 additions and 23185 deletions
1
.mailmap
1
.mailmap
|
@ -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>
|
||||
|
|
173
Cargo.lock
173
Cargo.lock
|
@ -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"
|
||||
|
|
44
RELEASES.md
44
RELEASES.md
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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>,
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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>,
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -91,7 +91,8 @@ impl Step for ToolBuild {
|
|||
compile::CargoMessage::CompilerArtifact {
|
||||
package_id,
|
||||
features,
|
||||
filenames
|
||||
filenames,
|
||||
target: _,
|
||||
} => {
|
||||
(package_id, features, filenames)
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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.
|
||||
|
|
24
src/doc/unstable-book/src/language-features/c-variadic.md
Normal file
24
src/doc/unstable-book/src/language-features/c-variadic.md
Normal 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
|
||||
}
|
||||
```
|
26
src/doc/unstable-book/src/library-features/c-variadic.md
Normal file
26
src/doc/unstable-book/src/library-features/c-variadic.md
Normal 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
|
||||
}
|
||||
```
|
|
@ -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)
|
||||
|
|
|
@ -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())) }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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")]
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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()
|
||||
})
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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) }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 function’s 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 language’s 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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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 })
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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`.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
///
|
||||
|
|
|
@ -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.
|
||||
///
|
||||
|
|
|
@ -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.
|
||||
///
|
||||
/// ```
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -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 } }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -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}, {}}
|
||||
|
|
|
@ -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
|
||||
///
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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]");
|
||||
}
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
#![feature(str_internals)]
|
||||
#![feature(test)]
|
||||
#![feature(trusted_len)]
|
||||
#![feature(try_from)]
|
||||
#![feature(try_trait)]
|
||||
#![feature(align_offset)]
|
||||
#![feature(reverse_bits)]
|
||||
|
|
|
@ -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" }
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
@ -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"),
|
||||
|
|
|
@ -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[¯o_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));
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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(),
|
||||
},
|
||||
|
|
|
@ -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
|
||||
});
|
|
@ -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
|
||||
});
|
||||
|
|
|
@ -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 });
|
|
@ -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
|
@ -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;
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -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,);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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(\
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
Loading…
Add table
Reference in a new issue